API Reference

Complete reference for the Tropic API. All endpoints require authentication via Clerk JWT or API key unless noted.

Base URLhttps://api.tropic.bot/api
AuthAuthorization: Bearer <token>
Rate limit60 req/min default

Policies

GET/policies

List policies

Returns all policy profiles belonging to the authenticated user. Policies define ALLOW/REQUIRE CONFIRM/DENY rules that control agent behavior.

Response
[
  {
    "id": "pol_8f3a2b1c",
    "userId": "user_abc123",
    "name": "Web Research Only",
    "rules": "ALLOW: browse any public website\nALLOW: read local files\nDENY: shell commands\nDENY: sudo",
    "createdAt": "2026-02-19T10:00:00.000Z",
    "updatedAt": "2026-02-19T10:00:00.000Z"
  }
]
GET/policies/:id

Get policy

Returns a single policy by ID. Returns 403 if the policy belongs to another user.

Response
{
  "id": "pol_8f3a2b1c",
  "userId": "user_abc123",
  "name": "Web Research Only",
  "rules": "ALLOW: browse any public website\nALLOW: read local files\nDENY: shell commands",
  "createdAt": "2026-02-19T10:00:00.000Z",
  "updatedAt": "2026-02-19T10:00:00.000Z"
}
POST/policies

Create policy

Create a new policy profile. Rules use the ALLOW / REQUIRE CONFIRM / DENY format, one rule per line.

Request body
{
  "name": "Strict Research",
  "rules": "ALLOW: browse any public website\nREQUIRE CONFIRM: download files\nDENY: shell commands\nDENY: sudo"
}
Response
{
  "id": "pol_9d4e3f2a",
  "userId": "user_abc123",
  "name": "Strict Research",
  "rules": "ALLOW: browse any public website\nREQUIRE CONFIRM: download files\nDENY: shell commands\nDENY: sudo",
  "createdAt": "2026-02-20T14:30:00.000Z",
  "updatedAt": "2026-02-20T14:30:00.000Z"
}
PUT/policies/:id

Update policy

Update an existing policy's name or rules. Only the fields you include will be changed. Agents using this policy will pick up the new rules on their next VM push.

Request body
{
  "name": "Relaxed Research",
  "rules": "ALLOW: browse any public website\nALLOW: download files\nALLOW: execute code in sandbox"
}
Response
{
  "id": "pol_9d4e3f2a",
  "name": "Relaxed Research",
  "rules": "ALLOW: browse any public website\nALLOW: download files\nALLOW: execute code in sandbox",
  "updatedAt": "2026-02-20T15:00:00.000Z"
}
DELETE/policies/:id

Delete policy

Permanently delete a policy. Any agents referencing this policy will have their policyId set to null.

Response
{
  "id": "pol_9d4e3f2a",
  "name": "Relaxed Research",
  "rules": "...",
  "createdAt": "2026-02-20T14:30:00.000Z",
  "updatedAt": "2026-02-20T15:00:00.000Z"
}

Agents

POST/agents10/min

Deploy agent

Deploy a new agent from a marketplace template. If policyId is omitted, the system auto-migrates your global settings into a policy. If the VM is running, the agent is pushed immediately via SSM. Otherwise it stays in "provisioning" until the VM starts.

Maximum 5 active agents per user. The policyId field is optional — omit it to use auto-migrated settings.

Request body
{
  "templateId": "tmpl_web-research",
  "name": "My Web Researcher",
  "policyId": "pol_8f3a2b1c"
}
Response
{
  "id": "agt_7b2c1d3e",
  "userId": "user_abc123",
  "templateId": "tmpl_web-research",
  "policyId": "pol_8f3a2b1c",
  "name": "My Web Researcher",
  "status": "provisioning",
  "config": {
    "agent": { "model": "claude-sonnet-4-6", "skills": ["web-search"] },
    "workspace": { "AGENTS.md": "..." }
  },
  "createdAt": "2026-02-19T10:00:00.000Z"
}
GET/agents

List agents

Returns all agents belonging to the authenticated user, ordered by creation date (newest first). Includes the template name/slug/icon and the attached policy name.

