Skip to main content
Twin exposes a REST API that lets you create agents, trigger runs, inspect events, and manage API keys programmatically.

Base URL

https://build.twin.so

OpenAPI Specification

A machine-readable OpenAPI 3.1 schema is available at:
https://build.twin.so/openapi.json
You can use this spec to generate client libraries, import into tools like Postman or Insomnia, or explore the API interactively in the docs playground above.

Authentication

Use the following header on every request:
x-api-key: YOUR_API_KEY
Generate an API key from your Twin account or via the API itself (see below).

Error Handling

Error responses follow RFC 9457 Problem Details and return Content-Type: application/problem+json.
{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "Description of what went wrong"
}
  • type is a URI identifying the problem type (about:blank means no extra semantics beyond the HTTP status).
  • status is the HTTP status code.
  • title is the standard HTTP reason phrase.
  • detail is a human-readable error message.
If you are migrating from the previous error.code / error.message format, update your error parsing logic.

API Keys

API key management endpoints currently use the /api/public/v1 path family. These endpoints use the same auth headers and Problem Detail error format as the /v1 endpoints.

List API keys

Returns all API keys for the authenticated user.Example
curl https://build.twin.so/api/public/v1/access-api-keys \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "keys": [
    {
      "key_id": "abc123",
      "name": "my-integration",
      "display_prefix": "tw_live_abc...",
      "created_at": 1706000000,
      "last_used_at": 1706100000
    }
  ]
}

Create an API key

Creates a new API key. The full key is only returned once, so store it securely.Request body
FieldTypeRequiredDescription
namestringYesKey name (1-128 characters)
Example
curl -X POST https://build.twin.so/api/public/v1/access-api-keys \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-integration"}'
Response
{
  "key_id": "abc123",
  "name": "my-integration",
  "api_key": "tw_live_...",
  "display_prefix": "tw_live_abc...",
  "created_at": 1706000000
}
The api_key field is only returned at creation time. Store it immediately.

Revoke an API key

Permanently revokes an API key. Requests using it stop working immediately.Path parameters
FieldTypeRequiredDescription
key_idstringYesID of the key to revoke
Example
curl -X DELETE https://build.twin.so/api/public/v1/access-api-keys/abc123 \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "revoked": true
}

Identity

Get current user

Returns the authenticated user ID.Example
curl https://build.twin.so/v1/me \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "user_id": "user_123"
}

Agents

Versioned agent endpoints live under /v1/agents.

List agents

Returns agents for the authenticated user, with optional pagination and workspace filtering.Query parameters
FieldTypeRequiredDescription
workspace_idstringNoFilter to a specific workspace
cursorstringNoCursor for pagination
limitintegerNoMax results to return
Example
curl "https://build.twin.so/v1/agents?limit=20" \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "agents": [
    {
      "agent_id": "agent_abc123",
      "latest_run_id": "run_xyz789",
      "latest_run_is_finished": true,
      "has_runs": true,
      "deployment_state": "deployed"
    }
  ]
}

Create an agent

Creates a new agent and returns the full agent object.Request body
FieldTypeRequiredDescription
workspace_idstringNoWorkspace to assign the agent to
owner_user_idstringNoOptional owner override
is_subagentbooleanNoWhether the new agent is a subagent
derived_from_agent_idstringNoSource agent ID for derived agents
agent_idstringNoExplicit agent ID override
Example
curl -X POST https://build.twin.so/v1/agents \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "proj_001"}'
Response 201 Created
{
  "agent": {
    "agent_id": "agent_abc123",
    "latest_run_id": "",
    "latest_run_is_finished": false,
    "has_runs": false,
    "workspace_id": "proj_001",
    "deployment_state": "not_deployed"
  }
}

Get an agent

