API reference

Operator control plane

Deployment-wide, for whoever runs the infrastructure. As a customer you should never need these.

Credential: HMAC-signed · scheme HMAC signature

12 operations · 11 captured against the live API.

Every example below is a real exchange recorded against a throwaway tenant, then redacted — not a shape transcribed from a schema. Ids and timestamps are stable fixtures so the same request always reads the same way. Back to the full index →

Rooms, members, tokens #

POST /internal/v1/rooms #

Create a room

createRoom captured live

Request

curl -X POST https://api.ollacore.com/internal/v1/rooms \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"tenant_id":"acct_fac91b282191cc02dd29912c8db43f1c","created_by":"alice","external_ref":"ops-room-1"}'
{
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "created_by": "alice",
  "external_ref": "ops-room-1"
}
ParameterTypeDescription
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
tenant_id required string The tenant to create the room in, 1–128 characters.
created_by required string The principal recorded as the room's creator.
external_ref string Your own reference for the room. If one with this external_ref exists in the tenant, it is returned instead.
expires_at string (date-time) Optional informational expiry. Nothing closes or deletes the room when it passes.

Response · 200

{
  "id": "00919f0a-cfeb-438d-bdb7-65af28b4f678",
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "external_ref": "ops-room-1",
  "created_by": "alice",
  "status": "active",
  "e2ee": false,
  "created_at": "2026-01-15T09:30:02Z"
}
Response fields (9)
FieldTypeDescription
id required string (uuid) The room's id, assigned by the server.
tenant_id required string The tenant that owns the room.
external_ref string Your own reference for the room, if you gave one. Creating a room with an external_ref that already exists in the tenant returns that room.
created_by required string The principal recorded as the room's creator.
status required one of: active, closed active, or closed (no new tokens are minted for it).
e2ee required boolean End-to-end encrypted room. When true, the server accepts only ciphertext message kinds, rejects search and reactions, and pushes are content-free — the client must encrypt before sending.
e2ee_scheme one of: mls, megolm Which client E2EE scheme the room's members run, when the creator declared it: mls (the primary scheme) or megolm (the matrix-sdk-crypto transport). The two cannot share a room. Absent when undeclared and on plaintext rooms.
created_at required string (date-time) When the room was created.
expires_at string (date-time) Informational expiry time, if one was set. Nothing closes or deletes the room when it passes.
Errors · 401 · 409 · 429
StatusWhen
401Missing, expired or invalid credentials
409Conflicts with current state
429Rate limit exceeded
GET /internal/v1/rooms #

Resolve by external_ref

lookupRoom captured live

Request

curl -X GET https://api.ollacore.com/internal/v1/rooms?tenant_id=acct_fac91b282191cc02dd29912c8db43f1c&external_ref=ops-room-1 \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
tenant_id query required string The tenant to look in.
external_ref query required string unique per tenant; the same ref always resolves to the same room, which is what makes room creation idempotent
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "id": "00919f0a-cfeb-438d-bdb7-65af28b4f678",
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "external_ref": "ops-room-1",
  "created_by": "alice",
  "status": "active",
  "e2ee": false,
  "created_at": "2026-01-15T09:30:02Z"
}
Response fields (9)
FieldTypeDescription
id required string (uuid) The room's id, assigned by the server.
tenant_id required string The tenant that owns the room.
external_ref string Your own reference for the room, if you gave one. Creating a room with an external_ref that already exists in the tenant returns that room.
created_by required string The principal recorded as the room's creator.
status required one of: active, closed active, or closed (no new tokens are minted for it).
e2ee required boolean End-to-end encrypted room. When true, the server accepts only ciphertext message kinds, rejects search and reactions, and pushes are content-free — the client must encrypt before sending.
e2ee_scheme one of: mls, megolm Which client E2EE scheme the room's members run, when the creator declared it: mls (the primary scheme) or megolm (the matrix-sdk-crypto transport). The two cannot share a room. Absent when undeclared and on plaintext rooms.
created_at required string (date-time) When the room was created.
expires_at string (date-time) Informational expiry time, if one was set. Nothing closes or deletes the room when it passes.
Errors · 401 · 404 · 429
StatusWhen
401Missing, expired or invalid credentials
404no room with that external_ref in the tenant
429Rate limit exceeded
PATCH /internal/v1/rooms/{room_id} #

