REST API
Authentication and API conventions
Access keys, permissions, pagination, errors, and rate limits.
All examples in these guides target https://api.getkato.io/v1 and use JSON. Send Content-Type: application/json with JSON request bodies.
Access keys and roles
Create access keys in Settings → Workspace → Developers. Key creation requires Pro. The full token is shown only at creation; save it before closing the dialog.
Workspace members can create read-only keys for non-environment resources. Workspace owners and admins can create write keys and keys with environment-variable scopes. Members manage their own keys; owners and admins can manage workspace keys.
Send the token on every request:
Authorization: Bearer kato_your_access_keyUse a developer access key. OAuth tokens issued for integrations such as Raycast are not accepted on the general developer API.
A key selects its workspace; you do not pass a workspace ID to switch workspaces. Task access also depends on the key owner's current workspace membership and role. See task visibility.
Scopes
A write scope includes the corresponding read permission.
| Scope | Available operations |
|---|---|
objects:read | Discover objects and field definitions |
records:read | List and retrieve records |
records:write | Create, update, archive, and restore records |
tasks:read | List and retrieve visible tasks |
tasks:write | Create, update, and archive visible tasks |
webhooks:read | List endpoints and supported events |
webhooks:write | Create and delete endpoints |
env:read | Read project environment variables through the CLI |
env:write | Push project environment variables through the CLI |
GET /v1/whoami needs a valid key but no additional resource scope. Permission choices in the key dialog do not imply that every resource has public endpoints: the current general API does not expose member management or object creation.
Grant the minimum scopes required. Revoke a key from Developers when it is no longer needed. To replace a key, create a new one, update your integration, verify it works, and revoke the old one.
Response conventions
Single-resource responses use { "data": { ... } }. Collections use a data array. Record and task list endpoints also include has_more and next_cursor.
Creation normally returns 201. Successful reads, updates, archive operations, and deletes in these guides return 200 with a JSON body. Record upsert returns 201 when it creates and 200 when it updates.
Response dates are ISO 8601 strings. Task write inputs are an exception: start_date and due_date accept Unix timestamps in milliseconds. Some response property names differ from input names; use the resource reference.
Pagination
GET /v1/records and GET /v1/tasks accept limit and cursor. The default limit is 25, with a maximum of 100. Results are ordered newest first by creation time, with ID as a tie-breaker.
{
"data": [],
"has_more": false,
"next_cursor": null
}When has_more is true, pass the returned next_cursor unchanged in the next request. Treat it as an opaque value and URL-encode it. Keep other filters the same while paging.
curl --fail-with-body --silent --show-error --get \
https://api.getkato.io/v1/records \
-H "Authorization: Bearer $KATO_API_KEY" \
--data-urlencode "limit=100" \
--data-urlencode "cursor=$KATO_NEXT_CURSOR"Set KATO_NEXT_CURSOR from the preceding response before running this command. Objects, field definitions, and webhook endpoints return unpaginated arrays.
Rate limits and retries
The general /v1 API allows 300 requests per minute per key. A 429 response includes a Retry-After header in seconds. Wait at least that long before retrying, and add backoff for repeated failures.
The CLI has a separate limit of 120 requests per minute per key; its rate-limit response includes retryAfterMs.
Avoid automatically retrying a resource-creation POST after a timeout: the server may already have created it. For records with a stable external identity, consider UUID-based upsert. There is no documented general Idempotency-Key mechanism.
Errors
Always check the HTTP status before consuming data. Route errors commonly look like this:
{
"error": {
"code": "insufficient_scope",
"message": "This API key lacks the records:write scope"
}
}Authentication and some middleware errors instead return error as a string; validation errors may use a different structure. Do not assume every error contains error.code.
| Status | What to check |
|---|---|
400 | Request JSON, required fields, field slugs, or cursor format |
401 | Missing, malformed, revoked, expired, or invalid access key |
403 | Missing scope, unsupported token kind, or insufficient permission |
404 | Resource absent, outside the workspace, archived for an operation, or inaccessible |
409 | Record upsert ID conflicts with another workspace or object |
423 | Workspace locked by its member limit; resolve in Kato |
429 | Rate limit; wait before retrying |
5xx | Server failure; use bounded backoff and account for possible completed writes |
When reporting a failed request, include the method, path, status, and redacted response. Never send an access key or environment-variable values in a support message.
Something missing? Let us know.