openapi: 3.2.0
info:
  title: Clyck API
  version: 2026-10-19
  summary: Run managed agents in your product. Choose your model, connect your
    tools, and stream results.
  description: |
    ### Introduction

    #### Build your product on managed agents

    Clyck runs agents for your application over HTTP. Configure an agent with your model, instructions and tools,
    start a session, and send it a task. Clyck manages the model and tool loop, conversation history and recovery.
    Your application receives results through a live event stream, signed webhooks or API reads.

    Your application stays in charge of the product: it decides when an agent works, which tools it can use and how its
    results reach your users. Clyck runs the model calls, tool calls, sandboxes and recovery.

    #### When to use Clyck

    - **Agents inside your product:** one session per customer, ticket, document or task, driven from your backend.
    - **Long-running and background work:** submit a task, let your user close the tab, and get a signed webhook when it finishes.
    - **Any model, your keys:** choose from the providers and models in `GET /models`, including Anthropic, OpenAI and Google. Select a model per agent version or per session.
    - **Your own tools:** connect MCP servers and HTTP endpoints, and grant each agent exactly the tools it needs.
    - **Built-in capabilities:** web search, browser automation, a managed sandbox for files and commands, and published file outputs.
    - **Live product experiences:** stream text, thinking and tool activity to your UI, and steer or follow up while the agent works.

    #### What Clyck runs, what your application owns

    | Area | Clyck runs | Your application owns |
    | --- | --- | --- |
    | Agent execution | Model calls, tool calls, retries, context summarization and recovery. | Instructions, model choice, when to submit work and what to do with results. |
    | Conversations | Durable sessions, history, live state streaming and webhooks. | Your product experience and your own records. |
    | Tools and sandboxes | Calls to your MCP and HTTP tools, sandbox lifecycle, web search and browser. | Your tool endpoints, which tools each agent may use, and sandbox choice. |
    | Identity and credentials | Tenant isolation, tool grant enforcement and encrypted credential storage. | End-user authentication and authorization, and your provider accounts. |
    | Outcomes | Recorded results for every submission and tool call. | Budgets, approvals and business-level checks on what the agent did. |

    #### Core concepts

    | Concept | What it is |
    | --- | --- |
    | **Agent** | A named configuration: model, instructions, tool grants and optional sandbox. Every change creates a new immutable version. |
    | **Session** | One durable conversation started from an agent version. Reuse it for follow-up tasks with its recorded history. |
    | **Submission** | Input you send to a session, with a status that ends `done`, `cancelled` or `failed`. A `done` input names its answer. |
    | **Entry** | A committed message in the session's history, such as your input, the agent's answer or a tool result. |
    | **Credential** | A stored API key for your model, sandbox, web search or browser provider. |
    | **Connection** | Your MCP server or HTTP endpoint, with its authentication. Agents use its tools through explicit grants. |
    | **Skill** | A tenant-owned collection of instructions and supporting files, attached by immutable version. Reading skills needs no sandbox. |
    | **Artifact** | A file the agent published from its sandbox, downloadable through `/files`. |

    ### Quick start

    Send a message to an agent and read its answer with a handful of API calls. You need a platform API key, which you create in
    the [dashboard](/dashboard), and an API key from a model provider. The API base URL is
    `https://api.useclyck.com/v1`.

    ```sh
    export CLYCK_API_URL="https://api.useclyck.com/v1"
    export CLYCK_API_KEY="your-platform-api-key"
    ```

    **1. Store your model API key.** Save the returned `id` as the credential ID.

    ```sh
    curl "$CLYCK_API_URL/credentials" -H "Authorization: Bearer $CLYCK_API_KEY" -H "Content-Type: application/json" \
      -d '{"name": "Anthropic", "category": "model", "provider": "anthropic", "api_key": "your-anthropic-api-key"}'
    ```

    **2. Choose a model.** `GET /models` lists the catalog of providers and model IDs; choose a model from your
    credential's provider.

    ```sh
    curl "$CLYCK_API_URL/models" -H "Authorization: Bearer $CLYCK_API_KEY"
    ```

    **3. Create an agent.** Save `latest_version.id` from the response.

    ```sh
    curl "$CLYCK_API_URL/agents" -H "Authorization: Bearer $CLYCK_API_KEY" -H "Content-Type: application/json" -d '{
      "name": "Assistant",
      "config": {
        "model": {"provider": "anthropic", "id": "claude-sonnet-5-5", "credential_id": "<credential_id>"},
        "instructions": "Answer clearly and concisely.",
        "tools": [{"type": "platform", "name": "web_search"}]
      }
    }'
    ```

    **4. Start a session.** Save the returned `id` as the session ID.

    ```sh
    curl "$CLYCK_API_URL/sessions" -H "Authorization: Bearer $CLYCK_API_KEY" -H "Content-Type: application/json" \
      -d '{"agent_version_id": "<latest_version.id>"}'
    ```

    **5. Submit input.** The `202` response is the saved submission. A `request_id` makes retries of this request safe.

    ```sh
    curl "$CLYCK_API_URL/sessions/<session_id>/submissions" -H "Authorization: Bearer $CLYCK_API_KEY" \
      -H "Content-Type: application/json" -d '{"content": "What is new in TypeScript this year?", "request_id": "req-1"}'
    ```

    **6. Read the outcome and the answer.** Read the submission until its `status` is `done`, `cancelled` or `failed`,
    then fetch the answer entry it names.

    ```sh
    curl "$CLYCK_API_URL/sessions/<session_id>/submissions/<submission_id>" -H "Authorization: Bearer $CLYCK_API_KEY"
    curl "$CLYCK_API_URL/sessions/<session_id>/entries?min_entry_id=<answer>&max_entry_id=<answer>" \
      -H "Authorization: Bearer $CLYCK_API_KEY"
    ```

    Your output looks similar to this:

    ```json
    {"id": 1, "conversation_id": 1, "request_id": "req-1", "type": "input", "status": "done", "entry": 2, "answer": 5}
    {"data": [{"id": 5, "conversation_id": 1, "kind": "message", "model": [{"role": "assistant",
      "content": [{"type": "text", "text": "Here are this year's TypeScript highlights..."}], "stop_reason": "stop"}]}],
     "next_cursor": null}
    ```

    What happened:

    1. Clyck saved your input and placed it in the session's conversation.
    2. The model wrote a `codemode` program that called `web_search`, and Clyck ran it and recorded each tool call.
    3. The model answered, and Clyck committed the answer as an entry and marked the submission `done`.
    4. The session kept its history, so the next submission continues the same conversation.

    The [runnable Python example](/reference/examples/saas.py) performs these steps with only the standard library:

    ```sh
    export MODEL_PROVIDER="anthropic"
    export MODEL_ID="claude-sonnet-5-5"
    export MODEL_API_KEY="your-model-api-key"
    python3 saas.py "Say hello in one sentence."
    python3 saas.py --session <session_id> "A follow-up question"
    ```

    Keep platform and provider API keys on your backend. From here, add your own tools, stream progress to your UI and
    register a webhook, as described in the guides below.

    ### Operate Clyck from your coding agent

    Connect an MCP-compatible coding agent to your Clyck MCP server URL to configure Clyck, start sessions,
    send input and read results. MCP uses an independent endpoint from the HTTP API's `/v1` base path.
    Local development exposes MCP at `http://localhost:8082/mcp` and the API at `http://localhost:8080/v1`.

    **Authentication.** Choose either OAuth or a platform API key:

    - **OAuth:** add the MCP URL to your client, then sign in with your Clyck account through WorkOS and approve
      access. Clients discover WorkOS through the MCP endpoint's OAuth protected-resource metadata and authentication
      challenge. Access tokens must be issued for this MCP endpoint and include its required scopes; the client
      handles obtaining and refreshing tokens. An MCP access token cannot be used directly with the HTTP API;
      API authorization requires a token issued for that API's resource audience.
    - **Platform API key:** configure a client that supports custom HTTP headers to send
      `Authorization: Bearer <platform-api-key>` on every request. The key has the same full-tenant access as it does
      through the HTTP API and stops authenticating new requests when revoked.

    Both methods act within the authenticated Clyck tenant, and each operation is authorized by Clyck's API.
    Configure model, sandbox and connection credentials through the Clyck dashboard or HTTP API before using MCP,
    then reference their stored IDs in tool arguments. MCP tools never accept authentication secrets or return
    stored secrets. Platform API key management is available through the dashboard and HTTP API.

    **Tools.** The MCP server exposes the following operations. Names use snake_case; inputs follow the corresponding
    HTTP operation, with path parameters, query parameters and JSON body properties supplied as tool arguments.

    | Area | Tools |
    | --- | --- |
    | Models | `list_models` |
    | BYO credentials | `list_credentials`, `delete_credential` |
    | Connections | `list_connections`, `get_connection`, `delete_connection` |
    | Agents and versions | `list_agents`, `get_agent`, `create_agent`, `list_agent_versions`, `create_agent_version` |
    | Sessions | `list_sessions`, `get_session`, `get_state`, `list_submissions`, `get_submission`, `list_entries`, `create_session`, `submit_input`, `cancel_submission`, `cancel_session`, `standby_session`, `delete_session` |

    Tools return the corresponding API JSON result as structured content and as JSON text. Successful operations
    whose HTTP response has no content return an empty object. API failures are tool errors containing the API's
    error code and message as JSON text. MCP request bodies are limited to 20 MiB; each operation's own limits also
    apply. Required inputs, pagination, dependency checks, immutable versions, cancellation and
    deletion have the behavior documented for the corresponding HTTP operations below.

    **First session.** Set up a model credential in the dashboard or HTTP API, and a sandbox credential if bringing
    your own sandbox. Use `list_models` and `list_credentials` to choose a model and find the stored credential IDs. Call
    `create_agent` with the model, instructions and desired tool grants, then pass its `latest_version.id` to
    `create_session`. OAuth MCP clients do not need a platform API key to use the MCP server.

    **Read results.** `submit_input` returns the saved submission immediately. Use its ID with `get_submission` to
    check for `done`, `cancelled` or `failed`. For a completed input, pass its `answer` entry ID as both `min_entry_id`
    and `max_entry_id` to `list_entries` to read the answer. `get_state` returns a single current snapshot;
    `list_entries` returns paginated committed history, including history removed from the current snapshot by
    summarization. MCP reads do not wait for a submission to finish or open a live event stream.

    **Revise and clean up.** Editing an agent means calling `create_agent_version` with a replacement configuration.
    Existing sessions keep their resolved configuration. Manage connection authentication through the dashboard or
    HTTP API; changing a connection's URL or type requires a new connection. `cancel_submission` withdraws queued input;
    `cancel_session` cancels active work and queued input while keeping the session available for new input.
    `standby_session` immediately releases an idle session's runtime resources while retaining the conversation and
    sandbox files, freeing its active-session slot. New input or context wakes it automatically. Active work must
    finish or be cancelled before entering standby.
    `delete_session` stops work, releases owned resources and deletes the session. Archive or delete dependent
    sessions before deleting credentials or connections. There is no agent-deletion tool.

    ### Build your integration

    Your backend maps product records and authenticated users to Clyck sessions. Clyck manages execution, tool grants,
    encrypted credentials and durable history; your application controls end-user access, budgets, approvals and how
    results reach your users. Store the session ID with your ticket, document or task, and check user access before
    forwarding messages or returning session data.

    #### Connect your own API as tools

    Agents call your systems through connections. Create a connection for an MCP server (Streamable HTTP) or an HTTP
    endpoint, then grant tools from it in the agent's `tools`. Connections are reached over public HTTPS.

    - **MCP:** `POST /connections` with `{type: "mcp", url, credentials}`, then grant
      `{type: "mcp", connection_id, tools: ["tool_name", ...]}` using the exact names your server advertises.
    - **HTTP:** `POST /connections` with `{type: "http", url, credentials}`, then grant
      `{type: "http", connection_id, name, description, parameters}`, where `parameters` is the JSON Schema for the
      arguments. Each call is a JSON `POST` of the arguments to the connection URL with a 120-second timeout. Give each
      HTTP tool its own connection URL when your endpoint routes by path.
    - **Results:** respond with `2xx` and a JSON body (or `204`) for every result the model should read, including
      business outcomes such as "customer not found". Other statuses fail the call, and the model sees only the status
      code, so put details the model needs in `2xx` results.
    - **Per-user access:** to scope tools to one end user or task, create a connection whose credentials are a
      short-lived token for that user, and start the session with `overrides.tools` listing the complete grants for the
      session, including the grant for that connection. Rotate credentials in place with
      `PATCH /connections/{connection_id}` as part of your application's token renewal flow.

    To build a support assistant, create a connection to your ticket lookup endpoint. Have your endpoint authorize
    access using the token, then return the ticket and account details as JSON:

    ```json
    {
      "name": "Ticket lookup for this customer",
      "type": "http",
      "url": "https://your-app.example.com/agent-tools/read-ticket",
      "credentials": {"api_key": "<customer-scoped-token>"}
    }
    ```

    Send that body to `POST /connections`, save its `id`, then start a ticket session with `POST /sessions`:

    ```json
    {
      "agent_version_id": "<latest_version.id>",
      "overrides": {
        "tools": [{
          "type": "http",
          "connection_id": "<connection_id>",
          "name": "read_ticket",
          "description": "Read an authorized support ticket and its account details.",
          "parameters": {
            "type": "object",
            "required": ["ticket_id"],
            "properties": {"ticket_id": {"type": "string"}},
            "additionalProperties": false
          }
        }]
      }
    }
    ```

    Submit "Read ticket #42 and suggest the next step" to this session. Clyck sends the tool arguments to your endpoint
    with `Authorization: Bearer <customer-scoped-token>`. The agent uses the result to answer, and your backend can
    inspect the arguments and response in the session's tool-call history. Each session keeps its resolved grants;
    include every tool it should use in `overrides.tools`.

    #### Stream progress to your UI

    Open `GET /sessions/{session_id}/events` from your backend and relay it to your UI. Each connection starts with a
    `snapshot` of the complete live state, followed by events for text and thinking deltas, tool activity, usage and
    submission outcomes. To render a session:

    1. Replace your state with each `snapshot`.
    2. Apply `message.started`, `message.delta` and `message.replaced` to the in-progress assistant message, and replace
       it with the committed message on `message.completed`.
    3. Show tool activity from `tool.started`, `tool.updated` and `tool.completed`. Nested calls carry `parent_call_id`.
    4. Use `submission.updated` to know when input is answered. Whenever a `snapshot` arrives after the first, read the
       submissions you are tracking, since a snapshot replaces events it supersedes.

    Streams close when the session enters standby. Opening a stream in standby returns a snapshot and then closes
    without waking the session. Submit new work, then open or reconnect the stream for its current snapshot. Work
    continues when a stream disconnects; read `GET entries` and tracked submissions for anything committed meanwhile.

    #### Get notified when work finishes

    Register a webhook for `submission.updated` and `artifact.created` to receive background results. Each notification
    names the session and submission or file; read that resource for its current state. See Webhooks for signing and
    delivery behavior.

    #### Bring your own skills

    Upload a directory containing `SKILL.md` and supporting files through `POST /skills`. Send individual files as
    multipart `files[]` parts with relative filenames, or send a ZIP as `application/zip`. The root `SKILL.md` uses
    YAML front matter with a `name` and `description`. A single enclosing directory is accepted and removed from
    stored relative paths. Keep the same skill name when uploading a new complete version through
    `POST /skills/{skill_id}/versions`.

    Each version contains at most 1,000 regular files and 30,000,000 bytes of uncompressed file contents. ZIP uploads
    contain at most 2,000 entries including directory entries. An upload
    request is at most 64,000,000 bytes including encoding and multipart overhead. Descriptions cannot contain NUL, must be non-blank and
    at most 1,024 Unicode characters; XML-like text is allowed. Oversized uploads return `413 skill_too_large`, and
    invalid bundles return `400 invalid_skill`. A version becomes available only after validation succeeds and all
    file contents have been stored successfully.
    There is currently no aggregate skill-storage limit. Skills do not consume the uploaded-file storage allowance.

    Attach skills in an agent configuration or session overrides:

    ```json
    {"skills": [{"skill_id": "10000000-0000-4000-8000-000000000002", "version": "3"}]}
    ```

    The version is required and accepts a positive integer string or `latest`. Creating an agent version resolves
    `latest` immediately; that agent version and its sessions retain the concrete version. A session's skill override
    resolves `latest` when the session is created. Omission inherits attachments, a supplied list replaces them, and
    `[]` clears them. Getters return concrete versions. Publishing another skill version never changes existing
    attachments. Skill contents remain available after standby and recovery.

    Attached skills automatically make `read_skill` available inside `codemode`, without a tool grant or sandbox.
    The model receives each skill's name, validated description, ID and pinned version in its catalog. It reads full
    instructions and supporting files only when needed:

    ```javascript
    text(await tools.read_skill({skill_id: "10000000-0000-4000-8000-000000000002"}));
    text(await tools.read_skill({skill_id: "10000000-0000-4000-8000-000000000002", path: "references/escalation.md"}));
    ```

    `read_skill` accepts `skill_id`, optional `path` (default `SKILL.md`), optional byte `offset` (default `0`) and
    optional byte `limit` (default `65536`, between `1` and `262144`). The result identifies `skill_id`, concrete
    `version`, `path`, `mime_type`, `size` (total file bytes), `offset`, `encoding`, `content`, `next_offset` and
    `truncated`. `next_offset` is the next byte position to read, or `null` at the end; `truncated` reports whether
    more bytes remain after this result. Follow `next_offset` to continue a large file. The selected bytes use `utf8`
    encoding when they are valid UTF-8 and otherwise use `base64`, including a slice that splits a UTF-8 character.
    Reading `SKILL.md` also returns the version's file manifest. The reader selects only exact uploaded paths from
    versions attached to this session. It cannot
    browse other skills, choose another version, access another tenant's files, or interpret paths as URLs, globs,
    shell expressions or host filesystem locations. Missing and inaccessible skills return the same not-found error.
    Attachment grants no tools or credentials and never executes uploaded scripts. Skills are not automatically
    mounted or copied into a sandbox.

    Relative paths contain at most 4,096 characters, cannot contain empty, `.` or `..` segments, backslashes or NULs,
    and cannot be absolute. Duplicate
    paths, symlinks, hard links and special files are rejected. Customer filenames never address the harness host's
    filesystem. `GET /skills/{skill_id}/versions/{version}` returns metadata and base64 file contents as JSON, or a
    downloadable ZIP when `Accept: application/zip` is supplied. Both forms identify the concrete version returned.

    #### Give the agent a sandbox

    Add `sandbox` to the agent configuration and grant its tools, for example
    `{type: "sandbox", tools: ["read", "write", "edit", "bash"]}`, to give the agent a filesystem and shell. Clyck
    creates the sandbox when a tool first needs it and binds it to the session, so every sandbox tool call works in the
    same environment. Sandboxes Clyck creates are deleted when their session is archived or deleted; an existing sandbox you attach with
    `sandbox_id` stays yours.

    | Start with | Configuration | Capabilities |
    | --- | --- | --- |
    | A Clyck-managed sandbox | `{provider: "clyck-managed"}` | `read`, `write`, `edit`, `bash`, uploaded input files and published output files. |
    | Your Blaxel workspace | `{provider: "blaxel", credential_id}` | `read`, `write`, `edit` and `bash`; attach an existing sandbox with `sandbox_id`. |
    | Your Daytona account | `{provider: "daytona", credential_id, snapshot}` | Commands, file operations and `computer_use_*` desktop tools; use `sandbox_id` in place of `snapshot` to attach an existing sandbox. |

    For Daytona, choose a snapshot available to your credential's account in the selected `target` region, which defaults
    to `us`. Computer use requires the snapshot or attached sandbox to include Daytona's required desktop software;
    Clyck starts those desktop services automatically. An attached sandbox must be accessible with the selected
    credential and running before tools can execute. Start or resume it in Daytona first: Clyck waits for startup
    already in progress, but does not start stopped sandboxes or resume paused or archived ones.

    For file workflows, choose the Clyck-managed sandbox. Upload input files with `POST /files` and reference them in a
    submission; the agent works on copies in its sandbox. When the agent produces a deliverable, it calls `publish_file`
    to save an immutable copy that you download with `GET /files/{file_id}`. Sandbox files are the agent's working
    state; published files are your durable output.

    For example, turn the quickstart agent into a CSV analyst by starting a session with these overrides:

    ```json
    {
      "agent_version_id": "<latest_version.id>",
      "overrides": {
        "instructions": "Analyze the supplied CSV, write a Markdown report, and publish the finished report with publish_file.",
        "sandbox": {"provider": "clyck-managed"},
        "tools": [
          {"type": "sandbox", "tools": ["read", "write", "edit", "bash"]},
          {"type": "platform", "name": "publish_file"}
        ]
      }
    }
    ```

    Send this body to `POST /sessions` and save the returned session ID. Upload your CSV as raw bytes and save the
    returned file `id`:

    ```sh
    curl "$CLYCK_API_URL/files" -H "Authorization: Bearer $CLYCK_API_KEY" \
      -H "X-Filename: sales.csv" -H "Content-Type: text/csv" --data-binary @sales.csv
    ```

    Submit the file and task to the analyst session with `POST /sessions/{session_id}/submissions`:

    ```json
    {
      "content": [
        {"type": "file", "file_id": "<file_id>"},
        {"type": "text", "text": "Summarize monthly sales and publish a Markdown report."}
      ],
      "request_id": "sales-report-1"
    }
    ```

    Follow the submission's outcome as in the quickstart. Use `GET /sessions/{session_id}/artifacts` to find published
    files and `GET /files/{file_id}` to download a report. For background completion, register a webhook before
    submitting the task. See Files for input sizes, working copies and artifact retention.

    #### Durable execution

    - **Accepted input is saved.** A `202` from `POST submissions` means the input is stored. Retrying with the same
      `request_id` returns the original submission.
    - **Sessions resume on their own.** History and accepted input persist across restarts and deploys, and active work
      continues automatically. Check a submission's status before submitting replacement work.
    - **Outcomes are explicit.** A submission's `status` is the source of truth for whether input was answered: `done`,
      `cancelled` or `failed` with a `reason`. Stream events report progress along the way.
    - **Every tool call is recorded.** `GET tool-calls` keeps arguments, results and outcomes for `codemode` and every
      tool it calls. During recovery, Clyck repeats only operations that are safe to repeat. A call interrupted after it
      started is recorded with `outcome` `unknown`, so your application can confirm the effect with the system that
      owns it before trying again.

    ### API conventions

    - **Authentication:** send `Authorization: Bearer <platform_api_key>`. Every resource belongs to the key's tenant;
      a resource of another tenant returns `404`.
    - **Account setup:** verify a card in the [dashboard](/dashboard) before creating or changing
      resources. Unverified writes return `402 card_verification_required`; reads and deletion remain available.
      Verification does not charge the account or start a paid subscription. Clyck may waive it for existing accounts.
    - **Errors:** errors return `{error: {code, message}}`. Branch on `code`; `message` is a human-readable explanation.
      Retry `503` errors after a short wait; the `message` names the unavailable dependency.
    - **Asynchronous work:** a `2xx` response means the request was accepted. The submission or tool-call record
      reports the outcome of the work.
    - **Pagination:** lists return `data` and `next_cursor`. Follow `next_cursor` until it is `null`, keeping the same
      filters, bounds and order; a page can be shorter than `limit`. Resource lists are newest first; submissions and
      tool calls default to ascending ID order, entries to descending ID order. A malformed cursor, or one reused with a
      different order, returns `400 invalid_request`. Lists reflect writes as they happen. Identifiers and cursors are
      opaque.
    - **Request bodies:** JSON endpoints accept `application/json` (case-insensitive, with optional parameters); other
      media types return `415 unsupported_media_type`. Request bodies are up to 16 MiB. String limits count Unicode
      code points; JSON strings and property names must be well-formed Unicode without `U+0000`, otherwise the request
      returns `400 invalid_request`. File uploads accept arbitrary bytes.
    - **Naming:** fields use `snake_case`; enum values and your own JSON keep their documented spelling.

    ### Guides

    #### Managed service limits

    Managed service allowances and session concurrency are shared across the current tenant's agents and sessions.
    Free includes 2 concurrent resident sessions and 100 MB of file storage. Its monthly allowances are 3,600 managed
    sandbox seconds, 3,600 managed browser seconds and 100 managed searches. Pro includes 50 concurrent resident
    sessions and 10 GB of file storage, with monthly allowances of 360,000 managed sandbox seconds, 360,000 managed
    browser seconds and 5,000 managed searches. Free monthly allowances follow the UTC calendar month. Paid Pro allowances
    follow the subscription's paid billing period, starting when the subscription begins and renewing on its monthly anniversary.
    File storage is current capacity, using decimal units (1 MB = 1,000,000 bytes; 1 GB = 1,000,000,000 bytes),
    and does not reset monthly. Enterprise allowances and customer-specific overrides are configured by Clyck.
    View current usage and effective limits in the [dashboard](/dashboard/usage).

    Sandbox time is an estimate: it begins when the managed sandbox is first accessed during an awake period,
    including input file preparation, and continues through the idle window until the session enters standby.
    Browser time runs while a managed browser is allocated, through release, expiry or session standby.
    Each new managed browser counts at least 60 seconds. Reconnecting to the same browser does not add another
    minimum. If browser creation has an unknown outcome and its resource cannot be released, usage may conservatively
    include its full configured timeout to account for the browser that may still be running.
    Standby time is excluded. Concurrent intervals add together. Customer-provided sandbox, browser and search
    credentials are excluded from managed service usage. Managed searches count when dispatched, including failed
    attempts. File storage includes uploaded files and published outputs, including reserved pending publications.
    Deleting a stored file frees storage capacity. Model-provider token usage is reported separately in session state and history.

    Concurrent sessions include active and idle sessions with a live runtime owner. Standby sessions do not count.
    Activating another session at the concurrency limit fails with `429 concurrency_limit_exceeded`.
    Exhausted managed allowances reject resource access with `409 usage_limit_exceeded`. Running sandbox and browser
    usage is checked approximately every five seconds; a session whose managed runtime allowance is exhausted has
    its current work stopped and enters standby. State and history remain available. Timed limits may overrun by
    the checking interval plus cleanup time, multiplied by concurrent resources. Managed runtime and search allowances reset monthly;
    there are no automatic overage charges.
    Stopped work is reported through the normal submission cancellation outcome; the dashboard identifies the
    exhausted allowance. A later input can continue the same session, but exhausted managed tools remain unavailable
    until the allowance resets or Clyck changes the account's limits.

    #### How agents use tools: code mode

    Agents compose tools through short JavaScript programs. The model calls `codemode` and uses the tools you granted
    as `await tools.<name>(args)`. A program can chain calls, loop over results and select what to return to the model,
    keeping its context focused. Each tool call is recorded individually for your UI and tool-call history.

    Inside `codemode`, platform tools keep their names (`web_search`, `browser_client`, `publish_file`), HTTP tools use
    their grant `name`, sandbox tools are named `sandbox_<name>`, and MCP tools are named `mcp_<name>_<suffix>` with a
    suffix that is stable for the connection and tool. `ALL_TOOLS` and `searchTools` list the callable names.

    Programs resume from recorded tool results after interruptions. Each program runs for up to 120 seconds, including
    its tool calls; a first line of `// @options: {"timeout_ms": 30000}` sets a shorter deadline. For longer work, such
    as a large build or test suite, the agent starts it in the background in the sandbox and checks its output in later
    programs.

    #### Browser automation

    Grant `{type: "platform", name: "browser"}` to give the agent a remote browser driven through a Playwright-style API.
    Clyck supplies the browser, or an optional `credential_id` selects your own Browserbase credential. Inside
    `codemode`, `browser_client` returns the client source and its API documentation.

    Each `codemode` program starts a fresh JavaScript environment, so bootstrap the client in each program:

    ```javascript
    const {browser, helper} = eval((await tools.browser_client()).source);
    const page = await browser.contexts()[0].newPage();
    await page.goto("https://example.com");
    text(await page.title());
    image(await page.screenshot());
    store("examplePage", helper.savePage(page));
    ```

    In a later program, bootstrap again and pick up the same page:

    ```javascript
    const {helper} = eval((await tools.browser_client()).source);
    const page = await helper.getPage(load("examplePage"));
    text(await page.title());
    ```

    **Keeping state between programs.** `store` and `load` keep JSON values after a successful program: up to 262144
    characters of serialized JSON per value and 1048576 characters in total. Create client and locator objects in each
    program, since stored JSON keeps data rather than methods. `helper.savePage(page)` synchronously returns a page
    reference; store it unchanged and pass it to `helper.getPage(reference)`, which asynchronously reattaches the same
    live page while its page and browser are open. It fails for a closed page, an expired browser, or a reference from
    another session or browser.

    **Browser lifecycle.** The session keeps its browser across submissions and reconnections for up to one hour.
    Session archival, deletion and `helper.reset()` release it. Standby releases a Clyck-provided browser (a browser grant without
    `credential_id`), losing its pages, cookies and page references; the next browser use creates a fresh browser.
    A browser using your `credential_id` is disconnected during standby but remains bound, retaining its provider state
    while available.
    Its provider lifetime continues during standby; waking the session reconnects to it if it is still available.
    `browser.contexts()`, `context.pages()` and `page.url()` synchronously return the most recently observed state, and
    each awaited browser command updates it; await `helper.refresh()` to pick up changes made outside this client.
    Await `helper.reset()` to release the browser and invalidate this client and its references, then bootstrap again
    for a new browser. When the bound browser is unreachable (its creation was interrupted or reconnection
    failed), `browser_client` still returns the client with `snapshot.status.state` `unavailable` and a stable `code`
    and safe `message`, so `helper.reset()` is always available; a connected browser has `state` `ready`. A refresh
    retries the connection to an existing browser. Bootstrap again to replace an expired browser; interrupted creation
    requires a reset. Old browser and page references never target a replacement browser. When the
    provider rejects browser creation, for example because of an invalid credential, `browser_client` fails without
    binding a browser and can be called again once the cause is fixed. Missing credentials, invalid configuration or
    cancelled work also stop client initialization.

    **Timing.** `Date.now()` inside `codemode` advances as tool results arrive, so wait with browser methods such as
    `waitForURL` or `waitForLoadState` rather than a loop. Playwright operations that accept a `timeout` default to
    30000 ms and accept 0 to 120000 ms; 0 disables the operation timeout within the program's own deadline of at most
    120 seconds. Commands can run concurrently, including `Promise.all` with `waitForURL` and a click that navigates.

    **API.** The client provides exactly the methods below. Locator and frame builders are synchronous and chainable;
    browser operations, locator actions and reads, and `locator.all()` are asynchronous unless listed as synchronous
    above.

    | Object | Methods |
    | --- | --- |
    | Browser | `contexts()` |
    | Context | `pages()`, `newPage()` |
    | Page | `close()`, `goto(url, options?)`, `goBack(options?)`, `goForward(options?)`, `reload(options?)`, `url()`, `title()`, `screenshot(options?)`, `setViewportSize(size)`, `waitForURL(urlOrRegExp, options?)`, `waitForLoadState(state?, options?)`, `evaluate(functionOrExpression, argument?)` |
    | Page, Locator and FrameLocator builders | `getByRole(role, options?)`, `getByText(textOrRegExp, options?)`, `getByLabel(textOrRegExp, options?)`, `getByPlaceholder(textOrRegExp, options?)`, `getByTestId(testIdOrRegExp)`, `locator(selector, options?)`, `frameLocator(selector)` |
    | Locator composition | `filter(options)`, `first()`, `last()`, `nth(index)`, `and(locator)`, `or(locator)`, `all()` |
    | Locator actions | `click(options?)`, `dblclick(options?)`, `fill(value, options?)`, `press(key, options?)`, `check(options?)`, `uncheck(options?)`, `selectOption(values, options?)`, `pressSequentially(text, options?)`, `setChecked(checked, options?)` |
    | Locator reads and waits | `innerText(options?)`, `textContent(options?)`, `allTextContents()`, `getAttribute(name, options?)`, `count()`, `isVisible(options?)`, `isEnabled(options?)`, `ariaSnapshot(options?)`, `waitFor(options?)`, `evaluate(functionOrExpression, argument?, options?)`, `evaluateAll(functionOrExpression, argument?)` |
    | `page.mouse` | `click(x, y, options?)`, `move(x, y, options?)`, `wheel(deltaX, deltaY)`, `dblclick(x, y, options?)`, `down(options?)`, `up(options?)` |
    | `page.keyboard` | `press(key, options?)`, `insertText(text)` |

    Methods follow Playwright argument conventions and work with the browser's existing contexts. Frame locators can be
    nested. `RegExp` arguments keep their patterns and flags for text and role filters and `waitForURL`. Pass locator
    objects from the same page, rather than selector strings, to `filter`'s `has`/`hasNot`, `and`/`or`, `locator()` and
    screenshot `mask` options.
    Navigation methods return a plain summary `{url, status, statusText, ok, headers}` or `null`. `screenshot()` returns
    an image block, PNG by default or JPEG on request; show it with `image(await page.screenshot())`. Screenshots take
    inline `style` strings, which run in the remote browser, rather than `path` or `stylePath`. Evaluation runs
    JavaScript in the page and can read or change page state; pass values in as an explicit argument, since evaluated
    functions run in the page rather than the program. Evaluation arguments and results support JSON, `undefined`,
    `NaN`, `Infinity`, `-Infinity` and `-0`; cycles, `BigInt`, `Date` objects and JavaScript handles are rejected.
    `evaluate` and `evaluateAll` are the methods that take functions.

    Browser actions act on real websites. An action interrupted mid-flight may already have taken effect, so inspect the
    page before repeating it. Browser credentials and provider endpoints stay inside Clyck and are never returned to
    `codemode`.