Patch status / expiry

patchRoom captured live

Request

curl -X PATCH https://api.ollacore.com/internal/v1/rooms/00919f0a-cfeb-438d-bdb7-65af28b4f678 \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"expires_at":"2026-01-16T09:30:02Z"}'
{
  "expires_at": "2026-01-16T09:30:02Z"
}
ParameterTypeDescription
room_id path required string (uuid) The room's id.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
status one of: active, closed closed stops new session tokens being minted for the room (409); members keep access with the tokens they hold. active reopens it.
expires_at string (date-time) Informational expiry time, stored and returned. Nothing closes or deletes the room when it passes.

Response · 200

{
  "id": "00919f0a-cfeb-438d-bdb7-65af28b4f678",
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "external_ref": "ops-room-1",
  "created_by": "alice",
  "status": "active",
  "e2ee": false,
  "created_at": "2026-01-15T09:30:02Z",
  "expires_at": "2026-01-16T09:30:02Z"
}
Response fields (9)
FieldTypeDescription
id required string (uuid) The room's id, assigned by the server.
tenant_id required string The tenant that owns the room.
external_ref string Your own reference for the room, if you gave one. Creating a room with an external_ref that already exists in the tenant returns that room.
created_by required string The principal recorded as the room's creator.
status required one of: active, closed active, or closed (no new tokens are minted for it).
e2ee required boolean End-to-end encrypted room. When true, the server accepts only ciphertext message kinds, rejects search and reactions, and pushes are content-free — the client must encrypt before sending.
e2ee_scheme one of: mls, megolm Which client E2EE scheme the room's members run, when the creator declared it: mls (the primary scheme) or megolm (the matrix-sdk-crypto transport). The two cannot share a room. Absent when undeclared and on plaintext rooms.
created_at required string (date-time) When the room was created.
expires_at string (date-time) Informational expiry time, if one was set. Nothing closes or deletes the room when it passes.
Errors · 401 · 404 · 429
StatusWhen
401Missing, expired or invalid credentials
404No such room, message, member or attachment
429Rate limit exceeded
GET /internal/v1/rooms/{room_id}/status #

Members, presence, live call roster

roomStatus captured live

Request

curl -X GET https://api.ollacore.com/internal/v1/rooms/25964f12-9ae9-4356-80e8-69bc5f749bd1/status \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
room_id path required string (uuid) The room's id.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "room": {
    "id": "25964f12-9ae9-4356-80e8-69bc5f749bd1",
    "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
    "external_ref": "order-7781",
    "created_by": "alice",
    "status": "active",
    "e2ee": false,
    "created_at": "2026-01-15T09:30:03Z"
  },
  "member_count": 4,
  "online_participants": [],
  "rtc_participants": []
}
Response fields (13)
FieldTypeDescription
room required Room The room.
room.id required string (uuid) The room's id, assigned by the server.
room.tenant_id required string The tenant that owns the room.
room.external_ref string Your own reference for the room, if you gave one. Creating a room with an external_ref that already exists in the tenant returns that room.
room.created_by required string The principal recorded as the room's creator.
room.status required one of: active, closed active, or closed (no new tokens are minted for it).
room.e2ee required boolean End-to-end encrypted room. When true, the server accepts only ciphertext message kinds, rejects search and reactions, and pushes are content-free — the client must encrypt before sending.
room.e2ee_scheme one of: mls, megolm Which client E2EE scheme the room's members run, when the creator declared it: mls (the primary scheme) or megolm (the matrix-sdk-crypto transport). The two cannot share a room. Absent when undeclared and on plaintext rooms.
room.created_at required string (date-time) When the room was created.
room.expires_at string (date-time) Informational expiry time, if one was set. Nothing closes or deletes the room when it passes.
member_count required integer (int64) How many active members the room has.
online_participants required array of string principals with a live chat WebSocket
rtc_participants required array of string principals currently published to the SFU
Errors · 401 · 404 · 429
StatusWhen
401Missing, expired or invalid credentials
404No such room, message, member or attachment
429Rate limit exceeded
POST /internal/v1/rooms/{room_id}/members #

Add a member

addMember captured live

Request

