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

# OAuth2 provider redirect callback

> Public / session-less — called by the OAuth provider's browser redirect. Authenticity comes from the signed `state` param (10-minute TTL), never from a bearer token. Always responds with an HTTP redirect to the web app's Settings > Integrations page (`?connected=<providerKey>` on success, `?error=oauth_denied|oauth_invalid_state|oauth_token_server_rejected|oauth_callback_param_missing|oauth_callback_param_invalid|oauth_exchange_failed` on failure) — never a JSON body. Multi-data-center providers (Zoho) also send the account's token server (`accounts-server`): it must be one of the connector's allow-listed origins, otherwise the connect is refused with `oauth_token_server_rejected` before any token call. Providers that name the connected tenant in the redirect (QuickBooks Online: `realmId`) must send it and it must match the connector's pattern, otherwise the connect is refused with `oauth_callback_param_missing` / `oauth_callback_param_invalid`, also before any token call.



## OpenAPI

````yaml /api-reference/openapi.json get /integrations/oauth/callback
openapi: 3.1.0
info:
  title: Atako API
  version: 0.1.0
  description: >-
    The Atako customer API — manage AI agents, their files, integrations,
    billing, and your company/team, programmatically.


    ## Authentication


    Every non-public endpoint takes a Bearer token that is either:

    - a **programmatic API key** (`aik_…`) — create one at
    [app.atako.ai](https://app.atako.ai) → Settings → API keys (company-admin
    only), or

    - a **Supabase session JWT** — what the web app itself sends; not practical
    to obtain outside a browser session.


    ```bash

    curl https://api.atako.ai/agents -H "Authorization: Bearer aik_..."

    ```


    An API key acts as its owning user, within the limits of the key:


    - **Scope** — a `read` key can only call GET operations (any other verb:
    `403 API_KEY_READ_ONLY`); a `write` key can call everything its user can,
    except the operations below.

    - **Forbidden to every key** — billing changes (every non-GET
    `/subscriptions/*`), minting agent tokens, listing or managing API keys
    (every `/users/api-keys` operation), deleting the account: `403
    API_KEY_FORBIDDEN`. These need a signed-in user in the app.

    - **Expiry** — optional (30, 90 or 365 days); an expired key gets `401
    API_KEY_EXPIRED`.


    Each operation carries `x-atako-api-key: read | write | forbidden` — the
    minimum key scope it needs, or `forbidden`.


    ## Live events


    `GET /notifications/sse` and `GET /agents/{agentId}/events` are Server-Sent
    Events streams (`text/event-stream`), authenticated with the same Bearer
    header — an API key works.


    ## Uploading a file


    Two steps: `POST /client/files/nodes` then `POST
    /client/files/{nodeId}/upload-url` return a signed storage URL; `PUT` the
    raw bytes to it, then call `POST /client/files/{nodeId}/complete-upload`.
    Grant it to an agent with `POST /agents/{agentId}/file-grants`.


    ## Other Atako HTTP surfaces (not covered by this spec)


    - **Atako MCP server** — `POST /mcp` (auth: same Bearer token as above)
    exposes the same capabilities as Model Context Protocol tools for AI clients
    (Claude Code, Claude Desktop, Cursor, ChatGPT), grouped in toolsets
    (`/mcp?toolsets=projects,agents`); a `read` key only gets read-only tools.
    See
    [docs.atako.ai/developers/mcp/overview](https://docs.atako.ai/developers/mcp/overview).

    - **Content API** (`cak_…` key, `/content/*`) — a separate, more restricted
    key type for headless CMS-style access to blog/news/use-case content. Not
    documented here.


    ## Errors


    Errors use a JSON envelope: `{ "error": string, "code"?: string }`. `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, not
    a stable enum across the whole API.


    ## Rate limits


    Authenticated routes: 6000 requests/min per user (`authRateLimit`). Public
    GET routes: 60/min per IP. A handful of sensitive public POST routes
    (newsletter signup, email-exists, invitation preview) are limited to 10
    requests / 15 min per IP.


    ## Pagination


    List endpoints use either simple `limit`/`offset` query params (marketing
    content — a plain JSON array response, capped at the documented max) or
    `page`/`limit` (credit transactions). Neither returns a total count today;
    fetch until a page comes back shorter than `limit`.
servers:
  - url: https://api.atako.ai
    description: Production
security: []
tags:
  - name: Agents
  - name: Messages
  - name: Activity
  - name: Agent Options
  - name: API Keys
  - name: Files
  - name: Cron Jobs
  - name: Sub-Agents
  - name: Interagent Messages
  - name: Integrations
  - name: Subscriptions
  - name: Users
  - name: Company
  - name: Teams
  - name: Floor
  - name: Search
  - name: Notices
  - name: Organization
  - name: Projects
  - name: Notifications
  - name: Agent Shared Items
  - name: Agent Email
  - name: Agent Webhooks
  - name: Company Dashboard
  - name: LLM Provider Keys
  - name: Public
  - name: Marketing Content
paths:
  /integrations/oauth/callback:
    get:
      tags:
        - Integrations
      summary: OAuth2 provider redirect callback
      description: >-
        Public / session-less — called by the OAuth provider's browser redirect.
        Authenticity comes from the signed `state` param (10-minute TTL), never
        from a bearer token. Always responds with an HTTP redirect to the web
        app's Settings > Integrations page (`?connected=<providerKey>` on
        success,
        `?error=oauth_denied|oauth_invalid_state|oauth_token_server_rejected|oauth_callback_param_missing|oauth_callback_param_invalid|oauth_exchange_failed`
        on failure) — never a JSON body. Multi-data-center providers (Zoho) also
        send the account's token server (`accounts-server`): it must be one of
        the connector's allow-listed origins, otherwise the connect is refused
        with `oauth_token_server_rejected` before any token call. Providers that
        name the connected tenant in the redirect (QuickBooks Online: `realmId`)
        must send it and it must match the connector's pattern, otherwise the
        connect is refused with `oauth_callback_param_missing` /
        `oauth_callback_param_invalid`, also before any token call.
      operationId: integrationOAuthCallback
      parameters:
        - name: code
          in: query
          required: false
          description: Authorization code from the provider.
          schema:
            type: string
        - name: state
          in: query
          required: false
          description: Signed state token from the /start call.
          schema:
            type: string
        - name: error
          in: query
          required: false
          description: Set by the provider when the user denies access.
          schema:
            type: string
        - name: accounts-server
          in: query
          required: false
          description: >-
            Multi-data-center providers only (Zoho): origin of the account's
            token server, e.g. `https://accounts.zoho.eu`. Used for the code
            exchange and every refresh when allow-listed.
          schema:
            type: string
      responses:
        '302':
          description: >-
            Redirect to the web app; see description for the query params it
            carries.
      security: []

````

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