API reference

One origin, one namespace

Everything lives under https://api.agentsky.dev/v1 with a Bearer token. Management is request/response; conversation is a 202 send plus one standing SSE stream.

The reference below is rendered from the machine-readable spec — the same schemas the routes validate with: https://api.agentsky.dev/v1/openapi.json.

Authentication

Every request sends Authorization: Bearer ast_…. Tokens are minted in Settings → API tokens or by sky auth login — never by other tokens. Scopes are ordered read ⊂ write ⊂ admin; a token is personal (acts as you everywhere) or scoped to one universe. Pass X-Universe: <slug> to act inside a non-personal universe.

Errors

Every non-2xx body is { "error": { "code", "message" } }:

HTTPcodeWhen
400invalid_requestmalformed JSON / validation failure
401invalid_tokenmissing, unknown, revoked, or expired token
402insufficient_creditsthe spend gate blocked the turn
403insufficient_scope · universe_mismatch · forbiddenscope too low; X-Universe conflicts with a scoped token; agent has no API binding
404not_foundunknown agent/universe (also masks unauthorized ids)
409conflictversion conflict
422invalid_specvalid JSON, invalid domain rules (e.g. llm not allowed for type)
429rate_limited120 requests/min per token exceeded — honor Retry-After

Identity

GET/whoamiread

Caller identity, resolved universe, effective scopes

Response · 200

userobjectrequired
▸ Show child attributes
idstring
emailstring
namestring | null
universeobjectrequired
▸ Show child attributes
slugstring
namestring
isPersonalboolean
scopesenum<string>[]required

"read" · "write" · "admin"

authenum<string>required

"token" · "session"

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/whoami \
  -H "Authorization: Bearer ast_..."

Universes

GET/universesread

List universes

Response · 200

universesobject[]required
▸ Show child attributes
slugstring
namestring
isPersonalboolean
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/universes \
  -H "Authorization: Bearer ast_..."
POST/universeswrite, personal tokens only

Create a universe

Body · application/json

slugstringrequired

max length 40 — pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$

namestring

max length 80

Response · 201

universeobjectrequired
▸ Show child attributes
slugstring
namestring
isPersonalboolean
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/universes \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"slug":"acme","name":"Acme"}'

Universe detail

Path parameters

slugstringrequired

The universe slug

Response · 200

universeobjectrequired
▸ Show child attributes
slugstring
namestring
isPersonalboolean
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/universes/slug \
  -H "Authorization: Bearer ast_..."

Agents

GET/agentsread

List agents in the resolved universe

Response · 200

agentsobject[]required
▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring

Engine: claude_code · codex · hermes · openclaw · pi · dsh · kimi_code · opencode

llmstring
harnessVersionstring | null

The engine CLI version this agent's sessions run; PATCH to move to the platform's current version

reasoningEffortstring | null

Harness-native reasoning effort; null = the harness's own default. Applies from the next provision/restart. Allowed values depend on agentType — hermes: none/minimal/low/medium/high/xhigh/max/ultra; claude_code: low/medium/high/xhigh/max; codex: none/minimal/low/medium/high/xhigh/max; openclaw: not supported; pi: off/minimal/low/medium/high/xhigh/max; dsh: not supported; kimi_code: not supported; opencode: none/minimal/low/medium/high/xhigh/max — "none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null

capabilitiesenum<string>[]

The built-in capabilities this agent is granted — the exact set its sessions may execute (enforced; empty = none). Ids are listed at /docs/capabilities. — "exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

versioninteger

Bumped on every update; see expectedVersion

archivedboolean
sessionCountinteger
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/agents \
  -H "Authorization: Bearer ast_..."
POST/agentswrite

Create an agent

An agent is a reusable configuration — engine, prompt, capabilities, secrets. Every field is optional: an empty body creates the default hermes agent with no built-in capabilities (capabilities are explicit opt-in; unknown ids → 400). The response's `id` (agent_…) is the agent's only address. One agent can run many sessions; creating the agent provisions nothing — the pod is provisioned by POST /v1/sessions.

Body · application/json

namestring

Prompt/display label only — NOT the handle. The addressable handle is the auto-minted `slug` in the response — max length 60

descriptionstring

max length 500

agentTypeenum<string>

"hermes" · "claude_code" · "codex" · "openclaw" · "pi" · "dsh" · "kimi_code" · "opencode"

llmstring
reasoningEffortenum<string>

Harness-native reasoning effort; omitted = the harness's own default. Allowed values depend on agentType — hermes: none/minimal/low/medium/high/xhigh/max/ultra; claude_code: low/medium/high/xhigh/max; codex: none/minimal/low/medium/high/xhigh/max; openclaw: not supported; pi: off/minimal/low/medium/high/xhigh/max; dsh: not supported; kimi_code: not supported; opencode: none/minimal/low/medium/high/xhigh/max — "none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra"

promptstring

max length 100000

displayNamestring

Seeds the minted `slug` (the unique addressable handle, returned in the response); omitted = an auto-generated asteroid name — max length 60

capabilitiesenum<string>[]

"exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe" — default: []

instructionsobject[]
▸ Show child attributes
namestringrequired

pattern .*\.md$

contentstring

default: ""

skillsobject[]

RFC-0073 skill attachments: store references ({type:'skill', skillId, version?: 'latest'|skr_…}) and GitHub shortcuts ({type:'github', url, ref?, tokenSecretRef?}). Max 20.

▸ Show child attributes
type: "skill"object
▸ Show child attributes
type"skill"required
skillIdstringrequired
versionstring

default: "latest"

type: "github"object
▸ Show child attributes
type"github"required
urlstringrequired
refstring

Branch or commit SHA; default branch when omitted.

tokenSecretRefstring

Agent secret key holding a clone token for private repos.

mcpServersobject[]

Remote streamable-HTTP MCP servers this agent connects to.

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

customDataobject[]
▸ Show child attributes
idstringrequired
namestringrequired

pattern ^[a-z0-9_]+$

kindenum<string>required

"spreadsheet" · "doc" · "private_api" · "other"

scopeenum<string>

"creator" · "user" — default: "creator"

descriptionstring
uristring
configobject

default: {}

metadataobject

Response · 201

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

The built-in capabilities this agent is granted — the exact set its sessions may execute (enforced; empty = none). Ids are listed at /docs/capabilities. — "exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

mcpServersobject[]

Declared remote MCP server references, including tool filters; runtime authentication fields are never returned

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/agents \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"displayName":"Research Agent","agentType":"hermes","llm":"deepseek-v4-pro","capabilities":["exa.search"]}'
Response · 201 Created
{
  "agent": {
    "id": "agent_cmtb2f0a8m9k7x51q4ez6r0d",
    "name": "Research Agent",
    "displayName": "Research Agent",
    "agentType": "hermes",
    "llm": "deepseek-v4-pro",
    "version": 1,
    "capabilities": [
      "exa.search"
    ],
    "defaultSessionId": null,
    "universe": "acme"
  }
}

Agent detail

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

The built-in capabilities this agent is granted — the exact set its sessions may execute (enforced; empty = none). Ids are listed at /docs/capabilities. — "exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

mcpServersobject[]

Declared remote MCP server references, including tool filters; runtime authentication fields are never returned

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
  -H "Authorization: Bearer ast_..."
PATCH/agents/{id}write

Update displayName / capabilities / metadata

Omitted fields preserved; capabilities replaced whole (explicit [] revokes all; effective on the next capability call, no restart); metadata key-merged (null deletes a key); optional expectedVersion → 409 version_conflict on mismatch.

Path parameters

idstringrequired

The agent id (agent_…)

Body · application/json

displayNamestring

max length 60

capabilitiesenum<string>[]

"exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

metadataobject
harnessVersionstring
reasoningEffortobject

Harness-native reasoning effort; null clears back to the harness default. Applies from the next provision/restart. Allowed values depend on agentType — hermes: none/minimal/low/medium/high/xhigh/max/ultra; claude_code: low/medium/high/xhigh/max; codex: none/minimal/low/medium/high/xhigh/max; openclaw: not supported; pi: off/minimal/low/medium/high/xhigh/max; dsh: not supported; kimi_code: not supported; opencode: none/minimal/low/medium/high/xhigh/max

▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
skillsobject[]

Replaces the whole skills array; omitted preserves. Applies from the next provision.

▸ Show child attributes
type: "skill"object
▸ Show child attributes
type"skill"required
skillIdstringrequired
versionstring

default: "latest"

type: "github"object
▸ Show child attributes
type"github"required
urlstringrequired
refstring

Branch or commit SHA; default branch when omitted.

tokenSecretRefstring

Agent secret key holding a clone token for private repos.

mcpServersobject[]

Replaces the whole MCP server list; omitted preserves. Applies from the next provision.

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

expectedVersioninteger

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

The built-in capabilities this agent is granted — the exact set its sessions may execute (enforced; empty = none). Ids are listed at /docs/capabilities. — "exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

mcpServersobject[]

Declared remote MCP server references, including tool filters; runtime authentication fields are never returned

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"displayName":"Research Agent","expectedVersion":1}'
DELETE/agents/{id}admin