Returns full details for a specific agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl https://build.twin.so/v1/agents/agent_abc123 \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "agent": {
    "agent_id": "agent_abc123",
    "latest_run_id": "run_xyz789",
    "last_activity_at": "2026-02-20T14:30:00Z",
    "latest_run_is_finished": true,
    "has_runs": true,
    "workspace_id": "proj_001",
    "deployment_state": "deployed",
    "deployed_at": "2026-02-18T10:00:00Z"
  }
}

Delete an agent

Permanently deletes an agent and its run data.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl -X DELETE https://build.twin.so/v1/agents/agent_abc123 \
  -H "x-api-key: YOUR_API_KEY"
Response 204 No Content — empty body on success. Returns 404 if the agent was not found.

Runs

Trigger, list, cancel, and delete runs under each agent.

List runs

Returns run history for an agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Query parameters
FieldTypeRequiredDescription
pageintegerNoPage number (default 1)
page_sizeintegerNoResults per page (default 100)
filter_statusstringNoRun status filter
filter_run_idstringNoFilter by exact run ID
filter_started_afterstringNoISO-8601 lower bound
filter_started_beforestringNoISO-8601 upper bound
filter_policy_typestringNoPolicy type filter
filter_policy_groupstringNoPolicy group filter (builder/runner)
Example
curl "https://build.twin.so/v1/agents/agent_abc123/runs?page=1&page_size=10&filter_status=finished" \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "runs": [
    {
      "run_id": "run_xyz789",
      "agent_id": "agent_abc123",
      "status": "finished",
      "started_at": "2026-02-20T14:30:00Z",
      "finished_at": "2026-02-20T14:32:15Z"
    }
  ],
  "total_runs": "42",
  "page": 1,
  "page_size": 10
}

Start a run

Starts a run for an existing agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Request body
FieldTypeRequiredDescription
run_modestringNo"build" or "run"
user_messagestringNoOptional user message for the run
skip_deploy_checkbooleanNoSkip deployment checks before starting
Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/runs \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"run_mode": "run", "user_message": "Please execute the latest workflow."}'
Response 201 Created
{
  "run": {
    "run_id": "run_xyz789",
    "agent_id": "agent_abc123",
    "status": "in_progress",
    "started_at": "2026-02-20T14:30:00Z",
    "is_finished": false,
    "is_paused": false,
    "run_number": 1,
    "policy_type": "runner_v2"
  }
}

Delete a run

Deletes a run for a specific agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
run_idstringYesThe run ID
Example
curl -X DELETE https://build.twin.so/v1/agents/agent_abc123/runs/run_xyz789 \
  -H "x-api-key: YOUR_API_KEY"
Response 204 No Content — empty body on success. Returns 404 if the run was not found.

Cancel a run

Cancels a running run. The request is idempotent — cancelling an already-finished run returns success.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
run_idstringYesThe run ID
Request body (optional)
FieldTypeRequiredDescription
reasonstringNoHuman-readable cancellation reason
The body is entirely optional — you may send an empty object {} or omit the body altogether.Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/runs/run_xyz789/cancel \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "User requested cancellation"}'
Response
{
  "error": ""
}
An empty error means success. A non-empty value is informational (e.g. the run was already stopped).

Events

List run events

Returns events for a specific run.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
run_idstringYesThe run ID
Query parameters
FieldTypeRequiredDescription
limitintegerNoMax events to return
after_indexintegerNoReturn events after this event index
Example
curl "https://build.twin.so/v1/agents/agent_abc123/runs/run_xyz789/events?limit=50" \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "events": [
    {
      "index": 1,
      "event": {
        "started": {}
      }
    }
  ]
}

Webhooks

Register webhook URLs to receive push notifications when runs change state. Instead of polling for run completion, your backend gets an HTTP POST for each lifecycle event.

Event types

EventFired when
run.startedA run begins executing
run.completedA run finishes (success, partial, or fail outcome)
run.failedA run hits a policy error
run.stoppedA run is stopped by the user
run.pausedA run is paused by the user, or paused by the agent for 15+ minutes

Create a webhook

