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

# Settings API

> Workspace settings, API keys, and team membership

# Settings API

Workspace settings, API keys, and team membership

**Base path:** `/api/v1/settings`

**Endpoint count:** 9

***

### List per-agent per-channel concurrency caps

<Note>
  `GET /api/v1/settings/agent-channel-caps`
</Note>

Return every configured per-agent per-channel max-concurrent cap for the tenant. Optionally narrow to a single agent with `?agent_user_id=`. A missing (agent, channel) row means "no cap, fail-OPEN"; a row with `max_concurrent=0` blocks that agent from that channel entirely. Owner/admin only.

<ParamField query="agent_user_id" type="string">
  Narrow the list to one agent's caps.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl "https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps" \
      -H "X-API-Key: dv_live_sk_your_key_here"
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps', {
      method: 'GET',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!
      }
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.get("https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps", headers=headers)
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### List Messenger personas

<Note>
  `GET /api/v1/settings/channels/messenger/personas`
</Note>

Lists the virtual sender personas configured on the connected Messenger Page. The Page access token is held server-side and never exposed to the browser.

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl "https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas" \
      -H "X-API-Key: dv_live_sk_your_key_here"
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas', {
      method: 'GET',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!
      }
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.get("https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas", headers=headers)
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Get your current IP address

<Note>
  `GET /api/v1/settings/ip-allowlist/current-ip`
</Note>

Returns your current IP address as the API sees it, plus whether IP-allowlist enforcement is active for your account. Use it to add the correct IP to your allowlist without locking yourself out. `ip` is null when your IP address cannot be determined; `enforced` is false when allowlist enforcement is not applied in the current environment.

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl "https://api.orbit.devotel.io/api/v1/settings/ip-allowlist/current-ip" \
      -H "X-API-Key: dv_live_sk_your_key_here"
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/ip-allowlist/current-ip', {
      method: 'GET',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!
      }
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.get("https://api.orbit.devotel.io/api/v1/settings/ip-allowlist/current-ip", headers=headers)
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Create an API key

<Note>
  `POST /api/v1/settings/api-keys`
</Note>

Mint a new tenant API key. The key value is returned ONLY on this response (Cache-Control: no-store) — store it immediately. `mode: 'test'` activates sandbox-mode (no real provider hits, no billing). Optional per-key `allowed_ips` enforces an IP allowlist at auth time.

<ParamField body="name" type="string" required>
  Human-readable label shown in the dashboard. Not used for authentication.
</ParamField>

<ParamField body="type" type="string (enum: secret|public)">
  secret = server-only `dv_*_sk_*` key; public = browser-safe `pk_*` key for the embed SDK.
</ParamField>

<ParamField body="scopes" type="string[]">
  API key permission scopes (e.g. messages:write). At least one scope is required for keys minted after 2026-08-01; empty-scope keys are deprecated and treated as least-privilege (viewer) / will be rejected after the grandfather deadline.
</ParamField>

<ParamField body="mode" type="string (enum: live|test)">
  `test` keys never deliver messages and never bill; useful for CI/staging.
</ParamField>

<ParamField body="expiresIn" type="string (enum: never|30d|90d|1y)">
  Key lifetime. `never` (the default) mints a non-expiring key; `30d`, `90d`, and `1y` set an automatic expiry measured from creation time.
</ParamField>

<ParamField body="allowed_ips" type="string[]">
  Optional IP/CIDR allowlist. Auth middleware rejects requests from a non-allowlisted source.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/settings/api-keys" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "string"
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/api-keys', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
      "name": "string"
    })
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"], "Content-Type": "application/json"}
    r = requests.post("https://api.orbit.devotel.io/api/v1/settings/api-keys", headers=headers, json={
      "name": "string"
    })
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Create a Messenger persona

<Note>
  `POST /api/v1/settings/channels/messenger/personas`
</Note>

Creates a new virtual sender persona on the connected Messenger Page. Meta mints the id; the supplied name and avatar are echoed back so the UI can render the row without a refetch.

<ParamField body="name" type="string" required>
  Display name shown to the recipient.
</ParamField>

