API reference

One origin, one namespace

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

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

Authentication

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

Errors

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

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

Identity

GET/whoamiread

Caller identity, resolved universe, effective scopes

Response · 200

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

"read" · "write" · "admin"

authenum<string>required

"token" · "session"

Response · 4xx

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

Universes

GET/universesread

List universes

Response · 200

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

ISO 8601

Response · 4xx

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

Create a universe

Body · application/json

slugstringrequired

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

namestring

max length 80

Response · 201

universeobjectrequired
▸ Show child attributes
slugstring
namestring
isPersonalboolean
createdAtstring

ISO 8601

Response · 4xx

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

Universe detail

Path parameters

slugstringrequired

The universe slug

Response · 200

universeobjectrequired
▸ Show child attributes
slugstring
namestring
isPersonalboolean
createdAtstring

ISO 8601

Response · 4xx

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

Agents

GET/agentsread

List agents in the resolved universe

Response · 200

agentsobject[]required
▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring

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

llmstring
harnessVersionstring | null

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

reasoningEffortstring | null

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

capabilitiesenum<string>[]

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

versioninteger

Bumped on every update; see expectedVersion

archivedboolean
sessionCountinteger
createdAtstring

ISO 8601

Response · 4xx

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

Create an agent

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

Body · application/json

namestring

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

descriptionstring

max length 500

agentTypeenum<string>

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

llmstring
reasoningEffortenum<string>

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

promptstring

max length 100000

displayNamestring

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

capabilitiesenum<string>[]

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

instructionsobject[]
▸ Show child attributes
namestringrequired

pattern .*\.md$

contentstring

default: ""

skillsobject[]

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

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

default: "latest"

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

Branch or commit SHA; default branch when omitted.

tokenSecretRefstring

Agent secret key holding a clone token for private repos.

mcpServersobject[]

Remote streamable-HTTP MCP servers this agent connects to.

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

customDataobject[]
▸ Show child attributes
idstringrequired
namestringrequired

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

kindenum<string>required

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

scopeenum<string>

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

descriptionstring
uristring
configobject

default: {}

metadataobject

Response · 201

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

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

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

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

mcpServersobject[]

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

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

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

Agent detail

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

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

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

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

mcpServersobject[]

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

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

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

Update displayName / capabilities / metadata

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

Path parameters

idstringrequired

The agent id (agent_…)

Body · application/json

displayNamestring

max length 60

capabilitiesenum<string>[]

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

metadataobject
harnessVersionstring
reasoningEffortobject

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

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

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

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

default: "latest"

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

Branch or commit SHA; default branch when omitted.

tokenSecretRefstring

Agent secret key holding a clone token for private repos.

mcpServersobject[]

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

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

expectedVersioninteger

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

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

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

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

mcpServersobject[]

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

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

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

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

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

oktruerequired

Response · 4xx

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

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

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

agentobjectrequired

Everything in the list item, plus configuration state.

▸ Show child attributes
idstring

The agent id (agent_…) — the only address

namestring
displayNamestring
agentTypestring
llmstring
harnessVersionstring | null
reasoningEffortstring | null

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

versioninteger
archivedboolean
sessionCountinteger
createdAtstring
descriptionstring | null
promptstring | null

The user prompt layer

promptVersioninteger | null
capabilitiesenum<string>[]

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

mcpServersobject[]

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

▸ Show child attributes
type"url"

default: "url"

namestringrequired

max length 255

urlstringrequired
toolsobject
▸ Show child attributes
includestring[]

default: []

excludestring[]

default: []

metadataobject

Your key-merged client metadata

defaultSessionIdstring | null

The session conversation verbs target when addressed by agent id

universestring

Resolved universe slug

Response · 4xx

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

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

Path parameters

idstringrequired

The agent id (agent_…)

Body · application/json

promptstringrequired

max length 100000

Response · 200

versioninteger
unchangedboolean