servers:
  - url: https://api.useclyck.com/v1
    description: Platform instance
security:
  - ApiKey: []
tags:
  - name: Skills
    description: Upload, inspect and attach tenant-owned, immutable skill versions.
      Skills provide instructions and supporting files without requiring a
      sandbox.
  - name: Agents
    description: >
      Configure reusable agents. Every configuration change creates an immutable
      version, and each session starts from

      a specific version, so you can roll out changes deliberately.
  - name: Model catalog
    description: >
      Discover model providers, model IDs and capabilities before selecting a
      model.
  - name: Sessions
    description: >
      A session is one durable conversation started from an agent version.
      Submit input, stream progress, and read

      history, submissions and tool calls.


      Sessions start in `standby`, become `active` when processing new input or
      context, and become `idle` when that

      execution finishes. After five minutes idle, the session automatically
      enters `standby`. New input or context

      wakes a standby session automatically. Reads, polling and open event
      streams do not reset the idle timer or

      prevent standby. Retrying a submission with the same `request_id` does not
      extend the idle period.


      Standby preserves the session's configuration, history and sandbox files,
      and releases any Clyck-provided browser,

      losing its state. Browsers using your `credential_id` remain bound,
      subject to their provider lifetime.

      Daytona VM sandboxes (Linux VM and Windows), including attached sandboxes,
      are paused on standby, preserving

      their files and memory. Daytona containers are not explicitly paused.
      Sandboxes created in your Daytona account

      use Daytona's default inactivity timers; attached sandboxes keep their
      existing settings. The next sandbox tool

      call resumes a paused Daytona sandbox or starts a stopped or archived one
      before executing. Stop and archive

      preserve files but lose running processes and memory. Blaxel manages
      sandbox suspension and resumption

      automatically; other connections or keep-alive work can keep a Blaxel
      sandbox running.

      Sandboxes are not deleted on standby. To release resources immediately,
      call

      `POST /sessions/{session_id}/standby`; it returns `409 session_busy`
      during active work. To remove a session and

      its owned sandbox, delete the session. To release owned resources
      permanently while retaining readable history, archive the session. An
      existing sandbox attached with `sandbox_id` stays yours.
  - name: Files
    description: >
      Upload files for the agent to work on, and download the files it
      publishes.


      Uploaded files, published outputs and reserved pending publications share
      the tenant's file storage capacity

      shown in the [dashboard](/dashboard/usage). A write
      that would exceed capacity fails with `409 usage_limit_exceeded`; existing
      files remain

      readable and deletable. Deleting a stored file frees its storage. Storage
      does not reset monthly, and sandbox

      working files are not counted toward stored file capacity.


      #### Input files


      Upload bytes to `/files`, then submit `{type: "file", file_id}` or `{type:
      "image", file_id}` blocks in `content`.

      File blocks use the Clyck-managed sandbox (`sandbox: {provider:
      "clyck-managed"}`);

      other configurations return `400 files_require_sandbox`. Before the
      submission is accepted, Clyck

      copies each file into the session's sandbox and gives the model the file's
      name and absolute path. Acceptance is

      all or nothing: if a copy fails, or the input is rejected with `409
      conversation_busy`, no copies are left behind.

      The copy is the agent's working copy: later steps see the agent's edits,
      and deleting the upload leaves it in

      place. Files of queued input are in the sandbox before earlier work
      finishes.


      Image blocks go directly to the model, with or without a sandbox; use a
      model whose `input` in `GET /models`

      includes `image`. Images can be inline base64 or a `file_id`

      in PNG, JPEG, GIF or WebP format. Clyck decodes and normalizes them to at
      most 2000 pixels per dimension and

      4.5 MiB, and the decoded format replaces a declared `mime_type`. Images
      that cannot be decoded return

      `400 invalid_image` before acceptance. A submission references up to 16
      MiB of file bytes, counting repeated

      references separately; larger input returns `413 input_files_too_large`.
      `Entry.input` keeps the submitted

      references and `entry.model` contains the model-facing content. Files are
      private to their tenant; a missing file

      or one belonging to another tenant returns `404`.


      #### Publishing output artifacts


      Grant `{type: "platform", name: "publish_file"}` to an agent with the
      Clyck-managed sandbox. When a file is

      finished, the agent calls `tools.publish_file({path, filename?,
      mime_type?})` inside `codemode`. `path` is an

      absolute path to a regular file; parent directory symlinks are resolved,
      and a symlink as the final path

      component or a special file is rejected. The filename defaults to the
      path's basename and the media type to

      `application/octet-stream`. Each artifact is up to 16 MiB. Clyck reads the
      bytes directly from the sandbox, so

      they never pass through the model, and returns the stored file metadata, a
      SHA-256 checksum and provenance.

      Publish a file after the agent has finished writing it.


      Each publication is an immutable copy. List it with `GET
      /sessions/{session_id}/artifacts`, download it with

      `GET /files/{file_id}` and delete it with `DELETE /files/{file_id}`.
      Published files are kept until you delete

      them, independently of the sandbox, the source file and the session; keep
      their file IDs if you delete the

      session first. Retrying the same publication returns the same file ID and
      bytes, and a separate call publishes a

      new copy. Lists and `artifact.created` webhooks include completed
      publications, including those from a

      submission that later fails.
  - name: Webhooks
    description: >
      Receive background results through signed HTTPS requests when a submission
      finishes or an artifact is published.

      Subscribe a public HTTPS URL to `submission.updated`, `artifact.created`,
      or both.


      - **`submission.updated`** fires when a submission reaches `done`,
      `cancelled` or `failed`. Context submissions
        reach `done` when placed and have no answer. The session stays ready for more input.
      - **`artifact.created`** fires when a published file is ready to download.


      Each notification carries the event `id`, `type`, `session_id` and the
      `submission_id` or `file_id`. Read that

      resource through this API for its current state, which also keeps retried
      deliveries from carrying stale data.


      **Delivery behavior**


      - **Duplicates:** delivery is at-least-once within the retry window.
      Retries keep the same event ID and body;
        deduplicate by event ID.
      - **Ordering:** notifications can arrive in any order; drive state from
      the resource you read.

      - **Retries:** each attempt has a 10-second timeout and counts any `2xx`
      as acknowledgement. Failed attempts
        retry after 60 seconds with exponential backoff up to one hour between attempts, for 24 hours from the event;
        a delivery still unacknowledged then is marked `failed`. `GET /webhooks/{webhook_id}/deliveries` shows each
        delivery's status, attempts and next attempt time. For complete coverage, also reconcile your tracked
        submissions through reads, for example on a schedule.
      - **Recipients:** an event goes to the registrations that exist when it is
      first queued.

      - **Destinations:** URLs are public HTTPS endpoints, called without
      following redirects. Keep credentials out of
        the URL; requests are authenticated by signature.
      - **Cancellation:** deleting a registration or a session cancels its
      pending deliveries; a request already in
        flight can still arrive. Deleting a session keeps its published files.

      **Verifying signatures**


      Registration returns `signing_secret` once; store it to verify requests.
      The URL, events and secret of a

      registration are fixed; create a new registration to change them. Each
      request carries `Webhook-Id` (equal to

      the body `id`), `Webhook-Timestamp` (Unix seconds) and `Webhook-Signature`
      (`v1=<hex>`). Compute HMAC-SHA256 with

      the `signing_secret` string as the key over the UTF-8 string
      `<timestamp>.<raw request body>`, and compare its

      hexadecimal digest to the signature with a constant-time comparison. Check
      that the timestamp is recent, verify

      the signature over the raw body before parsing it, and deduplicate by
      event ID. Each retry is signed with its own

      attempt timestamp.
  - name: BYO credentials
    description: >
      Store model, sandbox, web search and browser provider API keys in
      `/credentials`. `category` identifies the use:

      `model`, `sandbox`, `web_search` or `browser`. Clyck validates
      provider-specific settings at creation and checks

      authentication with the provider when the key is used. Models use your own
      keys. Web search and browser tools use

      Clyck's provider accounts unless a grant selects your credential, in which
      case that credential is always used.


      API keys are encrypted at rest and write-only. Settings and agent
      configuration are readable by every caller in

      your tenant, so keep secrets in `api_key`. Tool results are recorded as
      returned and reach the model, entries and

      tool calls, so design tools to return results rather than their own
      credentials.


      `PATCH` with `api_key` rotates the secret and keeps the credential's ID,
      `category`, `provider`, `settings` and

      session bindings. New model requests and tool operations, including those
      of running sessions, use the new

      secret; operations already in flight and established connections finish
      with the previous one, and an existing

      browser stays attached to the same pages.


      Delete a credential after archiving or deleting the sessions that use it.
      Deleting it in Clyck leaves the key active at your

      provider. Credentials and connections are separate resources with separate
      IDs; filter the credentials list with

      `category`.
  - name: Tool connections
    description: >
      Store your MCP servers (Streamable HTTP) and HTTP tool endpoints in
      `/connections` with `type` `mcp` or `http`,

      then grant agents the tools they need. Clyck validates the configuration
      at creation and checks authentication

      when the endpoint is used. Each agent's explicit grants select the tools
      it may call from a connection.

      Authentication is encrypted at rest and write-only.


      Connections are reached over the public internet. A URL naming `localhost`
      or a literal private, loopback,

      link-local, shared, multicast or other special-purpose address returns
      `400 destination_not_allowed`. Clyck

      resolves hostnames for every connection and contacts only public
      addresses: an MCP server that resolves to a

      special-purpose address fails session activation with `409
      invalid_configuration` naming the connection, and an

      HTTP tool call returns a tool error. Clyck calls endpoints directly,
      without following redirects. Tool results are

      recorded as returned and reach the model, entries and tool calls, so
      design endpoints to return results rather

      than their own credentials.


      `PATCH` with `credentials` rotates authentication and keeps the ID,
      `type`, URL and session bindings.

      `credentials` replaces the complete authentication object, and `{}`
      removes authentication. New operations use

      the new authentication; operations already in flight and established
      connections finish with the previous one.

      Delete a connection after archiving or deleting the sessions that use it.
      Filter the connections list with `type`.
  - name: Platform API keys
    description: >
      Create, list and revoke the keys that authenticate requests to this API.
      Each key has full access to its tenant,

      including key management.
