Errors and limits
Status codes
| Code | Meaning |
|---|---|
| 200, 201 | Success. Creating something answers 201 where noted. |
| 401 | The token is missing, malformed, expired or revoked. |
| 403 | The token is valid but lacks the scope, or the account has the module switched off (error explains which). |
| 404 | No such record in your account. Another account's id looks the same, on purpose. |
| 422 | Validation failed. |
| 429 | Rate limit reached. Wait for the Retry-After header. |
| 500 | Something broke on our side. Safe to retry reads; check before retrying a write. |
Error body
Most errors are small:
{ "error": "Please provide valid contact data" }
Scope errors name the scope:
{ "error": "insufficient_scope", "error_description": "This token does not have the \"contacts:write\" scope." }
Endpoints that use standard Laravel validation answer 422 with every failing field:
{
"message": "The subject field is required.",
"errors": { "subject": ["The subject field is required."] }
}
Handle all three shapes: read error, then message, and use errors for field-level display.
Rate limits
| Surface | Limit |
|---|---|
| Account-scoped API | 60 requests per minute per token |
POST /platform/contacts/sync |
30 per minute per token, on top of the above |
| MCP tool calls | 120 per minute per connection |
| OAuth token endpoint | per IP, see Retry-After |
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. On 429, wait for Retry-After seconds, then retry with a growing delay. Prefer the batch endpoints (/platform/contacts/sync takes 200 contacts a call) over many single calls.
Idempotency and retries
-
GETis always safe to retry. - Writes are not deduplicated by KLCT. If a
POSTtimes out, read the resource back before sending it again so you do not create a duplicate ticket or contact. - Webhook deliveries can arrive more than once. De-duplicate on the delivery
id. See Webhooks.
Data you can and cannot change
The API creates and updates. It does not hard-delete customer data (contacts, tickets, conversations). Removing records stays a decision a person makes inside KLCT.