API Reference

REST API

The Cowork server exposes a versioned REST API at /api/v1. All endpoints return JSON.

Base URL http://localhost:26866/api/v1

Responses

Stream AI responses from the agent. Compatible with the OpenAI Responses API shape.

Response object

json
{
  "id":              "resp_abc123",
  "conversation_id": "conv_xyz",
  "input":           "Summarise last week's sales data",
  "output":          [{ "type": "text", "text": "Here is the summary..." }],
  "status":          "completed",  // "in_progress" | "completed" | "failed"
  "model":           "claude-opus-4-8",
  "usage":           { "input_tokens": 120, "output_tokens": 340 },
  "created_at":      "2026-06-11T10:00:00Z"
}
POST /responses Create a streaming response

Body

conversation_idstringrequiredID of the conversation to append the response to.
inputstringrequiredUser message text.
streambooleanoptionalDefault true. Return server-sent events. Set to false for a single JSON response.
modelstringoptionalOverride the agent model for this turn. Defaults to the project setting.
skill_idsstring[]optionalSkill IDs to activate for this turn.
curl
curl -X POST http://localhost:26866/api/v1/responses \
  -H "Content-Type: application/json" \
  -d '{"conversation_id":"conv_xyz","input":"Summarise last week'\''s sales data","stream":true}'
GET /responses/in-flight-list List active streams

Query parameters

conversation_idstringoptionalFilter to a specific conversation.
GET /responses/in-flight Check a specific in-flight stream

Query parameters

conversation_idstringrequiredConversation whose active stream to retrieve.

Conversations

Manage conversation threads. Each conversation holds an ordered list of messages. Conversations and Tasks are the same concept — every task is a conversation with a goal and an assigned agent. The API uses both terms interchangeably.

Conversation object

json
{
  "id":           "conv_abc123",
  "project_id":   "proj_xyz",           // null if not project-scoped
  "title":        "Q2 analysis",
  "goal":         "Analyse Q2 revenue by region",  // task prompt, optional
  "status":       "active",             // "active" | "archived"
  "created_at":   "2026-06-11T10:00:00Z",
  "updated_at":   "2026-06-11T10:04:12Z"
}
GET /conversations List conversations

Query parameters

project_idstringoptionalFilter to a specific project.
statusstringoptionalactive or archived. Returns all if omitted.
limitintegeroptionalMax results to return. Default 50, max 200.
offsetintegeroptionalPagination offset. Default 0.
POST /conversations Create a conversation

Body

project_idstringoptionalAttach to a project.
titlestringoptionalHuman-readable name. Auto-generated from the first message if omitted.
goalstringoptionalTask prompt or goal that frames the conversation for the agent.
curl
curl -X POST http://localhost:26866/api/v1/conversations \
  -H "Content-Type: application/json" \
  -d '{"project_id":"proj_xyz","title":"Q2 analysis","goal":"Analyse Q2 revenue by region"}'
GET /conversations/{id} Get a conversation

Path parameters

idstringrequiredConversation ID.
PATCH /conversations/{id} Update title, goal, or status

Body

titlestringoptionalNew title.
goalstringoptionalUpdated task goal.
statusstringoptionalactive or archived.
GET /conversations/{id}/items Get messages in a conversation

Returns an ordered array of message items. Each item has role (user or assistant), content, and created_at.

Query parameters

limitintegeroptionalDefault 100.
beforestringoptionalReturn items before this item ID (cursor pagination).
DELETE /conversations/{id} Delete a conversation and all its messages

Projects

Projects are workspaces that group conversations, files, and artifacts.

Project object

json
{
  "id":             "proj_abc123",
  "name":           "Sales Automation",
  "description":    "Weekly reporting flows",
  "connector_ids":  ["conn_001", "conn_002"],
  "skill_ids":      ["skill_abc"],
  "created_at":     "2026-06-11T10:00:00Z",
  "updated_at":     "2026-06-11T10:00:00Z"
}
GET /projects List all projects

Query parameters

limitintegeroptionalDefault 50.
offsetintegeroptionalDefault 0.
POST /projects Create a project

Body

namestringrequiredDisplay name for the project.
descriptionstringoptionalShort description shown in the UI.
connector_idsstring[]optionalData source connections available within this project.
skill_idsstring[]optionalGlobal skills to activate for all conversations in this project.
curl
curl -X POST http://localhost:26866/api/v1/projects \
  -H "Content-Type: application/json" \
  -d '{"name":"Sales Automation","description":"Weekly reporting flows","connector_ids":["conn_001"]}'
PATCH /projects/{id} Update a project

