Agent API

Use this when: you want to embed long-lived agents inside your own product — create agents, start sessions, send messages, and stream responses back to your users.

Don't use this when: you only want to call an LLM with one key (use the API Gateway instead — no sessions, no agents, same key). Or if you want to use agents from an MCP client (see MCP server).

Everything lives under https://api.agentsky.dev/v1. Authenticate with Authorization: Bearer ast_… (an API key from Developer → API keys or sky auth login). Management is request/response; conversation is a 202-send plus one standing SSE stream.

The model in 30 seconds

text
Agent  ← reusable spec (harness, instructions, capabilities)
  └─ Session  ← one conversation thread; holds context and history
       └─ Events  ← messages in, responses out, as a stream

An agent is what you configure once. A session is what runs. Your application sends user.message events and reads the stream until session.status_idle — the same loop every time.

Basic: end to end in three API calls

1. Create an agent

bash
curl -X POST https://api.agentsky.dev/v1/agents \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Research Agent",
    "agentType": "hermes",
    "llm": "claude-sonnet-5"
  }'
# → { "id": "agent_…", "defaultSessionId": "sess_…", … }

2. Start a session and send the first message

bash
curl -X POST https://api.agentsky.dev/v1/sessions \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "agent_…",
    "initial_events": [
      { "type": "user.message",
        "content": [{ "type": "text", "text": "Summarize the signups from today" }] }
    ]
  }'
# → { "id": "sess_…", "status": "running", … }

3. Stream the response

bash
curl -N https://api.agentsky.dev/v1/sessions/sess_.../stream \
  -H "Authorization: Bearer ast_..."
# SSE frames until session.status_idle
# id: msg-77e0c4…
# event: agent.message
# data: {"id":"msg-…","type":"agent.message","text":"Signups today: 42…"}
# …
# event: session.status_idle
# data: {"stop_reason":{"type":"end_turn"}}

Read the stream until you see session.status_idle. The stream stays open — subsequent turns post another event and wait again.

Continue the conversation

bash
curl -X POST https://api.agentsky.dev/v1/sessions/sess_.../events \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "requireIdle": true,
    "events": [
      { "type": "user.message",
        "content": [{ "type": "text", "text": "Which cohort drove the increase?" }] }
    ]
  }'

requireIdle: true rejects the POST if the session is already running — use it to prevent double-sends.

Advanced topics

Idempotency

Wrap every mutating call in an Idempotency-Key header (a UUID you generate once per logical operation). Replaying the same key returns the first response without side effects. Network timeouts are safe to retry with the same key.

bash
curl -X POST https://api.agentsky.dev/v1/sessions \
  -H "Authorization: Bearer ast_..." \
  -H "Idempotency-Key: 40a9ae2a-4ea5-4a50-987e-d8b3c99c96f0" \
  ...

Budgets and spending limits

Cap what a session may spend with a spend policy:

bash
curl -X POST https://api.agentsky.dev/v1/sessions/sess_.../policies \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spend cap",
    "kind": "SPEND_CAP",
    "config": { "hardCapUsdMicros": 5000000, "warnUsdMicros": 4000000 }
  }'

The session stops with stop_reason.type: "budget_reached" when the hard cap is reached. GET /v1/sessions/{id} includes cumulative spend.

Interrupts

Stop a running session gracefully:

bash
curl -X POST https://api.agentsky.dev/v1/sessions/sess_.../events \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{ "events": [{ "type": "user.interrupt" }] }'

Send "mode": "save" to ask the agent to save what it has and end the turn cleanly.

Reconnect and replay

Missed stream events are kept in the event log forever. Replay from any event ID:

bash
# All events in order (same objects as the live stream; dedupe by event id)
curl "https://api.agentsky.dev/v1/sessions/sess_.../events" \
  -H "Authorization: Bearer ast_..."

# Resume stream from a known event id
curl -N "https://api.agentsky.dev/v1/sessions/sess_.../stream?after=msg-77e0c4…" \
  -H "Authorization: Bearer ast_..."

Files and workspace

Upload files and mount them into a session:

bash
# Upload
curl -X POST https://api.agentsky.dev/v1/files \
  -H "Authorization: Bearer ast_..." \
  -F "file=@report.pdf"
# → { "id": "file_…", … }

# Mount at session create or POST /sessions/{id}/resources
-d '{ "agent": "agent_…",
      "resources": [
        { "type": "file", "file_id": "file_…", "mount_path": "/data/report.pdf" }
      ] }'

GitHub repositories mount the same way ("type": "github_repository"); memory stores mount as "type": "memory_store".

Vaults and secrets

Store per-agent secrets (OAuth tokens, webhook signing keys) in the agent's vault:

bash
curl -X PUT https://api.agentsky.dev/v1/agents/agent_.../secrets/MY_TOKEN \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{ "value": "secret_…" }'

The agent sees the value as an environment variable; it never appears in API responses.

Webhooks

Subscribe to session events server-to-server:

bash
curl -X POST https://api.agentsky.dev/v1/webhooks \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/agentsky",
    "events": ["session.status_idle", "session.error"]
  }'

The routine_run.failed and routine.paused events are also available. Wire hook rules to call a URL or require human approval on specific tool uses (POST /hook_rules).

Environments (universes)

Create an isolated workspace for a customer, team, or environment:

bash
curl -X POST https://api.agentsky.dev/v1/universes \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{ "slug": "acme", "name": "Acme" }'

# All subsequent calls scoped to that workspace:
curl ... -H "X-Universe: acme"

Invite members (POST /universes/{slug}/invites), set policies, and pin agent versions (PUT /universes/{slug}/agents/{handle}).

Skills and agent.toml

Attach reusable instruction bundles to any agent with sky launch and an agent.toml file, or via PUT /agents/{id}/prompt. Skills are versioned bundles you upload once and attach by reference.

Reference

  • Full API reference — every /v1 endpoint, schemas, the error contract, and the complete stream event catalog
  • Authentication — tokens, scopes, X-Universe header
  • Concepts — agents, sessions, events, and billing explained
  • CLI — sky launch, sky agent, sky session and every other command
  • agent.toml — declarative agent configuration