Compass Docs
Developers

API, CLI & SDK

Call Compass over HTTP, from your terminal, or from Python — one surface, three clients, every example in all three.

Everything you can do in the app you can do from outside it. There's one HTTP API underneath, and three ways to call it:

  • API — the raw HTTP surface. Use it from any language or tool that can make a request.
  • CLI — the compass command. A management surface for your terminal — not just running and inspecting work, but authoring it: create agents, build and deploy workflows, manage connections and datasets, every command scriptable for automation and CI.
  • Python — the async Compass SDK, from compass_core import Compass. The same wheel as the CLI, imported as a library.

Pick your client once

Every example on this page comes in all three flavors. Switch any code block to API, CLI, or Python and the whole page follows — the choice is remembered next time you visit.

Install

The CLI and the SDK ship in a single Python wheel you download from the app, at Settings → Developer → SDK & CLI (the Download wheel button). The panel shows the exact file name and the commands to run. The API needs no install at all.

The SDK & CLI settings panel: a Download wheel button and three steps — install, authenticate, run.
Settings → Developer → SDK & CLI — download the wheel and copy the install, login, and run commands.

Nothing to install. Calls go to your Compass URL — the same address you use to sign in — under the /v1 prefix:

https://your-compass-url/v1

Authenticate

Every client authenticates with an API key — create one in Settings → Developer → API keys and copy it (it's shown only once).

A key is not a bearer token. It's a self-contained credential that you exchange for a short-lived access token, and that access token is what actually rides on each request. The CLI and the SDK do the exchange for you and refresh it as it expires; over raw HTTP you do it yourself.

Authenticating by hand is three steps: read the values out of your key, exchange them for an access token, then call the API with that token.

1 — Read the values out of your key. The key is base64url-encoded JSON. Any base64url decoder will do; this one needs nothing but Python:

python3 -c "import base64, os; k = os.environ['COMPASS_API_KEY']; print(base64.urlsafe_b64decode(k + '=' * (-len(k) % 4)).decode())"

It prints the three values the key carries:

{
  "token_url": "https://auth.your-compass-url/application/o/token/",
  "client_id": "…",
  "client_secret": "…"
}

Take token_url from the key rather than guessing it — it's your sign-in provider's token endpoint, which is a different hostname from the Compass API.

2 — Exchange the key for an access token using the OAuth2 client-credentials grant, posting those three values as form fields:

COMPASS_ACCESS_TOKEN=$(curl -s -X POST "<token_url>" \
  -d grant_type=client_credentials \
  -d client_id="<client_id>" \
  -d client_secret="<client_secret>" \
  -d scope=openid | jq -r .access_token)

The reply is a standard OAuth2 token response: access_token is the token to send, and expires_in says how many seconds it stays valid. It's short-lived, so a long-running caller repeats this exchange when it lapses — which is exactly what the SDK and CLI do on your behalf. Keep the key; it's what you re-exchange with.

3 — Call the API with that access token as the bearer:

curl https://your-compass-url/v1/projects/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN"

Every API example below assumes $COMPASS_ACCESS_TOKEN holds a token that's still valid.

Profiles, options, and environment

CLI credentials are stored in ~/.config/compass/config.json, and you can keep several profiles (for example, different organizations or environments):

compass config list          # show saved profiles
compass config use <name>    # switch the default profile
compass config path          # where the config file lives

A few options apply to every command. They're global, so they go right after compass, before the command group:

OptionPurpose
--profile <name>Use a saved profile for this command.
--project <id>Act in this project for this command.
-o, --output table|json|yamlOutput format.
--api-key, --base-urlOverride the profile's key or URL.
compass --project <project-id> -o json workflows list

Environment variables override the saved profile (and command-line options override both):

VariablePurpose
COMPASS_API_KEYThe API key to authenticate with.
COMPASS_BASE_URLYour Compass URL.
COMPASS_PROFILEWhich profile to use.
COMPASS_PROJECT_IDThe project to act in (see below).

Choose a project

Your API key is organization-scoped, so you tell Compass which project a call should act in. Skip it and calls act on your organization's default project.

Send the project's id on each request as a header:

X-Compass-Project-Id: <project-id>

GET /v1/projects/ lists the projects your key can reach and your role in each.

Run an execution

Execution is asynchronous: you dispatch work and get back an execution you then poll or stream until it finishes. Provide either a deployment_id (the live version) or a workflow_id (the latest draft of a workflow or agent), plus the input. The response has an id and a status — the id is typed by what you dispatched: workflow_execution_<hex> or agent_execution_<hex>.

curl -X POST https://your-compass-url/v1/executions/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "deployment_id": "<deployment-id>",
    "input_data": { "topic": "Q3 report" }
  }'

Optional fields:

FieldPurpose
conversation_idContinue a conversation, for agents with conversation history.
configValues for the definition's declared run settings.
tools, tool_targetsReplace a single agent's tools for this run, and pick live or draft for workflow and agent tools.
model_settings, reasoning, harnessOverride a single agent's sampling settings, reasoning effort, or harness for this run.

A run can be refused before it starts: 402 when a spend limit blocks it, 409 when its deployment is archived.

Get the result

Once dispatched, read the execution by id to check its status and output. Poll until it reaches a terminal state — or stream it instead.

An execution's status is one of pending, running, waiting_approval (paused on a human decision), completed, failed, or cancelled (stopped before it finished). While it runs, progress (0–1) and current_step say how far along it is. total_cost is its cost, and rollup_total_cost includes any child executions.

curl https://your-compass-url/v1/executions/<execution-id> \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN"

Stream it live

For real-time output, subscribe to the execution's event stream — a Server-Sent Events connection. Each event is a JSON object with a type: token and reasoning (text as it's generated), node and batch_item (steps starting and finishing), tool_call, tool_result, and child_run, approval_requested and approval_resolved, error, and finally complete. The stream replays from the start, so you never miss early events, and closes after complete.

Send Accept: text/event-stream — without it, the response is buffered rather than streamed:

curl -N https://your-compass-url/v1/streams/<execution-id> \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "Accept: text/event-stream"

Inspect executions

Beyond the execution itself, you can list your project's executions and read any execution's full trace — per-node details and the hierarchical tree, including child executions.

# List executions in the project, newest first
curl "https://your-compass-url/v1/executions/?status=failed&limit=20" \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>"

# Per-node details, and the hierarchical trace
curl https://your-compass-url/v1/executions/<execution-id>/node-executions \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN"
curl https://your-compass-url/v1/executions/<execution-id>/tree \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN"

The list is paged: it returns {items, next_cursor} — pass cursor to get the next page. Filter with workflow_id, deployment_id, status, q (search by name or id), since, and until; limit is up to 200.

GET /v1/executions/summary returns aggregate usage over a time window. The window is unbounded unless you pass since and/or until. group_by buckets it by workflow, deployment, day, week or month; pass tz (an IANA zone such as America/Chicago) to cut days, weeks and months in that zone rather than UTC.

Create an agent

Agents are workflows of type agent, so every client creates them through the workflows surface from a definition — the same YAML you see in the builder's YAML view. The CLI adds a first-class agents group on top, including an interactive wizard.

POST /v1/workflows/ with the definition as a string — YAML or JSON — and, optionally, a display_name and description. The easiest way to get a definition to start from is to build one in the app and copy it from the YAML view, or read the definition field of GET /v1/workflows/{id}:

curl -X POST https://your-compass-url/v1/workflows/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile def agent.yaml '{definition: $def}')"

Build, validate, deploy

The whole workflow lifecycle is available from code: create a workflow from a definition, validate it, and deploy it. Because agents are workflows under the hood, validate and deploy work on an agent's id too.

# Create
curl -X POST https://your-compass-url/v1/workflows/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile def workflow.yaml '{definition: $def}')"

# Validate — returns { valid, issues }
curl -X POST https://your-compass-url/v1/workflows/<workflow-id>/validate \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN"

# Deploy — freezes the draft into the next version and makes it live
curl -X POST https://your-compass-url/v1/deployments/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{ "workflow_id": "<workflow-id>" }'

Pass version_id to deploy an existing version instead of the draft. A definition with validation errors is refused with 422 and the list of issues.

Work with datasets

Datasets can be created, filled, and searched from any client. Uploading a file starts its ingestion and returns the execution, so you can wait for it like any other.

# Create — the embedding model comes from the connection, and can't change later
curl -X POST https://your-compass-url/v1/datasets/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{ "display_name": "Policies", "embedding_connection_id": "<connection-id>" }'

# Upload a file, then add it to the dataset
curl -X POST https://your-compass-url/v1/files/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -F file=@handbook.pdf
curl -X POST https://your-compass-url/v1/datasets/<dataset-id>/documents \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '<the file object returned by /v1/files/>'

# Search
curl -X POST https://your-compass-url/v1/datasets/<dataset-id>/search \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{ "query": "parental leave", "top_k": 5 }'

Sources are managed under /v1/datasets/{id}/sources — see the reference.

Manage connections

Connections, providers, and gateways can be managed from any client — creating or changing them needs a key with a Developer role, because they hold credentials. Deleting one that's still in use is refused with 409; see Managing connections.

curl https://your-compass-url/v1/providers/ \
  -H "Authorization: Bearer $COMPASS_ACCESS_TOKEN" \
  -H "X-Compass-Project-Id: <project-id>"

The same shape applies to /v1/connections/ and /v1/gateways/, each with GET/PATCH/DELETE on /{id} and GET /{id}/usage to see what uses it. PATCH with {"is_active": false} switches a connection off.

Scriptable end to end