Body

namestringoptional
descriptionstringoptional
connector_idsstring[]optionalReplaces the current list.
skill_idsstring[]optionalReplaces the current list.
DELETE /projects/{id} Delete a project and all its contents

Artifacts

Artifacts are mini apps — web apps, dashboards, reports, and documents generated by the agent and hosted within a project. Each artifact belongs to a project.

Artifact object

json
{
  "id":          "art_abc123",
  "project_id":  "proj_xyz",
  "title":       "Sales Dashboard",
  "type":        "app",      // "app" | "report" | "doc" | "dashboard"
  "path":        "sales_dashboard/index.html",  // relative path within project
  "created_at":  "2026-06-11T10:00:00Z",
  "updated_at":  "2026-06-11T10:00:00Z"
}
GET /artifacts List artifacts

Query parameters

project_idstringoptionalFilter to a project.
typestringoptionalapp, report, doc, or dashboard.
limitintegeroptionalDefault 50.
GET /artifacts/preview Preview an artifact by path

Query parameters

pathstringrequiredRelative artifact path, e.g. sales_dashboard/index.html.
project_idstringrequiredProject that owns the artifact.
POST /artifacts/open Open an artifact in the desktop shell

Body

artifact_idstringrequiredArtifact to open in the Electron window.
GET /artifacts/serve/{project_id}/{path} Serve a raw artifact file

Path parameters

project_idstringrequiredProject ID.
pathstringrequiredFile path within the artifact, e.g. index.html or assets/chart.js.

Schedules

Run tasks on a cron schedule. Schedules belong to a project and trigger a conversation or workflow automatically.

Schedule object

json
{
  "id":              "sched_abc123",
  "project_id":      "proj_xyz",
  "cron":            "0 9 * * 1",       // standard 5-field cron expression
  "timezone":        "America/New_York",
  "prompt":          "Generate weekly sales digest",
  "conversation_id": null,             // null = create new conversation each run
  "status":          "active",         // "active" | "paused"
  "last_run_at":     "2026-06-09T09:00:00Z",
  "next_run_at":     "2026-06-16T09:00:00Z",
  "created_at":      "2026-06-01T00:00:00Z"
}
GET /schedules List schedules

Query parameters

project_idstringoptionalFilter to a project.
statusstringoptionalactive or paused.
POST /schedules Create a schedule

Body

project_idstringrequiredProject this schedule belongs to.
cronstringrequiredStandard 5-field cron expression, e.g. "0 9 * * 1" = every Monday at 09:00.
promptstringrequiredTask the agent runs at each scheduled time.
timezonestringoptionalIANA timezone. Default UTC.
conversation_idstringoptionalAppend each run to an existing conversation. If omitted, a new conversation is created per run.
curl
curl -X POST http://localhost:26866/api/v1/schedules \
  -H "Content-Type: application/json" \
  -d '{"project_id":"proj_xyz","cron":"0 9 * * 1","prompt":"Generate weekly sales digest","timezone":"America/New_York"}'
PATCH /schedules/{id} Update a schedule

Body

cronstringoptionalNew cron expression.
promptstringoptionalUpdated task prompt.
timezonestringoptionalNew timezone.
statusstringoptionalactive or paused.
POST /schedules/{id}/run Trigger a schedule immediately
DELETE /schedules/{id} Delete a schedule

Files

Upload and manage files that the agent can read, search, and reference. Files can be attached to a project or to individual conversations.

File object

json
{
  "id":              "file_abc123",
  "name":            "Q2-report.pdf",
  "mime_type":       "application/pdf",
  "size":            204800,           // bytes
  "project_id":      "proj_xyz",       // null if conversation-scoped only
  "conversation_id": null,             // null if project-scoped only
  "created_at":      "2026-06-11T10:00:00Z"
}
GET /files List files

Query parameters

project_idstringoptionalFilter to a project.
conversation_idstringoptionalFilter to a conversation.
POST /files Upload a file

Multipart form-data upload.

Form fields

filefilerequiredThe file binary. Accepted: PDF, DOCX, XLSX, CSV, TXT, PNG, JPG, and more.
project_idstringoptionalAttach to a project.
conversation_idstringoptionalAttach to a conversation. Can be set alongside project_id.
curl
curl -X POST http://localhost:26866/api/v1/files \
  -F "file=@Q2-report.pdf" \
  -F "project_id=proj_xyz"
DELETE /files/{id} Delete a file

Connectors

Integrate external data sources. Connectors exist independently of any project but can be referenced inside any project. They are defined by specs (the connector type, e.g. PostgreSQL, Snowflake, Google Sheets) and instantiated as connections with encrypted credentials. Credentials are write-only — never returned after creation.