Response
[
  {
    "id": "agt_7b2c1d3e",
    "name": "My Web Researcher",
    "status": "ready",
    "policyId": "pol_8f3a2b1c",
    "template": {
      "name": "Web Research",
      "slug": "web-research",
      "icon": "search"
    },
    "policy": {
      "id": "pol_8f3a2b1c",
      "name": "Web Research Only"
    },
    "createdAt": "2026-02-19T10:00:00.000Z"
  }
]
GET/agents/:id

Get agent

Returns full details for a single agent, including the complete template and policy objects.

Response
{
  "id": "agt_7b2c1d3e",
  "name": "My Web Researcher",
  "status": "ready",
  "template": {
    "id": "tmpl_web-research",
    "name": "Web Research",
    "slug": "web-research",
    "icon": "search",
    "description": "...",
    "bundleConfig": { ... },
    "defaultPolicy": "..."
  },
  "policy": {
    "id": "pol_8f3a2b1c",
    "name": "Web Research Only",
    "rules": "ALLOW: browse any public website\n..."
  },
  "createdAt": "2026-02-19T10:00:00.000Z"
}
PATCH/agents/:id/policy

Update agent policy

Change or remove the security policy attached to an agent. If the agent's VM is running, the updated policy rules are pushed to the VM immediately via SSM. Set policyId to null to detach the policy.

To remove a policy entirely, send { "policyId": null }.

Request body
{
  "policyId": "pol_9d4e3f2a"
}
Response
{
  "id": "agt_7b2c1d3e",
  "name": "My Web Researcher",
  "status": "ready",
  "template": { "name": "Web Research", "slug": "web-research", "icon": "search" },
  "policy": { "id": "pol_9d4e3f2a", "name": "Strict Research" }
}
POST/agents/:id/stop

Stop agent

Sets the agent's status to "stopped". No-op if the agent is already stopped.

Response
{
  "id": "agt_7b2c1d3e",
  "name": "My Web Researcher",
  "status": "stopped"
}
DELETE/agents/:id

Remove agent

Permanently deletes the agent record. This cannot be undone.

Response
{ "success": true }

Templates

GET/templates

List templates

Returns all available agent templates in the marketplace. Templates are blueprints that define an agent's model, skills, workspace files, and default policy.

Response
[
  {
    "id": "tmpl_web-research",
    "name": "Web Research",
    "slug": "web-research",
    "description": "Research assistant with web browsing capabilities",
    "icon": "search",
    "bundleConfig": {
      "agent": { "model": "claude-sonnet-4-6", "skills": ["web-search", "summarize"] },
      "workspace": { "AGENTS.md": "...", "TOOLS.md": "..." }
    },
    "defaultPolicy": "ALLOW: web browsing\nDENY: file system write"
  }
]
GET/templates/:slug

Get template

Returns a single template by its slug identifier.

Response
{
  "id": "tmpl_web-research",
  "name": "Web Research",
  "slug": "web-research",
  "description": "Research assistant with web browsing capabilities",
  "icon": "search",
  "bundleConfig": { ... },
  "defaultPolicy": "ALLOW: web browsing\nDENY: file system write"
}

Agent Tasks

POST/agents/:agentId/tasks10/min

Submit task

Submit a new work item to an agent. The task enters "pending" and is picked up by the orchestrator on the VM. Tasks matching REQUIRE CONFIRM rules will pause for approval.

Request body
{
  "description": "Research the latest trends in AI safety and compile a summary"
}
Response
{
  "id": "task_1a2b3c4d",
  "agentId": "agt_7b2c1d3e",
  "description": "Research the latest trends in AI safety and compile a summary",
  "status": "pending",
  "createdAt": "2026-02-19T11:00:00.000Z"
}
GET/agents/:agentId/tasks

List tasks for agent

Returns all tasks submitted to a specific agent.

Response
[
  {
    "id": "task_1a2b3c4d",
    "agentId": "agt_7b2c1d3e",
    "description": "Research the latest trends in AI safety...",
    "status": "completed",
    "createdAt": "2026-02-19T11:00:00.000Z",
    "updatedAt": "2026-02-19T11:05:00.000Z"
  }
]
GET/agent-tasks

List all tasks