<ParamField body="profile_picture_url" type="string" required>
  HTTPS avatar URL. Meta fetches it at create time and rejects non-https schemes.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "string",
      "profile_picture_url": "string"
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
      "name": "string",
      "profile_picture_url": "string"
    })
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"], "Content-Type": "application/json"}
    r = requests.post("https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas", headers=headers, json={
      "name": "string",
      "profile_picture_url": "string"
    })
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Upsert one per-agent per-channel concurrency cap

<Note>
  `PUT /api/v1/settings/agent-channel-caps`
</Note>

Set the maximum simultaneous open interactions of one channel an agent can be routed (e.g. agent X = 3 chats). `max_concurrent=0` opts the agent OUT of that channel entirely; a positive value caps concurrency; deleting the row reverts to "no cap". Idempotent upsert keyed on (agent\_user\_id, channel). Owner/admin only.

<ParamField body="agent_user_id" type="string" required>
  Workspace user id of the agent the cap applies to (1-128 characters).
</ParamField>

<ParamField body="channel" type="string (enum: sms|whatsapp|email|rcs|viber|instagram|…)" required>
  Channel the cap governs (e.g. sms, whatsapp, email, voice, web\_chat).
</ParamField>

<ParamField body="max_concurrent" type="integer" required>
  Maximum simultaneous open interactions on this channel (0-1000). 0 opts the agent out of the channel entirely.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X PUT "https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "agent_user_id": "string",
      "channel": "string",
      "max_concurrent": 0
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps', {
      method: 'PUT',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
      "agent_user_id": "string",
      "channel": "string",
      "max_concurrent": 0
    })
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"], "Content-Type": "application/json"}
    r = requests.put("https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps", headers=headers, json={
      "agent_user_id": "string",
      "channel": "string",
      "max_concurrent": 0
    })
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Bulk upsert per-agent per-channel concurrency caps

<Note>
  `PUT /api/v1/settings/agent-channel-caps/bulk`
</Note>

Upsert a batch of (agent\_user\_id, channel, max\_concurrent) caps in one call — the team-members cap-matrix save. Idempotent: re-sending an (agent, channel) pair updates its existing cap instead of creating a duplicate. Up to 500 rows; duplicate (agent, channel) keys in the payload keep the last value. Owner/admin only.

<ParamField body="caps" type="object[]" required>
  Batch of (agent\_user\_id, channel, max\_concurrent) cap rows to upsert. 1-500 items; duplicate (agent, channel) keys keep the last value.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X PUT "https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/bulk" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "caps": []
    }'
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/bulk', {
      method: 'PUT',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
      "caps": []
    })
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"], "Content-Type": "application/json"}
    r = requests.put("https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/bulk", headers=headers, json={
      "caps": []
    })
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Clear a per-agent per-channel concurrency cap

<Note>
  `DELETE /api/v1/settings/agent-channel-caps/{agentUserId}/{channel}`
</Note>

Remove the cap row for one (agent, channel) pair, reverting it to the "no cap, fail-OPEN" default. Returns 404 when no cap was configured for that pair. Owner/admin only.

<ParamField path="agentUserId" type="string" required>
  Workspace user id of the agent whose cap is being cleared.
</ParamField>

<ParamField path="channel" type="string (enum: sms|whatsapp|email|rcs|viber|instagram|…)" required>
  Channel whose cap row is being cleared.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X DELETE "https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/{agentUserId}/{channel}" \
      -H "X-API-Key: dv_live_sk_your_key_here"
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/{agentUserId}/{channel}', {
      method: 'DELETE',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!
      }
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.delete("https://api.orbit.devotel.io/api/v1/settings/agent-channel-caps/{agentUserId}/{channel}", headers=headers)
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***

### Delete a Messenger persona

<Note>
  `DELETE /api/v1/settings/channels/messenger/personas/{personaId}`
</Note>

Removes a virtual sender persona from the connected Messenger Page by its Meta object id. Returns 204 on success.

<ParamField path="personaId" type="string" required>
  Meta persona object id (numeric string).
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X DELETE "https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas/{personaId}" \
      -H "X-API-Key: dv_live_sk_your_key_here"
    ```

    ```typescript Node.js theme={null}
    const res = await fetch('https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas/{personaId}', {
      method: 'DELETE',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!
      }
    });
    const data = await res.json();
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.delete("https://api.orbit.devotel.io/api/v1/settings/channels/messenger/personas/{personaId}", headers=headers)
    print(r.json())
    ```
  </CodeGroup>
</RequestExample>

***
