Programmatically provision sub-tenants for end users from a single parent account.
The agency tier lets a partner create and manage Claw Messenger sub-tenants — each with its own API key, message routing, and visible sending number — under one billing relationship with us. Every sub-tenant gets its own separate sending number at $199/month, charged when you create it, so every client conversation shows a different line. You hold the parent API key; your end users never see Claw Messenger directly.
The agency tier is invite-only. To request access, email clawmessenger@mail.tin.computer with your company name and rough scale (subaccounts and messages per month) so we can size the line pool — every subaccount gets its own visible number automatically.
POST starts that sub-tenant's $199/month subscription, charged immediately.Your parent API key looks like cm_live_AbCd1234_... and is the only credential you need to provision and manage subaccounts. Pass it as a Bearer token:
Authorization: Bearer cm_live_AbCd1234_...The key is available in your dashboard under API Keys. Rotate it from the same page at any time; rotation revokes the old key immediately.
The parent API key is for the /api/agency/* endpoints documented below. Each subaccount has its own API key, which is what you give to that subaccount's agent for sending and receiving messages.
Create a subaccount in one call. You get back an API key for that subaccount, shown only once.
POST /api/agency/subaccounts
Authorization: Bearer cm_live_<parent>
Content-Type: application/json
{
"name": "Acme Co",
"email": "founder@acme.com", // optional
"external_id": "your-internal-id", // optional, idempotency key
"message_limit": 1000 // optional monthly cap, default 1000
}HTTP/1.1 200 OK
{
"id": "uuid",
"api_key": "cm_live_XyZ9_...", // shown once
"key_prefix": "cm_live_XyZ9",
"sending_number": "+1XXXXXXXXXX",
"status": "active",
"message_limit": 1000,
"name": "Acme Co",
"email": "founder@acme.com",
"external_id": "your-internal-id"
}Idempotency. If you supply external_id, repeated calls with the same value return the existing subaccount instead of creating a duplicate. The response on the second call does not include api_key — to get a new key, call the rotate endpoint.
GET /api/agency/subaccounts — list all subaccounts with month-to-date countsGET /api/agency/subaccounts/{id} — fetch onePATCH /api/agency/subaccounts/{id} — change status (active/suspended) or message_limitPOST /api/agency/subaccounts/{id}/keys — rotate API key (revokes old, returns new)DELETE /api/agency/subaccounts/{id} — suspend and revoke all keys (data preserved)GET /api/agency/subaccounts/{id}/usage — month-to-date message count for one subaccountGET /api/agency/usage — aggregated current-period usage across all subaccountsEach subaccount registers the end-customer phone numbers it should communicate with. Inbound messages from those numbers route to that subaccount; outbound is allowed to those numbers.
POST /api/agency/subaccounts/<id>/phone-routes
Authorization: Bearer cm_live_<parent>
Content-Type: application/json
{ "phone_number": "+15551234567" }You can also register from the subaccount's own key against the standard endpoint:
POST /api/routes
Authorization: Bearer cm_live_<subaccount>
Content-Type: application/json
{ "phone_number": "+15551234567" }Phone numbers are globally unique. If the same end-customer phone is already registered to another subaccount (yours or anyone else's), the call returns 409 Conflict.
Subaccount API keys work exactly like consumer keys against our WebSocket endpoint. The only difference is the line: each subaccount sends from its own assigned sending number (shown as sending_number in the subaccount API responses), distinct from the self-serve plans and from every other subaccount in your agency.
const ws = new WebSocket("wss://claw-messenger.onrender.com/ws?key=cm_live_<subaccount>");
ws.onopen = () => {
ws.send(JSON.stringify({
type: "send",
id: "msg-1",
to: "+15551234567",
parts: [{ type: "text", value: "Hello from your agency-provisioned agent" }],
service: "iMessage"
}));
};See the main API docs for the full WebSocket protocol (typing indicators, reactions, group messages, delivery status).
Each sub-tenant's $199/month starts the moment you create it — charged to the card on file, then renewed monthly by Stripe. Deleting a sub-tenant stops future renewals (no refund for the current period). Usage overage ($0.005 per message over the 1,000 included per sub-tenant) is invoiced separately, monthly in arrears. If payment fails after Stripe's retries, your subaccounts are suspended until the open invoice is paid; pay it via Stripe's hosted invoice page to reactivate. Review your invoice history at /agency/invoices.
message_limit (default 1,000). Send attempts beyond the cap fail until the next month or until you raise the cap via PATCH /api/agency/subaccounts/{id}.Agency daily message limit reached until midnight UTC. Track today's totals via GET /api/agency/usage (today_total_messages, line_daily_limit).POST /api/agency/subaccounts calls per 10 minutes.401 Unauthorized — missing or invalid API key.404 Not Found — subaccount doesn't belong to your parent.409 Conflict — phone number already claimed by another tenant; or, on POST /api/agency/subaccounts, no sending lines available in the pool (no_agency_line_available).429 Too Many Requests — provisioning rate limit reached.All endpoints live under https://claw-messenger.onrender.com.
Authenticate with your parent API key as Authorization: Bearer cm_live_....
POST /api/agency/subaccounts — create a subaccount + initial API keyGET /api/agency/subaccounts — listGET /api/agency/subaccounts/{id} — detailPATCH /api/agency/subaccounts/{id} — update status or message_limitDELETE /api/agency/subaccounts/{id} — suspend and revoke keysPOST /api/agency/subaccounts/{id}/keys — rotate API keyPOST /api/agency/subaccounts/{id}/phone-routes — register an end-customer phoneGET /api/agency/subaccounts/{id}/phone-routes — listDELETE /api/agency/subaccounts/{id}/phone-routes/{phone} — releaseGET /api/agency/subaccounts/{id}/usage — single-subaccount month-to-dateGET /api/agency/usage — aggregatedGET /api/agency/invoices — billing historyGET /api/agency/invoices/{id} — line-item breakdownQuestions? Email clawmessenger@mail.tin.computer.