Registers a webhook URL for the given agent. The signing secret is returned only once in the response — store it immediately.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Request body
FieldTypeRequiredDescription
urlstringYesHTTPS (or HTTP) endpoint to receive events
eventsstring[]YesEvent types to subscribe to (at least one required)
Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/webhooks \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/twin",
    "events": ["run.completed", "run.failed"]
  }'
Response 201 Created
{
  "webhook_id": "01234567-89ab-cdef-0123-456789abcdef",
  "url": "https://example.com/webhooks/twin",
  "events": ["run.completed", "run.failed"],
  "signing_secret": "whsec_a1b2c3d4e5f6...",
  "status": "active",
  "created_at": "2026-03-11T12:00:00Z"
}
The signing_secret is only returned at creation time. Store it securely — you need it to verify incoming webhook signatures.

List webhooks

Returns all webhooks registered for the given agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl https://build.twin.so/v1/agents/agent_abc123/webhooks \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "webhooks": [
    {
      "webhook_id": "01234567-89ab-cdef-0123-456789abcdef",
      "agent_id": "agent_abc123",
      "user_id": "user_123",
      "url": "https://example.com/webhooks/twin",
      "events": ["run.completed", "run.failed"],
      "status": "active",
      "created_at": "2026-03-11T12:00:00Z",
      "updated_at": "2026-03-11T12:00:00Z"
    }
  ]
}

Get a webhook

Returns details for a specific webhook.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
webhook_idstringYesThe webhook ID
Example
curl https://build.twin.so/v1/agents/agent_abc123/webhooks/01234567-89ab-cdef-0123-456789abcdef \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "webhook_id": "01234567-89ab-cdef-0123-456789abcdef",
  "agent_id": "agent_abc123",
  "user_id": "user_123",
  "url": "https://example.com/webhooks/twin",
  "events": ["run.completed", "run.failed"],
  "status": "active",
  "created_at": "2026-03-11T12:00:00Z",
  "updated_at": "2026-03-11T12:00:00Z"
}

Update a webhook

Updates a webhook’s URL, subscribed events, or status. All fields are optional — only provided fields are changed.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
webhook_idstringYesThe webhook ID
Request body
FieldTypeRequiredDescription
urlstringNoNew endpoint URL
eventsstring[]NoNew set of event types
statusstringNo"active" or "disabled"
Example
curl -X PATCH https://build.twin.so/v1/agents/agent_abc123/webhooks/01234567-89ab-cdef-0123-456789abcdef \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "disabled"}'
Response
{
  "webhook_id": "01234567-89ab-cdef-0123-456789abcdef",
  "agent_id": "agent_abc123",
  "user_id": "user_123",
  "url": "https://example.com/webhooks/twin",
  "events": ["run.completed", "run.failed"],
  "status": "disabled",
  "created_at": "2026-03-11T12:00:00Z",
  "updated_at": "2026-03-11T13:00:00Z"
}

Delete a webhook

Permanently deletes a webhook. No further events will be delivered.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
webhook_idstringYesThe webhook ID
Example
curl -X DELETE https://build.twin.so/v1/agents/agent_abc123/webhooks/01234567-89ab-cdef-0123-456789abcdef \
  -H "x-api-key: YOUR_API_KEY"
Response 204 No Content

Webhook payload

When a subscribed event fires, Twin sends an HTTP POST to your webhook URL with a JSON body:
{
  "event": "run.completed",
  "timestamp": "2026-03-11T14:32:15Z",
  "data": {
    "run_id": "run_xyz789",
    "agent_id": "agent_abc123",
    "status": "completed",
    "outcome": "success",
    "finished_at": "2026-03-11T14:32:15Z"
  }
}
FieldDescription
eventThe event type (e.g. run.completed)
timestampISO-8601 timestamp of when the event was dispatched
data.run_idThe run that triggered the event
data.agent_idThe agent the run belongs to
data.statusRun status: in_progress, completed, error, stopped, or paused
data.outcomePresent on run.completed: success, partial, or fail
data.finished_atPresent on terminal events (run.completed, run.failed, run.stopped)