Content identical to the active version

Response · 4xx

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

Prompt version history

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

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

Response · 4xx

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

Declared secret keys + set/unset — never values

Path parameters

idstringrequired

The agent id (agent_…)

Response · 200

secretsobject[]required
▸ Show child attributes
keystring
descriptionstring

Response · 4xx

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

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

Path parameters

idstringrequired

The agent id (agent_…)

keystringrequired

Body · application/json

valuestringrequired

max length 10000

descriptionstring

max length 500

Response · 200

oktruerequired

Response · 4xx

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

Unset a secret

Path parameters

idstringrequired

The agent id (agent_…)

keystringrequired

Response · 200

oktruerequired

Response · 4xx

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

Skills

GET/skillsread

List skills in the resolved universe

Query parameters

cursorstring
limitinteger

Response · 200

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

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired
nextCursorstring | null

Response · 4xx

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

Create a skill (uploads revision 1)

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

Response · 201

skillobjectrequired
▸ Show child attributes
idstringrequired
displayNamestringrequired
latestRevisionIdstring | nullrequired

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired
revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

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

Response · 4xx

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

Skill detail

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

skillobjectrequired
▸ Show child attributes
idstringrequired
displayNamestringrequired
latestRevisionIdstring | nullrequired

What `latest` references resolve to.

createdAtstringrequired
updatedAtstringrequired

Response · 4xx

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

Delete a skill and all its revisions

409 skill_in_use while any agent references the skill.

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

Response · 4xx

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

List a skill's revisions, newest first

Path parameters

skillIdstringrequired

The skill id (skill_…)

Response · 200

revisionsobject[]required
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

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

Response · 4xx

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

Create a revision — a complete snapshot

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

Response · 201

revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

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

Response · 4xx

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

Skill revision detail (metadata + file manifest)

Path parameters

skillIdstringrequired

The skill id (skill_…)

revisionIdstringrequired

The skill revision id (skr_…)

Response · 200

revisionobjectrequired
▸ Show child attributes
idstringrequired
skillIdstringrequired
namestringrequired

Frontmatter name — the skill's identity name.

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

Response · 4xx

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

Delete one revision

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

Path parameters

skillIdstringrequired

The skill id (skill_…)

revisionIdstringrequired

The skill revision id (skr_…)

Response · 200

Response · 4xx

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

Files

POST/fileswrite

Upload a file — universe-scoped, write-once

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

Response · 200

typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

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

expires_atstring | nullrequired

Response · 4xx

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

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

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

Query parameters

limitinteger
pagestring

A next_page cursor

ids[]array
scope_idstring

sess_…

Response · 200

dataobject[]required

Newest first

▸ Show child attributes
typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

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

expires_atstring | nullrequired
next_pagestring | nullrequired

Pass back as ?page= for the next page

Response · 4xx

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

File metadata

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

typeenum<string>required

"file"

idstringrequired

file_…

created_atstringrequired
filenamestringrequired
mime_typestringrequired
size_bytesintegerrequired
downloadablebooleanrequired

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

expires_atstring | nullrequired

Response · 4xx

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

Delete a file

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

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

typeenum<string>required

"file_deleted"

idstringrequired

Response · 4xx

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

Download a file's bytes

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

Path parameters

file_idstringrequired

The file id (file_…)

Response · 200

The bytes, with content-type and content-disposition

Response · 4xx

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

Sessions

GET/sessionsread

List sessions; ?agent= filters to one spec

Query parameters

agentstring

The agent id (agent_…)

Response · 200

sessionsobject[]required
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

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

agentTypestring
llmstring

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

reasoningEffortstring | null

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

modelBillingenum<string>

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

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

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

resourcesobject[]

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

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

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

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

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

Body · application/json

agentstringrequired
llmstring

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

reasoningEffortobject

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

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

max length 120

metadataobject
instructionsobject[]
▸ Show child attributes
namestringrequired