curl -X POST https://api.ollacore.com/internal/v1/rooms/00919f0a-cfeb-438d-bdb7-65af28b4f678/members \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"principal_id":"alice","role":"owner"}'
{
  "principal_id": "alice",
  "role": "owner"
}
ParameterTypeDescription
room_id path required string (uuid) The room's id.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
principal_id required string Who to add, 1–128 characters. A removed member is restored.
role one of: owner, member, viewer default "member" owner, member or viewer. Defaults to member; anything else is 400.

Response · 200

{
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "room_id": "00919f0a-cfeb-438d-bdb7-65af28b4f678",
  "principal_id": "alice",
  "role": "owner",
  "joined_at": "2026-01-15T09:30:02Z"
}
Response fields (7)
FieldTypeDescription
tenant_id required string The tenant that owns the room.
room_id required string (uuid) The room.
principal_id required string The member's principal id.
role required string owner, member or viewer.
joined_at string (date-time) When the principal first joined the room. Restoring a removed member keeps the original time.
left_at string (date-time) set when the member was removed; the row is retained so history stays auditable
muted_until string (date-time) Until when this member has push notifications from the room silenced; absent when not muted. 9999-12-31T00:00:00Z stands for "until unmuted". Live delivery and call rings are unaffected.
Errors · 401 · 404 · 409 · 429
StatusWhen
401Missing, expired or invalid credentials
404No such room, message, member or attachment
409Conflicts with current state
429Rate limit exceeded
DELETE /internal/v1/rooms/{room_id}/members/{principal_id} #

Remove a member

removeMember captured live

Request

curl -X DELETE https://api.ollacore.com/internal/v1/rooms/00919f0a-cfeb-438d-bdb7-65af28b4f678/members/carol2 \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
room_id path required string (uuid) The room's id.
principal_id path required string The member to remove.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "removed": true
}
Response fields (1)
FieldTypeDescription
removed required boolean True if a matching row was removed; false if there was nothing to remove.
Errors · 401 · 404 · 429
StatusWhen
401Missing, expired or invalid credentials
404No such room, message, member or attachment
429Rate limit exceeded
POST /internal/v1/session-tokens #

Mint a token

mintSessionToken captured live

Request

curl -X POST https://api.ollacore.com/internal/v1/session-tokens \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"tenant_id":"acct_fac91b282191cc02dd29912c8db43f1c","room_id":"00919f0a-cfeb-438d-bdb7-65af28b4f678","principal_id":"alice","role":"owner","ttl_seconds":3600}'
{
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "room_id": "00919f0a-cfeb-438d-bdb7-65af28b4f678",
  "principal_id": "alice",
  "role": "owner",
  "ttl_seconds": 3600
}
ParameterTypeDescription
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
tenant_id required string The tenant the room belongs to.
room_id required string (uuid) The room the token is for. A token opens exactly one room.
principal_id required string Who the token is for. Must be an active member of the room.
role one of: owner, member, viewer Optional: mint with fewer rights than the member has. At or below the member's stored role (a higher one is 403); anything but owner|member|viewer is 400. Omit to use the member's own role.
ttl_seconds integer default 600 · min 60 · max 3600 Token lifetime in seconds. Defaults to 600 and is clamped to 60–3600.

Response · 200