Delete the agent — only with zero sessions (409 agent_has_sessions)

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

oktruerequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
  -H "Authorization: Bearer ast_..."

Archive the agent — read-only, sessions keep running, new sessions rejected

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

The built-in capabilities this agent is granted — the exact set its sessions may execute (enforced; empty = none). Ids are listed at /docs/capabilities. — "exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"

mcpServersobject[]

Declared remote MCP server references, including tool filters; runtime authentication fields are never returned

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/archive \
  -H "Authorization: Bearer ast_..."

Save the user prompt layer; applies to sessions started after the save

Path parameters

idstringrequired

The agent id (agent_…)

Body · application/json

promptstringrequired

max length 100000

Response · 200

versioninteger
unchangedboolean

Content identical to the active version

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PUT https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/prompt \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"prompt":"You are a meticulous research agent…"}'

Prompt version history

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

versionsobject[]required
▸ Show child attributes
versioninteger
notestring | null
createdAtstring
activeboolean
contentstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/prompt/versions \
  -H "Authorization: Bearer ast_..."

Declared secret keys + set/unset — never values

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

secretsobject[]required
▸ Show child attributes
keystring
descriptionstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/secrets \
  -H "Authorization: Bearer ast_..."

Set a declared secret's value (write-only)

Path parameters

idstringrequired

The agent id (agent_…)

keystringrequired

Body · application/json

valuestringrequired

max length 10000

descriptionstring

max length 500

Response · 200

oktruerequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PUT https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/secrets/NOTION_TOKEN \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"value":"secret_…"}'

Unset a secret

Path parameters

idstringrequired

The agent id (agent_…)

keystringrequired

Response · 200

oktruerequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/secrets/NOTION_TOKEN \
  -H "Authorization: Bearer ast_..."

Skills

GET/skillsread

List skills in the resolved universe

Query parameters

cursorstring
limitinteger

Response · 200

skillsobject[]required
▸ Show child attributes
idstringrequired
displayNamestringrequired
latestRevisionIdstring | nullrequired

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired
nextCursorstring | null

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/skills?cursor=&limit= \
  -H "Authorization: Bearer ast_..."
POST/skillswrite

Create a skill (uploads revision 1)

A skill is a universe-scoped, immutably-revisioned file bundle agents load on demand (RFC-0073). Attach it to agents via the `skills` array on create/patch.

Response · 201

skillobjectrequired
▸ Show child attributes
idstringrequired
displayNamestringrequired
latestRevisionIdstring | nullrequired

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired
revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

descriptionstringrequired
filesobject[]required
▸ Show child attributes
pathstringrequired
sizeintegerrequired
sha256stringrequired
executablebooleanrequired
createdAtstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/skills \
  -H "Authorization: Bearer ast_..."

Skill detail

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

skillobjectrequired
▸ Show child attributes
idstringrequired
displayNamestringrequired
latestRevisionIdstring | nullrequired

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/skills/skillId \
  -H "Authorization: Bearer ast_..."

Delete a skill and all its revisions

409 skill_in_use while any agent references the skill.

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/skills/skillId \
  -H "Authorization: Bearer ast_..."

List a skill's revisions, newest first

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

revisionsobject[]required
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

descriptionstringrequired
filesobject[]required
▸ Show child attributes
pathstringrequired
sizeintegerrequired
sha256stringrequired
executablebooleanrequired
createdAtstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/skills/skillId/revisions \
  -H "Authorization: Bearer ast_..."

Create a revision — a complete snapshot

Omitted files are not carried over. The new SKILL.md name must match the skill's name (400 name_mismatch).

Response · 201

revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

descriptionstringrequired
filesobject[]required
▸ Show child attributes
pathstringrequired
sizeintegerrequired
sha256stringrequired
executablebooleanrequired
createdAtstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/skills/skillId/revisions \
  -H "Authorization: Bearer ast_..."

Skill revision detail (metadata + file manifest)

Path parameters

skillIdstringrequired

The skill id (skill_…)

revisionIdstringrequired

The skill revision id (skr_…)

Response · 200

revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

descriptionstringrequired
filesobject[]required
▸ Show child attributes
pathstringrequired
sizeintegerrequired
sha256stringrequired
executablebooleanrequired
createdAtstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/skills/skillId/revisions/revisionId \
  -H "Authorization: Bearer ast_..."

Delete one revision

400 last_revision for a skill's only revision; 409 revision_in_use while pinned by an agent; deleting the latest repoints latestRevisionId.

Path parameters

skillIdstringrequired

The skill id (skill_…)

revisionIdstringrequired

The skill revision id (skr_…)

Response · 200

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/skills/skillId/revisions/revisionId \
  -H "Authorization: Bearer ast_..."

Files

POST/fileswrite

Upload a file — universe-scoped, write-once

multipart/form-data with a `file` part and an optional `expires_in_seconds` (3600–7776000). 32 MiB per file (413 file_too_large). Reference the returned id from a message as `{"type":"image","source":{"type":"file","file_id":"file_…"}}` or a `document` block.

Response · 200

typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

false for uploads (write-once); true for the per-session copies minted when a file rides a message

expires_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/files \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "type": "file",
  "id": "file_cmtb9x4p",
  "created_at": "2026-09-10T18:00:00.000Z",
  "filename": "design.pdf",
  "mime_type": "application/pdf",
  "size_bytes": 102400,
  "downloadable": false,
  "expires_at": null
}
GET/filesread

List files — your universe's uploads, or one session's files

Without `scope_id`, the universe's uploads. `scope_id=sess_…` lists that session's files: the copies minted from message content, channel attachments, and agent-stored files. `ids[]` (≤100) returns exactly those files in one page and cannot be combined with page/limit.

Query parameters

limitinteger
pagestring

A next_page cursor

ids[]array
scope_idstring

sess_…

Response · 200

dataobject[]required

Newest first

▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

false for uploads (write-once); true for the per-session copies minted when a file rides a message

expires_atstring | nullrequired
next_pagestring | nullrequired

Pass back as ?page= for the next page

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/files?limit=&page=&ids[]=&scope_id= \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "data": [
    {
      "type": "file",
      "id": "file_cmtb9x4p",
      "created_at": "2026-09-10T18:00:00.000Z",
      "filename": "design.pdf",
      "mime_type": "application/pdf",
      "size_bytes": 102400,
      "downloadable": false,
      "expires_at": null
    }
  ],
  "next_page": null
}

File metadata

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

false for uploads (write-once); true for the per-session copies minted when a file rides a message

expires_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/files/file_cmtb9x4p \
  -H "Authorization: Bearer ast_..."
DELETE/files/{file_id}write

Delete a file

Soft delete: the file stops resolving everywhere; sessions that already received a copy keep it.

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

typeenum<string>required

"file_deleted"

idstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/files/file_cmtb9x4p \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "type": "file_deleted",
  "id": "file_cmtb9x4p"
}

Download a file's bytes

Only `downloadable` files (every session-scoped file: message copies, channel attachments, agent outputs); an upload answers 400 not_downloadable. 404 once the file has expired.

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

The bytes, with content-type and content-disposition

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/files/file_cmtb9x4p/content \
  -H "Authorization: Bearer ast_..."

Sessions

GET/sessionsread

List sessions; ?agent= filters to one spec

Query parameters

agentstring

The agent id (agent_…)

Response · 200

sessionsobject[]required
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

provisioning = the sandbox is booting or installing the environment's packages (a turn sent meanwhile waits for it); running = a turn is in flight; terminated = archived — "provisioning" · "idle" · "running" · "terminated"

agentTypestring
llmstring

The model this session runs on (PATCH to change; the agent's model is unchanged)

reasoningEffortstring | null

The effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)

modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

Hard spend cap, or null when the session has none. A reached budget pauses the session (402 budget_reached on new work) until the cap is raised above consumed_cost or removed — removal is one-way.

resourcesobject[]

The files and GitHub repositories mounted into the working directory, oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions?agent= \
  -H "Authorization: Bearer ast_..."
POST/sessionswrite

Create a session — provisions the pod up front so the first turn isn't a cold boot

Optional llm and reasoningEffort override the agent's defaults for this session before billing selection or provisioning. A model must be current for the agent's harness; omitted or null reasoningEffort inherits the agent's setting. A non-empty initial_events list (user.message only, all-or-nothing) starts the first turn in the same call. Machine shape (vcpus/memoryMb) is per-session.

Body · application/json

agentstringrequired
llmstring

