curl -X POST "https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Idempotency-Key: topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5" \
-d '{"amount": 1000}'
const response = await fetch(
'https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_TOKEN',
'Idempotency-Key': 'topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5'
},
body: JSON.stringify({ amount: 1000 })
}
);
const data = await response.json();
console.log(data);
Agency
Add Top-Up Credits
Adds top-up message credits to a client workspace
POST
/
v1
/
agency
/
clients
/
{client_id}
/
topups
curl -X POST "https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Idempotency-Key: topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5" \
-d '{"amount": 1000}'
const response = await fetch(
'https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_TOKEN',
'Idempotency-Key': 'topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5'
},
body: JSON.stringify({ amount: 1000 })
}
);
const data = await response.json();
console.log(data);
Available on agency plans. The API token must belong to the agency owner.
Top-up credits sit in a separate bucket next to the client’s monthly allowance. The client’s AI agents draw on them only after the monthly
message_limit is used up, and the bucket carries over: it never expires at the monthly renewal or on reset_credits. Credits take effect within seconds.
Pairs with the client.credits_exhausted webhook for automated replenishment: charge the client in your own billing system when the event arrives, then call this endpoint with the event’s delivery id as your Idempotency-Key.
Top-ups require the client to have their own
message_limit of at least 1. Clients without one draw on your agency-wide pool and have no per-client budget to top up; the API returns 422 for them.Top-up credits freeze while a client is paused or suspended and come back untouched on resume. A soft pause drains only the remaining monthly allowance.
If messages were served past the monthly limit shortly before the client ran dry, that small overflow is charged against the next top-up.
messages_remaining in the response is the exact balance the client can serve.Path Parameters
| Name | Type | Description |
|---|---|---|
| client_id* | String | The ID of the client workspace. |
Headers
| Name | Type | Description |
|---|---|---|
| Accept* | String | application/json |
| Content-Type* | String | application/json |
| Authorization* | String | Bearer |
| Idempotency-Key* | String | A unique key for this request. Retrying with the same key returns the original response without adding credits again. |
Body
| Name | Type | Description |
|---|---|---|
| amount* | Integer | Number of message credits to add. Between 1 and 1,000,000. |
curl -X POST "https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Idempotency-Key: topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5" \
-d '{"amount": 1000}'
const response = await fetch(
'https://api.sitespeak.ai/v1/agency/clients/{client_id}/topups',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_TOKEN',
'Idempotency-Key': 'topup-5ad8e662-e7a7-44e2-9b8d-825043bf7be5'
},
body: JSON.stringify({ amount: 1000 })
}
);
const data = await response.json();
console.log(data);
Response
Returns the client workspace with the updated balances.topup_credits_remaining is the bucket balance and messages_remaining is the total the client can serve (monthly remaining plus top-up, capped by your agency pool).
- 200 Success
- 422 No message limit
- 403 Not an agency account
- 404 Not found
{
"client": {
"id": "dfcee2e1-3ace-41c6-9803-fb2b7c7cdfc7",
"name": "Acme Inc",
"external_reference": "billing-account-1001",
"status": "active",
"pause_mode": null,
"paused_at": null,
"byok_enabled": false,
"limits": {
"chatbots": 2,
"sources": 50,
"messages": 5000,
"response_tokens": null
},
"usage": {
"chatbots": 1,
"sources": 12,
"messages": 5000
},
"messages_remaining": 1000,
"topup_credits_remaining": 1000,
"credits_exhausted_at": null,
"credits_reset_at": null,
"created_at": "2026-07-22T19:31:40+00:00"
}
}
Returns when the client workspace has no
message_limit set. Set one with PATCH /clients/{client_id} first.Returns when the API token does not belong to an agency account owner.
Returns when no client workspace with this ID exists in your agency.
Last modified on August 25, 2026