API Reference
Rate Limits
Integrate with the Kantos REST API.
API requests are rate limited to keep the platform stable. The limits are the same on every plan. Each kind of request has its own limit, counted in a one-minute window. Most limits count per API key; the table shows the few that count per organisation or per form webhook.
Limits
| Kind of request | Limit | Counted per | Endpoints |
|---|---|---|---|
| Record reads | 300 a minute | API key | GET /api/crm/record/{id}, inbox conversations, scheduled emails |
| Record writes | 120 a minute | API key | POST /api/crm/record, PATCH and DELETE /api/crm/record/{id}, /api/crm/leads, and changes to templates, segments, sequences, follow-ups and campaigns |
| Queries | 200 a minute | API key | POST /api/crm/records/query, segment records, campaign previews |
| Search | 100 a minute | API key | /api/crm/records/search |
| Batch operations | 30 a minute | API key | /api/crm/records/batch, campaign sends, enrolling a segment, adding and removing suppressions |
| Exports | 10 a minute | API key | /api/crm/records/export, record audit exports |
| Objects and definitions | 100 a minute | API key | /api/crm/objects, and reading templates, segments, sequences, campaigns, follow-ups, domains, senders and suppressions |
| Media | 60 a minute | API key | /api/crm/media, /api/assets |
| Automation and settings | 60 a minute | API key | /api/crm/automation, AI fields, API keys, organisation and members, and changes to domains and senders |
| Email sends | 100 a minute | API key | /api/crm/emails/compose, /api/crm/emails/reply and /api/crm/emails/scheduled/{id}/cancel, sharing one counter |
| Email API | 100 a minute | API key | /api/email/send, with its own counter, separate from Email sends |
| Inbox replies | 60 a minute | API key | /api/crm/inbox/reply |
| Lead ingestion | 300 a minute | organisation | /api/ingest |
| Form webhooks | 60 a minute | form webhook | /api/intake/forms/{token} |
| MCP server | 60 a minute | organisation (a token that reaches every organisation you belong to: per user) | /api/mcp/v1 |
When you go over a limit
The API returns 429 Too Many Requests with this body:
{
"error": "rate_limited",
"message": "Rate limit exceeded."
}The 429 response carries these headers (form webhooks and /api/email/send answer 429 without them):
| Header | Description |
|---|---|
X-RateLimit-Limit | The limit for this kind of request |
X-RateLimit-Remaining | Requests left in the current window |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets |
The MCP server answers a JSON-RPC error with code -32029 and HTTP status 429, with the same headers. Successful responses don't carry rate-limit headers.
Retrying
Wait until the reset time, or back off and retry:
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
const reset = Number(response.headers.get('X-RateLimit-Reset'));
const waitMs = reset ? Math.max(0, reset * 1000 - Date.now()) : Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, waitMs));
}
throw new Error('Rate limit exceeded after retries');
}A refused request changes nothing
A request refused with 429 isn't carried out. Send it again after the reset.
Tips for staying within limits
- Batch writes —
/api/crm/records/batchcreates or updates many records in one request - Cache responses — avoid re-fetching data that hasn't changed
- Use pagination — fetch records in pages rather than all at once
Next Steps
- Authentication — Set up API keys
- Records API — Query and manage records