ConnectorSpec object

json
{
  "id":           "postgres",
  "name":         "PostgreSQL",
  "description":  "Connect to any PostgreSQL-compatible database.",
  "auth_type":    "credentials",  // "credentials" | "oauth2"
  "fields": [                       // credential fields required at connection time
    { "key": "host",     "label": "Host",     "secret": false },
    { "key": "port",     "label": "Port",     "secret": false },
    { "key": "database", "label": "Database", "secret": false },
    { "key": "user",     "label": "User",     "secret": false },
    { "key": "password", "label": "Password", "secret": true  }
  ]
}

Connection object

json
{
  "id":         "conn_abc123",
  "spec_id":    "postgres",       // which ConnectorSpec this uses
  "name":       "prod-db",
  "status":     "connected",      // "connected" | "error" | "pending"
  "created_at": "2026-06-11T10:00:00Z"
  // credentials are never returned
}
GET /connectors/specs List available connector specs
curl
curl "http://localhost:26866/api/v1/connectors/specs"
GET /connectors/connections List active connections

Query parameters

spec_idstringoptionalFilter by connector type (e.g. postgres).
POST /connectors/connections Create a connection

Body

spec_idstringrequiredThe connector spec to use (e.g. "postgres").
namestringrequiredHuman-readable label for this connection.
credentialsobjectrequiredKey-value map of credential fields defined by the spec. Secret fields are encrypted at rest and never returned.
curl
curl -X POST "http://localhost:26866/api/v1/connectors/connections" \
  -H "Content-Type: application/json" \
  -d '{
    "spec_id": "postgres",
    "name": "prod-db",
    "credentials": {
      "host": "db.example.com",
      "port": 5432,
      "database": "analytics",
      "user": "reader",
      "password": "s3cr3t"
    }
  }'
DELETE /connectors/connections/{id} Remove a connection
GET /connectors/oauth/{spec}/start Start OAuth 2.0 flow

Returns a redirect URL. Send the user's browser there; after authorization the platform receives the callback and stores the token automatically.

Path parameter

specstringrequiredThe connector spec ID (e.g. google-sheets, notion).

Memories

Persistent facts and context the agent retains across conversations. Memories can be global (shared across all projects and conversations) or project-scoped — omit project_id to create a global memory. The agent automatically surfaces relevant memories as context at the start of each conversation.

Memory object

json
{
  "id":           "mem_abc123",
  "content":      "Prefers executive summaries under 200 words.",
  "project_id":   null,            // null = global; string = project-scoped
  "source":       "user",          // "user" | "agent" — who created it
  "created_at":   "2026-06-11T10:00:00Z",
  "updated_at":   "2026-06-11T10:00:00Z"
}
GET /memories List memories

Query parameters

project_idstringoptionalReturn memories scoped to this project. Omit to return global memories.
sourcestringoptionalFilter by who created it: user or agent.
curl
curl "http://localhost:26866/api/v1/memories"               # global
curl "http://localhost:26866/api/v1/memories?project_id=..."  # project-scoped
POST /memories Create a memory

Body

contentstringrequiredThe fact or preference to remember. Plain text.
project_idstringoptionalScope to a project. Omit for a global memory.
curl
curl -X POST "http://localhost:26866/api/v1/memories" \
  -H "Content-Type: application/json" \
  -d '{"content": "Always use Q3 targets as the baseline.", "project_id": "proj_xyz"}'
PATCH /memories/{id} Update a memory

Body

contentstringoptionalUpdated text for the memory.
DELETE /memories/{id} Delete a memory

Skills

Reusable capabilities available globally across all projects — custom instructions, tools, or prompt templates the agent can invoke. Skills extend what the agent knows how to do without re-explaining it each time. Like Connectors, they exist independently of any single project.

Skill object

json
{
  "id":            "skill_abc123",
  "name":          "weekly-report",
  "description":   "Generates a weekly performance report from connected data sources.",
  "instructions":  "Always include a one-paragraph executive summary first. Use bullet points for metrics...",
  "tools": [        // external tool integrations this skill may invoke
    "sql_query",
    "send_email"
  ],
  "created_at":    "2026-06-11T10:00:00Z",
  "updated_at":    "2026-06-11T10:00:00Z"
}
GET /skills List all skills
curl
curl "http://localhost:26866/api/v1/skills"
POST /skills Register a skill

Body

