API reference

Every REST endpoint, grouped by resource, with its parameters and an example request and response.

Base URL https://api.arc0.ai, with Authorization: Bearer $ARC0_API_KEY on every request. See API keys for access levels and Errors for the failure shapes these endpoints can return.

Connect

POST /v1/connect/links

Creates a link that starts Arc0 Connect for one user and app.

Prop

Type

Request
curl -X POST https://api.arc0.ai/v1/connect/links \
  -H "Authorization: Bearer $ARC0_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user":"u_8f2","customer":"northwind","app":"salesforce"}'
Response
{
  "id": "rc_7384l23otyjm",
  "url": "https://connect.arc0.ai/c/7Hq2Vd9KxP4m",
  "expires_at": "2026-10-04T12:00:00Z"
}

Users

GET /v1/users

Lists connected users in the current project and environment.

Prop

Type

Request
curl "https://api.arc0.ai/v1/users?customer=northwind&status=active" \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "data": [
    {
      "id": "cu_rm176e9q8z",
      "external_id": "u_8f2",
      "customer": "northwind",
      "connection_count": 3,
      "calls_7d": 214,
      "last_active_at": "2026-09-27T09:41:00Z"
    }
  ],
  "cursor": null
}

GET /v1/users/{user}

Request
curl https://api.arc0.ai/v1/users/u_8f2 \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "id": "cu_rm176e9q8z",
  "external_id": "u_8f2",
  "customer": "northwind",
  "environment": "production",
  "connection_count": 3,
  "created_at": "2026-04-11T08:02:00Z",
  "last_active_at": "2026-09-27T09:41:00Z"
}

DELETE /v1/users/{user}

Deletes the user and their tokens. This can't be undone.

Request
curl -X DELETE https://api.arc0.ai/v1/users/u_8f2 \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{ "ok": true }

GET /v1/users/{user}/connections

Request
curl https://api.arc0.ai/v1/users/u_8f2/connections \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "data": [
    {
      "id": "conn_z663h86fl3z2",
      "app": "salesforce",
      "status": "active",
      "auth_kind": "oauth2",
      "granted_scopes": ["read", "write"],
      "last_used_at": "2026-09-27T09:30:00Z"
    }
  ]
}

Connections

GET /v1/connections/{id}

Prop

Type

Request
curl https://api.arc0.ai/v1/connections/conn_z663h86fl3z2 \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "id": "conn_z663h86fl3z2",
  "connected_user_id": "cu_rm176e9q8z",
  "app": "salesforce",
  "status": "active",
  "auth_kind": "oauth2",
  "granted_scopes": ["read", "write"],
  "access_token_expires_at": "2026-09-27T10:30:00Z",
  "last_refreshed_at": "2026-09-27T09:30:00Z",
  "refresh_count": 42
}

POST /v1/connections/{id}/refresh

Forces an immediate token refresh, the same as Refresh now in the dashboard.

Request
curl -X POST https://api.arc0.ai/v1/connections/conn_z663h86fl3z2/refresh \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{ "id": "conn_z663h86fl3z2", "status": "active", "last_refreshed_at": "2026-09-27T10:02:11Z" }

DELETE /v1/connections/{id}

Revokes the connection.

Request
curl -X DELETE https://api.arc0.ai/v1/connections/conn_z663h86fl3z2 \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{ "id": "conn_z663h86fl3z2", "status": "revoked" }

GET /v1/connections/{id}/export

Returns the tokens. Requires a key with Full access. See Token export.

Request
curl https://api.arc0.ai/v1/connections/conn_z663h86fl3z2/export \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "id": "conn_z663h86fl3z2",
  "app": "salesforce",
  "auth_kind": "oauth2",
  "access_token": "00D...",
  "refresh_token": "5Aep...",
  "expires_at": "2026-09-27T10:30:00Z"
}

POST /v1/connections/{id}/reconnect-link

Returns a link that works once and expires in 7 days.

Request
curl -X POST https://api.arc0.ai/v1/connections/conn_z663h86fl3z2/reconnect-link \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "url": "https://connect.arc0.ai/r/rc_7384l23otyjm",
  "expires_at": "2026-10-04T10:02:11Z"
}

