HTTP API reference

Exact request/response shapes for the AgentOS HTTP API. For when to use each, read the concepts first: Invoking hosted agents and Reporting runs.

  • Base URL: https://agentos-ai.dev
  • Auth: Authorization: Bearer <key>. Ingest and invoke accept an agent key (aos_agent_…, limited to its own agent) or a workspace key (aos_ws_…). See Authentication.
  • Envelope: every JSON response is { "data": …, "error": … }, with exactly one of the two set. Streaming invokes (stream: true) return text/event-stream instead.

Ingest API

Report runs your own code executes (non-hosted agents). Guide: Reporting runs.

Start a run

POST /api/ingest/v1/run/start
{
  "agent_id": "uuid",
  "trigger_type": "sdk",
  "input": { "query": "Hello" },
  "external_run_id": "optional-correlation-id",
  "parent_run_id": "uuid"
}
FieldTypeNotes
agent_iduuidRequired. An agent key must match its own agent.
trigger_type"manual" | "scheduled" | "webhook" | "sdk"Default "sdk".
inputobjectDefault {}.
external_run_idstringOptional, up to 128 characters. Idempotent: starting again with the same id returns the existing run.
parent_run_iduuidOptional. Links this run as a child of another run in the workspace.

Paused or archived agents return 403 FORBIDDEN.

Response

{ "data": { "run_id": "uuid" }, "error": null }

Emit events

POST /api/ingest/v1/events
{
  "run_id": "uuid",
  "events": [
    {
      "type": "step.completed",
      "level": "info",
      "payload": { "step": "fetch-data", "rows": 42 },
      "occurred_at": "2026-05-11T20:00:00.000Z"
    }
  ]
}

Send 1 to 500 events per request. level is "debug" | "info" | "warn" | "error" (default "info"). See Events.

To make an event a node in the run's trace tree, add span fields: span_id, parent_span_id, kind, started_at, ended_at and duration_ms (derived from the timestamps when omitted). See Tracing & spans.

Response (HTTP 202)

{ "data": { "accepted": 1, "run_id": "uuid" }, "error": null }

Complete a run

POST /api/ingest/v1/run/complete
{
  "run_id": "uuid",
  "output": { "result": "Done" },
  "input_tokens": 1200,
  "output_tokens": 350,
  "cache_read_tokens": 0,
  "cache_creation_tokens": 0
}

Token counts are optional and feed the cost views.

Fail a run

POST /api/ingest/v1/run/fail
{
  "run_id": "uuid",
  "error_message": "Something went wrong",
  "error_detail": { "step": "fetch" }
}

Cancel a run

POST /api/ingest/v1/run/cancel
{ "run_id": "uuid", "reason": "User aborted" }

reason is optional. Cancelling also cancels any pending human input request on the run.

Response (complete, fail and cancel)

{ "data": { "run_id": "uuid", "duration_ms": 5000 }, "error": null }

Repeating the same call on a finished run is safe and returns the same shape. Closing a run that already ended with a different status returns 409 CONFLICT.

Create / update a task

POST /api/ingest/v1/tasks
{
  "run_id": "uuid",
  "task": {
    "id": "uuid",
    "name": "parse-pdf",
    "status": "running",
    "input": { "file": "report.pdf" }
  }
}

status: "pending" | "running" | "completed" | "failed" | "skipped". Call again with the same id and a terminal status (plus output or error_message) to update. See Tasks.

Response

{ "data": { "task_id": "uuid" }, "error": null }

Ask a human

POST /api/ingest/v1/human-input/request
{
  "run_id": "uuid",
  "prompt": "Approve the refund for order #1234?",
  "context": { "amount": 120 },
  "timeout_seconds": 3600
}

A long poll: the request waits for someone to answer in the dashboard. timeout_seconds is 30 to 86400 (default 3600).

StatusBodyMeaning
200{ "input": …, "request_id": "uuid" }Answered.
202{ "request_id": "uuid", "status": "pending" }Still waiting after about 4.5 minutes. Call again with the same body plus request_id to keep waiting.
408TIMEOUTNo answer before timeout_seconds.
409CONFLICTThe request or run was cancelled.

The SDKs handle the retry for you.

Send OpenTelemetry traces

POST /api/ingest/v1/traces

Accepts OTLP/JSON trace exports, up to 1000 spans per request. Each trace becomes a run. With a workspace key, set the agentos.agent_id resource attribute. Returns 202 with { "accepted": <spans>, "runs": <runs> }. See Tracing & spans.


Invoke API

Ask AgentOS to run a hosted agent and return its output. Guide: Invoking hosted agents.

Invoke a hosted agent

POST /api/v1/agents/:agentId/invoke

Requires a workspace key or an agent key for that agent. Only works on hosted agents.

