Authentication and keys
Every request carries an organization API key as a bearer token:
Authorization: Bearer tko_...An owner or admin creates one in the portal under Settings → API keys and picks its scopes. The key is bound to the organization that made it, and no header can move it to another — there is no organization parameter on any endpoint.
Scopes
Section titled “Scopes”Each operation names the scope it needs; the reference shows it on every one.
| Scope | Grants |
|---|---|
read:customers |
Read customers |
read:conversations |
Read conversations and their messages |
read:tickets |
Read tickets and their history |
read:bookings |
Read bookings |
read:services |
Read services, resources and availability |
A write:x scope also grants read:x, so a key that manages tickets need not carry both.
Calling an operation your key does not have the scope for is 403:
{ "type": "about:blank", "title": "Insufficient scope", "status": 403, "code": "insufficient_scope", "detail": "This key does not have the read:tickets scope."}Fix it by editing the key’s scopes in the portal — the secret does not change, so nothing needs redeploying.
Keep the key secret
Section titled “Keep the key secret”The key is shown once, when it is created. It grants everything its scopes allow for the whole organization, so treat it like a password:
- Put it in your server’s secret store, never in a browser, a mobile app, or a repository.
- Give each integration its own key, so one can be revoked without breaking the others.
- Revoke immediately in the portal if one leaks; a revoked key is refused on the next call.
A key can also carry an expiry. An expired key is refused exactly like a revoked one.
Rate limits
Section titled “Rate limits”Each key has a per-minute limit. A response normally carries the current state:
X-RateLimit-Limit: 60X-RateLimit-Remaining: 41X-RateLimit-Reset: 1793200000Over the limit is 429 with code: rate_limited and a Retry-After header. Wait that
many seconds — retrying immediately just burns the next window.
Request ids
Section titled “Request ids”Every response carries X-Request-Id. Log it. Quoting one lets support find the exact
call in seconds instead of guessing from a timestamp.