pattern .*\.md$

contentstring

default: ""

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

default: "text/plain"

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

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

budgetobject

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

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

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

currency"USD"required
resourcesobject[]

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

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

max length 128

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

max length 2048

authorization_tokenstring

max length 1024

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

max length 255

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

max length 64

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

Response · 201

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

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

agentTypestring
llmstring

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

reasoningEffortstring | null

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

modelBillingenum<string>

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

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

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

resourcesobject[]

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

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

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

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

Path parameters

idstringrequired

The session id

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

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

agentTypestring
llmstring

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

reasoningEffortstring | null

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

modelBillingenum<string>

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

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

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

resourcesobject[]

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

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

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

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

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

Path parameters

idstringrequired

The session id

Body · application/json

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

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

reasoningEffortobject

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

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

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

budgetobject

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

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

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

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

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

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

agentTypestring
llmstring

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

reasoningEffortstring | null

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

modelBillingenum<string>

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

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

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

resourcesobject[]

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

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

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

Permanently delete the session, its events, and its pod

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

Path parameters

idstringrequired

The session id

Response · 200

oktruerequired

Response · 4xx

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

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

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

Path parameters

idstringrequired

The session id

Response · 200

sessionobjectrequired
▸ Show child attributes
idstring

sess_… identifier

agentIdstring | null

The agent id (agent_…)

titlestring | null
statusenum<string>

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

agentTypestring
llmstring

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

reasoningEffortstring | null

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

modelBillingenum<string>

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

defaultboolean

Is this the agent's default session

metadataobject
budgetobject | null

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

resourcesobject[]

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

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
createdAtstring

ISO 8601

Response · 4xx

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

List the session's resources, oldest first

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

Path parameters

idstringrequired

The session id (sess_…)

Query parameters

limitinteger
pagestring

A next_page cursor

Response · 200

dataobject[]required

Oldest first

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired
next_pagestring | nullrequired

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

Response · 4xx

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

Add a file to a running session

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

Path parameters

idstringrequired

The session id (sess_…)

Body · application/json

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

max length 128

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

max length 2048

authorization_tokenstring

max length 1024

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

max length 255

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

max length 64

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

Response · 200

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

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

One resource

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Response · 200

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

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

Rotate a repository's token

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

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Body · application/json

authorization_tokenstringrequired

max length 1024

Response · 200

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

"file"

idstringrequired

sesrsc_…

file_idstringrequired

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

mount_pathstringrequired

Absolute, under /workspace

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

"github_repository"

idstringrequired

sesrsc_…

urlstringrequired

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

mount_pathstringrequired

Absolute, under /workspace; the clone's root

checkoutobject

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

▸ Show child attributes
typeenum<string>

"branch" · "commit"

namestring
shastring
created_atstringrequired
updated_atstringrequired

Response · 4xx

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

Remove a file from the session

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

Path parameters

idstringrequired

The session id (sess_…)

ridstringrequired

The resource id (sesrsc_…)

Response · 200

typeenum<string>required

"session_resource_deleted"

idstringrequired

Response · 4xx

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

Conversation

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

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

Path parameters

idstringrequired

The session id

Body · application/json

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

default: ""

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

default: ""

redactedboolean

default: false

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

default: {}

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

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

resultobject

default: {}

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

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

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

default: false

Response · 202

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

Response · 4xx

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

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

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

Path parameters

idstringrequired

The session id

Body · application/json

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

default: "text/plain"

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

Response · 200

OK — one echo per event, in order

dataobject[]required

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

▸ Show child attributes
idstringrequired

Stable event id — the dedupe key across stream ∪ events

typestringrequired

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

sessionIdstringrequired
agentIdstring | null

The agent id (agent_…)

atstring

ISO 8601

messageIdstring

agent.message

partsobject[]

agent.message

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

default: ""

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

default: ""

redactedboolean

default: false

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

default: {}

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

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

resultobject

