Skip to main content
Browse the documentation

Getting started

Your first API call

Create an API key, call the Snaga API with curl, give the Chief of Staff a task and read the result.

Everything you can do in the web app goes through the same API, at https://api.snaga.ai. This page takes you from no key to a finished task in four requests. You need curl and a signed-in account; Quickstart covers sign-up.

Create an API key

An API key is how a program proves it acts for you, inside one company. Each key carries scopes — what it may do — so a script that only reads runs does not need a key that can delete agents.

In the web app, open Settings → Keys and webhooks and choose Create key. Give the key a name, choose what it can access (for example Agents, Runs and Sessions, each as read or write, or Full access) and create it.

Copy the key now — it will not be shown again. Snaga keeps only a hash. A key looks like this:

uarp_<prefix>_<secret>

Keep it out of source control. In a shell, put it in an environment variable:

export SNAGA_API_KEY='uarp_...'

You can also create keys from code with POST /api/v1/tenants/me/keys, using a key that has the api_keys:write scope. Without scopes in the body, a new key gets a default set, narrowed to what the calling key itself holds: agents, runs (create and read), sessions, notifications, memory and files (read and write), plus analytics:read — but not billing:read. Keys created this way do not expire: expires_at is null.

Call 1: who am I?

Every request sends the key as a bearer token:

curl -s https://api.snaga.ai/api/v1/me \
  -H "Authorization: Bearer $SNAGA_API_KEY"

GET /api/v1/me describes the caller. Read these fields:

FieldWhat it tells you
roleYour role in the company. Read it here, at the top level.
scopesWhat this key may do.
auth_methodapi_key for a key.
tenant.name, tenant.planThe company the key acts in, and its plan.
tenant.head_agent_idThe Chief of Staff's agent id — you need it below.

user may be null or filled, depending on how the key was made, and the role inside it is not always there. role at the top level is always present, so read it there.

GET /api/v1/tenants/me gives the company itself, including plan and the quotas that apply to it. Any valid key may call both.

Call 2: give the Chief of Staff a task

Work happens in a conversation (a session) with an agent. Open one with the Chief of Staff:

curl -s https://api.snaga.ai/api/v1/sessions \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "<agent_id>"}'

The answer carries a session_id. Now send the task:

curl -s https://api.snaga.ai/api/v1/sessions/<session_id>/messages \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"content": "Summarise what the company did this week in five bullet points."}'

The platform answers 202 Accepted with a run_id: the work is queued, not done. The Idempotency-Key header makes a retry safe — the same request with the same key within 24 hours returns the first answer instead of starting a second run.

These two calls need the sessions:write and runs:create scopes.

Call 3: wait for the result

The simplest way to get the answer is to wait for the run to finish:

curl -s "https://api.snaga.ai/api/v1/runs/<run_id>/wait?timeout_sec=60" \
  -H "Authorization: Bearer $SNAGA_API_KEY"

If the run finishes in time you get 200 with the run. If not, you get 202 with status: still_running and the run's real state in current_status; call it again. In the run:

  • status is completed when it worked; the answer is in output.response.
  • status is failed or timeout when it did not; error is a sentence for people and error_code is the value to branch on.

A run that is waiting for a person does not end the wait: you get 202 with current_status of awaiting_approval or awaiting_input until someone answers. See Approvals.

To watch the answer arrive as it is written, stream GET /api/v1/runs/<run_id>/events instead (server-sent events). The API reference has the details.

When something goes wrong

Errors come back as problem documents (application/problem+json). This is the real answer to a request without a key, trimmed:

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Missing Authorization header, token query parameter, or uarp_session cookie",
  "correlation_id": "<request id>",
  "code": "AUTH_ERROR"
}

Branch on status and code; show detail to a person. correlation_id is the same value as the X-Request-Id response header — quote it when you ask for help. A key without the scope an operation needs gets 403.

Revoke a key

In Settings → Keys and webhooks, revoke a key you no longer use: it stops working immediately, and anything using it breaks. From code, DELETE /api/v1/tenants/me/keys/<key_id> does the same; GET /api/v1/tenants/me/keys lists keys without ever showing a secret.

Next steps