{
  "input": { "query": "Summarise this" },
  "prompt_variables": { "SHEET_ID": "1pjdT1FADq-..." },
  "session_id": "uuid",
  "stream": false,
  "parent_run_id": "uuid"
}
FieldTypeNotes
inputobjectDefaults to {}.
prompt_variables{ KEY: string }Optional; fills {{KEY}} placeholders. Prompt variables.
session_id / start_sessionuuid / boolServer-managed conversation memory. Memory.
external_user_idstringYour id for the session's end user; only with session_id or start_session.
historyarrayClient-managed history, up to 50 { role, content } turns.
parent_run_iduuidLink as a child run (agent-to-agent).
streambooleanReturn a text/event-stream instead of JSON.
testbooleanSandboxed test run: tools do not act, and the run is left out of metrics and alerts. Allowed on paused agents.

session_id, start_session and history are mutually exclusive.

Response: completed

{ "data": { "run_id": "uuid", "output": { "summary": "…" }, "duration_ms": 4200, "session_id": "uuid" }, "error": null }

session_id is present only when the call used a session.

Response: paused (HTTP 202)

{ "data": { "run_id": "uuid", "awaiting_approval": { "approval_id": "uuid" }, "output": null, "duration_ms": 1800 }, "error": null }
{ "data": { "run_id": "uuid", "awaiting_input": { "request_id": "uuid", "question": "…", "options": ["…"] }, "output": null, "duration_ms": 1800 }, "error": null }

awaiting_input.question is always present; context and options only when the agent provided them.

Streaming

With stream: true the response is text/event-stream. Each frame is data: <json>, where the JSON has a type:

typeFieldsWhen
startrun_idThe run was created.
chunktextOutput text. Not sent for agents with an output schema.
toolname, status (calling | returned | failed)A tool call started or finished.
donerun_id, duration_ms, session_id?Terminal: the run finished.
awaiting_approvalrun_id, duration_ms, approval_id, session_id?Terminal: paused for approval.
awaiting_inputrun_id, duration_ms, request_id, question, context?, options?, session_id?Terminal: paused for human input.
errormessage, codeTerminal: the run failed.

See Invoking hosted agents.

Answer a paused run

When an invoke returns awaiting_input, send the answer to resume the run. Both endpoints require a workspace key.

POST /api/v1/runs/:runId/reply
{ "request_id": "uuid", "response": "Yes, go ahead." }
POST /api/v1/runs/:runId/human-input
{ "response": "Yes, go ahead." }

/human-input finds the pending request for you. response is up to 10,000 characters. Both return the same shapes as invoke: 200 when the run completes, or 202 if it pauses again. /reply returns 409 CONFLICT if the request was already answered.


Control plane

POST /api/v1/rpc/:method

Every MCP tool (agents_list, runs_invoke, alerts_create, …) as plain JSON over HTTP. The body is the tool's arguments; the response is { data, error }. Requires a workspace or personal key; with a personal key, include "workspace": "<slug or id>" in the body. Unknown methods return 404 UNKNOWN_METHOD. Full catalog: Control plane.

curl -X POST https://agentos-ai.dev/api/v1/rpc/agents_list \
  -H "Authorization: Bearer aos_ws_..." \
  -H "Content-Type: application/json" \
  -d '{ "status": "active" }'

Rate limits

Limits apply per workspace, per 60-second window. Run starts and invokes count against runs; each event or span counts against events.

PlanRuns / minEvents / min
Solo2001,200
Operations2001,200
Evolution4002,400
Enterprise1,0006,000

Over the limit, the API returns 429 RATE_LIMITED with a Retry-After header (seconds). A workspace with no plan gets 402 NO_PLAN.


Error responses

{ "data": null, "error": { "code": "UNAUTHENTICATED", "message": "Invalid or revoked key." } }
CodeHTTPMeaning
VALIDATION_ERROR400Bad request payload, or invoking a non-hosted agent
UNAUTHENTICATED401Missing, invalid, revoked or expired key
NO_PLAN402The workspace has no plan
FORBIDDEN403Key scoped to a different agent or not allowed on this endpoint; agent archived; run started on a paused agent
AGENT_PAUSED403Invoking a paused agent (use test: true for a test run)
WORKSPACE_SUSPENDED403The workspace is suspended
NOT_FOUND404Agent, run or session not found
TIMEOUT408A human input request timed out
CONFLICT409Run already ended with a different status, or request already answered
RATE_LIMITED429Too many requests; see Retry-After
INTERNAL_ERROR500Unexpected server error

Invoke, reply and human-input return 400 with one of these codes when the hosted run itself fails:

CodeMeaning
INVALID_AGENTThe agent or run can't be run or resumed as asked (for example, no system prompt, or the request was already answered)
LLM_ERRORThe model provider returned an error
OUTPUT_PARSE_ERRORThe output did not match the agent's output schema
MAX_ITERATIONSThe agent hit its iteration limit
OUTPUT_TRUNCATEDThe model hit the agent's max tokens before finishing
CANCELLEDThe run was cancelled