default: {}

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

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

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

default: false

textstring

agent.message — parts flattened to plain text

contentobject[]

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

partobject

reasoning / tool_use / tool_result / status events

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

default: ""

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

default: ""

redactedboolean

default: false

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

default: {}

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

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

resultobject

default: {}

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

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

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

default: false

stop_reasonobject

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

▸ Show child attributes
typestring

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

errorobject

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

▸ Show child attributes
typestring

e.g. "pod_unavailable"

messagestring
retry_statusstring

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

bystring

user.interrupt — who requested the interrupt

Response · 4xx

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

The event history — the same event objects the stream delivers

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

Path parameters

idstringrequired

The session id

Query parameters

cursorstring
limitinteger
types[]array

Response · 200

eventsobject[]required

Oldest-first

▸ Show child attributes
idstringrequired

Stable event id — the dedupe key across stream ∪ events

typestringrequired

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

sessionIdstringrequired
agentIdstring | null

The agent id (agent_…)

atstring

ISO 8601

messageIdstring

agent.message

partsobject[]

agent.message

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

default: ""

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

default: ""

redactedboolean

default: false

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

default: {}

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

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

resultobject

default: {}

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

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

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

default: false

textstring

agent.message — parts flattened to plain text

contentobject[]

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

partobject

reasoning / tool_use / tool_result / status events

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

default: ""

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

default: ""

redactedboolean

default: false

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

default: {}

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

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

resultobject

default: {}

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

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

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

default: false

stop_reasonobject

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

▸ Show child attributes
typestring

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

errorobject

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

▸ Show child attributes
typestring

e.g. "pod_unavailable"

messagestring
retry_statusstring

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

bystring

user.interrupt — who requested the interrupt

cursorstring | nullrequired

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

hasMorebooleanrequired

Response · 4xx

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

The standing event stream (SSE)

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

Path parameters

idstringrequired

The session id

Response · 200

SSE stream

Response · 4xx

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

Abort the in-flight turn

Path parameters

idstringrequired

The session id

Response · 200

statusenum<string>required

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

Response · 4xx

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

Post into a thread — markdown renders natively per platform

Path parameters

idstringrequired

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

Body · application/json

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

Platform-native payload, JSON-encoded

display_namestring

max length 80

doneboolean

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

Response · 201

message_idstring
thread_idstring

Response · 4xx

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

SSE mirror of your webhook events — for local development

Response · 200

SSE stream

Response · 4xx

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

Routines

GET/routinesread

List routines

Query parameters

cursorstring
limitinteger

1–500, default 50

Response · 200

itemsobject[]required
▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring
cursorstring | null
hasMoreboolean

Response · 4xx

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

Create a routine — scheduled agent execution

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

Body · application/json

namestringrequired

max length 256

descriptionstring

max length 2048

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

default: "text/plain"

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

max length 256

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

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

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

Response · 201

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

Routine detail

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

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

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

Path parameters

idstringrequired

The routine id (rtn_…)

Body · application/json

namestring

max length 256

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

default: "text/plain"

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

max length 256

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

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

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

Response · 200

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

Pause — suppress scheduled fires; manual runs still work

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

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

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

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

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 200

routineobjectrequired

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

▸ Show child attributes
idstring

rtn_… identifier

namestring
descriptionstring | null
metadataobject
targetobject

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

initial_eventsobject[]
scheduleobject | null

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

budgetobject | null

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

statusenum<string>

"active" · "paused"

paused_reasonobject | null

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

archived_atstring | null
created_atstring
updated_atstring

Response · 4xx

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

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

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

Path parameters

idstringrequired

The routine id (rtn_…)

Response · 201

runobjectrequired

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

▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

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

session_idstring | null
errorobject | null

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

agentobject

Resolved agent reference at fire time

created_atstring

Response · 4xx

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

List routine runs — every fire attempt

Query parameters

routinestring

