# Clyck API - **OpenAPI Version:** `3.2.0` - **API Version:** `2026-10-19` ### 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": ""}, "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": ""}' ``` **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//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//submissions/" -H "Authorization: Bearer $CLYCK_API_KEY" curl "$CLYCK_API_URL/sessions//entries?min_entry_id=&max_entry_id=" \ -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 "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 ` 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": ""} } ``` Send that body to `POST /connections`, save its `id`, then start a ticket session with `POST /sessions`: ```json { "agent_version_id": "", "overrides": { "tools": [{ "type": "http", "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 `. 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": "", "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": ""}, {"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 `. 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.(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_`, and MCP tools are named `mcp__` 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 ## Authentication - **ApiKey**: HTTP bearer