> ## Documentation Index
> Fetch the complete documentation index at: https://docs.callers.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Subaccounts and SIP

> Create and manage subaccounts, act on their behalf with one API key, roll out agents and voices, and connect SIP carriers and numbers through the API.

Agencies and platforms use subaccounts to give each client an isolated workspace: separate agents, contacts, phone numbers, and results. With the API you can create a subaccount for each new client, copy your template agents into it, connect the client's SIP trunk, and operate everything with your main account's API key.

See [Managing subaccounts](https://docs.callers.ai/documentation/agencies/managing-subaccounts.md) for the dashboard side and [SIP](https://docs.callers.ai/documentation/integrations/sip.md) for SIP concepts.

<ol />

## Act on a subaccount

Send the subaccount's ID in the `x-sub-organization-id` header with your main account's key. Every endpoint then behaves as if the subaccount made the request.

```bash theme={"dark"}
curl https://api.callers.ai/organization \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "x-sub-organization-id: $SUBACCOUNT_ID"
```

If the ID isn't one of your subaccounts, the request fails with `403 Forbidden resource`; it never falls back to your main account. Subaccounts can also have their own API keys if you enable API key management for them.

## List your account and subaccounts

`GET /organization` returns an array: the key's own account first, followed by its subaccounts.

```bash cURL theme={"dark"}
curl https://api.callers.ai/organization \
  -H "Authorization: $CALLERS_API_KEY"
```

```javascript Node.js theme={"dark"}
const res = await fetch("https://api.callers.ai/organization", {
  headers: { Authorization: process.env.CALLERS_API_KEY },
});
const { data } = await res.json();
const [main, ...subaccounts] = data;
```

```python Python theme={"dark"}
main, *subaccounts = requests.get(
    "https://api.callers.ai/organization",
    headers={"Authorization": os.environ["CALLERS_API_KEY"]},
).json()["data"]
```

```json Response theme={"dark"}
{
  "status": "success",
  "data": [
    { "id": "6650a0a0a1b2c3d4e5f60001", "name": "Acme Agency", "createdAt": "2025-02-01T09:00:00.000Z", "parentOrgId": null },
    { "id": "6650a0a0a1b2c3d4e5f60002", "name": "Client - Globex", "createdAt": "2026-06-12T14:30:00.000Z", "parentOrgId": "6650a0a0a1b2c3d4e5f60001" }
  ]
}
```

## Create a subaccount

`POST /organization/sub-organization` returns `{ "id": "…" }` with status `201`.

**name** `string` *required*

Subaccount name.

**retryAttemptsMaxValue** `number` *required*

The highest **Total Dial Attempts** value agents in this subaccount can use (1–10).

**permissions** `string[]`

Features to turn on for the subaccount. Values: `permission_enable_voip_and_phones`, `permission_enable_view_and_select_phone_numbers`, `permission_enable_manage_members`, `permission_enable_analytics`, `permission_enable_api_keys`, `permission_enable_twilio_integration`, `permission_enable_telnyx_integration`, `permission_enable_sip_integration`, `permission_enable_whatsapp_integration`, `permission_enable_cal_com_integration`, `permission_enable_slack_integration`, `permission_enable_limit_concurrent_calls`, `permission_enable_scan_spam_phone_numbers`, `permission_enable_sensitive_content_restriction`, `permission_enable_studio_chat`, `permission_enable_mfa`.

**webhooks** `object[]`

Account-level webhooks that fire for every agent in the subaccount. Each item has a `url` (HTTPS) and `events` (defaults to the five main outcome events). See [Webhooks overview](https://docs.callers.ai/documentation/webhook/webhook-overview.md#account-level-webhooks).

```bash cURL theme={"dark"}
curl -X POST https://api.callers.ai/organization/sub-organization \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Client - Globex",
    "retryAttemptsMaxValue": 5,
    "permissions": ["permission_enable_analytics", "permission_enable_view_and_select_phone_numbers"],
    "webhooks": [
      { "url": "https://example.com/callers/globex", "events": ["CALL_FINISHED"] }
    ]
  }'
```

```javascript Node.js theme={"dark"}
const res = await fetch("https://api.callers.ai/organization/sub-organization", {
  method: "POST",
  headers: {
    Authorization: process.env.CALLERS_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Client - Globex",
    retryAttemptsMaxValue: 5,
    permissions: ["permission_enable_analytics", "permission_enable_view_and_select_phone_numbers"],
    webhooks: [{ url: "https://example.com/callers/globex", events: ["CALL_FINISHED"] }],
  }),
});
const { data } = await res.json();
const subaccountId = data.id;
```

```python Python theme={"dark"}
subaccount_id = requests.post(
    "https://api.callers.ai/organization/sub-organization",
    headers={"Authorization": os.environ["CALLERS_API_KEY"]},
    json={
        "name": "Client - Globex",
        "retryAttemptsMaxValue": 5,
        "permissions": ["permission_enable_analytics", "permission_enable_view_and_select_phone_numbers"],
        "webhooks": [{"url": "https://example.com/callers/globex", "events": ["CALL_FINISHED"]}],
    },
).json()["data"]["id"]
```

## Roll out agents and voices

1. **Voices.** Create voices with `"subAccounts": true` (`POST /voices` or `POST /voices/voice-clone`) to add them to every subaccount at once. See [Voices and cloning](https://docs.callers.ai/api-reference/guides/voices-and-cloning.md).

2. **Agents.** Duplicate a template agent into the subaccount:

   ```bash theme={"dark"}
   curl -X POST "https://api.callers.ai/agents/$TEMPLATE_AGENT_ID/duplicate?toOrganizationId=$SUBACCOUNT_ID&name=Globex%20renewals" \
     -H "Authorization: $CALLERS_API_KEY"
   ```

3. **Per-client settings.** Update the copy's phone numbers and webhooks as the subaccount:

   ```bash theme={"dark"}
   curl -X PATCH "https://api.callers.ai/agents/$NEW_AGENT_ID" \
     -H "Authorization: $CALLERS_API_KEY" \
     -H "x-sub-organization-id: $SUBACCOUNT_ID" \
     -H "Content-Type: application/json" \
     -d '{"phoneNumbers": ["+14155552671"]}'
   ```

4. **Contacts and calls.** Use the normal contact and call endpoints with the `x-sub-organization-id` header.

## Delete a subaccount

`DELETE /organization/{id}` deletes one of your subaccounts.

> [!WARNING]
>
> Deleting a subaccount stops and archives all of its agents and contacts, disconnects its telephony provider accounts, and deletes its voices and API keys. This can't be undone from the API. Export anything you need first.

## Connect a SIP carrier

Bring your own carrier by creating a SIP connection in the account (send `x-sub-organization-id` to create it in a subaccount). `POST /organization/sip` returns `{ "id": "…" }`.

| Field | Default | Description |
| - | - | - |
| `name` | — | Required. Connection name. |
| `gateways[]` | One outbound UDP gateway on port 5060 | Your carrier's SIP gateways. Each has `ipv4` (required), `port` (default `5060`), `protocol` (`udp`, `tcp`, `tls`, `tls/srtp`; default `udp`), `netmask` (1–32, default `32`), `inbound`, `outbound`. |
| `requires_register` | `false` | Set to `true` if the carrier requires SIP registration, and send `register_username`, `register_password`, and optionally `register_sip_realm`, `register_from_user`, `register_from_domain`, `register_public_ip_in_contact`. |
| `e164_leading_plus` | `false` | Send numbers to the carrier with a leading `+`. |
| `tech_prefix` | — | Prefix the carrier requires before dialed numbers. |
| `diversion` | — | Diversion header value. |
| `outbound_sip_proxy` | — | Outbound proxy address. |
| `cps` | `10` | Maximum calls per second to the carrier (0.1–1000). |
| `phoneNumbers[]` | `[]` | Numbers on this trunk: `[{ "phone_number": "14155552671" }]`. |

```bash cURL theme={"dark"}
curl -X POST https://api.callers.ai/organization/sip \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "x-sub-organization-id: $SUBACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Globex carrier",
    "gateways": [
      { "ipv4": "203.0.113.10", "port": 5060, "protocol": "udp", "outbound": true, "inbound": true }
    ],
    "e164_leading_plus": true,
    "phoneNumbers": [{ "phone_number": "14155552671" }]
  }'
```

```javascript Node.js theme={"dark"}
const res = await fetch("https://api.callers.ai/organization/sip", {
  method: "POST",
  headers: {
    Authorization: process.env.CALLERS_API_KEY,
    "x-sub-organization-id": subaccountId,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Globex carrier",
    gateways: [{ ipv4: "203.0.113.10", port: 5060, protocol: "udp", outbound: true, inbound: true }],
    e164_leading_plus: true,
    phoneNumbers: [{ phone_number: "14155552671" }],
  }),
});
const { data } = await res.json(); // { id }
```

```python Python theme={"dark"}
sip_id = requests.post(
    "https://api.callers.ai/organization/sip",
    headers={
        "Authorization": os.environ["CALLERS_API_KEY"],
        "x-sub-organization-id": subaccount_id,
    },
    json={
        "name": "Globex carrier",
        "gateways": [{"ipv4": "203.0.113.10", "port": 5060, "protocol": "udp", "outbound": True, "inbound": True}],
        "e164_leading_plus": True,
        "phoneNumbers": [{"phone_number": "14155552671"}],
    },
).json()["data"]["id"]
```

### Add numbers to a SIP connection

* `GET /organization/sip-list` lists SIP connections (`id`, `name`, `createdAt`).
* `POST /organization/{sipId}/phone-number` with `{ "phoneNumbers": ["14155552672", "+442071234567"] }` adds numbers and returns `{ requested, added }`.

```bash theme={"dark"}
curl -X POST "https://api.callers.ai/organization/$SIP_ID/phone-number" \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumbers": ["14155552672"]}'
```

Once added, assign the numbers to agents with `PATCH /agents/{agentId}` (`phoneNumbers`).

> [!NOTE]
>
> If SIP telephony isn't available on your account, these requests are rejected. Contact [support@callers.ai](mailto:support@callers.ai).

## Play a warm-transfer summary

For calls that run over SIP, `POST /call/{sessionId}/warm-transfer-summary` plays the AI-generated handoff summary on a transferred call. Use the call's `sessionId` (included in webhook payloads). Send `{ "agentOnly": true }` to play it only to the person receiving the transfer. See [Call transfers](https://docs.callers.ai/documentation/voice/call-transfers.md).

```bash theme={"dark"}
curl -X POST "https://api.callers.ai/call/$SESSION_ID/warm-transfer-summary" \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agentOnly": true}'
```

## Set recording retention

`POST /organization/set-recording-retention` sets how many days call recordings are kept. Set `subAccounts: true` to apply the same period to all your subaccounts.

```bash theme={"dark"}
curl -X POST https://api.callers.ai/organization/set-recording-retention \
  -H "Authorization: $CALLERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"retentionConfig": {"retentionDays": 90, "subAccounts": true}}'
```

`retentionDays` must be at least 1. With `subAccounts: true` and no subaccounts, the request returns `400`. See [Security and privacy](https://docs.callers.ai/documentation/account/security-and-privacy.md).

## Troubleshooting

> **403 Forbidden resource with x-sub-organization-id**
>
> The ID isn't a subaccount of the key's account, or it's mistyped. List your subaccounts with `GET /organization`.

> **404 Campaign not found on a subaccount agent**
>
> You're acting on the wrong account. Add `x-sub-organization-id` for agents that live in a subaccount.

> **Duplicating an agent into a subaccount fails**
>
> The subaccount may have reached its agent limit, or `toOrganizationId` isn't one of your subaccounts.

## Related

> **[Managing subaccounts](https://docs.callers.ai/documentation/agencies/managing-subaccounts.md)**
>
> Subaccounts in the dashboard.

> **[White label](https://docs.callers.ai/documentation/agencies/white-label.md)**
>
> Your brand and domain for clients.

> **[SIP](https://docs.callers.ai/documentation/integrations/sip.md)**
>
> SIP trunk concepts and carrier setup.

> **[Manage agents](https://docs.callers.ai/api-reference/guides/manage-agents.md)**
>
> Duplicate and update agents.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.