Model for this session (a current model for the agent's harness). Omitted = the agent's model

reasoningEffortobject

Reasoning effort for this session; omitted or null inherits the agent's setting. Allowed values depend on agentType - hermes: none/minimal/low/medium/high/xhigh/max/ultra; claude_code: low/medium/high/xhigh/max; codex: none/minimal/low/medium/high/xhigh/max; openclaw: not supported; pi: off/minimal/low/medium/high/xhigh/max; dsh: not supported; kimi_code: not supported; opencode: none/minimal/low/medium/high/xhigh/max

▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
titlestring

max length 120

metadataobject
instructionsobject[]
▸ Show child attributes
namestringrequired

pattern .*\.md$

contentstring

default: ""

initial_eventsobject[]
▸ Show child attributes
type"user.message"required
contentobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "image"object
▸ Show child attributes
type"image"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
type: "document"object
▸ Show child attributes
type"document"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "text"object
▸ Show child attributes
type"text"required
media_type"text/plain"

default: "text/plain"

datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
titlestring | null
contextstring | null
environment_idstring
vault_idsstring[]
vcpusinteger
memoryMbinteger
modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription. Omitted = auto-apply (a connected subscription with "use for new agents" powers eligible compositions) — "platform" · "account"

budgetobject

Hard spend cap for this session. Attachable only at create; changeable or removable later via PATCH (removal is one-way)

▸ Show child attributes
type"limit"required
max_list_costobjectrequired
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15

currency"USD"required
resourcesobject[]

Files and GitHub repositories mounted into the agent's working directory before its first turn (max 100). `{type:"file", file_id, mount_path?}` copies an upload read-only to `/workspace<mount_path>` (default `/workspace/<file_id>`); `{type:"github_repository", url, authorization_token?, checkout?: {type:"branch", name} | {type:"commit", sha}, mount_path?}` clones `https://github.com/{owner}/{repo}` to `/workspace<mount_path>` (default `/workspace/<repo>`); the token never enters the sandbox

▸ Show child attributes
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired

max length 128

mount_pathobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "github_repository"object
▸ Show child attributes
type"github_repository"required
urlstringrequired

max length 2048

authorization_tokenstring

max length 1024

checkoutobject
▸ Show child attributes
option 1object
▸ Show child attributes
type: "branch"object
▸ Show child attributes
type"branch"required
namestringrequired

max length 255

type: "commit"object
▸ Show child attributes
type"commit"required
shastringrequired

max length 64

option 2object
▸ Show child attributes
mount_pathobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes

Response · 201

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

provisioning = the sandbox is booting or installing the environment's packages (a turn sent meanwhile waits for it); running = a turn is in flight; terminated = archived — "provisioning" · "idle" · "running" · "terminated"

agentTypestring
llmstring

The model this session runs on (PATCH to change; the agent's model is unchanged)

reasoningEffortstring | null

The effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)

modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

Hard spend cap, or null when the session has none. A reached budget pauses the session (402 budget_reached on new work) until the cap is raised above consumed_cost or removed — removal is one-way.

resourcesobject[]

The files and GitHub repositories mounted into the working directory, oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"agent":"agent_cmtb2f0a8m9k7x51q4ez6r0d","llm":"deepseek-flash","reasoningEffort":"high","title":"Signups digest","resources":[{"type":"file","file_id":"file_cmtb9x4p","mount_path":"/data/signups.csv"},{"type":"github_repository","url":"https://github.com/acme/growth","checkout":{"type":"branch","name":"main"}}],"initial_events":[{"type":"user.message","content":[{"type":"text","text":"Summarize today's signups"}]}]}'
Response · 201 Created
{
  "session": {
    "id": "sess-8c41f0…",
    "agent": "research-agent",
    "status": "idle",
    "default": true
  }
}

Session detail — status is provisioning (sandbox booting or installing packages) | idle | running | terminated

Path parameters

idstringrequired

The session id

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

provisioning = the sandbox is booting or installing the environment's packages (a turn sent meanwhile waits for it); running = a turn is in flight; terminated = archived — "provisioning" · "idle" · "running" · "terminated"

agentTypestring
llmstring

The model this session runs on (PATCH to change; the agent's model is unchanged)

reasoningEffortstring | null

The effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)

modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

Hard spend cap, or null when the session has none. A reached budget pauses the session (402 budget_reached on new work) until the cap is raised above consumed_cost or removed — removal is one-way.

resourcesobject[]

The files and GitHub repositories mounted into the working directory, oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."
PATCH/sessions/{id}write

Update title / metadata / model / reasoning effort / billing / budget

llm and reasoningEffort are session settings: they change this session only, never the agent or its other sessions, and must fit the session's harness. An idle session restarts its engine in place; a running session finishes its turn and applies the change at the next turn (the response is 200 either way). A parked session applies it at its next wake.

Path parameters

idstringrequired

The session id

Body · application/json

titleobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
metadataobject
llmstring

Switch this session's model (a current model for its harness; the agent's model is unchanged). Applies from the next turn

reasoningEffortobject

Session-level reasoning effort; null clears back to the agent's setting. Applies from the next turn. Allowed values depend on agentType — hermes: none/minimal/low/medium/high/xhigh/max/ultra; claude_code: low/medium/high/xhigh/max; codex: none/minimal/low/medium/high/xhigh/max; openclaw: not supported; pi: off/minimal/low/medium/high/xhigh/max; dsh: not supported; kimi_code: not supported; opencode: none/minimal/low/medium/high/xhigh/max

▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
modelBillingenum<string>

Who pays for model calls; switching restarts the agent's engine in place — "platform" · "account"

budgetobject

Change the spend cap (must be strictly above consumed cost) or null to remove it — removal is one-way

▸ Show child attributes
type: "limit"object
▸ Show child attributes
type"limit"required
max_list_costobjectrequired
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15

currency"USD"required
option 2object
▸ Show child attributes

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

provisioning = the sandbox is booting or installing the environment's packages (a turn sent meanwhile waits for it); running = a turn is in flight; terminated = archived — "provisioning" · "idle" · "running" · "terminated"

agentTypestring
llmstring

The model this session runs on (PATCH to change; the agent's model is unchanged)

reasoningEffortstring | null

The effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)

modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

Hard spend cap, or null when the session has none. A reached budget pauses the session (402 budget_reached on new work) until the cap is raised above consumed_cost or removed — removal is one-way.

resourcesobject[]

The files and GitHub repositories mounted into the working directory, oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/sessions/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"title":"Signups digest","metadata":{"team":"growth"},"llm":"claude-sonnet-5","reasoningEffort":"high"}'
DELETE/sessions/{id}write

Permanently delete the session, its events, and its pod

Hard delete — the record, event history, pod, and stored context snapshots are permanently removed; GET answers 404 after. A running session is refused with 400 session_running: interrupt and wait for idle first. Works on idle and archived/terminated sessions.

Path parameters

idstringrequired

The session id

Response · 200

oktruerequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/sessions/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Archive the session — irreversible; blocks new events, history stays readable

Sets status to terminated, tears down the pod and stored context, and refuses further messages (400 session_archived); the record and its events remain readable. A running session is refused with 400 session_running: interrupt and wait for idle first. Idempotent.

Path parameters

idstringrequired

The session id

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

provisioning = the sandbox is booting or installing the environment's packages (a turn sent meanwhile waits for it); running = a turn is in flight; terminated = archived — "provisioning" · "idle" · "running" · "terminated"

agentTypestring
llmstring

The model this session runs on (PATCH to change; the agent's model is unchanged)

reasoningEffortstring | null

The effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)

modelBillingenum<string>

Who pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

Hard spend cap, or null when the session has none. A reached budget pauses the session (402 budget_reached on new work) until the cap is raised above consumed_cost or removed — removal is one-way.

resourcesobject[]

The files and GitHub repositories mounted into the working directory, oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/archive \
  -H "Authorization: Bearer ast_..."

List the session's resources, oldest first

`limit` (1–1000) pages the list with an opaque `page` cursor; omitted lists every resource in one answer.

Path parameters

idstringrequired

The session id (sess_…)

Query parameters

limitinteger
pagestring

A next_page cursor

Response · 200

dataobject[]required

Oldest first

▸ Show child attributes
option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
next_pagestring | nullrequired

Pass back as ?page= for the next page; null when `limit` was omitted or the list ended

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions/sess_cmtb7q2j/resources?limit=&page= \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "data": [
    {
      "type": "file",
      "id": "sesrsc_cmtc1a2b",
      "file_id": "file_cmtc1a2c",
      "mount_path": "/workspace/data/signups.csv",
      "created_at": "2026-09-11T18:00:00.000Z",
      "updated_at": "2026-09-11T18:00:00.000Z"
    },
    {
      "type": "github_repository",
      "id": "sesrsc_cmtc1a2d",
      "url": "https://github.com/acme/growth",
      "mount_path": "/workspace/growth",
      "checkout": {
        "type": "branch",
        "name": "main"
      },
      "created_at": "2026-09-11T18:00:00.000Z",
      "updated_at": "2026-09-11T18:00:00.000Z"
    }
  ],
  "next_page": null
}

Add a file to a running session

