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

# Replace the stored floor arrangement

> Replaces the whole document, creating the row on the company's first edit (version 1). Every id must belong to the caller's company and two occupants of the SAME team cannot share a `slot` — either breach is a 400 with an explicit message, never a silent drop. `version` is an optional optimistic lock: when given and no longer current, 409 Version conflict rather than overwriting a colleague's whole rearrangement.



## OpenAPI

````yaml /api-reference/openapi.json put /floor/layout
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, with all of that user's permissions —
    there is no separate key scope in this release.


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


    - **Atako MCP server** — `POST /mcp` (auth: same Bearer token as above)
    exposes a read-only Model Context Protocol tool catalogue for AI clients
    (Claude Code, Claude Desktop, Cursor, ChatGPT). 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: Projects
  - name: Public
  - name: Marketing Content
paths:
  /floor/layout:
    put:
      tags:
        - Floor
      summary: Replace the stored floor arrangement
      description: >-
        Replaces the whole document, creating the row on the company's first
        edit (version 1). Every id must belong to the caller's company and two
        occupants of the SAME team cannot share a `slot` — either breach is a
        400 with an explicit message, never a silent drop. `version` is an
        optional optimistic lock: when given and no longer current, 409 Version
        conflict rather than overwriting a colleague's whole rearrangement.
      operationId: putFloorLayout
      requestBody:
        description: ''
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                pods:
                  type: array
                  items:
                    type: object
                    properties:
                      teamId:
                        type: string
                        format: uuid
                      x:
                        type: number
                      z:
                        type: number
                    required:
                      - teamId
                      - x
                      - z
                agents:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      slot:
                        type: integer
                        minimum: 0
                        maximum: 199
                        description: Desk index inside the pod of the occupant's own team.
                    required:
                      - id
                      - slot
                members:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      slot:
                        type: integer
                        minimum: 0
                        maximum: 199
                        description: Desk index inside the pod of the occupant's own team.
                    required:
                      - id
                      - slot
                version:
                  type: integer
                  minimum: 0
                  description: Expected current version. Omit for last-writer-wins.
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  layout:
                    $ref: '#/components/schemas/FloorLayout'
                  version:
                    type: integer
                required:
                  - layout
                  - version
        '400':
          description: Malformed body, or an id/slot the company cannot accept.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, malformed, or invalid bearer token / API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Admin only — every floor write is reserved to a company admin.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found, or the caller is not authorized to access this resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Version conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    FloorLayout:
      type: object
      description: >-
        Stored floor arrangement (AF-41). Only what the automatic layout cannot
        infer: where each team platform sits, and which desk of its own team an
        occupant stands at. Reconciled at read time — entries whose id is no
        longer on the floor are stripped from the served document (never from
        the stored row).
      properties:
        pods:
          type: array
          items:
            type: object
            properties:
              teamId:
                type: string
                format: uuid
              x:
                type: number
                description: Pod centre, world units.
              z:
                type: number
            required:
              - teamId
              - x
              - z
        agents:
          type: array
          description: >-
            id = agentId, slot = desk index inside the pod of ITS OWN team (slot
            0 of team A and slot 0 of team B are different desks).
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              slot:
                type: integer
            required:
              - id
              - slot
        members:
          type: array
          description: id = userId, same slot semantics as `agents`.
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              slot:
                type: integer
            required:
              - id
              - slot
      required:
        - pods
        - agents
        - members
    Error:
      type: object
      description: >-
        Atako's standard error envelope. `error` is either a short
        human-readable message or a SCREAMING_SNAKE_CASE code (routes are
        inconsistent about which — treat it as an opaque string and match on it
        exactly if you need to branch on error type). Some routes add extra
        fields alongside `error` (see the operation's own error responses).
      properties:
        error:
          type: string
        code:
          type: string
          description: >-
            Present on some routes; a stable machine-readable code duplicating
            or refining `error`.
      required:
        - error
      additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        An `aik_…` programmatic API key (app.atako.ai → Settings → API keys) or
        a Supabase session JWT.

````