Everything above composes: create an agent, deploy it, kick off an execution, and parse the result — from CI, a script, or your own backend, without the UI.

Reference

HTTP resources

All routes live under https://your-compass-url/v1 and take an access token as the bearer, plus (optionally) the project header shown above. Most errors return {type, code, message, context, hint, is_retryable}; a few — such as the 409 for an archived deployment, upload limits, and request-validation errors — return {detail} instead.

ResourceRoutes
ExecutionsGET/POST /v1/executions/, …/{id}, …/{id}/node-executions, …/{id}/tree, …/summary, POST …/{id}/cancel — stop it; answers 204, then the execution settles as cancelled and its stream closes
StreamsGET /v1/streams/{execution_id} — live Server-Sent Events
WorkflowsGET/POST /v1/workflows/, GET/PATCH/DELETE …/{id}, …/{id}/validate, …/{id}/versions, …/{id}/metrics, GET …/system
DeploymentsGET/POST /v1/deployments/ (POST deploys), GET/PATCH …/{id}, …/{id}/archive, …/{id}/bindings, …/{id}/triggers, …/{id}/metrics
ApprovalsGET /v1/approvals/, …/{id}, POST …/{id}/approve, …/{id}/reject
ConversationsGET/POST /v1/conversations/, GET/DELETE …/{id}, …/{id}/executions, POST …/{id}/rewind — drop a turn and everything after it, to edit or retry from there
FilesPOST /v1/files/ — upload a file (up to 20 MB) to attach or ingest
DatasetsGET/POST /v1/datasets/, GET/PATCH/DELETE …/{id}, …/{id}/documents, …/{id}/search, …/{id}/sources, …/{id}/sources/{source_id}/sync, …/{id}/runs, …/{id}/reingest, …/pipelines
Connections / Providers / GatewaysGET/POST /v1/connections/, /v1/providers/, /v1/gateways/, each with GET/PATCH/DELETE …/{id} and …/{id}/usage
IntegrationsGET/POST /v1/integrations/, GET/PATCH/DELETE …/{id} — custom (OpenAPI) integrations
Spend limitsGET/POST /v1/spend-limits/, PATCH/DELETE …/{id}
ProjectsGET/POST /v1/projects/, PATCH/DELETE …/{id}

CLI commands

GroupWhat it does
compass authlogin, logout, whoami.
compass configManage profiles: list, use, path.
compass projectslist the projects your key can reach, and use one.
compass workflowslist, get, create, update, delete, validate, deploy.
compass agentslist, get, create, update, execute, delete.
compass executeDispatch an execution of a deployment or workflow.
compass executionsInspect executions: list, get, node-executions, tree; cancel stops a running one.
compass approvalslist, get, approve, reject human-in-the-loop approvals.
compass conversationslist, get, create, runs, delete.
compass datasetslist, show, create, upload, documents, search, delete-document, delete, sources, add-source, sync, runs.
compass connections · providers · gatewaysManage each kind of connection.
compass integrationslist, get, register (from an OpenAPI spec), delete.
compass components · nodesBrowse the component catalog and every node type.

Run compass --help, or compass <group> --help, to see every option. Most commands print a readable table by default. For machine-readable output, add --json to the command, or set the global -o option before the group:

compass workflows list --json
compass -o yaml executions get <execution-id>

Python resources

The client groups calls by resource:

ResourceUse it for
client.executionsDispatch executions, read their results and traces, and cancel() a running one.
client.streamsSubscribe to an execution's live events.
client.workflowsList, get, create, update, validate, and deploy workflows and agents; system() lists built-in ones such as Compass Chat.
client.conversationsGroup executions into conversations.
client.approvalsList and decide human-in-the-loop approvals.
client.filesUpload files to attach to executions.
client.datasetsCreate, fill, sync, and search datasets.
client.connectionsManage integration connections.
client.integrationsManage custom (OpenAPI) integrations.
client.providersManage provider connections.
client.gatewaysManage gateway connections.
client.components · client.nodesBrowse the component catalog and every node type.
client.projectsList the projects your key can reach, with your role.

Python errors

The SDK raises typed exceptions you can import from compass_core.client:

ExceptionWhen
AuthErrorThe request was refused as unauthenticated or forbidden (401/403) — for example, no access to this project.
NotFoundErrorThe resource doesn't exist in your project.
ValidationErrorThe request was rejected as invalid.
RateLimitErrorYou've been rate limited. The client waits and retries once when the server asks for a short wait; otherwise it raises, with retry_after.
ServerErrorSomething failed server-side.

All of them derive from CompassClientError, which is also raised directly for other refusals — such as 402 (a spend limit blocked the run) and 409 (a conflict, such as deleting something still in use). Every error carries status_code and the response body. A key that can't be exchanged for an access token — malformed, revoked, or expired — raises CompassClientError before any API call is made.

Next

On this page