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" } }:
| HTTP | code | When |
|---|---|---|
| 400 | invalid_request | malformed JSON / validation failure |
| 401 | invalid_token | missing, unknown, revoked, or expired token |
| 402 | insufficient_credits | the spend gate blocked the turn |
| 403 | insufficient_scope · universe_mismatch · forbidden | scope too low; X-Universe conflicts with a scoped token; agent has no API binding |
| 404 | not_found | unknown agent/universe (also masks unauthorized ids) |
| 409 | conflict | version conflict |
| 422 | invalid_spec | valid JSON, invalid domain rules (e.g. llm not allowed for type) |
| 429 | rate_limited | 120 requests/min per token exceeded — honor Retry-After |
Identity
/whoamireadCaller identity, resolved universe, effective scopes
userrequired▸ Show child attributes▾ Hide child attributes
idemailnameuniverserequired▸ Show child attributes▾ Hide child attributes
slugnameisPersonalscopesrequired"read" · "write" · "admin"
authrequired"token" · "session"
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/whoami \
-H "Authorization: Bearer ast_..."Universes
/universesreadList universes
universesrequired▸ Show child attributes▾ Hide child attributes
slugnameisPersonalcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/universes \
-H "Authorization: Bearer ast_..."/universeswrite, personal tokens onlyCreate a universe
slugrequiredmax length 40 — pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$
namemax length 80
universerequired▸ Show child attributes▾ Hide child attributes
slugnameisPersonalcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/universes \
-H "Authorization: Bearer ast_..." \
-H "Content-Type: application/json" \
-d '{"slug":"acme","name":"Acme"}'Universe detail
slugrequiredThe universe slug
universerequired▸ Show child attributes▾ Hide child attributes
slugnameisPersonalcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/universes/slug \
-H "Authorization: Bearer ast_..."Agents
/agentsreadList agents in the resolved universe
agentsrequired▸ Show child attributes▾ Hide child attributes
idThe agent id (agent_…) — the only address
namedisplayNameagentTypeEngine: claude_code · codex · hermes · openclaw · pi · dsh · kimi_code · opencode
llmharnessVersionThe engine CLI version this agent's sessions run; PATCH to move to the platform's current version
reasoningEffortHarness-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
capabilitiesThe 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"
versionBumped on every update; see expectedVersion
archivedsessionCountcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/agents \
-H "Authorization: Bearer ast_..."/agentswriteCreate 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.
namePrompt/display label only — NOT the handle. The addressable handle is the auto-minted `slug` in the response — max length 60
descriptionmax length 500
agentType"hermes" · "claude_code" · "codex" · "openclaw" · "pi" · "dsh" · "kimi_code" · "opencode"
llmreasoningEffortHarness-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"
promptmax length 100000
displayNameSeeds the minted `slug` (the unique addressable handle, returned in the response); omitted = an auto-generated asteroid name — max length 60
capabilities"exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe" — default: []
instructions▸ Show child attributes▾ Hide child attributes
namerequiredpattern .*\.md$
contentdefault: ""
skillsRFC-0073 skill attachments: store references ({type:'skill', skillId, version?: 'latest'|skr_…}) and GitHub shortcuts ({type:'github', url, ref?, tokenSecretRef?}). Max 20.
▸ Show child attributes▾ Hide child attributes
type: "skill"▸ Show child attributes▾ Hide child attributes
typerequiredskillIdrequiredversiondefault: "latest"
type: "github"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredrefBranch or commit SHA; default branch when omitted.
tokenSecretRefAgent secret key holding a clone token for private repos.
mcpServersRemote streamable-HTTP MCP servers this agent connects to.
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
customData▸ Show child attributes▾ Hide child attributes
idrequirednamerequiredpattern ^[a-z0-9_]+$
kindrequired"spreadsheet" · "doc" · "private_api" · "other"
scope"creator" · "user" — default: "creator"
descriptionuriconfigdefault: {}
metadataagentrequiredEverything in the list item, plus configuration state.
▸ Show child attributes▾ Hide child attributes
idThe agent id (agent_…) — the only address
namedisplayNameagentTypellmharnessVersionreasoningEffort"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null
versionarchivedsessionCountcreatedAtdescriptionpromptThe user prompt layer
promptVersioncapabilitiesThe 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"
mcpServersDeclared remote MCP server references, including tool filters; runtime authentication fields are never returned
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
metadataYour key-merged client metadata
defaultSessionIdThe session conversation verbs target when addressed by agent id
universeResolved universe slug
{ "error": { "code", "message" } } — see the error table above.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"]}'{
"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"
}
}/agents/{id}readAgent detail
idrequiredThe agent id (agent_…)
agentrequiredEverything in the list item, plus configuration state.
▸ Show child attributes▾ Hide child attributes
idThe agent id (agent_…) — the only address
namedisplayNameagentTypellmharnessVersionreasoningEffort"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null
versionarchivedsessionCountcreatedAtdescriptionpromptThe user prompt layer
promptVersioncapabilitiesThe 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"
mcpServersDeclared remote MCP server references, including tool filters; runtime authentication fields are never returned
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
metadataYour key-merged client metadata
defaultSessionIdThe session conversation verbs target when addressed by agent id
universeResolved universe slug
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
-H "Authorization: Bearer ast_..."/agents/{id}writeUpdate 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.
idrequiredThe agent id (agent_…)
displayNamemax length 60
capabilities"exa.search" · "exa.contents" · "tinyfish.fetch" · "tinyfish.browser" · "dataforseo.serp" · "gptimage.generate" · "rembg.remove-background" · "seedance.generate" · "mm.i2v" · "fish-audio.transcribe"
metadataharnessVersionreasoningEffortHarness-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▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
skillsReplaces the whole skills array; omitted preserves. Applies from the next provision.
▸ Show child attributes▾ Hide child attributes
type: "skill"▸ Show child attributes▾ Hide child attributes
typerequiredskillIdrequiredversiondefault: "latest"
type: "github"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredrefBranch or commit SHA; default branch when omitted.
tokenSecretRefAgent secret key holding a clone token for private repos.
mcpServersReplaces the whole MCP server list; omitted preserves. Applies from the next provision.
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
expectedVersionagentrequiredEverything in the list item, plus configuration state.
▸ Show child attributes▾ Hide child attributes
idThe agent id (agent_…) — the only address
namedisplayNameagentTypellmharnessVersionreasoningEffort"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null
versionarchivedsessionCountcreatedAtdescriptionpromptThe user prompt layer
promptVersioncapabilitiesThe 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"
mcpServersDeclared remote MCP server references, including tool filters; runtime authentication fields are never returned
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
metadataYour key-merged client metadata
defaultSessionIdThe session conversation verbs target when addressed by agent id
universeResolved universe slug
{ "error": { "code", "message" } } — see the error table above.curl -X PATCH https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
-H "Authorization: Bearer ast_..." \
-H "Content-Type: application/json" \
-d '{"displayName":"Research Agent","expectedVersion":1}'/agents/{id}adminDelete the agent — only with zero sessions (409 agent_has_sessions)
idrequiredThe agent id (agent_…)
okrequired{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d \
-H "Authorization: Bearer ast_..."/agents/{id}/archiveadminArchive the agent — read-only, sessions keep running, new sessions rejected
idrequiredThe agent id (agent_…)
agentrequiredEverything in the list item, plus configuration state.
▸ Show child attributes▾ Hide child attributes
idThe agent id (agent_…) — the only address
namedisplayNameagentTypellmharnessVersionreasoningEffort"none" · "off" · "minimal" · "low" · "medium" · "high" · "xhigh" · "max" · "ultra" · null
versionarchivedsessionCountcreatedAtdescriptionpromptThe user prompt layer
promptVersioncapabilitiesThe 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"
mcpServersDeclared remote MCP server references, including tool filters; runtime authentication fields are never returned
▸ Show child attributes▾ Hide child attributes
typedefault: "url"
namerequiredmax length 255
urlrequiredtools▸ Show child attributes▾ Hide child attributes
includedefault: []
excludedefault: []
metadataYour key-merged client metadata
defaultSessionIdThe session conversation verbs target when addressed by agent id
universeResolved universe slug
{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/archive \
-H "Authorization: Bearer ast_..."/agents/{id}/promptwriteSave the user prompt layer; applies to sessions started after the save
idrequiredThe agent id (agent_…)
promptrequiredmax length 100000
versionunchangedContent identical to the active version
{ "error": { "code", "message" } } — see the error table above.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
idrequiredThe agent id (agent_…)
versionsrequired▸ Show child attributes▾ Hide child attributes
versionnotecreatedAtactivecontent{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/prompt/versions \
-H "Authorization: Bearer ast_..."Declared secret keys + set/unset — never values
idrequiredThe agent id (agent_…)
secretsrequired▸ Show child attributes▾ Hide child attributes
keydescription{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/secrets \
-H "Authorization: Bearer ast_..."Set a declared secret's value (write-only)
idrequiredThe agent id (agent_…)
keyrequiredvaluerequiredmax length 10000
descriptionmax length 500
okrequired{ "error": { "code", "message" } } — see the error table above.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
idrequiredThe agent id (agent_…)
keyrequiredokrequired{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/agents/agent_cmtb2f0a8m9k7x51q4ez6r0d/secrets/NOTION_TOKEN \
-H "Authorization: Bearer ast_..."Skills
/skillsreadList skills in the resolved universe
cursorlimitskillsrequired▸ Show child attributes▾ Hide child attributes
idrequireddisplayNamerequiredlatestRevisionIdrequiredWhat `latest` references resolve to.
createdAtrequiredupdatedAtrequirednextCursor{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/skills?cursor=&limit= \
-H "Authorization: Bearer ast_..."/skillswriteCreate 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.
skillrequired▸ Show child attributes▾ Hide child attributes
idrequireddisplayNamerequiredlatestRevisionIdrequiredWhat `latest` references resolve to.
createdAtrequiredupdatedAtrequiredrevisionrequired▸ Show child attributes▾ Hide child attributes
idrequiredskillIdrequirednamerequiredFrontmatter name — the skill's identity name.
descriptionrequiredfilesrequired▸ Show child attributes▾ Hide child attributes
pathrequiredsizerequiredsha256requiredexecutablerequiredcreatedAtrequired{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/skills \
-H "Authorization: Bearer ast_..."Skill detail
skillIdrequiredThe skill id (skill_…)
skillrequired▸ Show child attributes▾ Hide child attributes
idrequireddisplayNamerequiredlatestRevisionIdrequiredWhat `latest` references resolve to.
createdAtrequiredupdatedAtrequired{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/skills/skillId \
-H "Authorization: Bearer ast_..."/skills/{skillId}writeDelete a skill and all its revisions
409 skill_in_use while any agent references the skill.
skillIdrequiredThe skill id (skill_…)
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/skills/skillId \
-H "Authorization: Bearer ast_..."List a skill's revisions, newest first
skillIdrequiredThe skill id (skill_…)
revisionsrequired▸ Show child attributes▾ Hide child attributes
idrequiredskillIdrequirednamerequiredFrontmatter name — the skill's identity name.
descriptionrequiredfilesrequired▸ Show child attributes▾ Hide child attributes
pathrequiredsizerequiredsha256requiredexecutablerequiredcreatedAtrequired{ "error": { "code", "message" } } — see the error table above.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).
revisionrequired▸ Show child attributes▾ Hide child attributes
idrequiredskillIdrequirednamerequiredFrontmatter name — the skill's identity name.
descriptionrequiredfilesrequired▸ Show child attributes▾ Hide child attributes
pathrequiredsizerequiredsha256requiredexecutablerequiredcreatedAtrequired{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/skills/skillId/revisions \
-H "Authorization: Bearer ast_..."Skill revision detail (metadata + file manifest)
skillIdrequiredThe skill id (skill_…)
revisionIdrequiredThe skill revision id (skr_…)
revisionrequired▸ Show child attributes▾ Hide child attributes
idrequiredskillIdrequirednamerequiredFrontmatter name — the skill's identity name.
descriptionrequiredfilesrequired▸ Show child attributes▾ Hide child attributes
pathrequiredsizerequiredsha256requiredexecutablerequiredcreatedAtrequired{ "error": { "code", "message" } } — see the error table above.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.
skillIdrequiredThe skill id (skill_…)
revisionIdrequiredThe skill revision id (skr_…)
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/skills/skillId/revisions/revisionId \
-H "Authorization: Bearer ast_..."Files
/fileswriteUpload 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.
typerequired"file"
idrequiredfile_…
created_atrequiredfilenamerequiredmime_typerequiredsize_bytesrequireddownloadablerequiredfalse for uploads (write-once); true for the per-session copies minted when a file rides a message
expires_atrequired{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/files \
-H "Authorization: Bearer ast_..."{
"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
}/filesreadList 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.
limitpageA next_page cursor
ids[]scope_idsess_…
datarequiredNewest first
▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredfile_…
created_atrequiredfilenamerequiredmime_typerequiredsize_bytesrequireddownloadablerequiredfalse for uploads (write-once); true for the per-session copies minted when a file rides a message
expires_atrequirednext_pagerequiredPass back as ?page= for the next page
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/files?limit=&page=&ids[]=&scope_id= \
-H "Authorization: Bearer ast_..."{
"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
}/files/{file_id}readFile metadata
file_idrequiredThe file id (file_…)
typerequired"file"
idrequiredfile_…
created_atrequiredfilenamerequiredmime_typerequiredsize_bytesrequireddownloadablerequiredfalse for uploads (write-once); true for the per-session copies minted when a file rides a message
expires_atrequired{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/files/file_cmtb9x4p \
-H "Authorization: Bearer ast_..."/files/{file_id}writeDelete a file
Soft delete: the file stops resolving everywhere; sessions that already received a copy keep it.
file_idrequiredThe file id (file_…)
typerequired"file_deleted"
idrequired{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/files/file_cmtb9x4p \
-H "Authorization: Bearer ast_..."{
"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.
file_idrequiredThe file id (file_…)
The bytes, with content-type and content-disposition
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/files/file_cmtb9x4p/content \
-H "Authorization: Bearer ast_..."Sessions
/sessionsreadList sessions; ?agent= filters to one spec
agentThe agent id (agent_…)
sessionsrequired▸ Show child attributes▾ Hide child attributes
idsess_… identifier
agentIdThe agent id (agent_…)
titlestatusprovisioning = 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"
agentTypellmThe model this session runs on (PATCH to change; the agent's model is unchanged)
reasoningEffortThe effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)
modelBillingWho pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"
defaultIs this the agent's default session
metadatabudgetHard 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.
resourcesThe files and GitHub repositories mounted into the working directory, oldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequiredcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/sessions?agent= \
-H "Authorization: Bearer ast_..."/sessionswriteCreate 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.
agentrequiredllmModel for this session (a current model for the agent's harness). Omitted = the agent's model
reasoningEffortReasoning 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▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
titlemax length 120
metadatainstructions▸ Show child attributes▾ Hide child attributes
namerequiredpattern .*\.md$
contentdefault: ""
initial_events▸ Show child attributes▾ Hide child attributes
typerequiredcontentrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "image"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtype: "document"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "text"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typedefault: "text/plain"
datarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtitlecontextenvironment_idvault_idsvcpusmemoryMbmodelBillingWho 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"
budgetHard spend cap for this session. Attachable only at create; changeable or removable later via PATCH (removal is one-way)
▸ Show child attributes▾ Hide child attributes
typerequiredmax_list_costrequired▸ Show child attributes▾ Hide child attributes
amountrequiredWhole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15
currencyrequiredresourcesFiles 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▾ Hide child attributes
type: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredmax length 128
mount_path▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "github_repository"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredmax length 2048
authorization_tokenmax length 1024
checkout▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
type: "branch"▸ Show child attributes▾ Hide child attributes
typerequirednamerequiredmax length 255
type: "commit"▸ Show child attributes▾ Hide child attributes
typerequiredsharequiredmax length 64
option 2▸ Show child attributes▾ Hide child attributes
mount_path▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
sessionrequired▸ Show child attributes▾ Hide child attributes
idsess_… identifier
agentIdThe agent id (agent_…)
titlestatusprovisioning = 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"
agentTypellmThe model this session runs on (PATCH to change; the agent's model is unchanged)
reasoningEffortThe effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)
modelBillingWho pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"
defaultIs this the agent's default session
metadatabudgetHard 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.
resourcesThe files and GitHub repositories mounted into the working directory, oldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequiredcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.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"}]}]}'{
"session": {
"id": "sess-8c41f0…",
"agent": "research-agent",
"status": "idle",
"default": true
}
}/sessions/{id}readSession detail — status is provisioning (sandbox booting or installing packages) | idle | running | terminated
idrequiredThe session id
sessionrequired▸ Show child attributes▾ Hide child attributes
idsess_… identifier
agentIdThe agent id (agent_…)
titlestatusprovisioning = 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"
agentTypellmThe model this session runs on (PATCH to change; the agent's model is unchanged)
reasoningEffortThe effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)
modelBillingWho pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"
defaultIs this the agent's default session
metadatabudgetHard 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.
resourcesThe files and GitHub repositories mounted into the working directory, oldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequiredcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/sessions/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/sessions/{id}writeUpdate 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.
idrequiredThe session id
title▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
metadatallmSwitch this session's model (a current model for its harness; the agent's model is unchanged). Applies from the next turn
reasoningEffortSession-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▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
modelBillingWho pays for model calls; switching restarts the agent's engine in place — "platform" · "account"
budgetChange the spend cap (must be strictly above consumed cost) or null to remove it — removal is one-way
▸ Show child attributes▾ Hide child attributes
type: "limit"▸ Show child attributes▾ Hide child attributes
typerequiredmax_list_costrequired▸ Show child attributes▾ Hide child attributes
amountrequiredWhole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15
currencyrequiredoption 2▸ Show child attributes▾ Hide child attributes
sessionrequired▸ Show child attributes▾ Hide child attributes
idsess_… identifier
agentIdThe agent id (agent_…)
titlestatusprovisioning = 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"
agentTypellmThe model this session runs on (PATCH to change; the agent's model is unchanged)
reasoningEffortThe effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)
modelBillingWho pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"
defaultIs this the agent's default session
metadatabudgetHard 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.
resourcesThe files and GitHub repositories mounted into the working directory, oldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequiredcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.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"}'/sessions/{id}writePermanently 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.
idrequiredThe session id
okrequired{ "error": { "code", "message" } } — see the error table above.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.
idrequiredThe session id
sessionrequired▸ Show child attributes▾ Hide child attributes
idsess_… identifier
agentIdThe agent id (agent_…)
titlestatusprovisioning = 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"
agentTypellmThe model this session runs on (PATCH to change; the agent's model is unchanged)
reasoningEffortThe effective reasoning effort: this session's own setting, else the agent's, else null (the harness default)
modelBillingWho pays for model calls: platform wallet or the user's connected subscription — "platform" · "account"
defaultIs this the agent's default session
metadatabudgetHard 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.
resourcesThe files and GitHub repositories mounted into the working directory, oldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequiredcreatedAtISO 8601
{ "error": { "code", "message" } } — see the error table above.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.
idrequiredThe session id (sess_…)
limitpageA next_page cursor
datarequiredOldest first
▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequirednext_pagerequiredPass back as ?page= for the next page; null when `limit` was omitted or the list ended
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/sessions/sess_cmtb7q2j/resources?limit=&page= \
-H "Authorization: Bearer ast_..."{
"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.
idrequiredThe session id (sess_…)
type: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredmax length 128
mount_path▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "github_repository"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredmax length 2048
authorization_tokenmax length 1024
checkout▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
type: "branch"▸ Show child attributes▾ Hide child attributes
typerequirednamerequiredmax length 255
type: "commit"▸ Show child attributes▾ Hide child attributes
typerequiredsharequiredmax length 64
option 2▸ Show child attributes▾ Hide child attributes
mount_path▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequired{ "error": { "code", "message" } } — see the error table above.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"}'{
"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
idrequiredThe session id (sess_…)
ridrequiredThe resource id (sesrsc_…)
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequired{ "error": { "code", "message" } } — see the error table above.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.
idrequiredThe session id (sess_…)
ridrequiredThe resource id (sesrsc_…)
authorization_tokenrequiredmax length 1024
option 1▸ Show child attributes▾ Hide child attributes
typerequired"file"
idrequiredsesrsc_…
file_idrequiredThe per-session copy (file_…), read-only at mount_path
mount_pathrequiredAbsolute, under /workspace
created_atrequiredupdated_atrequiredoption 2▸ Show child attributes▾ Hide child attributes
typerequired"github_repository"
idrequiredsesrsc_…
urlrequiredhttps://github.com/{owner}/{repo}
mount_pathrequiredAbsolute, under /workspace; the clone's root
checkout{type:"branch", name} or {type:"commit", sha}; absent = the default branch
▸ Show child attributes▾ Hide child attributes
type"branch" · "commit"
nameshacreated_atrequiredupdated_atrequired{ "error": { "code", "message" } } — see the error table above.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.
idrequiredThe session id (sess_…)
ridrequiredThe resource id (sesrsc_…)
typerequired"session_resource_deleted"
idrequired{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/sessions/sess_cmtb7q2j/resources/sesrsc_cmtc1a2d \
-H "Authorization: Bearer ast_..."{
"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.
idrequiredThe session id
partsrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "reasoning"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
redacteddefault: false
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "tool_call"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredargsdefault: {}
args_partialtype: "tool_result"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredstatus"ok" · "error" — default: "ok"
resultdefault: {}
type: "file"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequirednamerequiredmedia_typerequireduridatasize_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "image"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "video"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
duration_ms▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
size_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
thumbnail_uritype: "status"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredlevelrequired"thinking" · "working" · "waiting" · "idle" · "done"
texttype: "error"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcoderequiredmessagerequiredretryabledefault: false
Accepted — body is {}; output arrives on the stream
{ "error": { "code", "message" } } — see the error table above.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"}]}'{}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.
idrequiredThe session id
eventsrequired▸ Show child attributes▾ Hide child attributes
type: "user.message"▸ Show child attributes▾ Hide child attributes
typerequiredcontentrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "image"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtype: "document"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "text"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typedefault: "text/plain"
datarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtitlecontexttype: "system.message"▸ Show child attributes▾ Hide child attributes
typerequiredcontentrequired▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "user.interrupt"▸ Show child attributes▾ Hide child attributes
typerequiredOK — one echo per event, in order
datarequiredOne echo per event, in order, in the events-history shape
▸ Show child attributes▾ Hide child attributes
idrequiredStable event id — the dedupe key across stream ∪ events
typerequireduser.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
sessionIdrequiredagentIdThe agent id (agent_…)
atISO 8601
messageIdagent.message
partsagent.message
▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "reasoning"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
redacteddefault: false
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "tool_call"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredargsdefault: {}
args_partialtype: "tool_result"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredstatus"ok" · "error" — default: "ok"
resultdefault: {}
type: "file"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequirednamerequiredmedia_typerequireduridatasize_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "image"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "video"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
duration_ms▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
size_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
thumbnail_uritype: "status"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredlevelrequired"thinking" · "working" · "waiting" · "idle" · "done"
texttype: "error"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcoderequiredmessagerequiredretryabledefault: false
textagent.message — parts flattened to plain text
contentuser.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
partreasoning / tool_use / tool_result / status events
▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "reasoning"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
redacteddefault: false
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "tool_call"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredargsdefault: {}
args_partialtype: "tool_result"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredstatus"ok" · "error" — default: "ok"
resultdefault: {}
type: "file"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequirednamerequiredmedia_typerequireduridatasize_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "image"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "video"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
duration_ms▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
size_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
thumbnail_uritype: "status"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredlevelrequired"thinking" · "working" · "waiting" · "idle" · "done"
texttype: "error"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcoderequiredmessagerequiredretryabledefault: false
stop_reasonsession.status_idle — discriminate on type; never break on bare idle
▸ Show child attributes▾ Hide child attributes
type"end_turn" (also after an interrupt) | "retries_exhausted" (preceded by an exhausted session.error) | "budget_reached"; more reserved
errorsession.error — the stream stays open; a session.status_idle follows once the turn is over
▸ Show child attributes▾ Hide child attributes
typee.g. "pod_unavailable"
messageretry_status"retrying" (the turn continues) | "exhausted" (the turn is over)
byuser.interrupt — who requested the interrupt
{ "error": { "code", "message" } } — see the error table above.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."}]}]}'{
"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).
idrequiredThe session id
cursorlimittypes[]eventsrequiredOldest-first
▸ Show child attributes▾ Hide child attributes
idrequiredStable event id — the dedupe key across stream ∪ events
typerequireduser.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
sessionIdrequiredagentIdThe agent id (agent_…)
atISO 8601
messageIdagent.message
partsagent.message
▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "reasoning"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
redacteddefault: false
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "tool_call"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredargsdefault: {}
args_partialtype: "tool_result"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredstatus"ok" · "error" — default: "ok"
resultdefault: {}
type: "file"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequirednamerequiredmedia_typerequireduridatasize_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "image"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "video"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
duration_ms▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
size_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
thumbnail_uritype: "status"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredlevelrequired"thinking" · "working" · "waiting" · "idle" · "done"
texttype: "error"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcoderequiredmessagerequiredretryabledefault: false
textagent.message — parts flattened to plain text
contentuser.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
partreasoning / tool_use / tool_result / status events
▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "reasoning"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredtextdefault: ""
redacteddefault: false
stream_id▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
stream_index▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "tool_call"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredargsdefault: {}
args_partialtype: "tool_result"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcall_idrequiredtool_namerequiredstatus"ok" · "error" — default: "ok"
resultdefault: {}
type: "file"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequirednamerequiredmedia_typerequireduridatasize_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "image"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
type: "video"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredmedia_typerequireduridataaltwidth▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
height▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
duration_ms▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
size_bytes▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
thumbnail_uritype: "status"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredlevelrequired"thinking" · "working" · "waiting" · "idle" · "done"
texttype: "error"▸ Show child attributes▾ Hide child attributes
indexrequiredtyperequiredcoderequiredmessagerequiredretryabledefault: false
stop_reasonsession.status_idle — discriminate on type; never break on bare idle
▸ Show child attributes▾ Hide child attributes
type"end_turn" (also after an interrupt) | "retries_exhausted" (preceded by an exhausted session.error) | "budget_reached"; more reserved
errorsession.error — the stream stays open; a session.status_idle follows once the turn is over
▸ Show child attributes▾ Hide child attributes
typee.g. "pod_unavailable"
messageretry_status"retrying" (the turn continues) | "exhausted" (the turn is over)
byuser.interrupt — who requested the interrupt
cursorrequiredPass back as ?cursor= for the next page; null when the session has no events
hasMorerequired{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/sessions/sess_cmtb7q2j/events?cursor=&limit=&types[]= \
-H "Authorization: Bearer ast_..."{
"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.
idrequiredThe session id
SSE stream
{ "error": { "code", "message" } } — see the error table above.curl -N https://agentsky.dev/sessions/sess_cmtb7q2j/stream \
-H "Authorization: Bearer ast_..."Abort the in-flight turn
idrequiredThe session id
statusrequiredno_turn = nothing in flight; otherwise user.interrupt echoes on the stream and the pod's session.status_idle follows — "interrupting" · "no_turn"
{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/sessions/sess_cmtb7q2j/interrupt \
-H "Authorization: Bearer ast_..."{
"status": "interrupting"
}Post into a thread — markdown renders natively per platform
idrequiredThe thread id (from message.received or channel events)
partsrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "markdown"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "raw"▸ Show child attributes▾ Hide child attributes
typerequiredplatformrequiredpayloadrequiredPlatform-native payload, JSON-encoded
display_namemax length 80
doneClears the working marker (✅) for the replied-to message
message_idthread_id{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages \
-H "Authorization: Bearer ast_..."SSE mirror of your webhook events — for local development
SSE stream
{ "error": { "code", "message" } } — see the error table above.curl -N https://agentsky.dev/channels/events/stream \
-H "Authorization: Bearer ast_..."Routines
/routinesreadList routines
cursorlimit1–500, default 50
itemsrequired▸ Show child attributes▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_atcursorhasMore{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/routines?cursor=&limit= \
-H "Authorization: Bearer ast_..."/routineswriteCreate 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.
namerequiredmax length 256
descriptionmax length 2048
metadatatargetrequired▸ Show child attributes▾ Hide child attributes
type: "new_session"▸ Show child attributes▾ Hide child attributes
typerequiredagentrequiredenvironment_idvault_idstype: "session"▸ Show child attributes▾ Hide child attributes
typerequiredsession_idrequiredinitial_eventsrequired▸ Show child attributes▾ Hide child attributes
typerequiredcontentrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "image"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtype: "document"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "text"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typedefault: "text/plain"
datarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtitlecontextschedule▸ Show child attributes▾ Hide child attributes
type: "cron"▸ Show child attributes▾ Hide child attributes
typerequiredexpressionrequiredmax length 256
timezonerequiredoption 2▸ Show child attributes▾ Hide child attributes
budget▸ Show child attributes▾ Hide child attributes
type: "limit"▸ Show child attributes▾ Hide child attributes
typerequiredmax_list_costrequired▸ Show child attributes▾ Hide child attributes
amountrequiredWhole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15
currencyrequiredoption 2▸ Show child attributes▾ Hide child attributes
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.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"}}'/routines/{id}readRoutine detail
idrequiredThe routine id (rtn_…)
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/routines/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/routines/{id}writeUpdate 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).
idrequiredThe routine id (rtn_…)
namemax length 256
description▸ Show child attributes▾ Hide child attributes
option 1▸ Show child attributes▾ Hide child attributes
option 2▸ Show child attributes▾ Hide child attributes
metadatatarget▸ Show child attributes▾ Hide child attributes
type: "new_session"▸ Show child attributes▾ Hide child attributes
typerequiredagentrequiredenvironment_idvault_idstype: "session"▸ Show child attributes▾ Hide child attributes
typerequiredsession_idrequiredinitial_events▸ Show child attributes▾ Hide child attributes
typerequiredcontentrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "image"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtype: "document"▸ Show child attributes▾ Hide child attributes
typerequiredsourcerequired▸ Show child attributes▾ Hide child attributes
type: "base64"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typerequireddatarequiredtype: "text"▸ Show child attributes▾ Hide child attributes
typerequiredmedia_typedefault: "text/plain"
datarequiredtype: "url"▸ Show child attributes▾ Hide child attributes
typerequiredurlrequiredtype: "file"▸ Show child attributes▾ Hide child attributes
typerequiredfile_idrequiredtitlecontextschedule▸ Show child attributes▾ Hide child attributes
type: "cron"▸ Show child attributes▾ Hide child attributes
typerequiredexpressionrequiredmax length 256
timezonerequiredoption 2▸ Show child attributes▾ Hide child attributes
budget▸ Show child attributes▾ Hide child attributes
type: "limit"▸ Show child attributes▾ Hide child attributes
typerequiredmax_list_costrequired▸ Show child attributes▾ Hide child attributes
amountrequiredWhole US cents as an integer decimal string, e.g. "125" for $1.25 — max length 15
currencyrequiredoption 2▸ Show child attributes▾ Hide child attributes
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.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"}}'/routines/{id}/pausewritePause — suppress scheduled fires; manual runs still work
idrequiredThe routine id (rtn_…)
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.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
idrequiredThe routine id (rtn_…)
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/unpause \
-H "Authorization: Bearer ast_..."Archive — terminal; the schedule stops and the routine becomes immutable
idrequiredThe routine id (rtn_…)
routinerequiredScheduled 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▾ Hide child attributes
idrtn_… identifier
namedescriptionmetadatatarget{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_eventsschedule5-field POSIX cron + IANA timezone, wall-clock matching, minute granularity; null = manual-run only
budgetPer-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.
status"active" · "paused"
paused_reason{type:"manual"} | {type:"error", error:{type}} — non-null exactly when paused
archived_atcreated_atupdated_at{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/archive \
-H "Authorization: Bearer ast_..."/routines/{id}/runwriteManual run — fire now, outside the schedule; works while paused
Records trigger_context {type:"manual"}; manual runs emit no routine_run webhooks.
idrequiredThe routine id (rtn_…)
runrequiredOne fire attempt. Exactly one of session_id / error is non-null.
▸ Show child attributes▾ Hide child attributes
idrrun_… identifier
routine_idtrigger_context{type:"schedule", scheduled_at} | {type:"manual"}
session_iderror{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.
agentResolved agent reference at fire time
created_at{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/routines/sess_cmtb7q2j/run \
-H "Authorization: Bearer ast_..."/routine-runsreadList routine runs — every fire attempt
routineFilter to one routine (rtn_…)
has_errortrue = failed runs, false = runs with a session
trigger_typecreated_at[gte]Also gt / lt / lte
cursorlimititemsrequired▸ Show child attributes▾ Hide child attributes
idrrun_… identifier
routine_idtrigger_context{type:"schedule", scheduled_at} | {type:"manual"}
session_iderror{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.
agentResolved agent reference at fire time
created_atcursorhasMore{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/routine-runs?routine=&has_error=&trigger_type=&created_at[gte]=&cursor=&limit= \
-H "Authorization: Bearer ast_..."Routine run detail
idrequiredThe run id (rrun_…)
runrequiredOne fire attempt. Exactly one of session_id / error is non-null.
▸ Show child attributes▾ Hide child attributes
idrrun_… identifier
routine_idtrigger_context{type:"schedule", scheduled_at} | {type:"manual"}
session_iderror{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.
agentResolved agent reference at fire time
created_at{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/routine-runs/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."Webhooks
List connected model subscriptions — metadata only, never credentials
modelSubscriptionsrequired▸ Show child attributes▾ Hide child attributes
provider"anthropic" · "openai"
labelstatus"connected" · "needs_reconnect"
expiresAtlastUsedAtuseForNewAgentscreatedAtagentsAgents in this universe running on the subscription
▸ Show child attributes▾ Hide child attributes
idagentIdname{ "error": { "code", "message" } } — see the error table above.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.
providerrequiredanthropic = Claude subscription · openai = ChatGPT plan
credentialrequiredmax length 100000
labelmax length 60
modelSubscriptionrequiredA 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▾ Hide child attributes
provider"anthropic" · "openai"
labelstatus"connected" · "needs_reconnect"
expiresAtlastUsedAtuseForNewAgentscreatedAtagentsAgents in this universe running on the subscription
▸ Show child attributes▾ Hide child attributes
idagentIdname{ "error": { "code", "message" } } — see the error table above.curl -X PUT https://agentsky.dev/model-subscriptions/provider \
-H "Authorization: Bearer ast_..."Update useForNewAgents / label
providerrequiredanthropic = Claude subscription · openai = ChatGPT plan
useForNewAgentslabelmax length 60
modelSubscriptionrequiredA 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▾ Hide child attributes
provider"anthropic" · "openai"
labelstatus"connected" · "needs_reconnect"
expiresAtlastUsedAtuseForNewAgentscreatedAtagentsAgents in this universe running on the subscription
▸ Show child attributes▾ Hide child attributes
idagentIdname{ "error": { "code", "message" } } — see the error table above.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
providerrequiredanthropic = Claude subscription · openai = ChatGPT plan
affectedAgents▸ Show child attributes▾ Hide child attributes
idagentIdname{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/model-subscriptions/provider \
-H "Authorization: Bearer ast_..."/webhooksreadList webhook endpoints
webhooksrequired▸ Show child attributes▾ Hide child attributes
idwhep_… identifier
urleventsstatus"active" · "disabled"
failure_countcreated_atsecretwhsec_… — present ONLY in the create response
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/webhooks \
-H "Authorization: Bearer ast_..."/webhookswriteRegister a webhook endpoint — the whsec_ secret appears only in this response
urlrequiredmax length 2048
eventsrequiredwebhookrequiredOutbound 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▾ Hide child attributes
idwhep_… identifier
urleventsstatus"active" · "disabled"
failure_countcreated_atsecretwhsec_… — present ONLY in the create response
{ "error": { "code", "message" } } — see the error table above.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"]}'/webhooks/{id}readWebhook endpoint detail
idrequiredThe webhook endpoint id (whep_…)
webhookrequiredOutbound 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▾ Hide child attributes
idwhep_… identifier
urleventsstatus"active" · "disabled"
failure_countcreated_atsecretwhsec_… — present ONLY in the create response
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/webhooks/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/webhooks/{id}writeUpdate url/events, or status:active to re-enable a disabled endpoint
idrequiredThe webhook endpoint id (whep_…)
urlmax length 2048
eventsstatus"active" · "disabled"
webhookrequiredOutbound 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▾ Hide child attributes
idwhep_… identifier
urleventsstatus"active" · "disabled"
failure_countcreated_atsecretwhsec_… — present ONLY in the create response
{ "error": { "code", "message" } } — see the error table above.curl -X PATCH https://agentsky.dev/webhooks/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/webhooks/{id}writeDelete a webhook endpoint
idrequiredThe webhook endpoint id (whep_…)
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/webhooks/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/channels/appsreadList BYO channel apps — credentials masked
appsrequired▸ Show child attributes▾ Hide child attributes
idplatform"telegram" · "slack" · "discord" · "whatsapp" · "imessage"
labelstatuscredential_keysKey names only — values are write-only
created_atsetupSteps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/channels/apps \
-H "Authorization: Bearer ast_..."/channels/appswriteRegister 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).
platformrequired"telegram" · "slack" · "discord" · "whatsapp" · "imessage"
labelrequiredmax length 120
credentialsrequiredWrite-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
idplatform"telegram" · "slack" · "discord" · "whatsapp" · "imessage"
labelstatuscredential_keysKey names only — values are write-only
created_atsetupSteps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)
{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/channels/apps \
-H "Authorization: Bearer ast_..."Channel app detail — credentials masked
idrequiredThe channel app id
idplatform"telegram" · "slack" · "discord" · "whatsapp" · "imessage"
labelstatuscredential_keysKey names only — values are write-only
created_atsetupSteps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/channels/apps/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/channels/apps/{id}writeRename or rotate credentials (rotation re-runs registration)
idrequiredThe channel app id
labelmax length 120
credentialsFull replacement bag; rotation re-runs the platform registration
idplatform"telegram" · "slack" · "discord" · "whatsapp" · "imessage"
labelstatuscredential_keysKey names only — values are write-only
created_atsetupSteps the platform cannot automate (per-app webhook_url / verify_token / events_url / invite_url)
{ "error": { "code", "message" } } — see the error table above.curl -X PATCH https://agentsky.dev/channels/apps/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."/channels/apps/{id}writeDelete the channel app
idrequiredThe channel app id
Deleted
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/channels/apps/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."List connections with their bound session
connectionsrequired▸ Show child attributes▾ Hide child attributes
idplatformchannel_idlabelstatus"PENDING" · "CONNECTED" · "DISCONNECTED"
bound_session▸ Show child attributes▾ Hide child attributes
idlabelcreated_atconnectPENDING only: the end-user ceremony (url, and for code flows phone + code)
▸ Show child attributes▾ Hide child attributes
urlphonecodeexpires_at{ "error": { "code", "message" } } — see the error table above.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.
platformrequired"telegram" · "slack" · "discord" · "whatsapp" · "imessage" · "loopback"
labelmax length 120
metadataEchoed on channel.connected and the callback redirect
destinationPre-bind: the claimed surface talks to this session
▸ Show child attributes▾ Hide child attributes
sessionappBYO ChannelApp id — the connect ceremony runs on your bot/number
invite_userSlack only: user id to invite into the created channel
callback_urlLink-flow platforms only: the hosted connect page redirects here after the claim with connection_id, status, and metadata query params
idplatformchannel_idlabelstatus"PENDING" · "CONNECTED" · "DISCONNECTED"
bound_session▸ Show child attributes▾ Hide child attributes
idlabelcreated_atconnectPENDING only: the end-user ceremony (url, and for code flows phone + code)
▸ Show child attributes▾ Hide child attributes
urlphonecodeexpires_at{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/channels/connections \
-H "Authorization: Bearer ast_..."Disconnect the surface
idrequiredThe connection id
Disconnected
{ "error": { "code", "message" } } — see the error table above.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)
idrequiredThe connection id
destinationrequiredExactly one of webhook (endpoint id) or session (session id)
▸ Show child attributes▾ Hide child attributes
webhooksessionconnection_idbinding_idsessionwebhook{ "error": { "code", "message" } } — see the error table above.curl -X PUT https://agentsky.dev/channels/connections/sess_cmtb7q2j/binding \
-H "Authorization: Bearer ast_..."Declared platform capabilities — branch on these instead of guessing
idrequiredThe connection id
connection_idplatformcapabilitiesthreads · reactions · markers · proactive · markdown · modals · ephemeral · streaming
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/channels/connections/sess_cmtb7q2j/capabilities \
-H "Authorization: Bearer ast_..."List bindings, optionally by connection
connection_idbindingsrequired▸ Show child attributes▾ Hide child attributes
idconnection_idthread_iddestinationExactly one of webhook (endpoint id) or session (session id)
▸ Show child attributes▾ Hide child attributes
webhooksessionis_defaultstatusroute_key{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/channels/bindings?connection_id= \
-H "Authorization: Bearer ast_..."/channels/bindingswriteRoute one thread of a connection to a session or your webhook
connection_idrequiredthread_idrequiredThe one thread this rule routes. Connection-level routing is a single slot — set it via PUT /connections/{id}/binding
destinationrequiredExactly one of webhook (endpoint id) or session (session id)
▸ Show child attributes▾ Hide child attributes
webhooksessionroute_keymax length 60
idconnection_idthread_iddestinationExactly one of webhook (endpoint id) or session (session id)
▸ Show child attributes▾ Hide child attributes
webhooksessionis_defaultstatusroute_key{ "error": { "code", "message" } } — see the error table above.curl -X POST https://agentsky.dev/channels/bindings \
-H "Authorization: Bearer ast_..."Delete the binding
idrequiredThe binding id
Deleted
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/channels/bindings/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."List webhook endpoints
webhooksrequired▸ Show child attributes▾ Hide child attributes
idurleventsstatussecretwhsec_ HMAC secret — returned on create only
{ "error": { "code", "message" } } — see the error table above.curl https://agentsky.dev/channels/webhooks \
-H "Authorization: Bearer ast_..."/channels/webhookswriteCreate 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.
urlrequiredhttps (http allowed for localhost only)
eventsDefault ["message.received"]
idurleventsstatussecretwhsec_ HMAC secret — returned on create only
{ "error": { "code", "message" } } — see the error table above.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
idrequiredThe webhook endpoint id
status"ACTIVE"
eventsidurleventsstatussecretwhsec_ HMAC secret — returned on create only
{ "error": { "code", "message" } } — see the error table above.curl -X PATCH https://agentsky.dev/channels/webhooks/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."Delete the webhook endpoint
idrequiredThe webhook endpoint id
Deleted
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/channels/webhooks/sess_cmtb7q2j \
-H "Authorization: Bearer ast_..."Add a reaction (platform-neutral emoji names)
idrequiredThe thread id
midrequiredemojirequiredReacted
{ "error": { "code", "message" } } — see the error table above.curl -X PUT https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages/mid/reactions/emoji \
-H "Authorization: Bearer ast_..."Remove a reaction
idrequiredThe thread id
midrequiredemojirequiredRemoved
{ "error": { "code", "message" } } — see the error table above.curl -X DELETE https://agentsky.dev/channels/threads/sess_cmtb7q2j/messages/mid/reactions/emoji \
-H "Authorization: Bearer ast_..."/channels/deliverieswriteProactive fan-out: post to every thread bound to a destination
destinationrequiredExactly one of webhook (endpoint id) or session (session id)
▸ Show child attributes▾ Hide child attributes
webhooksessionpartsrequired▸ Show child attributes▾ Hide child attributes
type: "text"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "markdown"▸ Show child attributes▾ Hide child attributes
typerequiredtextrequiredtype: "raw"▸ Show child attributes▾ Hide child attributes
typerequiredplatformrequiredpayloadrequiredPlatform-native payload, JSON-encoded
display_namemax length 80
OK — per-thread results
results▸ Show child attributes▾ Hide child attributes
thread_idstatus{ "error": { "code", "message" } } — see the error table above.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):
| event | payload | meaning |
|---|---|---|
user.message | content | history 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.message | content | history only and the POST echo — the per-turn system text sent alongside a user.message |
user.interrupt | by | an interrupt was accepted — echoed on the live stream and kept in history; the pod's session.status_idle follows |
agent.message | parts, text | a user-facing agent post; a turn may carry several |
agent.reasoning | part | raw engine event: thinking (live only) |
agent.tool_use | part | raw engine event: a tool invocation (live only) |
agent.tool_result | part | raw engine event: the tool's outcome (live only) |
agent.status | part | raw engine event: working / waiting / … (live only) |
session.status_running | — | a turn started |
session.status_idle | stop_reason | the 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.error | error | a 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_terminated | — | the session was archived; terminal — nothing follows; close the stream |
session.deleted | — | terminal — nothing follows; close the 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"}}
AgentSky