Filter to one routine (rtn_…)

has_errorboolean

true = failed runs, false = runs with a session

trigger_typestring
created_at[gte]string

Also gt / lt / lte

cursorstring
limitinteger

Response · 200

itemsobject[]required
▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

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

session_idstring | null
errorobject | null

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

agentobject

Resolved agent reference at fire time

created_atstring
cursorstring | null
hasMoreboolean

Response · 4xx

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

Routine run detail

Path parameters

idstringrequired

The run id (rrun_…)

Response · 200

runobjectrequired

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

▸ Show child attributes
idstring

rrun_… identifier

routine_idstring
trigger_contextobject

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

session_idstring | null
errorobject | null

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

agentobject

Resolved agent reference at fire time

created_atstring

Response · 4xx

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

Webhooks

List connected model subscriptions — metadata only, never credentials

Response · 200

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

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

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

Connect or replace a subscription credential (write-only)

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

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Body · application/json

credentialstringrequired

max length 100000

labelstring

max length 60

Response · 200

modelSubscriptionobjectrequired

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

▸ Show child attributes
providerenum<string>

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

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

Update useForNewAgents / label

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Body · application/json

useForNewAgentsboolean
labelstring

max length 60

Response · 200

modelSubscriptionobjectrequired

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

▸ Show child attributes
providerenum<string>

"anthropic" · "openai"

labelstring
statusenum<string>

"connected" · "needs_reconnect"

expiresAtstring | null
lastUsedAtstring | null
useForNewAgentsboolean
createdAtstring
agentsobject[]

Agents in this universe running on the subscription

▸ Show child attributes
idstring
agentIdstring | null
namestring

Response · 4xx

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

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

Path parameters

providerstringrequired

anthropic = Claude subscription · openai = ChatGPT plan

Response · 200

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

Response · 4xx

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

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

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

Path parameters

idstringrequired

The session id

Body · application/json

rotateboolean

default: false

Response · 200

shareUrlstringrequired

Response · 4xx

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

Turn sharing off — the link stops working immediately

Path parameters

idstringrequired

The session id

Response · 200

oktruerequired

Response · 4xx

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

List webhook endpoints

Response · 200

webhooksobject[]required
▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

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

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

Body · application/json

urlstringrequired

max length 2048

eventsstring[]required

Response · 201

webhookobjectrequired

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

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

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

Webhook endpoint detail

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Response · 200

webhookobjectrequired

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

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

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

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

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Body · application/json

urlstring

max length 2048

eventsstring[]
statusenum<string>

"active" · "disabled"

Response · 200

webhookobjectrequired

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

▸ Show child attributes
idstring

whep_… identifier

urlstring
eventsstring[]
statusenum<string>

"active" · "disabled"

failure_countinteger
created_atstring
secretstring

whsec_… — present ONLY in the create response

Response · 4xx

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

Delete a webhook endpoint

Path parameters

idstringrequired

The webhook endpoint id (whep_…)

Response · 200

Response · 4xx

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

List BYO channel apps — credentials masked

Response · 200

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

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

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

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

Response · 4xx

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

Register your own bot/number as a channel app

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

Body · application/json

platformenum<string>required

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

labelstringrequired

max length 120

credentialsobjectrequired

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

Response · 201

idstring
platformenum<string>

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

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

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

Response · 4xx

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

Channel app detail — credentials masked

Path parameters

idstringrequired

The channel app id

Response · 200

idstring
platformenum<string>

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

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

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

Response · 4xx

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

Rename or rotate credentials (rotation re-runs registration)

Path parameters

idstringrequired

The channel app id

Body · application/json

labelstring

max length 120

credentialsobject

Full replacement bag; rotation re-runs the platform registration

Response · 200

idstring
platformenum<string>

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

labelstring
statusstring
credential_keysstring[]

Key names only — values are write-only

created_atstring
setupobject

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

Response · 4xx

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

Delete the channel app