Returns all tasks across all agents for the authenticated user. Use the status query parameter to filter.

Filter by status: /agent-tasks?status=awaiting_approval

Response
[
  {
    "id": "task_1a2b3c4d",
    "agentId": "agt_7b2c1d3e",
    "description": "...",
    "status": "awaiting_approval",
    "createdAt": "2026-02-19T11:00:00.000Z"
  }
]
GET/agent-tasks/:taskId

Get task

Returns full details for a specific task including its event history.

Response
{
  "id": "task_1a2b3c4d",
  "agentId": "agt_7b2c1d3e",
  "description": "Research the latest trends in AI safety...",
  "status": "completed",
  "events": [
    { "status": "pending", "timestamp": "2026-02-19T11:00:00.000Z" },
    { "status": "running", "timestamp": "2026-02-19T11:00:05.000Z" },
    { "status": "completed", "timestamp": "2026-02-19T11:05:00.000Z" }
  ]
}
POST/agent-tasks/:taskId/approve10/min

Approve task

Approve a task that is waiting for human confirmation. Transitions the task from "awaiting_approval" to "running".

Response
{
  "id": "task_1a2b3c4d",
  "status": "running"
}
POST/agent-tasks/:taskId/reject10/min

Reject task

Reject a task that is waiting for human confirmation. The agent will not execute the action.

Response
{
  "id": "task_1a2b3c4d",
  "status": "rejected"
}

API Keys

POST/api-keys

Create API key

Generate a new API key for programmatic access. The full key is returned only once in this response — store it securely. Keys are stored as SHA-256 hashes.

The key field is only returned on creation. Store it immediately.

Response
{
  "id": "key_4f5e6d7c",
  "key": "tropic_live_sk_a1b2c3d4e5f6g7h8i9j0...",
  "prefix": "tropic_live_sk_a1b2",
  "createdAt": "2026-02-19T10:00:00.000Z"
}
GET/api-keys

List API keys

Returns all API keys for the authenticated user. Only the key prefix is shown — the full key is never returned after creation.

Response
[
  {
    "id": "key_4f5e6d7c",
    "prefix": "tropic_live_sk_a1b2",
    "lastUsedAt": "2026-02-20T08:30:00.000Z",
    "createdAt": "2026-02-19T10:00:00.000Z"
  }
]
DELETE/api-keys/:id

Revoke API key

Permanently revoke an API key. Any requests using this key will immediately return 401.

Response
{ "success": true }

Credits

GET/credits/:userId/balance

Get balance

Returns the user's current credit balance. VM runtime costs 5 credits/hour, deducted every 5 minutes.

Response
{
  "balance": 847.5,
  "userId": "user_abc123"
}
GET/credits/:userId/transactions

Get transactions

Returns the credit transaction history for the user, ordered by most recent first.

Response
[
  {
    "id": "txn_1a2b3c",
    "amount": 1000,
    "type": "purchase",
    "description": "1000 credits ($25.00)",
    "createdAt": "2026-02-19T10:00:00.000Z"
  },
  {
    "id": "txn_4d5e6f",
    "amount": -0.42,
    "type": "vm_runtime",
    "description": "VM runtime (5 min)",
    "createdAt": "2026-02-19T10:05:00.000Z"
  }
]
POST/credits/create-checkout-session

Create checkout session

Creates a Stripe Checkout session for purchasing credits. Returns a URL to redirect the user to.

Request body
{
  "quantity": 1000,
  "successUrl": "https://tropic.bot/credits?success=true",
  "cancelUrl": "https://tropic.bot/credits"
}
Response
{
  "url": "https://checkout.stripe.com/c/pay/cs_live_..."
}

VM

POST/vm/:userId/start

Start VM

Start the user's EC2 virtual machine. If no VM exists, one is provisioned from the custom AMI. Captures the client's IP for SSH access.

Response
{
  "status": "provisioning",
  "instanceId": "i-0abc123def456"
}
POST/vm/:userId/stop

Stop VM

Stop the user's VM. The instance is stopped (not terminated), preserving data on the EBS volume.

Response
{
  "status": "stopping"
}
GET/vm/:userId/status

Get VM status

Returns the current VM status. Possible values: stopped, provisioning, starting, running.

