> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getkato.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication and API conventions

> Access keys, permissions, pagination, errors, and rate limits.

The general developer API examples target `https://api.getkato.io/v1` and use JSON. Send `Content-Type: application/json` with JSON request bodies.

For other surfaces, see the separate [CLI conventions](/api-reference/cli/overview), [Raycast conventions](/api-reference/raycast/overview), and [OAuth flow](/api-reference/oauth/overview). Browse [all endpoints](/api-reference/endpoints) for the complete directory.

## 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:

```http theme={null}
Authorization: Bearer kato_your_access_key
```

Use 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](/api-reference/tasks/overview#visibility).

## Scopes

For resources with both access levels, a write scope includes the corresponding
read permission. `comments:write` is intentionally write-only.

| Scope            | Available operations                               |
| ---------------- | -------------------------------------------------- |
| `objects:read`   | Discover objects and field definitions             |
| `records:read`   | List and retrieve records                          |
| `records:write`  | Create, update, archive, and restore records       |
| `comments:write` | Add activity comments to 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.

```json theme={null}
{
  "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.

```bash theme={null}
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](/api-reference/objects-and-records#upsert-with-a-stable-id). There is no documented general `Idempotency-Key` mechanism.

## Errors

Always check the HTTP status before consuming `data`. Route errors commonly look like this:

```json theme={null}
{
  "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.


## Related topics

- [Developer quickstart](/api-reference/quickstart.md)
- [All endpoints](/api-reference/endpoints.md)
- [Raycast API](/api-reference/raycast/overview.md)
- [CLI API](/api-reference/cli/overview.md)
- [Identify your workspace](/api-reference/whoami.md)