paths:
  /api-keys:
    get:
      tags:
        - Platform API keys
      operationId: listApiKeys
      summary: List platform API key metadata
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of API key metadata.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiKeyList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Platform API keys
      operationId: createApiKey
      summary: Create a platform API key for the current tenant
      description: Any authenticated tenant caller may create keys. The secret is
        returned only in this response.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - name
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: \S
      responses:
        "201":
          description: Key metadata and one-time secret.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatedApiKey"
        default:
          $ref: "#/components/responses/Error"
  /api-keys/{key_id}:
    parameters:
      - name: key_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    delete:
      tags:
        - Platform API keys
      operationId: deleteApiKey
      summary: Revoke a platform API key
      responses:
        "204":
          description: The key can no longer authenticate new requests.
        default:
          $ref: "#/components/responses/Error"
  /models:
    get:
      tags:
        - Model catalog
      operationId: listModels
      summary: List supported model capabilities
      x-mcp-description: List supported providers, models and capabilities to choose
        an agent model.
      responses:
        "200":
          description: Available provider/model pairs and their capabilities.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ModelList"
        default:
          $ref: "#/components/responses/Error"
  /credentials:
    get:
      tags:
        - BYO credentials
      operationId: listCredentials
      summary: List BYO credentials
      x-mcp-description: List metadata and IDs to see which model, sandbox, search or
        browser credentials are stored in the Clyck platform. This tool cannot
        store or rotate a key or reveal credential secrets. Configure or rotate
        credentials in the Clyck dashboard or HTTP API.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
        - name: category
          in: query
          description: Include only credentials in this category. Keep this filter
            unchanged when using a cursor.
          schema:
            type: string
            enum:
              - model
              - sandbox
              - web_search
              - browser
      responses:
        "200":
          description: A page of credential metadata. API keys are write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - BYO credentials
      operationId: createCredential
      summary: Store a BYO credential
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCredential"
      responses:
        "201":
          description: Stored credential metadata. API keys are write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Credential"
        default:
          $ref: "#/components/responses/Error"
  /credentials/{credential_id}:
    parameters:
      - $ref: "#/components/parameters/CredentialId"
    patch:
      tags:
        - BYO credentials
      operationId: rotateCredential
      summary: Rotate provider API key
      description: Replaces the secret and keeps the credential's identity, settings
        and session bindings. New model requests and tool operations, including
        those of running sessions, use the new secret; operations already in
        flight and established connections finish with the previous one.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - api_key
              properties:
                api_key:
                  $ref: "#/components/schemas/ProviderApiKey"
      responses:
        "200":
          description: Credential metadata. API keys are write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Credential"
        default:
          $ref: "#/components/responses/Error"
    get:
      tags:
        - BYO credentials
      operationId: getCredential
      summary: Get credential metadata
      responses:
        "200":
          description: Credential metadata. API keys are write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Credential"
        default:
          $ref: "#/components/responses/Error"
    delete:
      tags:
        - BYO credentials
      operationId: deleteCredential
      summary: Delete a credential
      x-mcp-description: Delete a stored credential after archiving or deleting all
        sessions that use it. This does not revoke the key at its provider.
      description: Archive or delete the sessions that use a credential first; while
        any session that has not finished archiving references it, this returns
        `409 credential_in_use`. Agent versions keep the IDs they were created
        with, so create a new version that selects another credential before
        starting new sessions; a session from a version naming a deleted
        credential returns `404`.
      responses:
        "204":
          description: Credential deleted from Clyck. The API key stays active at your
            provider until you revoke it there.
        default:
          $ref: "#/components/responses/Error"
  /connections:
    get:
      tags:
        - Tool connections
      operationId: listConnections
      summary: List tool connections
      x-mcp-description: Find existing MCP and HTTP connection IDs. Configure
        connections in the Clyck dashboard or HTTP API.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
        - name: type
          in: query
          description: Include only connections of this type. Keep this filter unchanged
            when using a cursor.
          schema:
            type: string
            enum:
              - mcp
              - http
      responses:
        "200":
          description: A page of connection metadata. Authentication is write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConnectionList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Tool connections
      operationId: createConnection
      summary: Create a tool connection
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateConnection"
      responses:
        "201":
          description: Stored connection metadata. Authentication is write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Connection"
        default:
          $ref: "#/components/responses/Error"
  /connections/{connection_id}:
    parameters:
      - $ref: "#/components/parameters/ConnectionId"
    patch:
      tags:
        - Tool connections
      operationId: rotateConnection
      summary: Rotate connection authentication
      description: Replaces the authentication and keeps the connection's identity,
        URL and session bindings. New tool operations, including those of
        running sessions, use the new authentication; operations already in
        flight and established connections finish with the previous one.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - credentials
              properties:
                credentials:
                  $ref: "#/components/schemas/ToolEndpointCredentials"
      responses:
        "200":
          description: Connection metadata. Authentication is write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Connection"
        default:
          $ref: "#/components/responses/Error"
    get:
      tags:
        - Tool connections
      operationId: getConnection
      summary: Get connection metadata
      x-mcp-description: Read a connection's name, type and URL. Authentication
        secrets are never returned.
      responses:
        "200":
          description: Connection metadata. Authentication is write-only.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Connection"
        default:
          $ref: "#/components/responses/Error"
    delete:
      tags:
        - Tool connections
      operationId: deleteConnection
      summary: Delete a tool connection
      x-mcp-description: Delete a tool connection after archiving or deleting all
        sessions that use it.
      description: Archive or delete the sessions that use a connection first; while
        any session that has not finished archiving references it, this returns
        `409 connection_in_use`. Agent versions keep the IDs they were created
        with, so create a new version that selects another connection before
        starting new sessions; a session from a version naming a deleted
        connection returns `404`.
      responses:
        "204":
          description: Tool connection deleted.
        default:
          $ref: "#/components/responses/Error"
  /skills:
    get:
      tags:
        - Skills
      operationId: listSkills
      summary: List skills
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of skills, with descriptions from their latest versions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkillList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Skills
      operationId: createSkill
      summary: Upload skill
      description: >
        Creates a skill with immutable version `1`. Upload the complete
        directory as multipart `files[]` parts with

        relative filenames, or as a ZIP. Include

        `SKILL.md` at the upload root or inside one enclosing directory. Each
        bundle is limited to 1,000 regular

        files and 30,000,000 uncompressed bytes; ZIPs contain at most 2,000
        entries including directories, and file

        paths contain at most 4,096 characters. The complete HTTP body is
        limited to 64,000,000 bytes. Invalid

        bundles return `400 invalid_skill` and oversized bundles return `413
        skill_too_large`; neither publishes a

        version. Skill storage has no aggregate limit and does not consume
        uploaded-file allowances.
      requestBody:
        $ref: "#/components/requestBodies/SkillUpload"
      responses:
        "201":
          description: Skill identity with latest_version set to '1'.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Skill"
        default:
          $ref: "#/components/responses/Error"
  /skills/{skill_id}/versions:
    parameters:
      - $ref: "#/components/parameters/SkillId"
    get:
      tags:
        - Skills
      operationId: listSkillVersions
      summary: List skill versions
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of immutable version metadata and file manifests, newest
            first.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkillVersionList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Skills
      operationId: createSkillVersion
      summary: Update skill
      description: >
        Upload replacement files to create a new immutable version. Applies the
        same bundle validation and limits

        as uploading a skill. The name in `SKILL.md` must match the

        skill's existing name. This is a complete snapshot: omitted files are
        not carried forward. New versions

        do not change existing agent versions or sessions. Missing and other
        tenants' skills return `404`.
      requestBody:
        $ref: "#/components/requestBodies/SkillUpload"
      responses:
        "201":
          description: The newly published version's metadata and file manifest.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkillVersion"
        default:
          $ref: "#/components/responses/Error"
  /skills/{skill_id}/versions/{version}:
    parameters:
      - $ref: "#/components/parameters/SkillId"
      - name: version
        in: path
        required: true
        schema:
          $ref: "#/components/schemas/SkillVersionSelector"
    get:
      tags:
        - Skills
      operationId: getSkillVersion
      summary: Get skill version
      description: >
        Defaults to JSON metadata and every file's exact bytes encoded as
        base64. Send `Accept: application/zip`

        to download the complete version as a ZIP. `latest` is resolved for this
        request; both representations

        identify the concrete version returned. Missing and other tenants'
        skills return `404` without exposing

        their metadata or files.
      responses:
        "200":
          description: Complete skill version. ZIP responses have an attachment
            disposition and X-Skill-Version header.
          headers:
            X-Skill-Version:
              description: Concrete version returned, including when the request selected
                latest.
              schema:
                type: string
                pattern: ^[1-9][0-9]*$
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SkillVersionContents"
            application/zip:
              schema:
                type: string
                contentEncoding: binary
        default:
          $ref: "#/components/responses/Error"
  /agents:
    get:
      tags:
        - Agents
      operationId: listAgents
      summary: List agent identities
      x-mcp-description: List agents in your Clyck tenant. Use get_agent to read an
        agent's latest version and configuration.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of agent identities.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Agents
      operationId: createAgent
      summary: Create an agent and its first immutable version
      x-mcp-destructive: true
      x-mcp-description: Create an agent and its first immutable version using
        existing credential and connection IDs. Pass latest_version.id to
        create_session to start a conversation.
      description: >
        Creates the agent and its first immutable version. Sessions start from a
        specific version and can override

        `model`, `instructions`, `thinking_level`, `tools`, `skills` and
        `sandbox` for that session alone: each supplied field

        replaces the version's field, omitted fields are inherited, and
        `sandbox` `null` removes an inherited sandbox.

        Clyck resolves skill `latest` selectors when creating this agent
        version, validates the resolved configuration

        and keeps it fixed for the session. New versions apply to new

        sessions, so running sessions keep the configuration they started with.


        The model works through one tool, `codemode`, and calls the granted
        tools from the JavaScript programs it writes.

        Each grant names exactly the tools the agent may use. Inside `codemode`,
        HTTP tools use their grant name, sandbox

        tools are named `sandbox_<name>`, and MCP tools are named
        `mcp_<name>_<suffix>`, where characters other than

        letters, digits and `_` become `_` and the suffix is stable for the
        connection and tool; `ALL_TOOLS` and

        `searchTools` list the callable names. Programs run in a deterministic
        runtime so they resume exactly after an

        interruption: time advances as tool results arrive, so programs wait by
        calling tools rather than with timers

        such as `setTimeout`. Each program runs for up to 120 seconds; a first
        line of

        `// @options: {"timeout_ms": 30000}` sets a shorter deadline.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - name
                - config
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: \S
                config:
                  $ref: "#/components/schemas/AgentConfig"
      responses:
        "201":
          description: Agent with `latest_version` containing its first version.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        default:
          $ref: "#/components/responses/Error"
  /agents/{agent_id}:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    get:
      tags:
        - Agents
      operationId: getAgent
      summary: Get an agent and its latest version
      x-mcp-description: Read an agent and its latest immutable version, including the
        configuration and version ID used to create sessions.
      responses:
        "200":
          description: Agent and latest immutable version.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        default:
          $ref: "#/components/responses/Error"
  /agents/{agent_id}/versions:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    get:
      tags:
        - Agents
      operationId: listAgentVersions
      summary: List immutable versions newest first
      x-mcp-description: List an agent's immutable versions, newest first, to inspect
        configurations or choose a version for a new session.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of immutable agent versions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentVersionList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Agents
      operationId: createAgentVersion
      summary: Create a new immutable version
      x-mcp-destructive: true
      x-mcp-description: Save a replacement agent configuration as a new immutable
        version and make it the latest version. Existing sessions keep their
        original configuration.
      description: >
        Creates a new immutable version and makes it the agent's
        `latest_version`. New sessions can start from it, and existing sessions
        keep the configuration they started with.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - config
              properties:
                config:
                  $ref: "#/components/schemas/AgentConfig"
      responses:
        "201":
          description: New version. Existing sessions keep their original configuration.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentVersion"
        default:
          $ref: "#/components/responses/Error"
  /sessions:
    get:
      tags:
        - Sessions
      operationId: listSessions
      summary: List sessions
      x-mcp-description: List sessions, optionally filtered by archive status. Keep
        the same filter when following a pagination cursor.
      description: Includes archived sessions. Use `archived` to filter by archive
        status, and keep that filter when following a cursor.
      parameters:
        - name: archived
          in: query
          schema:
            type: boolean
          description: When supplied, return only archived sessions (true) or sessions
            that have not been archived (false).
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of sessions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SessionList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Sessions
      operationId: createSession
      summary: Create a session from a specific agent version
      x-mcp-destructive: true
      x-mcp-description: Start a durable conversation from an agent version ID.
        Overrides replace complete top-level fields; omitted fields inherit from
        the version, and sandbox null removes an inherited sandbox. Returns a
        standby session; submit_input starts work.
      description: >
        Starts a durable conversation from an agent version. `overrides` replace
        complete top-level configuration

        fields for this session, and omitted fields inherit from the version.
        Clyck validates the resolved configuration

        and keeps it fixed for the session; the agent version is unchanged. A
        supplied `overrides.skills` list replaces

        all inherited attachments and resolves `latest` selectors when the
        session is created; `[]` clears skills.


        **Durability and recovery.** Accepted input and conversation history
        persist across process crashes, restarts

        and deploys, and active work continues automatically afterwards. Check a
        submission's outcome before submitting

        replacement work. During recovery, Clyck repeats model requests and tool
        operations that are safe to repeat. A

        tool call interrupted after it started is recorded with `outcome`
        `unknown` rather than repeated, so confirm its

        effect with the service that owns it before trying again. A model answer
        interrupted mid-generation stays in

        history as an assistant message with `stop_reason` `aborted`, and the
        answer is then generated again.


        **Availability.** When a session runs or wakes from standby, Clyck
        connects its model, MCP servers and platform tools.

        If one is unreachable, Clyck retries with increasing delay of up to five
        minutes. New work and reads of an

        active or idle conversation retry activation immediately. Reads from
        standby do not connect model or tool

        providers. Requests requiring activation return `503
        session_unavailable`, or `409 invalid_configuration`

        when the configuration needs a change; the message names the model,
        sandbox, connection or platform tool

        involved. During a runtime failover, which takes up to about 30 seconds,
        session requests can wait and then return

        `503 runtime_unavailable`; retry them.


        **Sandbox and browser.** A configured sandbox is created or attached
        when a tool first needs it and is then bound

        to the session for its lifetime. Sandboxes Clyck creates are deleted
        when the session is archived or deleted; a

        sandbox attached with `sandbox_id` stays yours. If sandbox creation is
        rejected, for example for an invalid

        credential or rate limiting, a later tool operation tries again once the
        cause is fixed; if its outcome is

        uncertain, later operations look for that same sandbox. Paused, stopped
        and archived Daytona sandboxes are

        resumed or started before the next sandbox tool call, including after
        provider-side inactivity suspension.

        If a bound sandbox becomes unavailable, sandbox tools

        return errors while the conversation history stays intact; start a new
        session for a fresh sandbox.


        Daytona sandbox HTTP failures report `Sandbox tool call failed (HTTP
        <status>)`. When the provider returns a

        nonempty JSON `message` string of at most 2,000 characters before and
        after sanitization, the error appends

        `Daytona error: <message>` on a new line. Messages are normalized to one
        line, with control characters removed

        and reflected authentication credentials redacted. Missing, malformed or
        oversized messages produce a

        status-only error; the rest of the provider response is not relayed.


        Publish files you want to keep, since published artifacts have their own
        lifecycle (see Files). The browser stays with the

        session across submissions and reconnections for up to one hour. Session
        archival, deletion and `helper.reset()` release

        it and lose its state. Standby also releases Clyck-provided browsers;
        the next browser use creates a fresh

        browser. A browser using your `credential_id` remains bound across
        standby, subject to its provider lifetime.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - agent_version_id
              properties:
                agent_version_id:
                  type: string
                  format: uuid
                overrides:
                  $ref: "#/components/schemas/SessionOverrides"
      responses:
        "201":
          description: Session created in standby. Its model and tools connect when it
            first runs, and a configured sandbox is created or attached when
            first needed.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Session"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: getSession
      summary: Get session configuration
      x-mcp-description: Read a session's identity, archive status and resolved
        immutable configuration.
      responses:
        "200":
          description: Session identity and resolved immutable configuration.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Session"
        default:
          $ref: "#/components/responses/Error"
    delete:
      tags:
        - Sessions
      operationId: deleteSession
      summary: Stop work, release owned resources, and delete a session
      x-mcp-description: Stop work, release owned resources and delete the session and
        its history.
      responses:
        "204":
          description: Session deleted.
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/submissions:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: listSubmissions
      summary: List submissions and their outcomes
      x-mcp-description: List input and context submissions with their outcomes. Pages
        may be short or empty; follow next_cursor until it is null.
      description: Pages may be empty or shorter than `limit`. Continue using
        `next_cursor` until it is `null`.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of input and context submissions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubmissionList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Sessions
      operationId: submitInput
      summary: Submit input to a session
      x-mcp-destructive: true
      x-mcp-description: Save work or context and return its submission immediately.
        Use request_id for safe retries, get_submission to check the outcome and
        list_entries to read the answer. Context adds information without
        requesting an answer; when_busy controls how input joins busy work.
      x-mcp-examples:
        - session_id: 10000000-0000-4000-8000-000000000001
          content: Analyze the account.
        - session_id: 10000000-0000-4000-8000-000000000001
          type: context
          content: The account tier is premium.
          request_id: account-tier-1
      description: >
        Send work or context to the session. A `202` response means the input is
        saved; read the submission, stream

        events or use a webhook to follow its outcome.


        **Input.** `content` is text, or ordered text, image and file blocks.
        Images are inline base64 or a `file_id`;

        file blocks are copied into the Clyck-managed sandbox and images are
        decoded before acceptance (see Files).


        **Idempotency.** `request_id` makes the submission safe to retry:
        reusing it within the session returns the

        original submission unchanged, without rereading files. Reusing it for a
        different `type` returns

        `409 request_conflict`. To start a new attempt after a terminal `failed`
        or `cancelled` outcome, inspect the

        recorded tool effects and submit the task with a new `request_id`.


        **Outcomes.** A submission is `queued`, then `placed` in the
        conversation, and ends `done`, `cancelled` or

        `failed`. A `done` input names its `answer` entry; `cancelled`
        (explicitly aborted) and `failed` (ended

        unsuccessfully) include a `reason` and may name a placed entry. Work
        interrupted by a recoverable runtime event

        stays pending and continues until it reaches an outcome. `done` means
        the agent answered; your application judges

        whether the answer meets its own goals. Several steering submissions can
        share one answer, so use each

        submission's `status` to see whether it was answered.


        **When the agent is busy.** `when_busy` defaults to `followUp`, which
        waits for the current answer and then

        starts new work; follow-ups run one at a time. `steer` joins the current
        work at the next input boundary,

        normally after tool calls: every steering submission waiting there is
        placed together and shares the current

        answer, and steering still waiting when an answer finishes is placed
        with the next follow-up and shares that

        answer. `reject` returns `409 conversation_busy` unless the input can
        start immediately. Cancelling a queued

        submission withdraws only that input, which ends `cancelled` with
        `reason` `aborted`; cancelling the session

        does the same for active work and queued input. New submissions can
        start work afterwards.


        **Context.** `type` `context` appends user-provided context, such as
        history, facts or application updates,

        without requesting an answer. It is placed immediately when the session
        is idle, or at the next input boundary

        while it is busy, and is then `done` with no answer. Context takes no
        `when_busy`. It stays queued through

        session cancellation and is placed at the next boundary, which after
        cancellation is the next submission; cancel

        it individually to withdraw it. Context adds user messages and leaves
        instructions and tool grants unchanged.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateSubmission"
      responses:
        "202":
          description: Input accepted and saved, or the original submission for the same
            `request_id`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Submission"
        "409":
          $ref: "#/components/responses/Error"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/submissions/{submission_id}:
    parameters:
      - $ref: "#/components/parameters/SessionId"
      - name: submission_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
    get:
      tags:
        - Sessions
      operationId: getSubmission
      summary: Get a submission and its outcome
      x-mcp-description: Read a submission's status and outcome. Terminal states are
        done, cancelled and failed. For a completed input, use its answer entry
        ID with list_entries to read the answer.
      responses:
        "200":
          description: Current submission state and answer when present.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Submission"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/submissions/{submission_id}/cancel:
    parameters:
      - $ref: "#/components/parameters/SessionId"
      - name: submission_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
    post:
      tags:
        - Sessions
      operationId: cancelSubmission
      summary: Withdraw queued input
      x-mcp-description: Withdraw a queued input or context submission. If it is
        already placed, use cancel_session to stop active work. Settled
        submissions keep their outcome.
      description: >
        Withdraws queued input. `cancelled` means the input was withdrawn and
        ends `cancelled` with `reason` `aborted`;

        `already_placed` means it is already in the conversation, so cancel the
        session to stop its work; `settled` means

        it already has an outcome. An unknown submission returns `404
        not_found`.
      responses:
        "200":
          description: Cancellation result for this submission.
          content:
            application/json:
              schema:
                type: object
                required:
                  - status
                properties:
                  status:
                    type: string
                    enum:
                      - cancelled
                      - already_placed
                      - settled
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/cancel:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    post:
      tags:
        - Sessions
      operationId: cancelSession
      summary: Cancel active work and queued inputs
      x-mcp-description: Cancel active work and queued inputs. Queued context must be
        cancelled individually. The session can accept new input; tool effects
        that already happened remain in place.
      responses:
        "200":
          description: Active work and queued input submissions are cancelled. Queued
            context submissions stay queued for placement; cancel them
            individually to withdraw them. The session is ready for new input.
            Tool effects that already happened remain in place.
          content:
            application/json:
              schema:
                type: object
                required:
                  - cancelled
                properties:
                  cancelled:
                    const: true
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/lifecycle:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: getSessionLifecycle
      summary: Get the session's active, idle, standby or archived state
      description: Reading the lifecycle does not wake the session or reset its
        five-minute idle timer.
      responses:
        "200":
          description: Current session lifecycle state and the start of its current idle
            period, when idle.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SessionLifecycle"
              examples:
                active:
                  value:
                    state: active
                    idle_since: null
                idle:
                  value:
                    state: idle
                    idle_since: 2026-10-22T12:00:00.000Z
                standby:
                  value:
                    state: standby
                    idle_since: null
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/archive:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    post:
      tags:
        - Sessions
      operationId: archiveSession
      summary: Permanently stop a session and retain its history
      description: >
        Irreversibly closes the session to new work. Stops active work,
        including background work, and cancels all

        queued input and context submissions. Completed outcomes and tool
        effects that already happened remain in

        place. Interrupted submissions end `cancelled` with `reason` `aborted`.
        There is no unarchive operation.


        Releases session-owned sandbox and browser resources, including
        unpublished sandbox files. An attached

        customer-owned sandbox stays yours. Published artifacts retain their
        independent lifecycle.


        Returns success after final outcomes are saved and resource cleanup
        completes. Repeating archive succeeds

        without changing `archived_at`. If interrupted or cleanup fails, the
        session stays closed to new work;

        Clyck retries unfinished archival automatically, and the archive request
        can be retried. History reads may

        temporarily fail while unfinished archival is being completed.
        `archived_at` records when closure began.


        Configuration, history, tool calls, submissions, state and artifact
        listings remain readable. Reads never

        connect model or tool providers. The event stream returns a final
        snapshot and closes. Input and context

        submissions, including retries with an existing `request_id`,
        cancellation and standby return

        `409 session_archived`. Delete remains available and removes the stored
        session history. Outcome webhooks

        remain eligible for delivery. This operation takes no request body.
      responses:
        "200":
          description: The session is permanently archived and its final history is
            readable.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - state
                properties:
                  state:
                    const: archived
              example:
                state: archived
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/standby:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    post:
      tags:
        - Sessions
      operationId: standbySession
      summary: Release an idle session's runtime resources
      x-mcp-idempotent: true
      x-mcp-destructive: true
      x-mcp-description: Put an idle session into standby to free its active-session
        slot while retaining its history and sandbox files. New input wakes it
        automatically. Active work must finish or be cancelled first.
      description: >
        Enters standby immediately, preserving the session and its sandbox
        files. Releases any Clyck-provided browser

        and loses its state; the next browser use creates a fresh browser. A
        browser using your `credential_id` remains

        bound, subject to its provider lifetime. Pauses bound Daytona Linux VM
        and Windows sandboxes, including

        attached sandboxes, and waits for them to pause; already inactive or
        unavailable sandboxes are left alone.

        Daytona containers retain their provider lifecycle settings. The next
        sandbox tool call resumes or starts a

        paused, stopped or archived Daytona sandbox before executing. New input
        or context wakes the session automatically.

        Already in standby succeeds without changing the session. Returns `409
        session_busy` during active work;

        cancel that work first if it should stop. The operation takes no request
        body.
      responses:
        "200":
          description: The session is in standby. Bound Daytona VMs are paused when
            available; Blaxel manages its sandbox suspension automatically.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - state
                properties:
                  state:
                    const: standby
              example:
                state: standby
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/entries:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: listEntries
      summary: Read recorded conversation history
      x-mcp-description: Read paginated committed history, including entries removed
        from the current snapshot by summarization. Set min_entry_id and
        max_entry_id to a submission's answer ID to read that answer. Keep
        bounds and order unchanged when following a cursor.
      description: >
        Read the complete committed history in ID order, newest first unless
        `order` is `ascending`. `min_entry_id` and

        `max_entry_id` are inclusive bounds: set both to a submission's `answer`
        to read that answer, or use `ascending`

        order with `min_entry_id` one greater than the last entry you received
        to read new entries. Continue a paginated

        query with its cursor and the same bounds and order. History includes
        every committed entry, including entries

        that context summarization has removed from the live snapshot.


        Thinking returned by the provider appears as `thinking` blocks in
        history, state and streamed messages. Its

        content is what the provider returns for the model: full text, a
        summary, an empty string or content marked

        `redacted`. Provider signatures and replay metadata stay internal.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
        - name: order
          in: query
          schema:
            type: string
            enum:
              - ascending
              - descending
            default: descending
        - name: min_entry_id
          in: query
          schema:
            type: integer
            minimum: 1
        - name: max_entry_id
          in: query
          schema:
            type: integer
            minimum: 1
      responses:
        "200":
          description: A page of recorded conversation entries.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EntryList"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/tool-calls:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: listToolCalls
      summary: List retained top-level and nested tool calls
      description: >
        The durable record of `codemode` calls and every tool they called:
        arguments, recorded results, outcomes,

        diagnostics and available timing and usage, with `parent_call_id`
        linking nested calls. Records persist across

        reconnects and restarts, including results a `codemode` program did not
        pass back to the model, and are deleted

        with the session. Live output windows are shown in the event stream
        rather than stored here.


        Calls are listed in order of first appearance, ascending by default, and
        cursors keep the chosen order. Records

        progress while you paginate; read a call again for its current state.
        For an `unknown` outcome, confirm the

        effect with the service that owns it before retrying.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
        - name: order
          in: query
          schema:
            enum:
              - ascending
              - descending
            default: ascending
      responses:
        "200":
          description: A page of tool calls.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ToolCallList"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/tool-calls/{call_id}:
    parameters:
      - $ref: "#/components/parameters/SessionId"
      - name: call_id
        in: path
        required: true
        schema:
          type: string
    get:
      tags:
        - Sessions
      operationId: getToolCall
      summary: Get a retained tool call and its recorded response
      responses:
        "200":
          description: Tool call, including completion fields when available.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ToolCall"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/state:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: getState
      summary: Get the current conversation state
      x-mcp-description: Read one current snapshot of conversation entries, pending
        inputs, active work and usage. Use list_entries for complete committed
        history. Returns immediately.
      responses:
        "200":
          description: Conversation entries, pending inputs, current work and usage.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/State"
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/events:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Sessions
      operationId: observeEvents
      summary: Observe live conversation events
      description: >
        Follow a session live. Send `Accept: text/event-stream`. Each SSE frame
        has an event name in `event` and a JSON

        payload in `data`; `x-event-schemas` maps each event name to its data
        schema, and heartbeats are SSE comments.

        A connection follows submissions while the session is active or idle,
        and closes when the session enters

        standby or is archived. A stream opened in standby or after archival
        returns its snapshot and then closes without waking the session. Submit

        new work, then open or reconnect the stream for its current snapshot.
        Work continues when a stream disconnects.


        **Snapshots.** The first event is a `snapshot` of the complete live
        state (`State`), taken atomically with

        registration for later changes. Every later `snapshot` also replaces all
        live state, including previews and tool

        activity; a consumer that falls behind the stream's buffer receives a
        fresh snapshot to catch up, in place of the

        events it supersedes, including `submission.updated`. After any later
        snapshot, read the submissions you track

        for their outcomes. Snapshots take the place of event replay, so frames
        carry no `id`. To reconnect, open a new stream, read `GET entries` for

        history committed meanwhile, and read tracked submissions for their
        outcomes. Events are ordered on each

        connection, and progress updates can be coalesced rather than sent per
        token.


        **Messages.** `message.started` establishes a preview identified by
        `preview_id`, `message.delta` changes it and

        `message.replaced` replaces it entirely; apply replacements rather than
        concatenating updates. Content indexes

        address the public `content` array, including thinking blocks: a
        `content` insertion starts a block, and `text`

        or `thinking` deltas append to it. `message.completed` delivers the
        committed message with its durable

        `entry_id`, and a `preview_id` when it matches a preview; replace that
        preview, and use `entry_id` to reconcile the

        entry across snapshots, history pages and completion events. A preview
        ID is valid within its snapshot. A

        completed message can be a tool call or an intermediate answer;
        `submission.updated` and submission reads report

        whether input was answered, and `execution.ended` marks the end of a
        stretch of work.


        **Tools.** `call_id` identifies a tool operation and `parent_call_id`
        links a call made inside `codemode` to it.

        Both are opaque and stable across history and reconnects. Committed
        `toolCall.id` and `toolResult.tool_call_id`

        use the same IDs, and `entry_id` links to the committed tool-result
        entry when available. Tool-call IDs inside an

        assistant preview belong to that preview and are replaced by durable IDs
        at commitment. Tool output is a live

        window of recent output; `GET tool-calls` keeps the complete recorded
        results. An `unknown` outcome means the call

        ended without a recorded result, so confirm its effect before retrying.


        | Event | Data schema | Meaning |

        | --- | --- | --- |

        | `snapshot` | `State` | Replace all live state and preview identities.
        |

        | `submission.updated` | `Submission` | Current durable input outcome. |

        | `execution.started`, `execution.ended` | `ExecutionEvent` | Work began
        or ended for the listed submissions. |

        | `message.started` | `MessageStarted` | Establish an assistant preview.
        |

        | `message.delta` | `MessageDelta` | Insert content or append text,
        thinking or argument strings. |

        | `message.replaced` | `MessageReplaced` | Replace the entire preview. |

        | `message.completed` | `MessageCompleted` | Reconcile the authoritative
        committed entry. |

        | `tool.started` | `ToolStarted` | A model-facing or nested operation
        began. |

        | `tool.updated` | `ToolUpdated` | Update retained output, progress or
        diagnostics. |

        | `tool.completed` | `ToolCompleted` | Recorded result or explicitly
        unknown outcome. |

        | `retry.started`, `retry.ended` | `Retry`, `RetryEnded` | Retry waiting
        began or ended. |

        | `compaction.started`, `compaction.completed` | `CompactionStarted`,
        `CompactionCompleted` | Context summarization activity and outcome. |

        | `usage.updated` | `CumulativeUsage` | Replace cumulative recorded
        usage. |

        | `inbox.updated` | `InboxUpdated` | Replace the queued-input list. |

        | `execution.error` | `ExecutionFailed` | A safe execution-failure
        notification. |


        Snapshot `entries` hold the active conversation context; `GET entries`
        holds the complete history, including

        entries summarized out of the active context. Stored credentials never
        appear in conversation responses.
      x-event-schemas:
        snapshot:
          $ref: "#/components/schemas/State"
        submission.updated:
          $ref: "#/components/schemas/Submission"
        execution.started:
          $ref: "#/components/schemas/ExecutionEvent"
        execution.ended:
          $ref: "#/components/schemas/ExecutionEvent"
        message.started:
          $ref: "#/components/schemas/MessageStarted"
        message.delta:
          $ref: "#/components/schemas/MessageDelta"
        message.replaced:
          $ref: "#/components/schemas/MessageReplaced"
        message.completed:
          $ref: "#/components/schemas/MessageCompleted"
        tool.started:
          $ref: "#/components/schemas/ToolStarted"
        tool.updated:
          $ref: "#/components/schemas/ToolUpdated"
        tool.completed:
          $ref: "#/components/schemas/ToolCompleted"
        retry.started:
          $ref: "#/components/schemas/Retry"
        retry.ended:
          $ref: "#/components/schemas/RetryEnded"
        compaction.started:
          $ref: "#/components/schemas/CompactionStarted"
        compaction.completed:
          $ref: "#/components/schemas/CompactionCompleted"
        usage.updated:
          $ref: "#/components/schemas/CumulativeUsage"
        inbox.updated:
          $ref: "#/components/schemas/InboxUpdated"
        execution.error:
          $ref: "#/components/schemas/ExecutionFailed"
      responses:
        "200":
          description: A snapshot followed by typed live events until the connection closes.
          content:
            text/event-stream:
              schema:
                type: string
              example: |
                event: snapshot
                data: {"conversation":{"id":1},"entries":[],"agent":{},"inbox":[],"execution":{"busy":false,"inputs":[],"tools":[],"nested_tools":[],"compactions":[]},"usage":{"models":[],"tools":[]}}
        default:
          $ref: "#/components/responses/Error"
  /sessions/{session_id}/artifacts:
    parameters:
      - $ref: "#/components/parameters/SessionId"
    get:
      tags:
        - Files
      operationId: listSessionArtifacts
      summary: List published output artifacts
      description: Lists completed publications newest first. Retain file IDs before
        deleting a session; published files remain independently downloadable
        and deletable.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of immutable published files and provenance.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ArtifactList"
        default:
          $ref: "#/components/responses/Error"
  /webhooks:
    get:
      tags:
        - Webhooks
      operationId: listWebhooks
      summary: List webhook registrations
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: Registrations newest first, without signing secrets.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookList"
        default:
          $ref: "#/components/responses/Error"
    post:
      tags:
        - Webhooks
      operationId: createWebhook
      summary: Register a webhook endpoint
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - url
                - events
              properties:
                url:
                  type: string
                  format: uri
                  maxLength: 2048
                  description: Public HTTPS URL without credentials or a fragment.
                events:
                  type: array
                  minItems: 1
                  maxItems: 2
                  uniqueItems: true
                  items:
                    enum:
                      - submission.updated
                      - artifact.created
      responses:
        "201":
          description: Registration with its one-time signing secret. Save it to verify
            requests.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreatedWebhook"
        default:
          $ref: "#/components/responses/Error"
  /webhooks/{webhook_id}:
    parameters:
      - name: webhook_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    delete:
      tags:
        - Webhooks
      operationId: deleteWebhook
      summary: Delete a registration and its delivery history
      description: Cancels pending deliveries. A request already in flight may still arrive.
      responses:
        "204":
          description: Registration deleted.
        default:
          $ref: "#/components/responses/Error"
  /webhooks/{webhook_id}/deliveries:
    parameters:
      - name: webhook_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      tags:
        - Webhooks
      operationId: listWebhookDeliveries
      summary: Inspect webhook deliveries
      description: Lists deliveries newest first. Attempts count requests claimed for
        sending, including attempts interrupted before acknowledgement.
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Cursor"
      responses:
        "200":
          description: A page of delivery outcomes and retry times.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDeliveryList"
        default:
          $ref: "#/components/responses/Error"
  /files:
    post:
      tags:
        - Files
      operationId: uploadFile
      summary: Store a downloadable file
      description: Files are at most 16 MiB (`413 file_too_large`). Uploading beyond
        the tenant's available storage returns `409 usage_limit_exceeded`. The
        stored content type is the request `Content-Type`, or
        `application/octet-stream` when it is omitted.
      parameters:
        - name: X-Filename
          in: header
          required: true
          description: HTTP header values are Latin-1; percent-encoded or non-ASCII names
            are stored as received.
          schema:
            type: string
            minLength: 1
            maxLength: 255
            not:
              pattern: "[\\r\\n\\u0000]"
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              contentEncoding: binary
          "*/*":
            schema:
              type: string
              contentEncoding: binary
      responses:
        "201":
          description: File metadata. The original content type is retained.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/File"
        default:
          $ref: "#/components/responses/Error"
  /files/{file_id}:
    parameters:
      - name: file_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    get:
      tags:
        - Files
      operationId: downloadFile
      summary: Download original file bytes
      responses:
        "200":
          description: Original bytes with stored content type and attachment disposition.
          content:
            "*/*":
              schema:
                type: string
                contentEncoding: binary
        default:
          $ref: "#/components/responses/Error"
    delete:
      tags:
        - Files
      operationId: deleteFile
      summary: Delete a stored file
      responses:
        "204":
          description: File deleted.
        default:
          $ref: "#/components/responses/Error"
