Skip to main content
Twin exposes a REST API that lets you create agents, trigger runs, manage schedules, and more — all programmatically.

Base URL

https://api.twin.so

Authentication

All requests require an API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Generate an API key from your Twin account or via the API itself (see below).

Error Handling

All error responses follow this format:
{
  "code": 3,
  "message": "Description of what went wrong",
  "details": []
}

API Keys

RESTful endpoints for managing API keys.

List API keys

Returns all API keys for the authenticated user.Example
curl https://api.twin.so/api/public/v1/access-api-keys \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "keys": [
    {
      "keyId": "abc123",
      "name": "my-integration",
      "displayPrefix": "tw_live_abc...",
      "createdAt": 1706000000,
      "lastUsedAt": 1706100000
    }
  ]
}

Create an API key

Creates a new API key. The full key is only returned once — store it securely.Request body
FieldTypeRequiredDescription
namestringNoOptional name for the key
Example
curl -X POST https://api.twin.so/api/public/v1/access-api-keys \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-integration"}'
Response
{
  "keyId": "abc123",
  "name": "my-integration",
  "apiKey": "tw_live_...",
  "displayPrefix": "tw_live_abc..."
}
The apiKey field is only returned at creation time. Store it immediately.

Revoke an API key

Permanently revokes an API key. Any requests using it will stop working immediately.Path parameters
FieldTypeRequiredDescription
keyIdstringYesThe ID of the key to revoke
Example
curl -X DELETE https://api.twin.so/api/public/v1/access-api-keys/abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Agents

Create, list, update, and delete agents. All agent endpoints use POST with a JSON body.

Create an agent

Creates a new agent with a goal description.Request body
FieldTypeRequiredDescription
goalstringYesNatural-language description of the task
projectIdstringNoProject to assign the agent to
Example
curl -X POST https://api.twin.so/twin.service.TwinService/CreateAgentOnly \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"goal": "Monitor competitor pricing on stripe.com weekly"}'
Response
{
  "agentId": "agent_abc123"
}

Get an agent

Returns full details for a specific agent.Request body
FieldTypeRequiredDescription
agentIdstringYesThe agent’s ID
Example
curl -X POST https://api.twin.so/twin.service.TwinService/GetAgent \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agentId": "agent_abc123"}'
Response
{
  "agent": {
    "agentId": "agent_abc123",
    "goal": "Monitor competitor pricing on stripe.com weekly",
    "latestRunId": "run_xyz789",
    "lastActivityAt": "2026-02-20T14:30:00Z",
    "latestRunIsFinished": true,
    "hasRuns": true,
    "projectId": "proj_001",
    "deploymentState": "deployed",
    "deployedAt": "2026-02-18T10:00:00Z"
  }
}

List agents

Returns all agents, optionally filtered by project.Request body
FieldTypeRequiredDescription
projectIdstringNoFilter by project (omit for all)
Example
curl -X POST https://api.twin.so/twin.service.TwinService/ListAgents \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response
{
  "agents": [
    {
      "agentId": "agent_abc123",
      "goal": "Monitor competitor pricing on stripe.com weekly",
      "latestRunIsFinished": true,
      "hasRuns": true,
      "deploymentState": "deployed"
    }
  ]
}

Update agent goal

Updates the natural-language goal for an existing agent.Request body
FieldTypeRequiredDescription
agentIdstringYesThe agent’s ID
newGoalstringYesThe updated goal
Example
curl -X POST https://api.twin.so/twin.service.TwinService/UpdateAgentGoal \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent_abc123",
    "newGoal": "Monitor competitor pricing on stripe.com and notion.so daily"
  }'
Response
{
  "success": true,
  "previousGoal": "Monitor competitor pricing on stripe.com weekly"
}

Delete an agent

Permanently deletes an agent and all associated data.Request body
FieldTypeRequiredDescription
agentIdstringYesThe agent’s ID
Example
curl -X POST https://api.twin.so/twin.service.TwinService/DeleteAgent \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agentId": "agent_abc123"}'
Response
{
  "deleted": true
}

Runs

Trigger agent executions, check status, and retrieve results.

Start a run

Triggers a new run for a deployed agent.Request body
FieldTypeRequiredDescription
agentIdstringYesThe agent to run
Example
curl -X POST https://api.twin.so/twin.service.TwinService/StartRun \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agentId": "agent_abc123"}'
Response
{
  "agentId": "agent_abc123",
  "runId": "run_xyz789"
}

List runs

Returns paginated run history for an agent with optional filters.Request body
FieldTypeRequiredDescription
agentIdstringYesThe agent’s ID
pageintegerNoPage number (default 1)
pageSizeintegerNoResults per page (default 20)
filterStatusstringNo"finished", "running", or omit for all
filterStartedAfterstringNoISO 8601 date — only runs after this time
filterStartedBeforestringNoISO 8601 date — only runs before this time
Example
curl -X POST https://api.twin.so/twin.service.TwinService/ListAgentRuns \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent_abc123",
    "page": 1,
    "pageSize": 10,
    "filterStatus": "finished"
  }'
Response
{
  "runs": [
    {
      "runId": "run_xyz789",
      "agentId": "agent_abc123",
      "status": "finished",
      "startedAt": "2026-02-20T14:30:00Z",
      "finishedAt": "2026-02-20T14:32:15Z"
    }
  ],
  "totalRuns": 42,
  "page": 1,
  "pageSize": 10
}

Get run detail

Returns detailed information for a specific run, including step-by-step execution data.Request body
FieldTypeRequiredDescription
runIdstringYesThe run’s ID
Example
curl -X POST https://api.twin.so/twin.service.TwinService/GetRunDetail \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"runId": "run_xyz789"}'

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/{keyId}
Create agentPOST/twin.service.TwinService/CreateAgentOnly
Get agentPOST/twin.service.TwinService/GetAgent
List agentsPOST/twin.service.TwinService/ListAgents
Update agent goalPOST/twin.service.TwinService/UpdateAgentGoal
Delete agentPOST/twin.service.TwinService/DeleteAgent
Start runPOST/twin.service.TwinService/StartRun
List runsPOST/twin.service.TwinService/ListAgentRuns
Get run detailPOST/twin.service.TwinService/GetRunDetail
API key endpoints (/api/public/v1/...) use standard REST methods (GET, POST, DELETE). All other endpoints use POST with a JSON body — this is the gRPC-gateway convention used by Twin’s API.

Get your API key

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