# Organizations

> Organization and member management API

Source: https://docs.soosh.io/reference/api/organizations/

## Overview

Soosh is multi-tenant — each organization has its own isolated data (contacts, conversations, templates, etc.). Users can belong to multiple organizations with different roles in each.

## List Organizations

Retrieve all organizations. Requires a platform super administrator. Tenant members use `GET /api/me/organizations` for their own memberships.

`GET /api/organizations`

### Response

```json
{
  "status": "success",
  "data": {
    "organizations": [
      {
        "id": "uuid",
        "name": "Acme Corp",
        "slug": "acme-corp-a1b2c3d4",
        "created_at": "2024-01-01T00:00:00Z"
      }
    ]
  }
}
```

## Get Current Organization

Retrieve the current organization's details.

`GET /api/organizations/current`

### Response

```json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "name": "Acme Corp",
    "slug": "acme-corp-a1b2c3d4",
    "created_at": "2024-01-01T00:00:00Z"
  }
}
```

## Create Organization

Create a new organization. The creator is automatically added as an admin. System roles (Admin, Manager, Agent) and default chatbot settings are seeded automatically.

`POST /api/organizations`

> **Note:** Requires a platform super administrator.

### Request Body

```json
{
  "name": "New Organization",
  "features": { "chat": true, "chat.assign": true, "contacts": true }
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Organization name |
| `features` | object | No | Boolean component allocations, keyed by component. Omitted components are unavailable; unknown, required and grouped module keys are rejected, and so is a component without a component it requires (`400`). |

### Response

```json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "name": "New Organization",
    "slug": "new-organization-a1b2c3d4",
    "created_at": "2024-01-01T00:00:00Z"
  }
}
```

## Component Allocations

`GET /api/org/features` returns the active organization's `features` (each allocatable
component's allocation), the `components` catalog (key, label, description, section,
`required`, `platform`, `resources` and `requires`) and the allocation `version`. A
platform super administrator can read a specific organization with
`GET /api/organizations/{id}/features` and update it with:

```json
{
  "version": 1,
  "features": { "tags": false, "outgoing_calls": false }
}
```

Send updates to `PUT /api/organizations/{id}/features`. Only supplied components change.
The current version is required; stale updates return `409`. A component works only while
the components it requires are allocated: an update that leaves one on without them
returns `400` naming both. Disabling a component retains its records and role grants.
Retained grants become active when the component is enabled again. SSO is platform-wide
and cannot be changed through an organization allocation.

## Workspace Lifecycle (platform)

Platform super administrators close, reopen, delete and restore workspaces. Customers,
including the workspace Owner, cannot. Every change needs the `lifecycle_version` it was
reviewed against as `expected_version` (a stale one returns `409`), is recorded in the
workspace's audit log in the same transaction, and is idempotent: repeating a request that
already took effect changes nothing and returns `200`. A workspace that an active platform
administrator belongs to, or has as home workspace, can't be closed or deleted.

| Endpoint | Body | Notes |
| --- | --- | --- |
| `GET /api/admin/organizations/{id}/lifecycle` | | Works for deleted workspaces |
| `POST /api/admin/organizations/{id}/close` | `expected_version`, `confirm_name`, `reason` | |
| `POST /api/admin/organizations/{id}/reopen` | `expected_version`, `reason` (optional) | `409` while deleted |
| `POST /api/admin/organizations/{id}/delete` | `expected_version`, `confirm_name`, `reason` | Closes it too |
| `POST /api/admin/organizations/{id}/restore` | `expected_version`, `reason` | Leaves it closed |
| `GET /api/admin/organizations/deleted` | | Deleted workspaces, newest first |
| `GET /api/admin/organizations/{id}/audit-logs` | | `page`, `limit`; works for closed and deleted workspaces |

`confirm_name` must repeat the workspace name exactly. Each change returns the lifecycle:

```json
{
  "status": "success",
  "data": {
    "organization_id": "uuid",
    "name": "Acme Corp",
    "status": "closed",
    "lifecycle_version": 4,
    "closed_at": "2026-10-09T10:00:00Z",
    "closed_by": "Platform Admin",
    "closed_reason": "Account closed at the customer's request",
    "deleted": true,
    "deleted_at": "2026-10-09T10:00:00Z",
    "deleted_by": "Platform Admin",
    "deleted_reason": "Account closed at the customer's request",
    "paused_campaigns": 2
  }
}
```

`paused_campaigns` is the number of campaigns paused by the request. It is `0` when the
request changes no state, including repeated close, delete, or restore requests. The
field is omitted from the response when it is `0`.

**Deleting** soft-deletes the workspace and closes it. Nothing is removed: members, owner,
roles and grants, WhatsApp accounts, wallet and ledger, audit history and all workspace
data stay. A deleted workspace is left out of `GET /api/organizations` and of every
member's `GET /api/me/organizations`. Its members' sessions in it end (`401`), and its API
keys stop working. Its WhatsApp numbers stay reserved to it, so no other workspace can
connect them until it is restored and the numbers are removed there.

**Restoring** brings it back closed with everything it had. Reopen it separately.

`GET /api/admin/organizations/{id}/audit-logs` returns the workspace's
`organization_lifecycle`, `organization_owner`, `organization_member` and `wallet` audit
records in the same shape as `GET /api/audit-logs`.

## Organization Members

Manage which users have access to an organization. Members are users from other organizations who have been granted access with a specific role.

### List Members

Retrieve all members of the current organization.

`GET /api/organizations/members`

> **Note:** Requires `organizations:read` permission.

#### Query Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `search` | string | Filter by name or email |
| `page` | integer | Page number (default: 1) |
| `limit` | integer | Items per page (default: 50) |

#### Response

```json
{
  "status": "success",
  "data": {
    "members": [
      {
        "id": "uuid",
        "user_id": "uuid",
        "organization_id": "uuid",
        "role_id": "uuid",
        "role_name": "agent",
        "is_default": true,
        "email": "user@example.com",
        "full_name": "John Doe",
        "is_active": true,
        "created_at": "2024-01-01T00:00:00Z"
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 50
  }
}
```

### Add Member

Add an existing user to the organization. The user can be identified by `user_id` or `email`.

`POST /api/organizations/members`

> **Note:** Requires `organizations:assign` permission.

#### Request Body

```json
{
  "user_id": "uuid",
  "role_id": "uuid"
}
```

Or by email:

```json
{
  "email": "user@example.com",
  "role_id": "uuid"
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `user_id` | string | One of `user_id` or `email` | UUID of the user to add |
| `email` | string | One of `user_id` or `email` | Email of the user to add |
| `role_id` | string | No | Role to assign. If omitted, uses the organization's default role |

#### Response

```json
{
  "status": "success",
  "data": {
    "message": "Member added successfully"
  }
}
```

### Update Member Role

Change a member's role within the organization.

`PUT /api/organizations/members/{member_id}`

> **Note:** Requires `organizations:assign` permission. The `member_id` is the user's UUID.

#### Request Body

```json
{
  "role_id": "uuid"
}
```

#### Response

```json
{
  "status": "success",
  "data": {
    "message": "Member role updated successfully"
  }
}
```

### Remove Member

Remove a user from the organization. This only removes the membership — the user's account remains intact.

`DELETE /api/organizations/members/{member_id}`

> **Note:** Requires `organizations:assign` permission.

> **Careful:** You cannot remove yourself from the organization.

#### Response

```json
{
  "status": "success",
  "data": {
    "message": "Member removed successfully"
  }
}
```

## Organization Settings

### Get Settings

`GET /api/org/settings`

#### Response

```json
{
  "status": "success",
  "data": {
    "name": "Acme Corp",
    "settings": {
      "mask_phone_numbers": false,
      "timezone": "UTC",
      "date_format": "YYYY-MM-DD"
    }
  }
}
```

### Update Settings

`PUT /api/org/settings`

#### Request Body

```json
{
  "name": "Updated Name",
  "mask_phone_numbers": true,
  "timezone": "Asia/Kolkata",
  "date_format": "DD/MM/YYYY"
}
```

All fields are optional — only provided fields are updated.

### Upload Audio

Upload a hold-music or ringback audio file for the organization's calling features. The file is transcoded to OGG/Opus and the resulting filename is stored on the organization's settings (`hold_music_file` / `ringback_file`).

`POST /api/org/audio?type=hold_music`

> **Note:** Requires `organizations:write` permission. Send the file as `multipart/form-data` with a `file` field.

#### Query Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string | Yes | Either `hold_music` or `ringback` |

Accepted formats include OGG/Opus, MP3, and WAV. Maximum file size is 5 MB.

#### Response

```json
{
  "status": "success",
  "data": {
    "filename": "org_<uuid>_hold_music.ogg",
    "type": "hold_music",
    "mime_type": "audio/mpeg",
    "size": 204800
  }
}
```

## See Also

- [Authentication](https://docs.soosh.io/reference/api/authentication) - Organization switching via `POST /api/auth/switch-org`
- [Users](https://docs.soosh.io/reference/api/users) - User management within an organization
- [Roles & Permissions](https://docs.soosh.io/features/roles-permissions) - Permission system details