Path parameters

idstringrequired

The channel app id

Response · 204

Deleted

Response · 4xx

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

List connections with their bound session

Response · 200

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

"PENDING" · "CONNECTED" · "DISCONNECTED"

bound_sessionobject
▸ Show child attributes
idstring
labelstring
created_atstring
connectobject

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

▸ Show child attributes
urlstring
phonestring
codestring
expires_atstring

Response · 4xx

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

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

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

Body · application/json

platformenum<string>required

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

labelstring

max length 120

metadataobject

Echoed on channel.connected and the callback redirect

destinationobject

Pre-bind: the claimed surface talks to this session

▸ Show child attributes
sessionstring
appstring

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

invite_userstring

Slack only: user id to invite into the created channel

callback_urlstring

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

Response · 201

idstring
platformstring
channel_idstring
labelstring
statusenum<string>

"PENDING" · "CONNECTED" · "DISCONNECTED"

bound_sessionobject
▸ Show child attributes
idstring
labelstring
created_atstring
connectobject

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

▸ Show child attributes
urlstring
phonestring
codestring
expires_atstring

Response · 4xx

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

Disconnect the surface

Path parameters

idstringrequired

The connection id

Response · 204

Disconnected

Response · 4xx

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

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

Path parameters

idstringrequired

The connection id

Body · application/json

destinationobjectrequired

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

▸ Show child attributes
webhookstring
sessionstring

Response · 200

connection_idstring
binding_idstring
sessionstring
webhookstring

Response · 4xx

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

Declared platform capabilities — branch on these instead of guessing

Path parameters

idstringrequired

The connection id

Response · 200

connection_idstring
platformstring
capabilitiesobject

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

Response · 4xx

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

List bindings, optionally by connection

Query parameters

connection_idstring

Response · 200

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

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

▸ Show child attributes
webhookstring
sessionstring
is_defaultboolean
statusstring
route_keystring

Response · 4xx

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

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

Body · application/json

connection_idstringrequired
thread_idstringrequired

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

destinationobjectrequired

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

▸ Show child attributes
webhookstring
sessionstring
route_keystring

max length 60

Response · 201

idstring
connection_idstring
thread_idstring
destinationobject

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

▸ Show child attributes
webhookstring
sessionstring
is_defaultboolean
statusstring
route_keystring

Response · 4xx

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

Delete the binding

Path parameters

idstringrequired

The binding id

Response · 204

Deleted

Response · 4xx

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

List webhook endpoints

Response · 200

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

whsec_ HMAC secret — returned on create only

Response · 4xx

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

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

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

Body · application/json

urlstringrequired

https (http allowed for localhost only)

eventsstring[]

Default ["message.received"]

Response · 201

idstring
urlstring
eventsstring[]
statusstring
secretstring

whsec_ HMAC secret — returned on create only

Response · 4xx

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

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

Path parameters

idstringrequired

The webhook endpoint id

Body · application/json

statusenum<string>

"ACTIVE"

eventsstring[]

Response · 200

idstring
urlstring
eventsstring[]
statusstring
secretstring

whsec_ HMAC secret — returned on create only

Response · 4xx

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

Delete the webhook endpoint

Path parameters

idstringrequired

The webhook endpoint id

Response · 204

Deleted

Response · 4xx

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

Add a reaction (platform-neutral emoji names)

Path parameters

idstringrequired

The thread id

midstringrequired
emojistringrequired

Response · 204

Reacted

Response · 4xx

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

Remove a reaction

Path parameters

idstringrequired

The thread id

midstringrequired
emojistringrequired

Response · 204

Removed

Response · 4xx

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

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

Body · application/json

destinationobjectrequired

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

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

Platform-native payload, JSON-encoded

display_namestring

max length 80

Response · 200

OK — per-thread results

resultsobject[]
▸ Show child attributes
thread_idstring
statusstring

Response · 4xx

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

Stream events

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

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

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