{
  "access_token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6ImEwM2I1NjQ4MjM3YjlmZWIifQ.eyJpc3MiOiJjaGF0Ym94LWJhY2tlbmQiLCJhdWQiOiJjaGF0Ym94LXJlYWx0aW1lIiwic3ViIjoiYWxpY2UiLCJ0aWQiOiJhY2N0X2ZhYzkxYjI4MjE5MWNjMDJkZDI5OTEyYzhkYjQzZjFjIiwicmlkIjoiMDA5MTlmMGEtY2ZlYi00MzhkLWJkYjctNjVhZjI4YjRmNjc4Iiwicm9sZSI6Im93bmVyIiwicGVybWlzc2lvbnMiOlsiY2hhdDpzZW5kIiwiY2hhdDpoaXN0b3J5IiwiYXR0YWNobWVudDp1cGxvYWQiLCJhdHRhY2htZW50OmRvd25sb2FkIiwicnRjOnB1Ymxpc2giLCJydGM6c3Vic2NyaWJlIl0sImp0aSI6ImJmZThlYzg2LTVkZmUtNDM1YS1iNTk3LTkwZjBkY2RhM2FiZSIsImlhdCI6MTc5MjMyNDY2NSwibmJmIjoxNzkyMzI0NjY1LCJleHAiOjE3OTIzMjgyNjV9.SIGNATURE_REMOVED",
  "expires_at": "2026-01-15T10:30:02Z",
  "rtc_websocket_url": "wss://api.ollacore.com/v1/rtc/ws",
  "chat_websocket_url": "wss://api.ollacore.com/v1/chat/ws",
  "ice_servers": [
    {
      "urls": [
        "stun:api.ollacore.com:3478"
      ]
    },
    {
      "urls": [
        "turn:api.ollacore.com:3478",
        "turns:api.ollacore.com:5349"
      ],
      "username": "1789064267:alice",
      "credential": "EXAMPLE_TURN_CREDENTIAL="
    }
  ]
}
Response fields (8)
FieldTypeDescription
access_token required string The room-scoped session token (an Ed25519-signed JWT). Present it as Authorization: Bearer … over HTTP and as the WebSocket subprotocol bearer.<token>, never in a URL.
expires_at required string (date-time) When the token expires. Mint a new one before then; a socket closes with 4401 at expiry.
rtc_websocket_url required string (uri) The call-signalling WebSocket URL.
chat_websocket_url required string (uri) The chat WebSocket URL.
ice_servers required array of object STUN and TURN servers for WebRTC, with short-lived TURN credentials. Pass them to RTCPeerConnection unchanged.
ice_servers[].urls required array of string The server URLs. They never carry a ?transport= query, which Safari refuses.
ice_servers[].username string expiry_unix:principal — ephemeral, 600 s
ice_servers[].credential string base64(HMAC-SHA1(turn_secret, username))
Errors · 400 · 401 · 403 · 404 · 429
StatusWhen
400role is not one of owner | member | viewer.
401Missing, expired or invalid credentials
403The principal is not an active member of the room, or role is above the member's stored role (a viewer cannot be minted an owner token).
404Room not found in tenant
429Rate limit exceeded
GET /internal/v1/principals/{principal_id}/unread #

Per-room unread for a principal

principalUnread captured live

Request

curl -X GET https://api.ollacore.com/internal/v1/principals/bob/unread?tenant_id=acct_fac91b282191cc02dd29912c8db43f1c \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
principal_id path required string The principal whose unread counts to return.
tenant_id query required string The tenant the principal belongs to.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "rooms": [
    {
      "room_id": "25964f12-9ae9-4356-80e8-69bc5f749bd1",
      "unread_count": 0
    }
  ],
  "total": 0
}
Response fields (4)
FieldTypeDescription
total required integer (int64) Unread messages across all the principal's rooms, for an app-icon badge.
rooms required array of object Per-room unread counts.
rooms[].room_id required string (uuid) The room.
rooms[].unread_count required integer (int64) Messages after the principal's read cursor in that room.
Errors · 401 · 429
StatusWhen
401Missing, expired or invalid credentials
429Rate limit exceeded

Provisioning & lifecycle #

POST /internal/v1/api-keys #

Issue a customer key

createApiKey captured live

Request

curl -X POST https://api.ollacore.com/internal/v1/api-keys \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"tenant_id":"acct_fac91b282191cc02dd29912c8db43f1c","name":"sandbox-key","environment":"test","scopes":["rooms:read","rooms:write"]}'
{
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "name": "sandbox-key",
  "environment": "test",
  "scopes": [
    "rooms:read",
    "rooms:write"
  ]
}
ParameterTypeDescription
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
tenant_id required string The tenant the key acts on, 1–128 characters. Must not contain ::, which is reserved for the test namespace.
name string Optional label for the key.
environment required one of: live, test live or test. A test key works in the {tenant_id}::test namespace.
scopes required array of one of: rooms:read, rooms:write, members:write, tokens:mint, messages:write, webhooks:manage, usage:read, rooms:delete, data:erase The scopes to grant. Each must be a known scope.
expires_at string (date-time) Optional expiry. After it the key is refused as if revoked.
plan string Rate-tier plan name (see the plans table); defaults to 'default'.

Response · 200