Verifying webhook signatures

Every webhook delivery includes two headers:
HeaderValue
X-Cobb-Signaturesha256=<hex HMAC-SHA256>
X-Cobb-EventThe event type (e.g. run.completed)
To verify authenticity, compute HMAC-SHA256(signing_secret, raw_request_body) and compare it to the signature in the header. Example (Node.js)
const crypto = require("crypto");

function verifyWebhookSignature(secret, body, signatureHeader) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", secret).update(body).digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader)
  );
}

Schedules

Manage cron-based schedules for agents. Each agent can have at most one schedule.

Get agent schedule

Returns the current schedule for an agent, if one exists.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl https://build.twin.so/v1/agents/agent_abc123/schedule \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "schedule": {
    "cron": "0 0 9 * * * *",
    "paused": false
  }
}
Returns {"schedule": null} if no schedule is set.

Set agent schedule

Creates or replaces the cron schedule for an agent. The agent must be deployed.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Request body
FieldTypeRequiredDescription
cronstringYesCron expression (7-field format)
Example
curl -X PUT https://build.twin.so/v1/agents/agent_abc123/schedule \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"cron": "0 0 9 * * * *"}'
Response
{
  "success": true
}
Twin uses 7-field cron expressions: sec min hour day month day-of-week year.

Delete agent schedule

Removes the schedule from an agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl -X DELETE https://build.twin.so/v1/agents/agent_abc123/schedule \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "success": true
}

Pause schedule

Pauses the agent’s schedule. The schedule is retained but will not trigger runs until resumed.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/schedule/pause \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "success": true
}

Resume schedule

Resumes a paused schedule.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/schedule/resume \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "success": true
}

List all schedules

Returns all schedules for the authenticated user across all agents.Example
curl https://build.twin.so/v1/schedules \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "schedules": [
    {
      "agent_id": "agent_abc123",
      "cron": "0 0 9 * * * *",
      "paused": false
    }
  ]
}

Instructions

Read and update the auto-generated instructions for an agent, with version history.

Get instructions

Returns the current instructions for an agent.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Example
curl https://build.twin.so/v1/agents/agent_abc123/instructions \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "instructions": {
    "content": "Check email every morning and summarize unread messages."
  }
}

Update instructions

Replaces the agent’s instructions. Each update creates a new version in the history.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Request body
FieldTypeRequiredDescription
contentstringYesThe new instructions text
source_typestringNoSource of the update (e.g. "api", "builder")
source_idstringNoIdentifier for the source
Example
curl -X PUT https://build.twin.so/v1/agents/agent_abc123/instructions \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Check email and Slack every morning."}'
Response
{
  "success": true
}

Get instructions history

Returns previous versions of the agent’s instructions.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Query parameters
FieldTypeRequiredDescription
limitintegerNoMax versions to return (default: all)
Example
curl "https://build.twin.so/v1/agents/agent_abc123/instructions/history?limit=10" \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "instruction_versions": [
    {
      "content": "Check email and Slack every morning.",
      "created_at": "2026-03-11T15:00:00Z"
    },
    {
      "content": "Check email every morning and summarize unread messages.",
      "created_at": "2026-03-11T14:00:00Z"
    }
  ]
}

Workspaces

Organize agents into workspaces (folders). Every user has at least one default workspace.

List workspaces

Returns all workspaces for the authenticated user.Example
curl https://build.twin.so/v1/workspaces \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "workspaces": [
    {
      "workspace_id": "ws_001",
      "name": "My Workspace"
    }
  ]
}

Create a workspace

Creates a new workspace.Request body
FieldTypeRequiredDescription
namestringYesWorkspace name
Example
curl -X POST https://build.twin.so/v1/workspaces \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Marketing Agents"}'
Response 201 Created
{
  "workspace": {
    "workspace_id": "ws_002",
    "name": "Marketing Agents"
  }
}

