Tenant management
The admin endpoints live under /api/v1 and are protected by the
X-Admin-Key header (platform operator). They handle the entire lifecycle
of a tenant after provisioning.
Parameter convention
Section titled “Parameter convention”A single rule to remember:
provision/tenanttakes a JSON body (notenant_id, it is generated);- all other operations take
?tenant_id=as a query parameter, and a JSON body only when there is something to write (update/tenant).
The list of operations
Section titled “The list of operations”| Method | Path | Parameter | Effect |
|---|---|---|---|
POST | /provision/tenant | body | Creates the tenant; returns tenant_id + tenant_secret + widget_public_key (once) |
POST | /update/tenant | ?tenant_id= + body | Partial update (exclude_unset) |
POST | /rotate/tenant-secret | ?tenant_id= | New secret; the old one is invalid immediately |
POST | /rotate/widget-key | ?tenant_id= | New widget key; the old one stops working immediately |
POST | /suspend/tenant | ?tenant_id= | HMAC#1 calls return 403 until reactivation |
POST | /reactivate/tenant | ?tenant_id= | Lifts the suspension |
GET | /fetch/tenant | ?tenant_id= | Returns the tenant (without secret) |
GET | /fetch/tenants | ?limit=&offset= | Paginated list (without secrets) |
Update the configuration
Section titled “Update the configuration”update/tenant writes only the fields present in the body. Use it for the
rate limit, the callback URL, branding, origins, feature flags, quotas, the
plan_tier and the stripe_customer_id.
curl "$BASE_URL/api/v1/update/tenant?tenant_id=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "plan_tier": "pro", "monthly_msg_quota": 50000, "agent_seats": 25, "branding_primary_color": "#0055FF" }'Secret rotation and status changes do not go through update/tenant —
they have their own endpoints, below.
Rotate the backend secret
Section titled “Rotate the backend secret”rotate/tenant-secret generates a new tenant_secret. The old one is
invalid immediately: every backend that signs with HMAC#1 must switch
to the new value at the same instant.
curl "$BASE_URL/api/v1/rotate/tenant-secret?tenant_id=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "status_code": 200, "data": { "tenant_id": "019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f", "tenant_secret": "sk_...", "rotated_at": "2026-06-21T11:00:00Z" }, "message": "Secret rotated. Save the new tenant_secret — old secret is now invalid."}Rotate the widget key
Section titled “Rotate the widget key”rotate/widget-key generates a new widget_public_key. This is a
chat-specific operation (the Auth Relay has no equivalent). The old key
stops working immediately: update every <script data-public-key=...>
tag and every SDK configuration.
curl "$BASE_URL/api/v1/rotate/widget-key?tenant_id=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "status_code": 200, "data": { "tenant_id": "019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f", "widget_public_key": "pk_...", "rotated_at": "2026-06-21T11:05:00Z" }, "message": "Widget public key rotated. Update <script data-public-key=...> on every tenant page; old key stops working immediately."}Suspend and reactivate
Section titled “Suspend and reactivate”Suspending a tenant makes all of its HMAC#1 calls return 403 until
reactivation — useful in case of abuse or non-payment.
- Suspend —
POST /suspend/tenant?tenant_id=.... Signed backend calls are refused (403); the configuration stays intact. - Reactivate —
POST /reactivate/tenant?tenant_id=.... Calls resume immediately.
# Suspendcurl "$BASE_URL/api/v1/suspend/tenant?tenant_id=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -X POST -H "X-Admin-Key: YOUR_ADMIN_KEY"
# Reactivatecurl "$BASE_URL/api/v1/reactivate/tenant?tenant_id=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -X POST -H "X-Admin-Key: YOUR_ADMIN_KEY"Read one or more tenants
Section titled “Read one or more tenants”fetch/tenant returns a full tenant without its tenant_secret (the
widget_public_key is present, though). fetch/tenants paginates the list
via limit (1–500, default 100) and offset.
curl "$BASE_URL/api/v1/fetch/tenants?limit=50&offset=0" \ -H "X-Admin-Key: YOUR_ADMIN_KEY"Next steps
Section titled “Next steps”- Full surface and exact schemas. See the API reference.
- The same operations in self-service. See Console.
- Understand the generic lifecycle. See Tenant lifecycle.