{
  "key_id": "key-id-sandbox",
  "api_key": "ak_live_EXAMPLE.NOT_A_REAL_KEY",
  "tenant_id": "acct_fac91b282191cc02dd29912c8db43f1c",
  "environment": "test",
  "scopes": [
    "rooms:read",
    "rooms:write"
  ]
}
Response fields (5)
FieldTypeDescription
key_id required string The key's public id (ak_live_… or ak_test_…). Use it to revoke the key; it is not a credential.
api_key required string Full ak_<env>_<id>.<secret>, shown once.
tenant_id required string The tenant the key acts on. A test key's data lives in its own namespace, {tenant_id}::test, and never mixes with live data.
environment required one of: live, test live or test. A test key sees only test data.
scopes required array of one of: rooms:read, rooms:write, members:write, tokens:mint, messages:write, webhooks:manage, usage:read, rooms:delete, data:erase What the key may do. A call outside these scopes is refused with 403 when it is made, not when the key is created.
Errors · 401
StatusWhen
401Missing, expired or invalid credentials
DELETE /internal/v1/api-keys/{key_id} #

Revoke a key

revokeApiKey captured live

Request

curl -X DELETE https://api.ollacore.com/internal/v1/api-keys/key-id-sandbox \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
key_id path required string The API key's public id (ak_live_… or ak_test_…).
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "revoked": true
}
Response fields (1)
FieldTypeDescription
revoked boolean True once the key no longer works.
Errors · 401 · 404
StatusWhen
401Missing, expired or invalid credentials
404No such room, message, member or attachment
PUT /internal/v1/plans/{name} #

Create/update a rate + quota plan

putPlan captured on a test deployment

Request

curl -X PUT https://api.ollacore.com/internal/v1/plans/docs-example \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d '{"rate_limit":120,"rate_window_seconds":10,"monthly_message_quota":5000000,"monthly_byte_quota":549755813888,"retention_days":365,"description":"Example tier for documentation"}'
{
  "rate_limit": 120,
  "rate_window_seconds": 10,
  "monthly_message_quota": 5000000,
  "monthly_byte_quota": 549755813888,
  "retention_days": 365,
  "description": "Example tier for documentation"
}
ParameterTypeDescription
name path required string The plan's name, 1–64 characters. The call creates the plan or replaces it.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Request fields

FieldTypeDescription
rate_limit required integer (int64) Requests allowed per window, per API key on this plan. Must be positive.
rate_window_seconds required integer (int64) The rate-limit window in seconds. Must be positive.
monthly_message_quota integer (int64), nullable Monthly message cap; omit or null for unlimited.
monthly_byte_quota integer (int64), nullable Monthly attachment-byte cap; omit or null for unlimited.
retention_days integer (int64), nullable Auto-expire messages older than this many days; omit or null to keep forever.
description string Optional human description of the plan.

Response · 200

{
  "plan": "docs-example"
}
Response fields (1)
FieldTypeDescription
plan string The plan's name.
Errors · 401
StatusWhen
401Missing, expired or invalid credentials
Captured against a test deployment: `plans` is deployment-wide, so writing it on production would re-tier every existing tenant.
DELETE /internal/v1/tenants/{tenant_id} #

Offboard a tenant — revokes the account and its logins, keys and directory at once, then erases rooms, blobs, webhooks and usage

purgeTenant captured live

Request

curl -X DELETE https://api.ollacore.com/internal/v1/tenants/acct_fac91b282191cc02dd29912c8db43f1c \
  -H "X-Chatbox-Key-Id: $KEY_ID" \
  -H "X-Chatbox-Timestamp: $TS" \
  -H "X-Chatbox-Nonce: $NONCE" \
  -H "X-Chatbox-Signature: $SIG"
ParameterTypeDescription
tenant_id path required string The tenant to erase.
X-Request-Id header string Your own id for this request. It is returned in the response's X-Request-Id header and attached to every log line kept for the request, so quote it when you contact support. Use printable ASCII. Without it, the server assigns a UUID.

Response · 200

{
  "purging": true
}
Response fields (1)
FieldTypeDescription
purging required boolean True: every room and all of the tenant's data are being erased in the background. Irreversible.
Errors · 401
StatusWhen
401Missing, expired or invalid credentials

Errors on this plane #

Every failure uses the same body — code and message. These were triggered deliberately against the live API.

401 · signature does not match the canonical string

{
  "code": "unauthorized",
  "message": "unauthorized: signature mismatch"
}

401 · timestamp outside the 120-second window

{
  "code": "unauthorized",
  "message": "unauthorized: timestamp outside allowed window"
}

The full code list and retry guidance is on Errors & rate limits.