Files only — a `github_repository` body answers 400 (repositories are attached at session create and stay for the session's lifetime). The file is copied read-only to `/workspace<mount_path>` before the session's next turn; `mount_path` follows the create rules (rooted under /workspace, no escape, no overlap with another resource). 400 too_many_resources past 500 per session; 400 session_archived on an archived session.

Path parameters

idstringrequired

The session id (sess_…)

Body · application/json

type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired

max length 128

mount_pathobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "github_repository"object
▸ Show child attributes
type"github_repository"required
urlstringrequired

max length 2048

authorization_tokenstring

max length 1024

checkoutobject
▸ Show child attributes
option 1object
▸ Show child attributes
type: "branch"object
▸ Show child attributes
type"branch"required
namestringrequired

max length 255

type: "commit"object
▸ Show child attributes
type"commit"required
shastringrequired

max length 64

option 2object
▸ Show child attributes
mount_pathobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes

Response · 200

option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/resources \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"type":"file","file_id":"file_cmtb9x4p","mount_path":"/data/signups.csv"}'
Response · 200 OK
{
  "type": "file",
  "id": "sesrsc_cmtc1a2b",
  "file_id": "file_cmtc1a2c",
  "mount_path": "/workspace/data/signups.csv",
  "created_at": "2026-09-11T18:00:00.000Z",
  "updated_at": "2026-09-11T18:00:00.000Z"
}

One resource

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Response · 200

option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions/sess_cmtb7q2j/resources/sesrsc_cmtc1a2d \
  -H "Authorization: Bearer ast_..."

Rotate a repository's token

Only `github_repository` resources accept an update, and the token is the only field: it is re-encrypted and the session's egress policy is recompiled and pushed to its live pod — nothing changes inside the sandbox. A file answers 400. A token that conflicts with another secret's Authorization header on github.com answers 400 egress_header_conflict.

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Body · application/json

authorization_tokenstringrequired

max length 1024

Response · 200

option 1object
▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

sesrsc_…

file_idstringrequired

The per-session copy (file_…), read-only at mount_path

mount_pathstringrequired

Absolute, under /workspace

created_atstringrequired
updated_atstringrequired
option 2object
▸ Show child attributes
typeenum<string>required

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

https://github.com/{owner}/{repo}

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

{type:"branch", name} or {type:"commit", sha}; absent = the default branch

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/resources/sesrsc_cmtc1a2d \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"authorization_token":"github_pat_…"}'

Remove a file from the session

Files only — the resource and its per-session copy are deleted and the pod unlinks the file before the session's next turn. A `github_repository` answers 400: repositories cannot be removed mid-session.

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Response · 200

typeenum<string>required

"session_resource_deleted"

idstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/sessions/sess_cmtb7q2j/resources/sesrsc_cmtc1a2d \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "type": "session_resource_deleted",
  "id": "sesrsc_cmtc1a2b"
}

Conversation

Deprecated — use POST /sessions/{id}/events

The legacy input shape ({parts}); accepted for one release and translated to a single user.message, then 410. Optional Idempotency-Key header dedupes retries.

Path parameters

idstringrequired

The session id

Body · application/json

partsobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
indexintegerrequired
type"text"required
textstring

default: ""

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "reasoning"object
▸ Show child attributes
indexintegerrequired
type"reasoning"required
textstring

default: ""

redactedboolean

default: false

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "tool_call"object
▸ Show child attributes
indexintegerrequired
type"tool_call"required
call_idstringrequired
tool_namestringrequired
argsobject

default: {}

args_partialstring | null
type: "tool_result"object
▸ Show child attributes
indexintegerrequired
type"tool_result"required
call_idstringrequired
tool_namestringrequired
statusenum<string>

"ok" · "error" — default: "ok"

resultobject

default: {}

type: "file"object
▸ Show child attributes
indexintegerrequired
type"file"required
namestringrequired
media_typestringrequired
uristring | null
datastring | null
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "image"object
▸ Show child attributes
indexintegerrequired
type"image"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "video"object
▸ Show child attributes
indexintegerrequired
type"video"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
duration_msobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
thumbnail_uristring | null
type: "status"object
▸ Show child attributes
indexintegerrequired
type"status"required
levelenum<string>required

"thinking" · "working" · "waiting" · "idle" · "done"

textstring | null
type: "error"object
▸ Show child attributes
indexintegerrequired
type"error"required
codestringrequired
messagestringrequired
retryableboolean

default: false

Response · 202

Accepted — body is {}; output arrives on the stream

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/messages \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"parts":[{"type":"text","index":0,"text":"Summarize today's signups"}]}'
Response · 202 Accepted
{}

Send events — the one input: user.message, user.interrupt, system.message

The conversation plane (edge-routed to the chat-proxy). Body {events: [...]} (1–50), validated all-or-nothing. A user.message carries content blocks: text, image and document with base64 / url / file sources (inline base64 ≤ 20 MiB per request; larger content goes through POST /files). A system.message (text only) must be last and follow the user.message it accompanies: privileged context for that turn and, through the agent's transcript, later turns. user.interrupt stops the in-flight turn. Every event echoes back in the history shape with a stable id; sources are echoed as file sources naming per-session copies (never base64). Optional Idempotency-Key header: a replay returns the original echo. 402 insufficient_credits / budget_reached, 503 egress_policy_failed, 400 session_archived refuse the whole request before any row is written.

Path parameters

idstringrequired

The session id

Body · application/json

eventsobject[]required
▸ Show child attributes
type: "user.message"object
▸ Show child attributes
type"user.message"required
contentobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "image"object
▸ Show child attributes
type"image"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
type: "document"object
▸ Show child attributes
type"document"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "text"object
▸ Show child attributes
type"text"required
media_type"text/plain"

default: "text/plain"

datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
titlestring | null
contextstring | null
type: "system.message"object
▸ Show child attributes
type"system.message"required
contentobject[]required
▸ Show child attributes
type"text"required
textstringrequired
type: "user.interrupt"object
▸ Show child attributes
type"user.interrupt"required

Response · 200

OK — one echo per event, in order

dataobject[]required

One echo per event, in order, in the events-history shape

▸ Show child attributes
idstringrequired

Stable event id — the dedupe key across stream ∪ events

typestringrequired

user.message · system.message (both history only — never on the live stream; they carry `content`) · agent.message · agent.reasoning · agent.tool_use · agent.tool_result · agent.status · user.interrupt · session.status_running · session.status_idle · session.error · session.status_terminated · session.deleted

sessionIdstringrequired
agentIdstring | null

The agent id (agent_…)

atstring

ISO 8601

messageIdstring

agent.message

partsobject[]

agent.message

▸ Show child attributes
type: "text"object
▸ Show child attributes
indexintegerrequired
type"text"required
textstring

default: ""

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "reasoning"object
▸ Show child attributes
indexintegerrequired
type"reasoning"required
textstring

default: ""

redactedboolean

default: false

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "tool_call"object
▸ Show child attributes
indexintegerrequired
type"tool_call"required
call_idstringrequired
tool_namestringrequired
argsobject

default: {}

args_partialstring | null
type: "tool_result"object
▸ Show child attributes
indexintegerrequired
type"tool_result"required
call_idstringrequired
tool_namestringrequired
statusenum<string>

"ok" · "error" — default: "ok"

resultobject

default: {}

type: "file"object
▸ Show child attributes
indexintegerrequired
type"file"required
namestringrequired
media_typestringrequired
uristring | null
datastring | null
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "image"object
▸ Show child attributes
indexintegerrequired
type"image"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "video"object
▸ Show child attributes
indexintegerrequired
type"video"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
duration_msobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
thumbnail_uristring | null
type: "status"object
▸ Show child attributes
indexintegerrequired
type"status"required
levelenum<string>required

"thinking" · "working" · "waiting" · "idle" · "done"

textstring | null
type: "error"object
▸ Show child attributes
indexintegerrequired
type"error"required
codestringrequired
messagestringrequired
retryableboolean

default: false

textstring

agent.message — parts flattened to plain text

contentobject[]

user.message / system.message — the CMA content blocks as sent (text · image · document); every image/document source is a `file` source naming a per-session copy readable through GET /files/{file_id}/content

partobject

reasoning / tool_use / tool_result / status events

▸ Show child attributes
type: "text"object
▸ Show child attributes
indexintegerrequired
type"text"required
textstring

default: ""

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "reasoning"object
▸ Show child attributes
indexintegerrequired
type"reasoning"required
textstring

default: ""

redactedboolean

default: false

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "tool_call"object
▸ Show child attributes
indexintegerrequired
type"tool_call"required
call_idstringrequired
tool_namestringrequired
argsobject

default: {}

args_partialstring | null
type: "tool_result"object
▸ Show child attributes
indexintegerrequired
type"tool_result"required
call_idstringrequired
tool_namestringrequired
statusenum<string>

"ok" · "error" — default: "ok"

resultobject

default: {}

type: "file"object
▸ Show child attributes
indexintegerrequired
type"file"required
namestringrequired
media_typestringrequired
uristring | null
datastring | null
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "image"object
▸ Show child attributes
indexintegerrequired
type"image"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "video"object
▸ Show child attributes
indexintegerrequired
type"video"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
duration_msobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
thumbnail_uristring | null
type: "status"object
▸ Show child attributes
indexintegerrequired
type"status"required
levelenum<string>required

"thinking" · "working" · "waiting" · "idle" · "done"

textstring | null
type: "error"object
▸ Show child attributes
indexintegerrequired
type"error"required
codestringrequired
messagestringrequired
retryableboolean

default: false

stop_reasonobject

session.status_idle — discriminate on type; never break on bare idle

▸ Show child attributes
typestring

"end_turn" (also after an interrupt) | "retries_exhausted" (preceded by an exhausted session.error) | "budget_reached"; more reserved