namestringrequiredKebab-case identifier. Used to invoke the skill from a conversation.
descriptionstringrequiredShort summary of what this skill does. Shown in the UI and used by the agent to decide whether to invoke it.
instructionsstringoptionalDetailed prompt injected whenever this skill is active. Explains how to carry out the task, preferred format, constraints, etc.
toolsstring[]optionalList of tool identifiers the agent may call when running this skill (e.g. "sql_query", "send_email").
curl
curl -X POST "http://localhost:26866/api/v1/skills" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "weekly-report",
    "description": "Generates a weekly performance report.",
    "instructions": "Always start with an executive summary. Limit to 3 charts.",
    "tools": ["sql_query", "send_email"]
  }'
PATCH /skills/{id} Update a skill

Body

namestringoptionalNew identifier.
descriptionstringoptionalUpdated summary.
instructionsstringoptionalRevised prompt instructions.
toolsstring[]optionalReplace the full list of allowed tools.
DELETE /skills/{id} Delete a skill

Scratchpads

Notebook-style workspaces scoped to a conversation. A scratchpad is made up of ordered cells — the agent writes to cells as it reasons, drafts, and executes code. Each cell has a type (markdown, code, or output) and tracks its own execution state. Scratchpads persist for the lifetime of the conversation and can be promoted to an Artifact.

Scratchpad object

json
{
  "id":              "sp_abc123",
  "conversation_id": "conv_xyz",
  "title":           "Sales analysis draft",
  "cells":           [ /* ordered array of Cell objects */ ],
  "saved":           false,     // true once promoted / pinned
  "created_at":      "2026-06-11T10:00:00Z",
  "updated_at":      "2026-06-11T10:04:12Z"
}

Cell object

json
{
  "id":        "cell_001",
  "type":      "code",          // "markdown" | "code" | "output"
  "content":   "df.describe()",
  "language":  "python",        // present when type = "code"
  "status":    "success",       // "pending" | "running" | "success" | "error"
  "outputs":   [                 // present when type = "output"
    {
      "mime":    "text/plain",
      "data":    "count    12.0\nmean     4.2\n..."
    },
    {
      "mime":    "image/png",
      "data":    "data:image/png;base64,..."
    }
  ],
  "error":     null,            // error message when status = "error"
  "index":     0                 // display order within the scratchpad
}

typemarkdown cells are prose written by the agent; code cells are executable snippets; output cells are the results attached to the preceding code cell (stdout, images, tables).
status — only relevant on code cells. pending means queued, running means currently executing, success/error are terminal states.
outputs — multi-modal: a single code cell can produce several output objects with different MIME types (plain text, HTML, PNG charts, JSON).

GET /scratchpads List scratchpads for a conversation
curl
curl "http://localhost:26866/api/v1/scratchpads?conversation_id=..."
POST /scratchpads Create a scratchpad
curl
curl -X POST "http://localhost:26866/api/v1/scratchpads" \
  -H "Content-Type: application/json" \
  -d '{"conversation_id":"...","title":"Sales analysis draft","cells":[]}'
GET /scratchpads/{scratchpad_id} Get a scratchpad with all cells
PATCH /scratchpads/{scratchpad_id} Update title or save state
curl
curl -X PATCH "http://localhost:26866/api/v1/scratchpads/{scratchpad_id}" \
  -H "Content-Type: application/json" \
  -d '{"title":"Final analysis","saved":true}'
DELETE /scratchpads/{scratchpad_id} Delete a scratchpad and all its cells

Cells

Cells are managed individually so the agent can append, edit, or re-run a single cell without replacing the whole scratchpad.

POST /scratchpads/{scratchpad_id}/cells Append a cell
curl
curl -X POST "http://localhost:26866/api/v1/scratchpads/{scratchpad_id}/cells" \
  -H "Content-Type: application/json" \
  -d '{"type":"code","language":"python","content":"df.head()"}'
PATCH /scratchpads/{scratchpad_id}/cells/{cell_id} Edit a cell's content or index
curl
curl -X PATCH "http://localhost:26866/api/v1/scratchpads/{scratchpad_id}/cells/{cell_id}" \
  -H "Content-Type: application/json" \
  -d '{"content":"df.tail(10)","index":2}'
POST /scratchpads/{scratchpad_id}/cells/{cell_id}/run Execute a code cell

Runs the cell and streams output back as server-sent events. Each event carries a partial output object. Terminal event has status: "success" or status: "error".

curl
curl -X POST "http://localhost:26866/api/v1/scratchpads/{scratchpad_id}/cells/{cell_id}/run"
DELETE /scratchpads/{scratchpad_id}/cells/{cell_id} Delete a cell