Update a workspace

Updates a workspace’s name or icon.Path parameters
FieldTypeRequiredDescription
workspace_idstringYesThe workspace ID
Request body
FieldTypeRequiredDescription
namestringYesNew workspace name
icon_configstringNoIcon configuration string
Example
curl -X PUT https://build.twin.so/v1/workspaces/proj_002 \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Renamed Workspace"}'
Response
{
  "workspace": {
    "workspace_id": "ws_002",
    "name": "Renamed Workspace"
  }
}

Delete a workspace

Deletes a workspace and all agents inside it.Path parameters
FieldTypeRequiredDescription
workspace_idstringYesThe workspace ID
Example
curl -X DELETE https://build.twin.so/v1/workspaces/proj_002 \
  -H "x-api-key: YOUR_API_KEY"
Response
{
  "deleted": true
}
This permanently deletes the workspace and all agents within it.

Reorder workspaces

Sets the display order of workspaces.Request body
FieldTypeRequiredDescription
workspace_idsstring[]YesWorkspace IDs in the desired order
Example
curl -X POST https://build.twin.so/v1/workspaces/reorder \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workspace_ids": ["proj_002", "proj_001"]}'
Response
{
  "success": true
}

Move agent to workspace

Moves an agent from its current workspace to a different one.Path parameters
FieldTypeRequiredDescription
agent_idstringYesThe agent ID
Request body
FieldTypeRequiredDescription
workspace_idstringYesTarget workspace ID
Example
curl -X POST https://build.twin.so/v1/agents/agent_abc123/move \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"workspace_id": "proj_002"}'
Response
{
  "success": true
}

Quick Reference

ActionMethodEndpoint
List API keysGET/api/public/v1/access-api-keys
Create API keyPOST/api/public/v1/access-api-keys
Revoke API keyDELETE/api/public/v1/access-api-keys/{key_id}
Get current userGET/v1/me
List agentsGET/v1/agents
Create agentPOST/v1/agents
Get agentGET/v1/agents/{agent_id}
Delete agentDELETE/v1/agents/{agent_id}
List runsGET/v1/agents/{agent_id}/runs
Start runPOST/v1/agents/{agent_id}/runs
Delete runDELETE/v1/agents/{agent_id}/runs/{run_id}
Cancel runPOST/v1/agents/{agent_id}/runs/{run_id}/cancel
List run eventsGET/v1/agents/{agent_id}/runs/{run_id}/events
Create webhookPOST/v1/agents/{agent_id}/webhooks
List webhooksGET/v1/agents/{agent_id}/webhooks
Get webhookGET/v1/agents/{agent_id}/webhooks/{webhook_id}
Update webhookPATCH/v1/agents/{agent_id}/webhooks/{webhook_id}
Delete webhookDELETE/v1/agents/{agent_id}/webhooks/{webhook_id}
Get scheduleGET/v1/agents/{agent_id}/schedule
Set schedulePUT/v1/agents/{agent_id}/schedule
Delete scheduleDELETE/v1/agents/{agent_id}/schedule
Pause schedulePOST/v1/agents/{agent_id}/schedule/pause
Resume schedulePOST/v1/agents/{agent_id}/schedule/resume
List all schedulesGET/v1/schedules
Get instructionsGET/v1/agents/{agent_id}/instructions
Update instructionsPUT/v1/agents/{agent_id}/instructions
Instructions historyGET/v1/agents/{agent_id}/instructions/history
List workspacesGET/v1/workspaces
Create workspacePOST/v1/workspaces
Update workspacePUT/v1/workspaces/{workspace_id}
Delete workspaceDELETE/v1/workspaces/{workspace_id}
Reorder workspacesPOST/v1/workspaces/reorder
Move agentPOST/v1/agents/{agent_id}/move
Agent, run, and event APIs are now versioned REST endpoints under /v1 with standard HTTP methods.

Get your API key

Sign in to Twin to generate your API key and start building.