errorobject

session.error — the stream stays open; a session.status_idle follows once the turn is over

▸ Show child attributes
typestring

e.g. "pod_unavailable"

messagestring
retry_statusstring

"retrying" (the turn continues) | "exhausted" (the turn is over)

bystring

user.interrupt — who requested the interrupt

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/events \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"events":[{"type":"user.message","content":[{"type":"text","text":"What is in this screenshot?"},{"type":"image","source":{"type":"file","file_id":"file_cmtb9x4p"}}]},{"type":"system.message","content":[{"type":"text","text":"Answer in one paragraph."}]}]}'
Response · 200 OK
{
  "data": [
    {
      "id": "api-user-3f2c…",
      "type": "user.message",
      "sessionId": "sess_cmtb7q2j",
      "agentId": "agent_cmtb2f0a8m9k7x51q4ez6r0d",
      "at": "2026-09-10T18:00:00.000Z",
      "content": [
        {
          "type": "text",
          "text": "What is in this screenshot?"
        },
        {
          "type": "image",
          "source": {
            "type": "file",
            "file_id": "file_cmtb9y1q"
          }
        }
      ]
    },
    {
      "id": "api-user-3f2c…#system",
      "type": "system.message",
      "sessionId": "sess_cmtb7q2j",
      "agentId": "agent_cmtb2f0a8m9k7x51q4ez6r0d",
      "at": "2026-09-10T18:00:00.000Z",
      "content": [
        {
          "type": "text",
          "text": "Answer in one paragraph."
        }
      ]
    }
  ]
}

The event history — the same event objects the stream delivers

The session's history, one event per message: user.message and system.message (with content), agent.message (with parts), user.interrupt, and the turn marks session.status_running, session.status_idle (stop_reason.type is end_turn, retries_exhausted or budget_reached) and session.error. agent.reasoning, agent.tool_use, agent.tool_result and agent.status appear on the live stream only, not in history. Oldest-first with an opaque numeric cursor. Reconnect = open the stream, list events, dedupe by event id. types[] filters (e.g. types[]=user.message&types[]=agent.message is the transcript view).

Path parameters

idstringrequired

The session id

Query parameters

cursorstring
limitinteger
types[]array

Response · 200

eventsobject[]required

Oldest-first

▸ Show child attributes
idstringrequired

Stable event id — the dedupe key across stream ∪ events

typestringrequired

user.message · system.message (both history only — never on the live stream; they carry `content`) · agent.message · agent.reasoning · agent.tool_use · agent.tool_result · agent.status · user.interrupt · session.status_running · session.status_idle · session.error · session.status_terminated · session.deleted

sessionIdstringrequired
agentIdstring | null

The agent id (agent_…)

atstring

ISO 8601

messageIdstring

agent.message

partsobject[]

agent.message

▸ Show child attributes
type: "text"object
▸ Show child attributes
indexintegerrequired
type"text"required
textstring

default: ""

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "reasoning"object
▸ Show child attributes
indexintegerrequired
type"reasoning"required
textstring

default: ""

redactedboolean

default: false

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "tool_call"object
▸ Show child attributes
indexintegerrequired
type"tool_call"required
call_idstringrequired
tool_namestringrequired
argsobject

default: {}

args_partialstring | null
type: "tool_result"object
▸ Show child attributes
indexintegerrequired
type"tool_result"required
call_idstringrequired
tool_namestringrequired
statusenum<string>

"ok" · "error" — default: "ok"

resultobject

default: {}

type: "file"object
▸ Show child attributes
indexintegerrequired
type"file"required
namestringrequired
media_typestringrequired
uristring | null
datastring | null
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "image"object
▸ Show child attributes
indexintegerrequired
type"image"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "video"object
▸ Show child attributes
indexintegerrequired
type"video"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
duration_msobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
thumbnail_uristring | null
type: "status"object
▸ Show child attributes
indexintegerrequired
type"status"required
levelenum<string>required

"thinking" · "working" · "waiting" · "idle" · "done"

textstring | null
type: "error"object
▸ Show child attributes
indexintegerrequired
type"error"required
codestringrequired
messagestringrequired
retryableboolean

default: false

textstring

agent.message — parts flattened to plain text

contentobject[]

user.message / system.message — the CMA content blocks as sent (text · image · document); every image/document source is a `file` source naming a per-session copy readable through GET /files/{file_id}/content

partobject

reasoning / tool_use / tool_result / status events

▸ Show child attributes
type: "text"object
▸ Show child attributes
indexintegerrequired
type"text"required
textstring

default: ""

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "reasoning"object
▸ Show child attributes
indexintegerrequired
type"reasoning"required
textstring

default: ""

redactedboolean

default: false

stream_idobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
stream_indexobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "tool_call"object
▸ Show child attributes
indexintegerrequired
type"tool_call"required
call_idstringrequired
tool_namestringrequired
argsobject

default: {}

args_partialstring | null
type: "tool_result"object
▸ Show child attributes
indexintegerrequired
type"tool_result"required
call_idstringrequired
tool_namestringrequired
statusenum<string>

"ok" · "error" — default: "ok"

resultobject

default: {}

type: "file"object
▸ Show child attributes
indexintegerrequired
type"file"required
namestringrequired
media_typestringrequired
uristring | null
datastring | null
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "image"object
▸ Show child attributes
indexintegerrequired
type"image"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
type: "video"object
▸ Show child attributes
indexintegerrequired
type"video"required
media_typestringrequired
uristring | null
datastring | null
altstring | null
widthobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
heightobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
duration_msobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
size_bytesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
thumbnail_uristring | null
type: "status"object
▸ Show child attributes
indexintegerrequired
type"status"required
levelenum<string>required

"thinking" · "working" · "waiting" · "idle" · "done"

textstring | null
type: "error"object
▸ Show child attributes
indexintegerrequired
type"error"required
codestringrequired
messagestringrequired
retryableboolean

default: false

stop_reasonobject

session.status_idle — discriminate on type; never break on bare idle

▸ Show child attributes
typestring

"end_turn" (also after an interrupt) | "retries_exhausted" (preceded by an exhausted session.error) | "budget_reached"; more reserved

errorobject

session.error — the stream stays open; a session.status_idle follows once the turn is over

▸ Show child attributes
typestring

e.g. "pod_unavailable"

messagestring
retry_statusstring

"retrying" (the turn continues) | "exhausted" (the turn is over)

bystring

user.interrupt — who requested the interrupt

cursorstring | nullrequired

Pass back as ?cursor= for the next page; null when the session has no events

hasMorebooleanrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions/sess_cmtb7q2j/events?cursor=&limit=&types[]= \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "events": [
    {
      "id": "turn_8c41f0…#idle",
      "type": "session.status_idle",
      "sessionId": "sess-8c41f0…",
      "agent": "agent_cmtb2f0a8m9k7x51q4ez6r0d",
      "stop_reason": {
        "type": "end_turn"
      }
    }
  ],
  "cursor": "42",
  "hasMore": false
}

The standing event stream (SSE)

text/event-stream, live-only, stays open across turns. Events: agent.message, agent.reasoning, agent.tool_use, agent.tool_result, agent.status, session.status_running, session.status_idle (carries stop_reason — never break on bare idle), session.error (the stream stays open; an idle follows), user.interrupt, session.status_terminated (terminal), session.deleted (terminal). User messages are not sent on the live stream — they appear in the event history only. Reconnect = reopen + list events + dedupe by event id.

Path parameters

idstringrequired

The session id

Response · 200

SSE stream

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -N https://agentsky.dev/sessions/sess_cmtb7q2j/stream \
  -H "Authorization: Bearer ast_..."

Abort the in-flight turn

Path parameters

idstringrequired

The session id

Response · 200

statusenum<string>required

no_turn = nothing in flight; otherwise user.interrupt echoes on the stream and the pod's session.status_idle follows — "interrupting" · "no_turn"

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/interrupt \
  -H "Authorization: Bearer ast_..."
Response · 200 OK
{
  "status": "interrupting"
}

Post into a thread — markdown renders natively per platform

Path parameters

idstringrequired

The thread id (from message.received or channel events)

Body · application/json

partsobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "markdown"object
▸ Show child attributes
type"markdown"required
textstringrequired
type: "raw"object
▸ Show child attributes
type"raw"required
platformstringrequired
payloadstringrequired

Platform-native payload, JSON-encoded

display_namestring

max length 80

doneboolean

Clears the working marker (✅) for the replied-to message

Response · 201

message_idstring
thread_idstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages \
  -H "Authorization: Bearer ast_..."

SSE mirror of your webhook events — for local development

Response · 200

SSE stream

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -N https://agentsky.dev/channels/events/stream \
  -H "Authorization: Bearer ast_..."

Goals

The session's standing goal, or null

A goal is an objective the session works toward on its own: after each turn settles, the platform grades the work against the goal's criteria and either takes another turn or stops. At most one goal per session.

Path parameters

idstringrequired

The session id

Response · 200

goalobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired
option 2object
▸ Show child attributes

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/sessions/sess_cmtb7q2j/goal \
  -H "Authorization: Bearer ast_..."