components:
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
  parameters:
    Limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 100
    Cursor:
      name: cursor
      in: query
      schema:
        type: string
    CredentialId:
      name: credential_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    ConnectionId:
      name: connection_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    AgentId:
      name: agent_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    SessionId:
      name: session_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    SkillId:
      name: skill_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
  requestBodies:
    SkillUpload:
      required: true
      content:
        multipart/form-data:
          schema:
            type: object
            additionalProperties: false
            required:
              - files[]
            properties:
              files[]:
                type: array
                minItems: 1
                maxItems: 1000
                description: File parts use their relative skill paths as filenames. A ZIP may
                  be sent as one file part.
                items:
                  type: string
                  contentEncoding: binary
        application/zip:
          schema:
            type: string
            contentEncoding: binary
  responses:
    Error:
      description: >
        Error object. Codes include `invalid_request`,
        `invalid_webhook_signature`, `destination_not_allowed`,
        `files_require_sandbox`, `invalid_image`,

        `invalid_media_type`, `invalid_filename` and `invalid_skill` (`400`);
        `unauthorized` (`401`); `card_verification_required` (`402`);
        `not_found` (`404`); `conversation_busy`,

        `request_conflict`, `credential_in_use`, `connection_in_use`,
        `invalid_configuration`, `session_busy`, `session_deleting` and
        `usage_limit_exceeded` (`409`);

        `concurrency_limit_exceeded` (`429`);

        `body_too_large`, `file_too_large`, `input_files_too_large` and
        `skill_too_large` (`413`); `unsupported_media_type` (`415`);

        `internal_error` (`500`); and `session_unavailable`,
        `runtime_unavailable`, `files_unavailable`, `skills_unavailable` and
        `webhooks_unavailable` (`503`, temporary: retry after a short wait).

        Branch on `code`; `message` is a human-readable explanation whose
        wording can change.
      content:
        application/json:
          schema:
            type: object
            required:
              - error
            properties:
              error:
                type: object
                required:
                  - code
                  - message
                properties:
                  code:
                    type: string
                  message:
                    type: string
  schemas:
    ApiKeyList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ApiKey"
        next_cursor:
          type:
            - string
            - "null"
    CredentialList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Credential"
        next_cursor:
          type:
            - string
            - "null"
    ConnectionList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Connection"
        next_cursor:
          type:
            - string
            - "null"
    AgentList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Agent"
        next_cursor:
          type:
            - string
            - "null"
    AgentVersionList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/AgentVersion"
        next_cursor:
          type:
            - string
            - "null"
    SessionList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Session"
        next_cursor:
          type:
            - string
            - "null"
    SubmissionList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Submission"
        next_cursor:
          type:
            - string
            - "null"
    EntryList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Entry"
        next_cursor:
          type:
            - string
            - "null"
    ApiKey:
      type: object
      required:
        - id
        - name
        - prefix
        - suffix
        - created_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        prefix:
          type: string
        suffix:
          type: string
        created_at:
          type: string
          format: date-time
    CreatedApiKey:
      type: object
      required:
        - id
        - name
        - prefix
        - suffix
        - created_at
        - secret
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        prefix:
          type: string
        suffix:
          type: string
        created_at:
          type: string
          format: date-time
        secret:
          type: string
          description: Returned only on creation.
    ProviderApiKey:
      type: string
      writeOnly: true
      description: Provider API key; encrypted at rest and write-only. Authentication
        is checked when the key is used. A selected customer key is always the
        one used.
      minLength: 1
      maxLength: 10000
      pattern: \S
      not:
        pattern: "[\\r\\n]"
    CreateCredential:
      description: Store a provider secret. `category` and `provider` determine the
        accepted `settings`; secrets are write-only.
      discriminator:
        propertyName: category
        mapping:
          model: "#/components/schemas/CreateModelCredential"
          sandbox: "#/components/schemas/CreateSandboxCredential"
          web_search: "#/components/schemas/CreateWebSearchCredential"
          browser: "#/components/schemas/CreateBrowserCredential"
      oneOf:
        - $ref: "#/components/schemas/CreateModelCredential"
        - $ref: "#/components/schemas/CreateSandboxCredential"
        - $ref: "#/components/schemas/CreateWebSearchCredential"
        - $ref: "#/components/schemas/CreateBrowserCredential"
    Credential:
      description: Provider credential metadata. API keys are write-only.
      discriminator:
        propertyName: category
        mapping:
          model: "#/components/schemas/ModelCredential"
          sandbox: "#/components/schemas/SandboxCredential"
          web_search: "#/components/schemas/WebSearchCredential"
          browser: "#/components/schemas/BrowserCredential"
      oneOf:
        - $ref: "#/components/schemas/ModelCredential"
        - $ref: "#/components/schemas/SandboxCredential"
        - $ref: "#/components/schemas/WebSearchCredential"
        - $ref: "#/components/schemas/BrowserCredential"
    CreateModelCredential:
      type: object
      additionalProperties: false
      required:
        - name
        - category
        - provider
        - api_key
      examples:
        - name: My anthropic account
          category: model
          provider: anthropic
          settings: {}
          api_key: your-provider-api-key
      properties:
        category:
          const: model
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          type: string
          minLength: 1
          maxLength: 100
          pattern: \S
          description: Provider identifier from `GET /models`. The provider/model pair is
            validated when creating an agent version or session.
        settings:
          type: object
          additionalProperties: false
        api_key:
          $ref: "#/components/schemas/ProviderApiKey"
    ModelCredential:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - category
        - provider
        - settings
        - created_at
      properties:
        category:
          const: model
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          type: string
          minLength: 1
          maxLength: 100
          pattern: \S
          description: Provider identifier from `GET /models`. The provider/model pair is
            validated when creating an agent version or session.
        settings:
          type: object
          additionalProperties: false
        created_at:
          type: string
          format: date-time
    CreateSandboxCredential:
      type: object
      additionalProperties: false
      required:
        - name
        - category
        - provider
        - api_key
      examples:
        - name: My blaxel account
          category: sandbox
          provider: blaxel
          settings:
            workspace: your-workspace
          api_key: your-provider-api-key
      oneOf:
        - properties:
            provider:
              const: daytona
            settings:
              type: object
              additionalProperties: false
        - required:
            - settings
          properties:
            provider:
              const: blaxel
            settings:
              type: object
              additionalProperties: false
              required:
                - workspace
              properties:
                workspace:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: \S
      properties:
        category:
          const: sandbox
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          type: string
          enum:
            - daytona
            - blaxel
        settings:
          type: object
        api_key:
          $ref: "#/components/schemas/ProviderApiKey"
    SandboxCredential:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - category
        - provider
        - settings
        - created_at
      oneOf:
        - properties:
            provider:
              const: daytona
            settings:
              type: object
              additionalProperties: false
        - required:
            - settings
          properties:
            provider:
              const: blaxel
            settings:
              type: object
              additionalProperties: false
              required:
                - workspace
              properties:
                workspace:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: \S
      properties:
        category:
          const: sandbox
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          type: string
          enum:
            - daytona
            - blaxel
        settings:
          type: object
        created_at:
          type: string
          format: date-time
    CreateWebSearchCredential:
      type: object
      additionalProperties: false
      required:
        - name
        - category
        - provider
        - api_key
      examples:
        - name: My exa account
          category: web_search
          provider: exa
          settings: {}
          api_key: your-provider-api-key
      properties:
        category:
          const: web_search
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          const: exa
        settings:
          type: object
          additionalProperties: false
        api_key:
          $ref: "#/components/schemas/ProviderApiKey"
    WebSearchCredential:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - category
        - provider
        - settings
        - created_at
      properties:
        category:
          const: web_search
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          const: exa
        settings:
          type: object
          additionalProperties: false
        created_at:
          type: string
          format: date-time
    CreateBrowserCredential:
      type: object
      additionalProperties: false
      required:
        - name
        - category
        - provider
        - api_key
      examples:
        - name: My browserbase account
          category: browser
          provider: browserbase
          settings:
            project_id: your-project-id
          api_key: your-provider-api-key
      properties:
        category:
          const: browser
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          const: browserbase
        settings:
          type: object
          additionalProperties: false
          properties:
            project_id:
              type: string
              minLength: 1
              maxLength: 200
              pattern: \S
        api_key:
          $ref: "#/components/schemas/ProviderApiKey"
    BrowserCredential:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - category
        - provider
        - settings
        - created_at
      properties:
        category:
          const: browser
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        provider:
          const: browserbase
        settings:
          type: object
          additionalProperties: false
          properties:
            project_id:
              type: string
              minLength: 1
              maxLength: 200
              pattern: \S
        created_at:
          type: string
          format: date-time
    ToolEndpointCredentials:
      type: object
      writeOnly: true
      additionalProperties: false
      description: Endpoint authentication; encrypted at rest and never returned. Omit
        for unauthenticated endpoints, or supply `headers` and an optional
        `api_key` sent as a `Bearer` `Authorization` header. Keys and header
        values must not contain carriage returns or newlines. Authentication is
        checked when the endpoint is used.
      properties:
        api_key:
          $ref: "#/components/schemas/ProviderApiKey"
        headers:
          type: object
          propertyNames:
            pattern: ^[!#$%&'*+.^_`|~0-9A-Za-z-]+$
          additionalProperties:
            type: string
            not:
              pattern: "[\\r\\n]"
    CreateConnection:
      type: object
      additionalProperties: false
      required:
        - name
        - type
        - url
      examples:
        - name: My tools
          type: mcp
          url: https://tools.example.com/mcp
          credentials:
            api_key: your-tool-endpoint-token
      properties:
        type:
          enum:
            - mcp
            - http
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        url:
          type: string
          format: uri
          minLength: 1
          maxLength: 2048
          description: Absolute HTTPS endpoint URL without embedded credentials.
        credentials:
          $ref: "#/components/schemas/ToolEndpointCredentials"
    Connection:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - type
        - url
        - created_at
      properties:
        type:
          enum:
            - mcp
            - http
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        url:
          type: string
          format: uri
          minLength: 1
          maxLength: 2048
          description: Absolute HTTPS endpoint URL without embedded credentials.
        created_at:
          type: string
          format: date-time
    SkillVersionSelector:
      type: string
      pattern: ^(latest|[1-9][0-9]*)$
      description: A concrete positive version number encoded as a string, or latest.
        Getters always identify a concrete version.
    SkillAttachment:
      type: object
      additionalProperties: false
      required:
        - skill_id
        - version
      properties:
        skill_id:
          type: string
          format: uuid
        version:
          $ref: "#/components/schemas/SkillVersionSelector"
    Skill:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - description
        - latest_version
        - created_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
        description:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: \S
          description: Description from the latest version. XML-like text is allowed.
        latest_version:
          type: string
          pattern: ^[1-9][0-9]*$
        created_at:
          type: string
          format: date-time
    SkillManifestFile:
      type: object
      additionalProperties: false
      required:
        - path
        - size
        - sha256
        - mime_type
      properties:
        path:
          type: string
          minLength: 1
          maxLength: 4096
          description: Exact relative path of a regular uploaded file. Absolute paths,
            empty or dot segments, backslashes and NULs are rejected.
        size:
          type: integer
          minimum: 0
          maximum: 30000000
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        mime_type:
          type: string
    SkillVersion:
      type: object
      additionalProperties: false
      required:
        - skill_id
        - version
        - name
        - description
        - size
        - sha256
        - created_at
        - files
      properties:
        skill_id:
          type: string
          format: uuid
        version:
          type: string
          pattern: ^[1-9][0-9]*$
        name:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
        description:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: \S
        size:
          type: integer
          minimum: 1
          maximum: 30000000
          description: Sum of all decoded uncompressed file contents in bytes.
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: Content hash of the complete version.
        created_at:
          type: string
          format: date-time
        files:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            $ref: "#/components/schemas/SkillManifestFile"
    SkillVersionContents:
      type: object
      additionalProperties: false
      required:
        - skill_id
        - version
        - name
        - description
        - size
        - sha256
        - created_at
        - files
      properties:
        skill_id:
          type: string
          format: uuid
        version:
          type: string
          pattern: ^[1-9][0-9]*$
        name:
          type: string
          minLength: 1
          maxLength: 64
          pattern: ^[a-z0-9]+(-[a-z0-9]+)*$
        description:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: \S
        size:
          type: integer
          minimum: 1
          maximum: 30000000
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_at:
          type: string
          format: date-time
        files:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            type: object
            additionalProperties: false
            required:
              - path
              - size
              - sha256
              - mime_type
              - encoding
              - content
            properties:
              path:
                type: string
                minLength: 1
                maxLength: 4096
              size:
                type: integer
                minimum: 0
                maximum: 30000000
              sha256:
                type: string
                pattern: ^[a-f0-9]{64}$
              mime_type:
                type: string
              encoding:
                const: base64
              content:
                type: string
                contentEncoding: base64
                description: Exact original file bytes encoded as base64.
    SkillList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Skill"
        next_cursor:
          type:
            - string
            - "null"
    SkillVersionList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/SkillVersion"
        next_cursor:
          type:
            - string
            - "null"
    AgentConfig:
      type: object
      additionalProperties: false
      required:
        - model
        - tools
      examples:
        - model:
            provider: anthropic
            id: claude-sonnet-5-5
            credential_id: 10000000-0000-4000-8000-000000000001
          instructions: Answer the user's questions.
          tools:
            - type: platform
              name: web_search
            - type: platform
              name: browser
      properties:
        model:
          $ref: "#/components/schemas/AgentModel"
        instructions:
          type: string
          maxLength: 100000
        skills:
          type: array
          description: Attached skill versions, at most one per skill ID. Omission means
            no skills. latest resolves when creating this agent version;
            returned configurations contain concrete versions. Attached skills
            automatically enable read_skill without a sandbox or separate tool
            grant.
          items:
            $ref: "#/components/schemas/SkillAttachment"
        thinking_level:
          type: string
          enum:
            - off
            - minimal
            - low
            - medium
            - high
            - xhigh
            - max
          default: off
          description: Reasoning level for this agent version. Configure it on the agent
            rather than individual submissions.
        tools:
          type: array
          maxItems: 100
          description: Explicit grants available inside `codemode`. Tool names must be
            unique. A single browser grant enables the browser API with
            platform-provided credentials or a customer Browserbase credential.
            HTTP tools cannot use `codemode`, `read_skill`, `browser_client`,
            `browser_command`, or the reserved `mcp_` and `sandbox_` prefixes.
          items:
            $ref: "#/components/schemas/ToolGrant"
        sandbox:
          $ref: "#/components/schemas/Sandbox"
    AgentModel:
      type: object
      additionalProperties: false
      required:
        - provider
        - id
        - credential_id
      properties:
        provider:
          type: string
          minLength: 1
          maxLength: 100
        id:
          type: string
          minLength: 1
          maxLength: 300
        credential_id:
          type: string
          format: uuid
          description: A model API key whose provider matches the selected provider.
    Sandbox:
      description: One sandbox per session, bound for its lifetime when a tool first
        needs it. Sandboxes Clyck creates belong to the session and are deleted
        when it is archived or deleted. An existing `sandbox_id` attaches your
        own sandbox, which stays yours. If the bound sandbox becomes
        unavailable, sandbox tools return errors; start a new session for a
        fresh sandbox.
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - provider
            - credential_id
          oneOf:
            - required:
                - snapshot
              not:
                required:
                  - sandbox_id
            - required:
                - sandbox_id
              not:
                required:
                  - snapshot
          properties:
            provider:
              const: daytona
            credential_id:
              type: string
              format: uuid
              description: Customer Daytona credential.
            snapshot:
              type: string
              minLength: 1
              maxLength: 500
              description: >
                Snapshot used to create the sandbox. Required unless attaching
                `sandbox_id`. It must be available to

                the selected credential's account in the `target` region. A
                snapshot existing in Daytona does not

                guarantee availability in that region. Computer use requires a
                snapshot containing Daytona's required

                desktop software; Clyck starts its desktop services
                automatically.
            sandbox_id:
              type: string
              minLength: 1
              maxLength: 500
              description: >
                Existing sandbox accessible with the selected credential. It
                must be running before tools can execute.

                Clyck waits for startup already in progress, but does not start
                stopped sandboxes or resume paused or

                archived ones; start or resume the sandbox in Daytona before
                using it. Missing, stopped, paused or

                archived sandboxes cause tool errors. Computer use requires
                Daytona's desktop software to be installed;

                Clyck starts its desktop services automatically.
            target:
              type: string
              minLength: 1
              maxLength: 500
              default: us
              description: Creation region. The selected snapshot must be available in this
                region. Ignored when attaching an existing sandbox with
                `sandbox_id`.
        - type: object
          additionalProperties: false
          required:
            - provider
          description: Clyck-managed sandboxes use 2048 MiB of memory and a Clyck-selected
            image and region. Only the working directory may be customized. No
            customer credentials are needed.
          properties:
            provider:
              const: clyck-managed
            cwd:
              type: string
              pattern: ^/
              maxLength: 500
              default: /workspace
              description: Absolute working directory for filesystem and shell tools.
        - type: object
          additionalProperties: false
          required:
            - provider
            - credential_id
          description: A sandbox in your own Blaxel workspace, using your stored Blaxel
            API key.
          properties:
            provider:
              const: blaxel
            credential_id:
              type: string
              format: uuid
              description: Customer Blaxel credential.
            sandbox_id:
              type: string
              minLength: 1
              maxLength: 500
              description: Existing sandbox in the credential's workspace.
            image:
              type: string
              minLength: 1
              maxLength: 500
              description: Image for a new sandbox; omitted uses the Clyck default sandbox
                image.
            region:
              type: string
              minLength: 1
              maxLength: 500
              description: Region for a new sandbox; omitted uses the platform default.
            memory:
              type: integer
              minimum: 1
              description: Memory in MiB for a new sandbox; omitted uses 2048 MiB.
            cwd:
              type: string
              pattern: ^/
              maxLength: 500
              default: /workspace
              description: Absolute working directory for filesystem and shell tools.
    ToolGrant:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - type
            - name
          properties:
            type:
              const: platform
            name:
              const: publish_file
              description: Publish a regular file from a Clyck-managed sandbox.
        - type: object
          additionalProperties: false
          required:
            - type
            - name
          properties:
            type:
              const: platform
            name:
              enum:
                - web_search
                - browser
              description: "`web_search` enables web search. `browser` enables the browser
                automation API inside `codemode`. Both use platform-provided
                credentials unless `credential_id` selects a customer
                credential."
            credential_id:
              type: string
              format: uuid
              description: Optional Exa credential for `web_search` or Browserbase credential
                for `browser`.
        - type: object
          additionalProperties: false
          required:
            - type
            - connection_id
            - tools
          properties:
            type:
              const: mcp
            connection_id:
              type: string
              format: uuid
            tools:
              type: array
              minItems: 1
              maxItems: 100
              uniqueItems: true
              items:
                type: string
                minLength: 1
                maxLength: 200
              description: Exact tool names your MCP server advertises. Sessions call the
                server for these tools, so keep it reachable and offering them.
        - type: object
          additionalProperties: false
          required:
            - type
            - tools
          properties:
            type:
              const: sandbox
            tools:
              type: array
              minItems: 1
              maxItems: 100
              uniqueItems: true
              description: Clyck-managed and Blaxel sandboxes provide `read`, `write`, `edit`
                and `bash`; Daytona sandboxes provide the other listed names,
                including `computer_use_*` desktop tools. Daytona computer use
                requires a snapshot or attached sandbox with Daytona's required
                desktop software installed; Clyck starts desktop services
                automatically, so no startup call is needed. Use these
                unprefixed names in grants; inside `codemode` their callable
                names begin with `sandbox_`. Daytona `file_download` returns
                decoded text; for lossless binary reads, base64-encode the file
                with `execute_command`. The session configuration and lifecycle
                create and delete the sandbox itself.
              items:
                enum:
                  - read
                  - write
                  - edit
                  - bash
                  - execute_command
                  - file_upload
                  - file_download
                  - create_folder
                  - get_file_info
                  - list_files
                  - move_file
                  - delete_file
                  - computer_use_status
                  - computer_use_mouse_position
                  - computer_use_mouse_move
                  - computer_use_mouse_click
                  - computer_use_mouse_drag
                  - computer_use_mouse_scroll
                  - computer_use_keyboard_type
                  - computer_use_keyboard_press
                  - computer_use_keyboard_hotkey
                  - computer_use_screenshot
                  - computer_use_screenshot_region
                  - computer_use_screenshot_compressed
                  - computer_use_screenshot_compressed_region
                  - computer_use_display_info
                  - computer_use_windows
                  - computer_use_accessibility_tree
                  - computer_use_accessibility_find
                  - computer_use_accessibility_focus
                  - computer_use_accessibility_invoke
                  - computer_use_accessibility_set_value
        - type: object
          additionalProperties: false
          required:
            - type
            - connection_id
            - name
            - description
            - parameters
          description: >
            Calling the tool sends `POST` to the connection URL with the
            arguments as a JSON body, `Content-Type`:

            `application/json`, the connection's `headers`, and `Authorization:
            Bearer <api_key>` when the connection has an

            `api_key`. Every tool of a connection uses the connection URL, so
            give tools that your endpoint routes

            separately their own connection URLs. Respond directly rather than
            with a redirect. A `2xx` JSON body becomes

            the tool result, and `204` returns `null`; return business outcomes
            the model should read, such as "not found",

            as `2xx` results. Any other status fails the call with its HTTP
            status code.
          properties:
            type:
              const: http
            connection_id:
              type: string
              format: uuid
            name:
              type: string
              maxLength: 100
              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
              not:
                anyOf:
                  - enum:
                      - codemode
                      - read_skill
                      - browser_client
                      - browser_command
                  - pattern: ^(mcp_|sandbox_)
            description:
              type: string
              minLength: 1
              maxLength: 10000
            parameters:
              type: object
              description: Object JSON Schema for tool arguments.
              additionalProperties: true
    Agent:
      type: object
      required:
        - id
        - name
        - created_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        created_at:
          type: string
          format: date-time
        latest_version:
          $ref: "#/components/schemas/AgentVersion"
    AgentVersion:
      type: object
      required:
        - id
        - agent_id
        - version
        - config
        - created_at
      properties:
        id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        config:
          $ref: "#/components/schemas/AgentConfig"
        created_at:
          type: string
          format: date-time
    Session:
      type: object
      required:
        - id
        - agent_version_id
        - config
        - created_at
        - archived_at
      properties:
        id:
          type: string
          format: uuid
        agent_version_id:
          type: string
          format: uuid
        config:
          $ref: "#/components/schemas/AgentConfig"
        created_at:
          type: string
          format: date-time
        archived_at:
          type:
            - string
            - "null"
          format: date-time
          description: When the session was permanently closed to new work, or null before
            archival.
    SessionLifecycle:
      type: object
      additionalProperties: false
      required:
        - state
        - idle_since
      properties:
        state:
          enum:
            - active
            - idle
            - standby
            - archived
          description: Active is processing work; idle is retaining runtime resources
            during the five-minute grace period; standby has released runtime
            resources; archived is permanently closed to new work and retains
            readable history.
        idle_since:
          type:
            - string
            - "null"
          format: date-time
          description: Start of the current idle period, or null when active, in standby
            or archived.
    SessionOverrides:
      type: object
      additionalProperties: false
      description: Supplied top-level fields replace the version's fields completely.
        Omission inherits. `sandbox` `null` removes the sandbox; `tools` must
        also be replaced if inherited grants require it. Empty `instructions`,
        `tools` or `skills` clears that field. Skill latest selectors resolve
        when the session is created. The resolved `config` follows `AgentConfig`
        validation.
      properties:
        model:
          $ref: "#/components/schemas/AgentModel"
        instructions:
          type: string
          maxLength: 100000
        thinking_level:
          enum:
            - off
            - minimal
            - low
            - medium
            - high
            - xhigh
            - max
        tools:
          type: array
          maxItems: 100
          items:
            $ref: "#/components/schemas/ToolGrant"
        skills:
          type: array
          items:
            $ref: "#/components/schemas/SkillAttachment"
        sandbox:
          oneOf:
            - $ref: "#/components/schemas/Sandbox"
            - type: "null"
    CreateSubmission:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - content
          properties:
            type:
              const: input
              default: input
            content:
              $ref: "#/components/schemas/InputContent"
            when_busy:
              type: string
              enum:
                - steer
                - followUp
                - reject
              default: followUp
            request_id:
              type: string
              minLength: 1
              maxLength: 200
              pattern: \S
        - type: object
          additionalProperties: false
          required:
            - type
            - content
          properties:
            type:
              const: context
            content:
              $ref: "#/components/schemas/InputContent"
            request_id:
              type: string
              minLength: 1
              maxLength: 200
              pattern: \S
      examples:
        - content: Analyze the account.
        - type: context
          content: The account tier is premium.
          request_id: account-tier-1
    InputContent:
      oneOf:
        - type: string
          minLength: 1
          maxLength: 100000
        - type: array
          minItems: 1
          maxItems: 100
          items:
            $ref: "#/components/schemas/InputBlock"
    InputBlock:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - type
            - text
          properties:
            type:
              const: text
            text:
              type: string
        - type: object
          additionalProperties: false
          required:
            - type
            - data
            - mime_type
          properties:
            type:
              const: image
            data:
              type: string
              contentEncoding: base64
              minLength: 4
            mime_type:
              enum:
                - image/png
                - image/jpeg
                - image/webp
                - image/gif
        - type: object
          additionalProperties: false
          required:
            - type
            - file_id
          properties:
            type:
              enum:
                - file
                - image
            file_id:
              type: string
              format: uuid
              description: An uploaded file owned by this tenant. A file block is copied into
                the session's sandbox as a working copy; an image block supplies
                decoded image content directly to the model.
    Submission:
      type: object
      additionalProperties: false
      required:
        - id
        - conversation_id
        - type
        - status
      description: >
        The durable outcome of accepted input. `queued` is waiting; `placed`
        identifies its input entry; `done` identifies

        its input entry and `answer` entry. `cancelled` and `failed` are
        terminal and include a stable `reason` and public `error`.

        Explicit abortion yields `cancelled`; other unsuccessful endings yield
        `failed`.

        Multiple input submissions may share one answer. For `type` `context`,
        `done` means the context entry was placed;

        context requests no work and has no `answer` field. `queued` context can
        be withdrawn individually.
      properties:
        id:
          type: integer
          minimum: 1
        conversation_id:
          type: integer
          minimum: 1
        request_id:
          type: string
          description: The `request_id` supplied with the submission; absent when none was
            supplied.
        type:
          enum:
            - input
            - context
        status:
          enum:
            - queued
            - placed
            - done
            - cancelled
            - failed
        entry:
          type: integer
          minimum: 1
        answer:
          type: integer
          minimum: 1
        reason:
          enum:
            - aborted
            - model_error
            - no_model
            - reset
            - execution_failed
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - id: 7
          conversation_id: 1
          type: input
          status: done
          entry: 40
          answer: 42
        - id: 8
          conversation_id: 1
          type: input
          status: failed
          reason: model_error
          error:
            code: model_error
            message: The model could not complete the answer. Check the model configuration
              and retry the submission.
    Entry:
      type: object
      additionalProperties: false
      required:
        - id
        - conversation_id
        - kind
        - model
      properties:
        id:
          type: integer
          minimum: 1
          description: Durable history reference.
        conversation_id:
          type: integer
          minimum: 1
        kind:
          enum:
            - message
            - summary
            - reset
            - other
          description: Public entry classification; use `model` messages to render
            content. `other` entries record session bookkeeping, have no public
            messages and are not streamed as message events.
        head:
          type: integer
          minimum: 1
        input:
          $ref: "#/components/schemas/InputContent"
          description: Original submitted content for context and file-reference inputs,
            preserving file IDs independently of transformed model content.
        model:
          type: array
          items:
            $ref: "#/components/schemas/Message"
    ContentBlock:
      description: >
        Public message content, including provider-returned thinking. Thinking
        is what the provider returns for the

        model: full text, a summary, an empty string or content marked
        `redacted`. Provider signatures and replay

        metadata stay internal.
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - type
            - text
          properties:
            type:
              const: text
            text:
              type: string
        - type: object
          additionalProperties: false
          required:
            - type
            - thinking
          properties:
            type:
              const: thinking
            thinking:
              type: string
              description: Provider-returned thinking text or summary; may be empty.
            redacted:
              type: boolean
              description: When `true`, the provider marked this content as redacted.
        - type: object
          additionalProperties: false
          required:
            - type
            - data
            - mime_type
          properties:
            type:
              const: image
            data:
              type: string
              contentEncoding: base64
            mime_type:
              type: string
        - type: object
          additionalProperties: false
          required:
            - type
            - id
            - name
            - arguments
          properties:
            type:
              const: toolCall
            id:
              type: string
              description: Opaque execution identity for committed messages; preview-scoped
                identity before commitment.
            name:
              type: string
            arguments:
              type: object
              additionalProperties: true
    Message:
      type: object
      additionalProperties: false
      required:
        - role
        - content
      properties:
        role:
          enum:
            - user
            - assistant
            - toolResult
        content:
          type: array
          items:
            $ref: "#/components/schemas/ContentBlock"
        timestamp:
          type: number
          description: Unix time in milliseconds.
        stop_reason:
          enum:
            - pending
            - stop
            - length
            - toolUse
            - error
            - aborted
          description: "`pending` is a preview; `stop` is a normal completion; `length` is
            a limit; `toolUse` requests tools; `error` and `aborted` are
            unsuccessful endings. An `aborted` message keeps the partial content
            generated before cancellation or interruption; the submission's
            `answer` names the answer entry."
        tool_call_id:
          type: string
          description: Canonical execution ID of the tool call answered by this committed
            result.
        tool_name:
          type: string
        is_error:
          type: boolean
        duration_ms:
          type: number
          minimum: 0
          description: Generation time of an assistant message or execution time of a tool
            result, when available.
        usage:
          $ref: "#/components/schemas/Usage"
    ExecutionError:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      description: >
        A stable category and a safe, actionable explanation, free of raw
        provider errors, response bodies and

        credentials; a tool's own result can describe its failure in more
        detail. The `message` is for display; branch

        on `code`. Submission status and tool outcomes report the overall
        result.
      properties:
        code:
          enum:
            - aborted
            - model_error
            - no_model
            - reset
            - execution_failed
            - retry_scheduled
            - compaction_failed
            - tool_error
            - tool_unavailable
            - invalid_arguments
            - blocked
            - invalid_structured_output
            - unknown_outcome
        message:
          type: string
    Usage:
      type: object
      additionalProperties: false
      required:
        - tokens
        - cost
      description: >
        Token counters and estimated cost in USD, as reported by the provider
        and the model catalog. `null` means the

        measurement is unavailable. Zero counters within an available object are
        reported or calculated zeros, and an

        object that would be entirely zero is represented as `null`, which can
        include a free operation. Costs are

        estimates for your own tracking; your provider's bill is authoritative.
        Counters on a preview are provisional

        and become final at commitment. An aborted message reports the usage
        known when it stopped.
      properties:
        tokens:
          oneOf:
            - type: "null"
            - type: object
              additionalProperties: false
              required:
                - input
                - output
                - cache_read
                - cache_write
                - total
              properties:
                input:
                  type: number
                  minimum: 0
                output:
                  type: number
                  minimum: 0
                cache_read:
                  type: number
                  minimum: 0
                cache_write:
                  type: number
                  minimum: 0
                total:
                  type: number
                  minimum: 0
                cache_write_1h:
                  type: number
                  minimum: 0
                  description: Optional subset of `cache_write` with one-hour retention; do not
                    add it again.
                reasoning:
                  type: number
                  minimum: 0
                  description: Optional subset of `output`; do not add it again.
        cost:
          oneOf:
            - type: "null"
            - type: object
              additionalProperties: false
              required:
                - currency
                - input
                - output
                - cache_read
                - cache_write
                - total
              properties:
                currency:
                  const: USD
                input:
                  type: number
                  minimum: 0
                output:
                  type: number
                  minimum: 0
                cache_read:
                  type: number
                  minimum: 0
                cache_write:
                  type: number
                  minimum: 0
                total:
                  type: number
                  minimum: 0
      examples:
        - tokens:
            input: 20
            output: 5
            cache_read: 0
            cache_write: 0
            total: 25
          cost: null
        - tokens: null
          cost: null
    CumulativeUsage:
      type: object
      additionalProperties: false
      required:
        - models
        - tools
      description: >
        The session's cumulative recorded usage, grouped by model and tool.
        Model totals include committed

        assistant messages and context summarization attempts. Tool totals
        include reported tool usage. The value

        replaces previous cumulative usage, so use each `usage.updated` value as
        the new total. A source without a

        bucket has no recorded usage. Totals cover usage that providers and
        tools reported.
      properties:
        models:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - provider
              - model_id
              - usage
            properties:
              provider:
                type: string
              model_id:
                type: string
              usage:
                $ref: "#/components/schemas/Usage"
        tools:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - name
              - usage
            properties:
              name:
                type: string
              usage:
                $ref: "#/components/schemas/Usage"
      examples:
        - models: []
          tools: []
    Inbox:
      type: array
      description: Current queued inputs, in queue order. Replace the previous inbox
        with this value.
      items:
        type: object
        additionalProperties: false
        required:
          - id
          - mode
        properties:
          id:
            type: integer
            minimum: 1
          mode:
            enum:
              - steer
              - followUp
              - context
    Retry:
      type: object
      additionalProperties: false
      required:
        - attempt
        - at
        - error
      properties:
        attempt:
          type: integer
          minimum: 0
          description: Attempt index supplied for the current generation.
        at:
          type: number
          description: Scheduled retry time as Unix milliseconds; actual execution may
            start later.
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - attempt: 1
          at: 1792195200000
          error:
            code: retry_scheduled
            message: The model request failed and a retry is scheduled.
    ToolDiagnostic:
      type: object
      additionalProperties: false
      required:
        - severity
        - code
        - message
      properties:
        severity:
          enum:
            - info
            - warn
            - error
        code:
          enum:
            - aborted
            - model_error
            - no_model
            - reset
            - execution_failed
            - retry_scheduled
            - compaction_failed
            - tool_error
            - tool_unavailable
            - invalid_arguments
            - blocked
            - invalid_structured_output
            - unknown_outcome
            - tool_diagnostic
          description: Stable public diagnostic category; `tool_diagnostic` is an
            informational or warning diagnostic from the tool.
        message:
          type: string
          description: Safe display text.
    ToolProgress:
      type: object
      additionalProperties: false
      description: >
        Optional progress reported by a tool. Each value replaces the previous
        progress object. Units and

        completeness are tool-dependent; tools that report no progress can still
        be working.
      properties:
        message:
          type: string
        completed:
          type: number
          minimum: 0
        total:
          type: number
          minimum: 0
        unit:
          type: string
    ToolCallList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ToolCall"
        next_cursor:
          type:
            - string
            - "null"
    ToolCall:
      type: object
      additionalProperties: false
      required:
        - call_id
        - name
        - args
        - status
      description: >
        Durable execution record for `codemode` or an inner tool. `call_id` and
        `parent_call_id` match stream/state IDs and

        remain stable for the session. `args` are the latest recorded execution
        arguments, including repairs; `pending`

        calls expose requested arguments. `done` means execution ended, and
        `outcome` reports how: `success` and `error`

        have a recorded result, and `unknown` means the call ended without one,
        so confirm any external effect with the

        service that owns it before retrying. Result, diagnostics, duration and
        usage follow `ToolCompleted`. Nested

        usage is reported separately from the parent's usage, so add each once.
      properties:
        call_id:
          type: string
        name:
          type: string
        parent_call_id:
          type: string
        args:
          type: object
          additionalProperties: true
        status:
          enum:
            - pending
            - running
            - done
        started_at:
          type: number
          description: Unix milliseconds when execution started, when available.
        ended_at:
          type: number
          description: Unix milliseconds when execution ended, when available.
        outcome:
          enum:
            - success
            - error
            - unknown
        entry_id:
          type: integer
          minimum: 1
        result:
          description: Recorded JSON result for an inner tool, or public `content` array
            for a model-facing tool.
        duration_ms:
          type: number
          minimum: 0
        usage:
          $ref: "#/components/schemas/Usage"
        progress:
          $ref: "#/components/schemas/ToolProgress"
        diagnostics:
          type: array
          items:
            $ref: "#/components/schemas/ToolDiagnostic"
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - call_id: c2
          parent_call_id: c1
          name: search
          args:
            query: streaming
          status: done
          outcome: success
          result:
            matches: 2
          duration_ms: 25
          diagnostics: []
    ToolActivity:
      type: object
      additionalProperties: false
      required:
        - call_id
        - name
        - status
      description: >
        Current tool activity. `call_id` is opaque; `parent_call_id` identifies
        the enclosing operation for nested calls.

        `args` are the requested arguments for a model-facing call; for a
        running nested call they are its current

        execution arguments. `tool.started` supplies execution arguments after
        any repair. `output` is a live window of

        recent output; the dropped byte and line counts describe output trimmed
        from its front. `done` means execution

        ended, and `outcome` reports how; `unknown` means the call ended without
        a recorded result, so confirm any

        external effect before retrying. When a snapshot carries only the
        summary of a failed nested call, it omits

        `outcome` and `error`; `GET tool-calls/{call_id}` has the recorded
        outcome. Nested calls can remain listed after

        their parent completes, and `GET tool-calls` keeps every call with its
        results.
      properties:
        call_id:
          type: string
        name:
          type: string
        parent_call_id:
          type: string
        status:
          enum:
            - pending
            - running
            - done
        args:
          type: object
          additionalProperties: true
        entry_id:
          type: integer
          minimum: 1
          description: Durable tool-result entry when available.
        output:
          type: string
        dropped_bytes:
          type: integer
          minimum: 0
        dropped_lines:
          type: integer
          minimum: 0
        progress:
          $ref: "#/components/schemas/ToolProgress"
        diagnostics:
          type: array
          items:
            $ref: "#/components/schemas/ToolDiagnostic"
        outcome:
          enum:
            - success
            - error
            - unknown
        duration_ms:
          type: number
          minimum: 0
          description: Execution time of the attempt that produced a result; omitted when
            unavailable.
        usage:
          $ref: "#/components/schemas/Usage"
        error:
          $ref: "#/components/schemas/ExecutionError"
    Compaction:
      type: object
      additionalProperties: false
      required:
        - compaction_id
        - reason
        - blocking
        - attempt
      description: Current context summarization activity. `compaction_id` is opaque
        and scoped to the current snapshot.
      properties:
        compaction_id:
          type: string
        reason:
          enum:
            - manual
            - threshold
            - overflow
        blocking:
          type: boolean
          description: Whether generation is waiting for this summarization.
        attempt:
          type: integer
          minimum: 0
        retry:
          $ref: "#/components/schemas/Retry"
    CompactionFailure:
      type: object
      additionalProperties: false
      required:
        - compaction_id
        - reason
        - error
      description: Most recent summarization failure since a summary was last produced.
      properties:
        compaction_id:
          type: string
        reason:
          enum:
            - manual
            - threshold
            - overflow
        error:
          $ref: "#/components/schemas/ExecutionError"
    State:
      type: object
      additionalProperties: false
      required:
        - conversation
        - entries
        - agent
        - inbox
        - execution
        - usage
      description: >
        Complete replacement live state used by `GET state` and `snapshot`
        events. Every snapshot establishes fresh

        preview and compaction identities. `entries` are the committed entries
        in the current active conversation

        context, which can omit earlier history after summarization or a context
        reset; retrieve complete or missing

        history through `GET entries`. Partial generation content is only a
        preview. This state has queued inputs

        and active submission IDs, not every terminal submission; reconcile
        tracked submissions using their read

        endpoints.
      properties:
        conversation:
          type: object
          additionalProperties: false
          required:
            - id
          properties:
            id:
              type: integer
              minimum: 1
            parent:
              type: object
              additionalProperties: false
              required:
                - conversation_id
                - at
              properties:
                conversation_id:
                  type: integer
                  minimum: 1
                at:
                  type: integer
                  minimum: 1
        entries:
          type: array
          items:
            $ref: "#/components/schemas/Entry"
        agent:
          type: object
          additionalProperties: false
          properties:
            model:
              type: object
              additionalProperties: false
              required:
                - provider
                - model_id
              properties:
                provider:
                  type: string
                model_id:
                  type: string
            thinking_level:
              type: string
        inbox:
          $ref: "#/components/schemas/Inbox"
        execution:
          type: object
          additionalProperties: false
          required:
            - busy
            - inputs
            - tools
            - nested_tools
            - compactions
          properties:
            busy:
              type: boolean
            inputs:
              type: array
              items:
                type: integer
                minimum: 1
            generation:
              type: object
              additionalProperties: false
              required:
                - attempt
              properties:
                attempt:
                  type: integer
                  minimum: 0
                preview_id:
                  type: string
                  description: Opaque identity established by this snapshot.
                message:
                  $ref: "#/components/schemas/Message"
                retry:
                  $ref: "#/components/schemas/Retry"
            tools:
              type: array
              items:
                $ref: "#/components/schemas/ToolActivity"
            nested_tools:
              type: array
              items:
                $ref: "#/components/schemas/ToolActivity"
            compactions:
              type: array
              items:
                $ref: "#/components/schemas/Compaction"
            compaction_failure:
              $ref: "#/components/schemas/CompactionFailure"
        usage:
          $ref: "#/components/schemas/CumulativeUsage"
    ExecutionEvent:
      type: object
      additionalProperties: false
      required:
        - inputs
      description: >
        Execution started or ended for these submission IDs. When
        `execution.ended` arrives, discard any remaining

        preview and active tool activity for that execution, and read the
        submissions for their outcomes.
      properties:
        inputs:
          type: array
          items:
            type: integer
            minimum: 1
      examples:
        - inputs:
            - 7
    MessageStarted:
      type: object
      additionalProperties: false
      required:
        - preview_id
        - message
      description: >
        Establish an assistant preview with its initial public content.
        `preview_id` is opaque and valid only until

        the next snapshot or the preview is completed or discarded by
        `execution.ended`.
      properties:
        preview_id:
          type: string
        message:
          $ref: "#/components/schemas/Message"
      examples:
        - preview_id: p1
          message:
            role: assistant
            content: []
    MessageDelta:
      description: >
        Changes to one preview. `content` inserts a new block at the zero-based
        public `content_index`, including the

        initial `thinking` block. `text` appends `delta` to the `text` field of
        the `text` block there; `thinking` appends `delta`

        to the `thinking` field of the `thinking` block there. `arguments`
        appends `delta` to the existing string at `path`

        within that `toolCall` block's `arguments` object, as a parsed value
        rather than serialized JSON. Path strings

        name object properties and integers name array indexes. Indexes address
        the public `content` array, including

        thinking blocks. Content replacement, changes to redacted markers,

        argument shape changes and other non-append changes use
        `message.replaced`, which supplies full thinking blocks.

        Snapshots and completed messages also contain full blocks. Apply changes
        in delivery order.
      discriminator:
        propertyName: type
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - preview_id
            - content_index
            - type
            - block
          properties:
            preview_id:
              type: string
            content_index:
              type: integer
              minimum: 0
            type:
              const: content
            block:
              $ref: "#/components/schemas/ContentBlock"
        - type: object
          additionalProperties: false
          required:
            - preview_id
            - content_index
            - type
            - delta
          properties:
            preview_id:
              type: string
            content_index:
              type: integer
              minimum: 0
            type:
              const: text
            delta:
              type: string
        - type: object
          additionalProperties: false
          required:
            - preview_id
            - content_index
            - type
            - delta
          properties:
            preview_id:
              type: string
            content_index:
              type: integer
              minimum: 0
            type:
              const: thinking
            delta:
              type: string
        - type: object
          additionalProperties: false
          required:
            - preview_id
            - content_index
            - type
            - path
            - delta
          properties:
            preview_id:
              type: string
            content_index:
              type: integer
              minimum: 0
            type:
              const: arguments
            path:
              type: array
              minItems: 1
              items:
                oneOf:
                  - type: string
                  - type: integer
                    minimum: 0
            delta:
              type: string
      examples:
        - preview_id: p1
          content_index: 0
          type: content
          block:
            type: text
            text: ""
        - preview_id: p1
          content_index: 0
          type: text
          delta: Hello
        - preview_id: p2
          content_index: 0
          type: arguments
          path:
            - code
          delta: text(result);
        - preview_id: p3
          content_index: 0
          type: content
          block:
            type: thinking
            thinking: ""
        - preview_id: p3
          content_index: 0
          type: thinking
          delta: Considering the available options.
    MessageReplaced:
      type: object
      additionalProperties: false
      required:
        - preview_id
        - message
      description: >
        Replace the entire preview under `preview_id`, including all `content`
        and `usage`. Replacements can shorten

        content, revise tool arguments or start a new generation attempt. Never
        append the replacement to the

        previous message. `preview_id` remains the same until completion or a
        fresh snapshot.
      properties:
        preview_id:
          type: string
        message:
          $ref: "#/components/schemas/Message"
      examples:
        - preview_id: p1
          message:
            role: assistant
            content:
              - type: text
                text: Starting again.
    MessageCompleted:
      type: object
      additionalProperties: false
      required:
        - entry_id
        - entry
        - message
      description: >
        An authoritative committed message with its durable history entry.
        Replace the matching preview when

        `preview_id` is present; otherwise append or reconcile by `entry_id`.
        Completion may be delivered without a

        preceding preview, including user and tool-result messages. The full
        entry is the same projection returned

        by `GET entries`. Work can continue after a message completes;
        submission status reports when input is answered.
      properties:
        entry_id:
          type: integer
          minimum: 1
        entry:
          $ref: "#/components/schemas/Entry"
        preview_id:
          type: string
        message:
          $ref: "#/components/schemas/Message"
        usage:
          $ref: "#/components/schemas/Usage"
      examples:
        - entry_id: 42
          preview_id: p1
          entry:
            id: 42
            conversation_id: 1
            kind: message
            model:
              - role: assistant
                content:
                  - type: text
                    text: Hello there.
          message:
            role: assistant
            content:
              - type: text
                text: Hello there.
    ToolStarted:
      type: object
      additionalProperties: false
      required:
        - call_id
        - name
        - args
      description: >
        A tool began execution with these arguments. Applies to `codemode` and
        calls made inside it. A nested call

        includes `parent_call_id`. Match operations by opaque `call_id`, never
        by parsing its value or assuming a name is

        unique. A tool can complete without a start notification when it could
        not start or updates were coalesced.
      properties:
        call_id:
          type: string
        name:
          type: string
        parent_call_id:
          type: string
        args:
          type: object
          additionalProperties: true
      examples:
        - call_id: c2
          name: search
          parent_call_id: c1
          args:
            query: streaming
    ToolOutputChange:
      description: >
        A change to the retained output window. `replace` discards all prior
        retained text and uses `text`. `append`

        first removes `trim_start` UTF-16 code units from the front of the
        retained string, then appends `text`. An

        empty `text` is meaningful: it can represent a trim without an append.
        Use string slicing in JavaScript;

        clients in other languages must account for UTF-16 surrogate pairs. This
        is not an append-only full log.

        A fresh snapshot supplies the replacement retained window and available
        dropped byte/line totals.
      discriminator:
        propertyName: type
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - type
            - text
          properties:
            type:
              const: replace
            text:
              type: string
        - type: object
          additionalProperties: false
          required:
            - type
            - trim_start
            - text
          properties:
            type:
              const: append
            trim_start:
              type: integer
              minimum: 0
            text:
              type: string
      examples:
        - type: replace
          text: Recent output
        - type: append
          trim_start: 7
          text: " plus new output"
    ToolUpdated:
      type: object
      additionalProperties: false
      required:
        - call_id
        - name
      description: >
        Changes to current output, progress or diagnostics. Fields omitted from
        an update remain unchanged.

        `progress` replaces the previous progress object; `null` clears it.
        `diagnostics` replaces the previous list.

        These fields contain the documented tool-facing presentation, not
        arbitrary internal execution details.
      properties:
        call_id:
          type: string
        name:
          type: string
        parent_call_id:
          type: string
        output:
          $ref: "#/components/schemas/ToolOutputChange"
        progress:
          oneOf:
            - $ref: "#/components/schemas/ToolProgress"
            - type: "null"
        diagnostics:
          type: array
          items:
            $ref: "#/components/schemas/ToolDiagnostic"
      examples:
        - call_id: c2
          name: search
          parent_call_id: c1
          output:
            type: replace
            text: Found 2 results
          progress:
            completed: 2
            total: 5
            unit: pages
    ToolCompleted:
      type: object
      additionalProperties: false
      required:
        - call_id
        - name
        - outcome
        - diagnostics
      description: >
        End of a tool operation. `success` and `error` mean a result was
        recorded; `unknown` means execution ended

        without a recorded result, including a call interrupted after it
        started, so confirm any external effect before

        retrying. `error.code` is `aborted` when cancellation ended the call,
        and a call that had already started can

        have taken effect. For nested

        tools, `result` is the tool's JSON result, according to its own output
        schema; for a model-facing tool it is

        the public result content array. The result envelope is stable, while
        tool-defined JSON is application

        data. Errors may still include `result` data. `duration_ms` and `usage`
        are omitted when unavailable. Clear the

        running `output` and `progress` unless completion supplies final
        `progress`. Completed calls can leave the live

        snapshot; retrieve their recorded results through `GET tool-calls` after
        reconnect.
      properties:
        call_id:
          type: string
        name:
          type: string
        parent_call_id:
          type: string
        outcome:
          enum:
            - success
            - error
            - unknown
        entry_id:
          type: integer
          minimum: 1
        result:
          description: Tool-defined JSON result or public model-facing result content.
        duration_ms:
          type: number
          minimum: 0
        usage:
          $ref: "#/components/schemas/Usage"
        progress:
          $ref: "#/components/schemas/ToolProgress"
        diagnostics:
          type: array
          items:
            $ref: "#/components/schemas/ToolDiagnostic"
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - call_id: c2
          name: search
          parent_call_id: c1
          outcome: success
          result:
            matches: 2
          duration_ms: 25
          diagnostics: []
        - call_id: c3
          name: update_account
          outcome: unknown
          diagnostics: []
          error:
            code: unknown_outcome
            message: The call ended without a known result. External effects may have
              occurred.
    RetryEnded:
      type: object
      additionalProperties: false
      required:
        - attempt
      description: Retry waiting ended for this attempt. Later events report what
        happened next.
      properties:
        attempt:
          type: integer
          minimum: 0
      examples:
        - attempt: 1
    CompactionStarted:
      type: object
      additionalProperties: false
      required:
        - compaction_id
        - reason
        - blocking
      description: Context summarization began. `compaction_id` is opaque and scoped
        to this snapshot.
      properties:
        compaction_id:
          type: string
        reason:
          enum:
            - manual
            - threshold
            - overflow
        blocking:
          type: boolean
      examples:
        - compaction_id: compact1
          reason: threshold
          blocking: false
    CompactionCompleted:
      type: object
      additionalProperties: false
      required:
        - compaction_id
        - reason
        - outcome
      description: >
        Context summarization ended. `completed` means it ended without a
        failure, which includes cancellation and

        having nothing to summarize; a produced summary appears as a committed
        `summary` entry.

        `error` includes a public failure. Remove this compaction from current
        activity.
      properties:
        compaction_id:
          type: string
        reason:
          enum:
            - manual
            - threshold
            - overflow
        outcome:
          enum:
            - completed
            - error
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - compaction_id: compact1
          reason: threshold
          outcome: completed
    InboxUpdated:
      type: object
      additionalProperties: false
      required:
        - items
      properties:
        items:
          $ref: "#/components/schemas/Inbox"
      examples:
        - items:
            - id: 7
              mode: followUp
    ExecutionFailed:
      type: object
      additionalProperties: false
      required:
        - error
      description: An execution failure notification. Submission outcomes remain
        authoritative for whether input was answered.
      properties:
        error:
          $ref: "#/components/schemas/ExecutionError"
      examples:
        - error:
            code: execution_failed
            message: Execution failed. Inspect submission status before deciding whether to
              retry.
    ModelList:
      type: object
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            type: object
            required:
              - provider
              - id
            properties:
              provider:
                type: string
              id:
                type: string
              name:
                type: string
              input:
                type: array
                items:
                  enum:
                    - text
                    - image
                description: Supported input content types.
              context_window:
                type: integer
                minimum: 1
                description: Maximum model context in tokens.
            additionalProperties: true
        next_cursor:
          type: "null"
    File:
      type: object
      required:
        - id
        - filename
        - mime_type
        - size
        - created_at
      properties:
        id:
          type: string
          format: uuid
        filename:
          type: string
          minLength: 1
          maxLength: 255
          not:
            pattern: "[\\r\\n\\u0000]"
        mime_type:
          type: string
        size:
          type: integer
          minimum: 0
        created_at:
          type: string
          format: date-time
    Artifact:
      type: object
      additionalProperties: false
      required:
        - id
        - filename
        - mime_type
        - size
        - created_at
        - sha256
        - session_id
        - tool_call_id
        - source_path
      properties:
        id:
          type: string
          format: uuid
          description: File ID for download or deletion.
        filename:
          type: string
          minLength: 1
          maxLength: 255
        mime_type:
          type: string
        size:
          type: integer
          minimum: 0
          maximum: 16777216
        created_at:
          type: string
          format: date-time
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        session_id:
          type: string
          format: uuid
        tool_call_id:
          type: string
          description: Producing tool execution reference.
        source_path:
          type: string
          pattern: ^/
    ArtifactList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Artifact"
        next_cursor:
          type:
            - string
            - "null"
    Webhook:
      type: object
      additionalProperties: false
      required:
        - id
        - url
        - events
        - created_at
      properties:
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
        events:
          type: array
          minItems: 1
          maxItems: 2
          uniqueItems: true
          items:
            enum:
              - submission.updated
              - artifact.created
        created_at:
          type: string
          format: date-time
    CreatedWebhook:
      type: object
      additionalProperties: false
      required:
        - id
        - url
        - events
        - created_at
        - signing_secret
      properties:
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
        events:
          type: array
          minItems: 1
          maxItems: 2
          uniqueItems: true
          items:
            enum:
              - submission.updated
              - artifact.created
        created_at:
          type: string
          format: date-time
        signing_secret:
          type: string
          description: Returned only by registration creation.
    WebhookList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Webhook"
        next_cursor:
          type:
            - string
            - "null"
    WebhookEvent:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - id
            - type
            - created_at
            - session_id
            - submission_id
          properties:
            id:
              type: string
              format: uuid
            type:
              const: submission.updated
            created_at:
              type: string
              format: date-time
            session_id:
              type: string
              format: uuid
            submission_id:
              type: integer
              minimum: 1
        - type: object
          additionalProperties: false
          required:
            - id
            - type
            - created_at
            - session_id
            - file_id
          properties:
            id:
              type: string
              format: uuid
            type:
              const: artifact.created
            created_at:
              type: string
              format: date-time
            session_id:
              type: string
              format: uuid
            file_id:
              type: string
              format: uuid
      examples:
        - id: 20000000-0000-4000-8000-000000000001
          type: submission.updated
          created_at: 2026-10-19T12:00:00Z
          session_id: 30000000-0000-4000-8000-000000000001
          submission_id: 7
    WebhookDelivery:
      type: object
      additionalProperties: false
      required:
        - id
        - event_id
        - status
        - attempts
        - created_at
        - next_attempt_at
        - expires_at
        - delivered_at
        - last_status_code
        - last_error
      properties:
        id:
          type: string
          format: uuid
        event_id:
          type: string
          format: uuid
        status:
          enum:
            - pending
            - succeeded
            - failed
            - cancelled
        attempts:
          type: integer
          minimum: 0
        created_at:
          type: string
          format: date-time
        next_attempt_at:
          type:
            - string
            - "null"
          description: Next eligible attempt time while pending.
        expires_at:
          type: string
          format: date-time
        delivered_at:
          type:
            - string
            - "null"
        last_status_code:
          type:
            - integer
            - "null"
        last_error:
          type:
            - string
            - "null"
          description: Safe delivery error code; never includes the signing secret or
            response body.
    WebhookDeliveryList:
      type: object
      additionalProperties: false
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/WebhookDelivery"
        next_cursor:
          type:
            - string
            - "null"
