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

# REST API

> Base URL, authentication, rate limits, errors, and pagination for the Atako REST API.

Atako exposes a REST API at `https://api.atako.ai` covering agents, their files,
integrations, billing, and your company/team — everything the web app itself does,
callable from scripts, CI, or your own backend. The full, browsable reference is the
[API reference](/api-reference/openapi.json) section, generated from the same
[OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.0) document the API itself serves at
[`GET /openapi.json`](https://api.atako.ai/openapi.json).

<Note>
  Prefer talking to an AI client instead of writing HTTP calls by hand? See the
  [Atako MCP server](/developers/mcp/overview) — same auth, same data, no code.
</Note>

## Base URL

```
https://api.atako.ai
```

## Authentication

Every non-public endpoint takes a Bearer token — either:

* a **programmatic API key** (`aik_…`) — see [API keys](/developers/api-keys) for how
  to create one, or
* a Supabase session JWT, which is what the web app itself sends (not practical to
  obtain outside a browser session).

```bash theme={null}
curl https://api.atako.ai/agents \
  -H "Authorization: Bearer aik_..."
```

An API key acts as its owning user, within its **scope** (`read` keys can only
`GET`) — and a few operations (billing changes, API key management, account
deletion) are refused to every key. Each operation of the reference carries
`x-atako-api-key: read | write | forbidden`; see [API keys](/developers/api-keys).
Some endpoints additionally require you to be a
**company admin** (billing, team management, inviting members); the reference notes
this per operation.

A handful of routes are public and need no token at all — pricing, published blog/news
articles, use cases, integration marketing pages, and the OpenAPI document itself.

## Live events

Two endpoints stream [Server-Sent Events](https://developer.mozilla.org/docs/Web/API/Server-sent_events)
(`text/event-stream`) with the same Bearer header — an API key works:

* `GET /notifications/sse` — your notifications, plus live events of the agents you
  can see (`agent_status`, `notice_created`, `email_message`, `webhook_event`…).
* `GET /agents/{agentId}/events` — one agent's chat: new messages, typing, activity.

```bash theme={null}
curl -N https://api.atako.ai/notifications/sse -H "Authorization: Bearer aik_..."
```

## Uploading a file

Files go straight to storage through a signed URL:

```bash theme={null}
# 1. Create the file node in your Context (optional parentId = a folder)
curl -X POST https://api.atako.ai/client/files/nodes -H "Authorization: Bearer aik_..." \
  -H "Content-Type: application/json" -d '{"name":"brief.pdf"}'
# 2. Get a signed upload URL ({ signedUrl, storagePath }), then PUT the bytes there
curl -X POST https://api.atako.ai/client/files/<nodeId>/upload-url -H "Authorization: Bearer aik_..."
curl -X PUT "<signedUrl>" -H "Content-Type: application/pdf" --data-binary @brief.pdf
# 3. Mark it complete, then give an agent access
curl -X POST https://api.atako.ai/client/files/<nodeId>/complete-upload -H "Authorization: Bearer aik_..." \
  -H "Content-Type: application/json" -d '{"storagePath":"<storagePath>","fileSize":48213,"mimeType":"application/pdf"}'
curl -X POST https://api.atako.ai/agents/<agentId>/file-grants -H "Authorization: Bearer aik_..." \
  -H "Content-Type: application/json" -d '{"nodeIds":["<nodeId>"]}'
```

## Rate limits

| Plane | Limit |
| - | - |
| Authenticated routes (most of the API) | 6000 requests / minute, per user |
| Public `GET` routes | 60 requests / minute, per IP |
| A few sensitive public `POST` routes (newsletter signup, email-exists check, invitation preview) | 10 requests / 15 minutes, per IP |

Exceeding a limit returns `429` with the standard `error`/`code` envelope below.

## Errors

Errors use a small JSON envelope:

```json theme={null}
{ "error": "AGENT_LIMIT_REACHED" }
```

`error` is either a short human-readable message or a `SCREAMING_SNAKE_CASE` code,
depending on the route — treat it as an opaque string to match against rather than a
single stable enum across the whole API. Some routes add extra fields alongside
`error` (for example `LAST_ADMIN_OF_COMPANY` also returns `companyName` and
`agentCount`) — see each operation's error responses in the reference.

Common status codes:

| Status | Meaning |
| - | - |
| `400` | Invalid request body/params |
| `401` | Missing, malformed, or invalid bearer token |
| `402` | No active subscription / payment required |
| `403` | Authenticated, but not permitted (e.g. not a company admin) |
| `404` | Not found — also returned instead of `403` on several resource-scoped routes, so a caller can't distinguish "doesn't exist" from "not yours" |
| `409` | Conflict with current state (e.g. agent already ended) |
| `429` | Rate limit exceeded |

## Pagination

List endpoints use one of two conventions, and neither returns a total count today —
fetch pages until one comes back shorter than the limit you asked for:

* **`limit`/`offset`** — most list endpoints (agents, marketing content). A plain JSON
  array response.
* **`page`/`limit`** — the credit transaction ledger (`GET /subscriptions/credits/transactions`).

## What's not in this reference

A few HTTP surfaces on `api.atako.ai` are deliberately outside this customer API
reference:

* **Admin, internal, orchestrator, and webhook-delivery routes** — not part of the
  customer-facing surface (separate secret-based auth, or third-party webhook
  ingestion).
* **The Content API** (`cak_…` keys, `/content/*`) — a separate, more restricted key
  type for headless CMS-style access to blog/news/use-case content.
* **The Atako MCP server** (`/mcp`) — see its [own docs](/developers/mcp/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.