Actions

GET /v1/actions

Lists actions with their scope.

Prop

Type

Request
curl "https://api.arc0.ai/v1/actions?app=gmail" \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "data": [
    { "action": "gmail.send_email", "scope": "write" },
    { "action": "gmail.search_messages", "scope": "read" }
  ]
}

POST /v1/actions/{action}/run

Prop

Type

Request
curl -X POST https://api.arc0.ai/v1/actions/gmail.send_email/run \
  -H "Authorization: Bearer $ARC0_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user":"u_8f2","input":{"to":"ops@acme.com","subject":"Refund issued","body":"..."}}'
Response
{ "ok": true, "data": { "id": "18abf2..." } }

Proxy

ANY /v1/proxy/{app}/{path}

The authenticated proxy. Arc0 injects the user's credentials and still applies policies and audit. The scope is graded by HTTP method: GET → read, POST/PUT/PATCH → write, DELETE → destructive. See REST API and proxy.

Prop

Type

Request
curl https://api.arc0.ai/v1/proxy/stripe/v1/charges \
  -H "Authorization: Bearer $ARC0_API_KEY" \
  -H "Arc0-User: u_8f2"
Response
{ "object": "list", "data": [{ "id": "ch_1", "amount": 2000 }] }

Audit

GET /v1/audit

Prop

Type

Request
curl "https://api.arc0.ai/v1/audit?user=u_8f2&decision=blocked" \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "data": [
    {
      "id": "evt_01k61z9m4c5f0rce9dxyt3h7qb",
      "action": "salesforce.delete_record",
      "scope": "destructive",
      "decision": "blocked",
      "reason": "Requires approval",
      "agent_id": "support-bot",
      "via": "mcp",
      "time": "2026-09-27T09:41:00Z"
    }
  ],
  "cursor": null
}

GET /v1/audit/{event_id}

Returns the full event, including request and response.

Request
curl https://api.arc0.ai/v1/audit/evt_01k61z9m4c5f0rce9dxyt3h7qb \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "id": "evt_01k61z9m4c5f0rce9dxyt3h7qb",
  "action": "salesforce.delete_record",
  "decision": "blocked",
  "reason": "Requires approval",
  "approval": { "id": "apr_9k2m", "status": "pending" },
  "request": { "action": "salesforce.delete_record", "user": "u_8f2", "via": "mcp" },
  "response": null,
  "trace_id": "tr_4f0a..."
}

Approvals

GET /v1/approvals/{id}

Request
curl https://api.arc0.ai/v1/approvals/apr_9k2m \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "id": "apr_9k2m",
  "requested_from": ["ops@acme.com"],
  "status": "pending",
  "decided_by": null,
  "decided_at": null
}

POST /v1/approvals/{id}/approve

Request
curl -X POST https://api.arc0.ai/v1/approvals/apr_9k2m/approve \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{ "id": "apr_9k2m", "status": "approved", "decided_by": "ops@acme.com" }

POST /v1/approvals/{id}/reject

Request
curl -X POST https://api.arc0.ai/v1/approvals/apr_9k2m/reject \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{ "id": "apr_9k2m", "status": "rejected", "decided_by": "ops@acme.com" }

Policies

GET /v1/policies

Request
curl https://api.arc0.ai/v1/policies \
  -H "Authorization: Bearer $ARC0_API_KEY"
Response
{
  "data": [
    { "id": "pol_acme_support", "name": "acme-support", "environment": "production", "agents": ["*"], "version": 14 },
    { "id": "pol_backend_sync", "name": "backend-sync", "environment": "production", "agents": ["acme-backend"], "version": 3 }
  ]
}

PUT /v1/policies/{id}

Replaces the rules and creates a new version.

Prop

Type

Request
curl -X PUT https://api.arc0.ai/v1/policies/pol_acme_support \
  -H "Authorization: Bearer $ARC0_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"defaults":{"read":"allow","write":"ask","destructive":"deny"}}'
Response
{ "id": "pol_acme_support", "version": 15, "updated_by": "naomi@acme.com" }

On this page