Set the session's goal, replacing any existing one

Work starts immediately — no separate message is needed, and sending one is not how a goal begins. Criteria are optional: omitted, they are derived from the objective so completion is always judged against an explicit list, which the response returns and PATCH can correct. A person's message always outranks the loop: while a turn is running the goal waits, and takes the turn after it.

Path parameters

idstringrequired

The session id

Body · application/json

objectivestringrequired

What the agent should work toward, in the user's words — max length 4000

criteriastring[]

Independently checkable requirements; omitted = derived from the objective — max length 500

max_iterationsinteger

Self-started turns this goal may take before it stops. Default 20

max_spendobject

Spend ceiling for this goal; null = none

▸ Show child attributes
option 1object
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "500" for $5.00 — max length 15

currency"USD"required
option 2object
▸ Show child attributes
max_duration_minutesobject

Wall-clock ceiling from the goal's start, extended by any time it spends paused

▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes

Response · 201

goalobjectrequired
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
resultenum<string>required

"satisfied" · "needs_revision" · "failed"

explanationstringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired
metbooleanrequired
reasonstringrequired
iterationintegerrequired
atstringrequired
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/goal \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"objective":"Get the failing integration tests in packages/api passing without weakening them.","criteria":["npm test in packages/api exits zero","No test assertion was deleted, skipped, or loosened","The fix is in source, not in the tests"],"max_iterations":15,"max_spend":{"amount":"500","currency":"USD"}}'

Edit the goal in place

A course correction, not a restart: the iteration count and the spend already consumed carry over. Editing criteria marks them as the caller's.

Path parameters

idstringrequired

The session id

Body · application/json

objectivestring

max length 4000

criteriastring[]

max length 500

max_iterationsinteger
max_spendobject
▸ Show child attributes
option 1object
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "500" for $5.00 — max length 15

currency"USD"required
option 2object
▸ Show child attributes
max_duration_minutesobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes

Response · 200

goalobjectrequired
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
resultenum<string>required

"satisfied" · "needs_revision" · "failed"

explanationstringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired
metbooleanrequired
reasonstringrequired
iterationintegerrequired
atstringrequired
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/sessions/sess_cmtb7q2j/goal \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"criteria":["npm test in packages/api exits zero","No test assertion was deleted, skipped, or loosened"]}'

Clear the goal

Stops the loop for good with stop_reason "cleared". The record stays readable so the session can still report what it was working on; setting a new goal replaces it.

Path parameters

idstringrequired

The session id

Response · 200

goalobjectrequired
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
resultenum<string>required

"satisfied" · "needs_revision" · "failed"

explanationstringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired
metbooleanrequired
reasonstringrequired
iterationintegerrequired
atstringrequired
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/sessions/sess_cmtb7q2j/goal \
  -H "Authorization: Bearer ast_..."

Stop driving the goal

The turn already in flight finishes — the loop only ever takes the next turn. To stop the current one, use POST /sessions/{id}/interrupt. Refused with 409 invalid_state unless the goal is active.

Path parameters

idstringrequired

The session id

Response · 200

goalobjectrequired
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
resultenum<string>required

"satisfied" · "needs_revision" · "failed"

explanationstringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired
metbooleanrequired
reasonstringrequired
iterationintegerrequired
atstringrequired
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/goal/pause \
  -H "Authorization: Bearer ast_..."

Drive the goal again

Any wall-clock deadline moves out by the time the pause consumed. Refused with 409 invalid_state unless the goal is paused.

Path parameters

idstringrequired

The session id

Response · 200

goalobjectrequired
▸ Show child attributes
idstringrequired

goal_…

sessionstringrequired

sess_…

objectivestringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired

Stable within the goal, e.g. c1

textstringrequired
criteria_sourceenum<string>required

Whether the caller supplied the criteria or the platform derived them from the objective — "user" · "derived"

statusenum<string>required

"active" · "paused" · "completed" · "stopped"

stop_reasonstring | nullrequired

Why a stopped goal stopped; null in every other status — "failed" · "max_iterations" · "spend_budget" · "time_budget" · "no_progress" · "cleared" · "session_ended" · null

iterationintegerrequired

Self-started turns taken so far

max_iterationsintegerrequired
max_spendobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
amountstring
currencyenum<string>

"USD"

option 2object
▸ Show child attributes
consumed_spendobjectrequired

What this session has spent since the goal started

▸ Show child attributes
amountstring
currencyenum<string>

"USD"

deadline_atstring | nullrequired
last_evaluationobjectrequired
▸ Show child attributes
option 1object
▸ Show child attributes
resultenum<string>required

"satisfied" · "needs_revision" · "failed"

explanationstringrequired
criteriaobject[]required
▸ Show child attributes
idstringrequired
metbooleanrequired
reasonstringrequired
iterationintegerrequired
atstringrequired
option 2object
▸ Show child attributes
created_atstringrequired
updated_atstringrequired
completed_atstring | nullrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/goal/resume \
  -H "Authorization: Bearer ast_..."

Routines

GET/routinesread

List routines

Query parameters

cursorstring
limitinteger

1–500, default 50

Response · 200

itemsobject[]required
▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring
cursorstring | null
hasMoreboolean

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/routines?cursor=&limit= \
  -H "Authorization: Bearer ast_..."
POST/routineswrite

Create a routine — scheduled agent execution

initial_events (1–50 user.message events) are delivered on every fire. target picks the mode: new_session creates a fresh session per run; session sends the turn into an existing session (busy target → failed run session_busy_error). schedule is a 5-field POSIX cron with an IANA timezone; omit it for a manual-run-only routine. budget bounds each run separately.

Body · application/json

namestringrequired

max length 256

descriptionstring

max length 2048

metadataobject
targetobjectrequired
▸ Show child attributes
type: "new_session"object
▸ Show child attributes
type"new_session"required
agentstringrequired
environment_idstring
vault_idsstring[]
type: "session"object
▸ Show child attributes
type"session"required
session_idstringrequired
initial_eventsobject[]required
▸ Show child attributes
type"user.message"required
contentobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "image"object
▸ Show child attributes
type"image"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
type: "document"object
▸ Show child attributes
type"document"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "text"object
▸ Show child attributes
type"text"required
media_type"text/plain"

default: "text/plain"

datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
titlestring | null
contextstring | null
scheduleobject
▸ Show child attributes
type: "cron"object
▸ Show child attributes
type"cron"required
expressionstringrequired

max length 256

timezonestringrequired
option 2object
▸ Show child attributes
budgetobject
▸ Show child attributes
type: "limit"object
▸ Show child attributes
type"limit"required
max_list_costobjectrequired
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15

currency"USD"required
option 2object
▸ Show child attributes

Response · 201

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/routines \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"Weekly compliance scan","target":{"type":"new_session","agent":"agent_cmtb2f0a8m9k7x51q4ez6r0d"},"initial_events":[{"type":"user.message","content":[{"type":"text","text":"Run the weekly compliance scan."}]}],"schedule":{"type":"cron","expression":"0 20 * * 5","timezone":"America/New_York"}}'

Routine detail

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/routines/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."
PATCH/routines/{id}write

Update a routine — omit preserves; null clears schedule/budget

initial_events is a full replacement; metadata is key-patched (null deletes a key); name and target cannot be cleared. Archived routines are immutable (409).

Path parameters

idstringrequired

The routine id (rtn_…)

Body · application/json

namestring

max length 256

descriptionobject
▸ Show child attributes
option 1object
▸ Show child attributes
option 2object
▸ Show child attributes
metadataobject
targetobject
▸ Show child attributes
type: "new_session"object
▸ Show child attributes
type"new_session"required
agentstringrequired
environment_idstring
vault_idsstring[]
type: "session"object
▸ Show child attributes
type"session"required
session_idstringrequired
initial_eventsobject[]
▸ Show child attributes
type"user.message"required
contentobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "image"object
▸ Show child attributes
type"image"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
type: "document"object
▸ Show child attributes
type"document"required
sourceobjectrequired
▸ Show child attributes
type: "base64"object
▸ Show child attributes
type"base64"required
media_typestringrequired
datastringrequired
type: "text"object
▸ Show child attributes
type"text"required
media_type"text/plain"

default: "text/plain"

datastringrequired
type: "url"object
▸ Show child attributes
type"url"required
urlstringrequired
type: "file"object
▸ Show child attributes
type"file"required
file_idstringrequired
titlestring | null
contextstring | null
scheduleobject
▸ Show child attributes
type: "cron"object
▸ Show child attributes
type"cron"required
expressionstringrequired

max length 256

timezonestringrequired
option 2object
▸ Show child attributes
budgetobject
▸ Show child attributes
type: "limit"object
▸ Show child attributes
type"limit"required
max_list_costobjectrequired
▸ Show child attributes
amountstringrequired

Whole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15

currency"USD"required
option 2object
▸ Show child attributes

Response · 200

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/routines/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"schedule":{"type":"cron","expression":"0 9 * * 1-5","timezone":"UTC"}}'

Pause — suppress scheduled fires; manual runs still work

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/pause \
  -H "Authorization: Bearer ast_..."

