Skip to content

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.

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.

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.

Each key has a per-minute limit. A response normally carries the current state:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
X-RateLimit-Reset: 1793200000

Over the limit is 429 with code: rate_limited and a Retry-After header. Wait that many seconds — retrying immediately just burns the next window.

Every response carries X-Request-Id. Log it. Quoting one lets support find the exact call in seconds instead of guessing from a timestamp.