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 requestLimitCounted perEndpoints
Record reads300 a minuteAPI keyGET /api/crm/record/{id}, inbox conversations, scheduled emails
Record writes120 a minuteAPI keyPOST /api/crm/record, PATCH and DELETE /api/crm/record/{id}, /api/crm/leads, and changes to templates, segments, sequences, follow-ups and campaigns
Queries200 a minuteAPI keyPOST /api/crm/records/query, segment records, campaign previews
Search100 a minuteAPI key/api/crm/records/search
Batch operations30 a minuteAPI key/api/crm/records/batch, campaign sends, enrolling a segment, adding and removing suppressions
Exports10 a minuteAPI key/api/crm/records/export, record audit exports
Objects and definitions100 a minuteAPI key/api/crm/objects, and reading templates, segments, sequences, campaigns, follow-ups, domains, senders and suppressions
Media60 a minuteAPI key/api/crm/media, /api/assets
Automation and settings60 a minuteAPI key/api/crm/automation, AI fields, API keys, organisation and members, and changes to domains and senders
Email sends100 a minuteAPI key/api/crm/emails/compose, /api/crm/emails/reply and /api/crm/emails/scheduled/{id}/cancel, sharing one counter
Email API100 a minuteAPI key/api/email/send, with its own counter, separate from Email sends
Inbox replies60 a minuteAPI key/api/crm/inbox/reply
Lead ingestion300 a minuteorganisation/api/ingest
Form webhooks60 a minuteform webhook/api/intake/forms/{token}
MCP server60 a minuteorganisation (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):

HeaderDescription
X-RateLimit-LimitThe limit for this kind of request
X-RateLimit-RemainingRequests left in the current window
X-RateLimit-ResetUnix 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/batch creates 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