Unpause — resumes from the NEXT occurrence; missed fires are never backfilled

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/unpause \
  -H "Authorization: Bearer ast_..."

Archive — terminal; the schedule stops and the routine becomes immutable

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

Scheduled agent execution: initial_events + a target (new_session per fire, or an existing session) bound to a cron schedule. Fires record routine runs.

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

{type:"new_session", agent, environment_id?, vault_ids?} — a fresh session per fire (CMA parity) · {type:"session", session_id} — a turn into the existing session every fire (busy target skips with session_busy_error)

initial_eventsobject[]
scheduleobject | null

5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only

budgetobject | null

Per-run cap (RFC-0080 shape): copied onto each new session (mode new_session) or granted as a per-fire delta allowance consumed+budget (mode session). Clearable.

statusenum<string>

"active" · "paused"

paused_reasonobject | null

{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/archive \
  -H "Authorization: Bearer ast_..."

Manual run — fire now, outside the schedule; works while paused

Records trigger_context {type:"manual"}; manual runs emit no routine_run webhooks.

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 201

runobjectrequired

One fire attempt. Exactly one of session_id / error is non-null.

▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

{type:"schedule", scheduled_at} | {type:"manual"}

session_idstring | null
errorobject | null

{type, message}. Types: agent_archived_error · agent_not_found_error · session_archived_error · session_not_found_error · session_busy_error · environment_archived_error · environment_not_found_error · vault_not_found_error · insufficient_credits_error · rate_limited_error · run_rejected_error · unknown_error. Unrecoverable types auto-pause the routine; transient ones (credits, rate limit, busy) leave it active for the next occurrence.

agentobject

Resolved agent reference at fire time

created_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/run \
  -H "Authorization: Bearer ast_..."

List routine runs — every fire attempt

Query parameters

routinestring

Filter to one routine (rtn_…)

has_errorboolean

true = failed runs, false = runs with a session

trigger_typestring
created_at[gte]string

Also gt / lt / lte

cursorstring
limitinteger

Response · 200

itemsobject[]required
▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

{type:"schedule", scheduled_at} | {type:"manual"}

session_idstring | null
errorobject | null

{type, message}. Types: agent_archived_error · agent_not_found_error · session_archived_error · session_not_found_error · session_busy_error · environment_archived_error · environment_not_found_error · vault_not_found_error · insufficient_credits_error · rate_limited_error · run_rejected_error · unknown_error. Unrecoverable types auto-pause the routine; transient ones (credits, rate limit, busy) leave it active for the next occurrence.

agentobject

Resolved agent reference at fire time

created_atstring
cursorstring | null
hasMoreboolean

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/routine-runs?routine=&has_error=&trigger_type=&created_at[gte]=&cursor=&limit= \
  -H "Authorization: Bearer ast_..."

Routine run detail

Path parameters

idstringrequired

The run id (rrun_…)

Response · 200

runobjectrequired

One fire attempt. Exactly one of session_id / error is non-null.

▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

{type:"schedule", scheduled_at} | {type:"manual"}

session_idstring | null
errorobject | null

{type, message}. Types: agent_archived_error · agent_not_found_error · session_archived_error · session_not_found_error · session_busy_error · environment_archived_error · environment_not_found_error · vault_not_found_error · insufficient_credits_error · rate_limited_error · run_rejected_error · unknown_error. Unrecoverable types auto-pause the routine; transient ones (credits, rate limit, busy) leave it active for the next occurrence.

agentobject

Resolved agent reference at fire time

created_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/routine-runs/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Webhooks

List connected model subscriptions — metadata only, never credentials

Response · 200

modelSubscriptionsobject[]required
▸ Show child attributes
providerenum<string>

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/model-subscriptions \
  -H "Authorization: Bearer ast_..."

Connect or replace a subscription credential (write-only)

anthropic: the sk-ant-oat… token from `claude setup-token`. openai: the contents of ~/.codex/auth.json from `codex login`. Eligible agents can then run at $0 model usage; with useForNewAgents (default on), new eligible agents use it automatically.

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Body · application/json

credentialstringrequired

max length 100000

labelstring

max length 60

Response · 200

modelSubscriptionobjectrequired

A connected consumer AI subscription (Claude Pro/Max or ChatGPT plan) powering eligible agents at $0 model usage. The credential itself is write-only.

▸ Show child attributes
providerenum<string>

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PUT https://agentsky.dev/model-subscriptions/provider \
  -H "Authorization: Bearer ast_..."

Update useForNewAgents / label

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Body · application/json

useForNewAgentsboolean
labelstring

max length 60

Response · 200

modelSubscriptionobjectrequired

A connected consumer AI subscription (Claude Pro/Max or ChatGPT plan) powering eligible agents at $0 model usage. The credential itself is write-only.

▸ Show child attributes
providerenum<string>

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/model-subscriptions/provider \
  -H "Authorization: Bearer ast_..."

Disconnect — affected agents keep their pointer and fail until reconnected or switched

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Response · 200

affectedAgentsobject[]
▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/model-subscriptions/provider \
  -H "Authorization: Bearer ast_..."

Turn sharing on and get the share link — idempotent; {"rotate": true} replaces it

The returned URL opens the session's guest page for anyone holding it, with no account; turns sent through it bill the session's owner. Rotating kills the old URL immediately.

Path parameters

idstringrequired

The session id

Body · application/json

rotateboolean

default: false

Response · 200

shareUrlstringrequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/share \
  -H "Authorization: Bearer ast_..."

Turn sharing off — the link stops working immediately

Path parameters

idstringrequired

The session id

Response · 200

oktruerequired

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/sessions/sess_cmtb7q2j/share \
  -H "Authorization: Bearer ast_..."
GET/webhooksread

List webhook endpoints

Response · 200

webhooksobject[]required
▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/webhooks \
  -H "Authorization: Bearer ast_..."
POST/webhookswrite

Register a webhook endpoint — the whsec_ secret appears only in this response

Body · application/json

urlstringrequired

max length 2048

eventsstring[]required

Response · 201

webhookobjectrequired

Outbound webhook endpoint. Deliveries carry x-asteroids-event/-delivery/-timestamp/-signature (v1=hmac-sha256(secret, "<ts>.<body>")), retry 3× (0s/5s/30s), and sustained failure disables (PATCH status:active re-enables). Payloads are thin {id, type, created_at, data:{type, id}} — fetch the resource, dedupe on the event id.

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/webhooks \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hooks/agentsky","events":["routine_run.failed","routine.paused"]}'

Webhook endpoint detail

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Response · 200

webhookobjectrequired

Outbound webhook endpoint. Deliveries carry x-asteroids-event/-delivery/-timestamp/-signature (v1=hmac-sha256(secret, "<ts>.<body>")), retry 3× (0s/5s/30s), and sustained failure disables (PATCH status:active re-enables). Payloads are thin {id, type, created_at, data:{type, id}} — fetch the resource, dedupe on the event id.

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/webhooks/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."
PATCH/webhooks/{id}write

Update url/events, or status:active to re-enable a disabled endpoint

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Body · application/json

urlstring

max length 2048

eventsstring[]
statusenum<string>

"active" · "disabled"

Response · 200

webhookobjectrequired

Outbound webhook endpoint. Deliveries carry x-asteroids-event/-delivery/-timestamp/-signature (v1=hmac-sha256(secret, "<ts>.<body>")), retry 3× (0s/5s/30s), and sustained failure disables (PATCH status:active re-enables). Payloads are thin {id, type, created_at, data:{type, id}} — fetch the resource, dedupe on the event id.

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/webhooks/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."
DELETE/webhooks/{id}write

Delete a webhook endpoint

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Response · 200

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/webhooks/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

List BYO channel apps — credentials masked

Response · 200

appsobject[]required
▸ Show child attributes
idstring
platformenum<string>

"telegram" · "slack" · "discord" · "whatsapp" · "imessage"

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

Steps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/apps \
  -H "Authorization: Bearer ast_..."

Register your own bot/number as a channel app

Credentials are proven against the platform where an API exists, stored encrypted, and write-only from then on. The response's setup object carries the steps the platform cannot automate (webhook URLs to paste, invite links).

Body · application/json

platformenum<string>required

"telegram" · "slack" · "discord" · "whatsapp" · "imessage"

labelstringrequired

max length 120

credentialsobjectrequired

Write-only. Required keys per platform — telegram: bot_token · discord: bot_token · slack: bot_token, signing_secret · whatsapp: access_token, phone_number_id, app_secret · imessage (coming soon — answers 501 coming_soon today): api_key, phone_number, webhook_secret

Response · 201

idstring
platformenum<string>

"telegram" · "slack" · "discord" · "whatsapp" · "imessage"

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

Steps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/apps \
  -H "Authorization: Bearer ast_..."

Channel app detail — credentials masked

Path parameters

idstringrequired

The channel app id

Response · 200

idstring
platformenum<string>

"telegram" · "slack" · "discord" · "whatsapp" · "imessage"

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

Steps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/apps/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Rename or rotate credentials (rotation re-runs registration)

Path parameters

idstringrequired

The channel app id

Body · application/json

labelstring

max length 120

credentialsobject

Full replacement bag; rotation re-runs the platform registration

Response · 200

idstring
platformenum<string>

"telegram" · "slack" · "discord" · "whatsapp" · "imessage"

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

Steps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/channels/apps/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Delete the channel app

Path parameters

idstringrequired

The channel app id

Response · 204

Deleted

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/channels/apps/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

List connections with their bound session

Response · 200

connectionsobject[]required
▸ Show child attributes
idstring
platformstring
channel_idstring
labelstring
statusenum<string>

"PENDING" · "CONNECTED" · "DISCONNECTED"

bound_sessionobject
▸ Show child attributes
idstring
labelstring
created_atstring
connectobject

PENDING only: the end-user ceremony (url, and for code flows phone + code)

▸ Show child attributes
urlstring
phonestring
codestring
expires_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/connections \
  -H "Authorization: Bearer ast_..."

Connect a surface — link-flow platforms return a pending connect ceremony

telegram/imessage/whatsapp mint a connect link (deep link + code) the end user claims in-platform; slack/discord create the channel synchronously under the app identity. Pass app for BYO; callback_url (link flows) redirects the hosted connect page to you after the claim.

Body · application/json

platformenum<string>required

"telegram" · "slack" · "discord" · "whatsapp" · "imessage" · "loopback"

labelstring

max length 120

metadataobject

Echoed on channel.connected and the callback redirect

destinationobject

Pre-bind: the claimed surface talks to this session

▸ Show child attributes
sessionstring
appstring

BYO ChannelApp id — the connect ceremony runs on your bot/number

invite_userstring

Slack only: user id to invite into the created channel

callback_urlstring

Link-flow platforms only: the hosted connect page redirects here after the claim with connection_id, status, and metadata query params

Response · 201

idstring
platformstring
channel_idstring
labelstring
statusenum<string>

"PENDING" · "CONNECTED" · "DISCONNECTED"

bound_sessionobject
▸ Show child attributes
idstring
labelstring
created_atstring
connectobject

PENDING only: the end-user ceremony (url, and for code flows phone + code)

▸ Show child attributes
urlstring
phonestring
codestring
expires_atstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/connections \
  -H "Authorization: Bearer ast_..."

Disconnect the surface

Path parameters

idstringrequired

The connection id

Response · 204

Disconnected

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/channels/connections/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Set where the surface routes — a session or your webhook endpoint (single active binding)

Path parameters

idstringrequired

The connection id

Body · application/json

destinationobjectrequired

Exactly one of webhook (endpoint id) or session (session id)

▸ Show child attributes
webhookstring
sessionstring

Response · 200

connection_idstring
binding_idstring
sessionstring
webhookstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PUT https://agentsky.dev/channels/connections/sess_cmtb7q2j/binding \
  -H "Authorization: Bearer ast_..."

Declared platform capabilities — branch on these instead of guessing

Path parameters

idstringrequired

The connection id

Response · 200

connection_idstring
platformstring
capabilitiesobject

threads · reactions · markers · proactive · markdown · modals · ephemeral · streaming

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/connections/sess_cmtb7q2j/capabilities \
  -H "Authorization: Bearer ast_..."

List bindings, optionally by connection

Query parameters

connection_idstring

Response · 200

bindingsobject[]required
▸ Show child attributes
idstring
connection_idstring
thread_idstring
destinationobject

Exactly one of webhook (endpoint id) or session (session id)

▸ Show child attributes
webhookstring
sessionstring
is_defaultboolean
statusstring
route_keystring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/bindings?connection_id= \
  -H "Authorization: Bearer ast_..."

Route one thread of a connection to a session or your webhook

Body · application/json

connection_idstringrequired
thread_idstringrequired

The one thread this rule routes. Connection-level routing is a single slot — set it via PUT /connections/{id}/binding

destinationobjectrequired

Exactly one of webhook (endpoint id) or session (session id)

▸ Show child attributes
webhookstring
sessionstring
route_keystring

max length 60

Response · 201

idstring
connection_idstring
thread_idstring
destinationobject

Exactly one of webhook (endpoint id) or session (session id)

▸ Show child attributes
webhookstring
sessionstring
is_defaultboolean
statusstring
route_keystring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/bindings \
  -H "Authorization: Bearer ast_..."

Delete the binding

Path parameters

idstringrequired

The binding id

Response · 204

Deleted

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/channels/bindings/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

List webhook endpoints

Response · 200

webhooksobject[]required
▸ Show child attributes
idstring
urlstring
eventsstring[]
statusstring
secretstring

whsec_ HMAC secret — returned on create only

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl https://agentsky.dev/channels/webhooks \
  -H "Authorization: Bearer ast_..."

Create a webhook endpoint — HMAC-signed deliveries, 0/5/30s retries

Deliveries carry X-Asteroids-{Event,Delivery,Timestamp,Signature}; ~20 consecutive failures disable the endpoint. Consumers must be idempotent by delivery id.

Body · application/json

urlstringrequired

https (http allowed for localhost only)

eventsstring[]

Default ["message.received"]

Response · 201

idstring
urlstring
eventsstring[]
statusstring
secretstring

whsec_ HMAC secret — returned on create only

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/webhooks \
  -H "Authorization: Bearer ast_..."

Re-enable a disabled endpoint (resets failures, keeps the secret) and/or re-pick events

Path parameters

idstringrequired

The webhook endpoint id

Body · application/json

statusenum<string>

"ACTIVE"

eventsstring[]

Response · 200

idstring
urlstring
eventsstring[]
statusstring
secretstring

whsec_ HMAC secret — returned on create only

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PATCH https://agentsky.dev/channels/webhooks/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Delete the webhook endpoint

Path parameters

idstringrequired

The webhook endpoint id

Response · 204

Deleted

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/channels/webhooks/sess_cmtb7q2j \
  -H "Authorization: Bearer ast_..."

Add a reaction (platform-neutral emoji names)

Path parameters

idstringrequired

The thread id

midstringrequired
emojistringrequired

Response · 204

Reacted

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X PUT https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages/mid/reactions/emoji \
  -H "Authorization: Bearer ast_..."

Remove a reaction

Path parameters

idstringrequired

The thread id

midstringrequired
emojistringrequired

Response · 204

Removed

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X DELETE https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages/mid/reactions/emoji \
  -H "Authorization: Bearer ast_..."

Proactive fan-out: post to every thread bound to a destination

Body · application/json

destinationobjectrequired

Exactly one of webhook (endpoint id) or session (session id)

▸ Show child attributes
webhookstring
sessionstring
partsobject[]required
▸ Show child attributes
type: "text"object
▸ Show child attributes
type"text"required
textstringrequired
type: "markdown"object
▸ Show child attributes
type"markdown"required
textstringrequired
type: "raw"object
▸ Show child attributes
type"raw"required
platformstringrequired
payloadstringrequired

Platform-native payload, JSON-encoded

display_namestring

max length 80

Response · 200

OK — per-thread results

resultsobject[]
▸ Show child attributes
thread_idstring
statusstring

Response · 4xx

{ "error": { "code", "message" } } — see the error table above.
Request
curl -X POST https://agentsky.dev/channels/deliveries \
  -H "Authorization: Bearer ast_..."

Stream events

Send and listen are decoupled: POST …/events, then read …/stream until session.status_idle — there is no non-streaming reply mode. Frames are id: + event: + one data: JSON object { id, type, sessionId, agent, at, …payload } (the id is the dedupe key against GET …/events):

eventpayloadmeaning
user.messagecontenthistory only (GET …/events) and the POST echo — user messages are not sent on the live stream; content is the CMA block list you sent, every image/document source rewritten to a file source
system.messagecontenthistory only and the POST echo — the per-turn system text sent alongside a user.message
user.interruptbyan interrupt was accepted — echoed on the live stream and kept in history; the pod's session.status_idle follows
agent.messageparts, texta user-facing agent post; a turn may carry several
agent.reasoningpartraw engine event: thinking (live only)
agent.tool_usepartraw engine event: a tool invocation (live only)
agent.tool_resultpartraw engine event: the tool's outcome (live only)
agent.statuspartraw engine event: working / waiting / … (live only)
session.status_runninga turn started
session.status_idlestop_reasonthe turn is over (stop_reason.type is end_turn — also after an interrupt — budget_reached, or retries_exhausted after an exhausted session.error); never break on bare idle; the stream stays open
session.errorerrora failure inside the turn (error.type, error.message, error.retry_status retrying or exhausted); the stream stays open and a session.status_idle follows
session.status_terminatedthe session was archived; terminal — nothing follows; close the stream
session.deletedterminal — nothing follows; close the stream
One turn on the standing stream
id: msg-77e0c4…
event: agent.message
data: {"id":"msg-77e0c4…","type":"agent.message","sessionId":"sess-8c41f0…","agent":"nemesis-ee87","at":"…","text":"Signups today: 42, up 12%.","parts":[]}

id: turn_9d52a1…#idle
event: session.status_idle
data: {"id":"turn_9d52a1…#idle","type":"session.status_idle","sessionId":"sess-8c41f0…","agent":"nemesis-ee87","at":"…","stop_reason":{"type":"end_turn"}}