Response
{
  "status": "running",
  "instanceId": "i-0abc123def456",
  "publicIp": "54.123.45.67",
  "region": "ap-southeast-1"
}
GET/vm/:userId/openclaw/gateway/status

Get gateway status

Returns the OpenClaw gateway status on the VM. The gateway is the HTTP/WebSocket server that handles chat sessions.

Response
{
  "gatewayStatus": "running",
  "uptime": 3600
}
POST/vm/:userId/openclaw/gateway/restart

Restart gateway

Restarts the OpenClaw gateway systemd service on the VM via SSM.

Response
{
  "status": "restarting"
}

Settings

GET/settings/:userId/commands

Get command bundles

Returns the user's enabled command bundles. Available bundles: browser-search, code-execution, os-commands.

Response
{
  "bundles": ["browser-search", "code-execution"]
}
POST/settings/:userId/commands

Update command bundles

Set which command bundles are enabled for the user's agent. Changes are synced to the VM if running.

Request body
{
  "bundles": ["browser-search", "code-execution", "os-commands"]
}
Response
{
  "bundles": ["browser-search", "code-execution", "os-commands"]
}
GET/settings/:userId/firewall-rules

Get firewall rules

Returns the user's firewall rules by port. Each port maps to a list of allowed CIDR blocks.

Response
{
  "rules": {
    "22": ["203.0.113.45/32"],
    "80": ["0.0.0.0/0"],
    "443": ["0.0.0.0/0"],
    "18789": []
  }
}
POST/settings/:userId/firewall-rules

Update firewall rules

Replace the firewall rules for all ports. Rules are applied to the VM's security group immediately.

Request body
{
  "rules": {
    "22": ["203.0.113.45/32"],
    "80": ["0.0.0.0/0"],
    "443": ["0.0.0.0/0"]
  }
}
Response
{ "success": true }
GET/settings/:userId/current-ip

Detect current IP

Returns the public IP address of the requesting client. Useful for populating the "My IP" button in firewall settings.

Response
{
  "ip": "203.0.113.45"
}

Instances

POST/instances/:userId/local

Register local instance

Register a local OpenClaw installation as a managed instance. Returns an activation code that must be verified on the local machine.

Request body
{
  "name": "My MacBook",
  "description": "Local development machine"
}
Response
{
  "id": "inst_3c4d5e6f",
  "type": "local",
  "name": "My MacBook",
  "status": "pending",
  "activationCode": "TRPC-A1B2-C3D4"
}
GET/instances/:userId

List instances

Returns all managed instances (EC2 and local) for the user.

Response
[
  {
    "id": "inst_3c4d5e6f",
    "type": "local",
    "name": "My MacBook",
    "status": "active",
    "lastSeenAt": "2026-02-20T08:30:00.000Z"
  },
  {
    "id": "inst_7g8h9i0j",
    "type": "ec2",
    "name": "Cloud VM",
    "status": "running",
    "instanceId": "i-0abc123def456"
  }
]
PATCH/instances/:userId/:id

Update instance

Update an instance's name or description.

Request body
{
  "name": "Work Laptop",
  "description": "Office machine"
}
Response
{
  "id": "inst_3c4d5e6f",
  "name": "Work Laptop",
  "description": "Office machine"
}
DELETE/instances/:userId/:id

Remove instance

Unregister a managed instance. For EC2 instances, this does not terminate the VM.

Response
{ "success": true }

Credentials

POST/credentials/:userId/claude-key

Save Claude API key

Encrypt and store a Claude API key. The key is encrypted with AES-256-GCM before storage and synced to the VM on next start.

Request body
{
  "apiKey": "sk-ant-api03-..."
}
Response
{ "success": true }
GET/credentials/:userId/ssh-key

Download SSH key

Download the SSH private key for the user's VM. Returns a .pem file. The key is only available once — store it securely.

Response
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----

Errors

All errors return a consistent JSON body with a status code, message, and error type.

{
  "statusCode": 404,
  "message": "Agent agt_7b2c1d3e not found",
  "error": "Not Found"
}
400Bad Request
401Unauthorized
403Forbidden
404Not Found
429Rate Limited
500Server Error