Invoking hosted agents

Invoking means asking AgentOS to run a hosted agent and return its output. AgentOS handles the LLM calls, tool routing, and execution; you supply an input and consume the result.

This page is about hosted agents. If your own code runs the agent and you only report what happened, that's the opposite flow. See Reporting runs.


The invoke flow

your call ──▶ run created (status: running)
                │
                ├─ LLM ⇄ tool loop  (each tool call logged as an event)
                │
                ├─ pauses?  ──▶ awaiting_approval  /  awaiting_input  /  awaiting_child   (HTTP 202)
                │                     └─ you approve / answer, or the child ends ─▶ resumes
                │
                └─ done  ──▶ status: completed,  { output }

A run can finish in one request, or pause mid-flight if the agent calls an approval-gated tool (see Approvals) or asks a person a question (the ask_human tool), or when a script it calls as a tool pauses (see Scripts as tools). A paused invoke returns 202 with the run id; you resume it by approving or answering, and the agent continues. See Paused runs.


Ways to invoke

A hosted agent can be triggered from several surfaces. The run's trigger_type records where it came from:

SurfaceHowtrigger_type
Dashboardthe Run/Test panel on the agent's Configuration tab, or Chatmanual
Schedulea cron schedule (Scheduling)scheduled
HTTP / SDKPOST /api/v1/agents/:id/invoke, client.invoke(), or client.invokeStream()sdk
Agent → agentthe invoke_agent tool; pipelines invoke their orchestrator, which runs sub-agents this wayagent
MCPruns_invoke in the AgentOS MCP server or control planesdk

trigger_type is read-only: it's recorded on the run, and callers don't pass it on the invoke endpoint.

The rest of this page covers the HTTP / SDK path.


Basic invoke

import { AgentOS } from "@agentos-sdk/core";

const client = new AgentOS({ agentId: "<agentId>", apiKey: "aos_ws_…" });

const result = await client.invoke({ query: "Summarise the Q1 report" });
if (result.status === "completed") console.log(result.output);

Authenticate with a workspace key (aos_ws_…) or an agent key scoped to that agent. See Authentication.

Response

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

The SDK result has status (completed, awaiting_approval, awaiting_input, or awaiting_child), output (null while the run is paused), runId, durationMs, and sessionId. When a session is in use, the response also includes session_id.

The server allows a run up to 300 seconds per request. The SDK's client timeout defaults to 310 seconds (timeoutMs in TypeScript, timeout_seconds in Python).


Options

FieldTypePurpose
inputobjectThe data the agent operates on. Defaults to {}.
prompt_variables{ KEY: string }Fill {{KEY}} placeholders in the system prompt. Overrides schedule and config values. See Prompt variables.
session_iduuidContinue a server-managed conversation; AgentOS loads and saves history. An unknown id returns 404. See Memory.
start_sessionbooleanBegin a new server-managed session; the response returns the new session_id.
external_user_idstring, 1 to 200 charsYour own id for the end user a session belongs to. Only valid with session_id or start_session.
historyarray, up to 50 turnsClient-managed history ({ role, content }) instead of a session.
parent_run_iduuidLink this run as a child of another run, shown as a tree in the dashboard.
testbooleanRun as a sandboxed test run: write tools return a stub instead of acting, read tools run for real, and the run is kept out of metrics and alerts. Allowed on paused agents.
streambooleanStream text and tool events as they happen (see below).

session_id, start_session, and history are mutually exclusive. The SDKs take the same options in camelCase (TypeScript) or snake_case (Python).


Streaming

Pass stream: true to receive a text/event-stream of progressive events instead of a buffered JSON body, useful for chat UIs. In the SDK, use client.invokeStream() (Python: invoke_stream()), which yields the same events.

for await (const event of client.invokeStream({ query: "…" })) {
  if (event.type === "chunk") process.stdout.write(event.text);
}
FrameFields
startrun_id
chunktext
toolname, status (calling, returned, or failed)
donerun_id, duration_ms, session_id when a session is in use
awaiting_approvalrun_id, duration_ms, approval_id, session_id
awaiting_inputrun_id, duration_ms, request_id, question, optional context and options, session_id
awaiting_childrun_id, duration_ms, child_run_ids, session_id
errormessage, code

The stream ends after one terminal frame: done, awaiting_approval, awaiting_input, awaiting_child, or error. Agents with an output_schema can stream too, but they send no chunk frames: the structured output isn't valid until it's complete.


Paused runs

If the agent calls an approval-gated tool or ask_human, or a script it calls as a tool pauses, the buffered invoke returns HTTP 202 with the run id and no output yet:

{ "data": { "run_id": "uuid", "awaiting_approval": { "approval_id": "uuid" }, "output": null, "duration_ms": 1830 }, "error": null }
{
  "data": {
    "run_id": "uuid",
    "awaiting_input": {
      "request_id": "uuid",
      "question": "Which account should I charge?",
      "options": ["Account A", "Account B"]
    },
    "output": null,
    "duration_ms": 1830
  },
  "error": null
}

question is always present (show it to your user); context and options appear only when the agent provided them.

{ "data": { "run_id": "uuid", "awaiting_child": { "run_ids": ["uuid"] }, "output": null, "duration_ms": 1830 }, "error": null }

awaiting_child lists the child runs that paused (a script waiting on an approval, say). The SDK result carries them as childRunIds (TypeScript) or child_run_ids (Python).

To resume:

  • Human input: answer from the run page, or call POST /api/v1/runs/:id/reply with { "request_id": "…", "response": "…" } (SDK: client.reply(runId, response, { requestId })). This needs a workspace key and returns the continued run's result, which may pause again.
  • Approval: decide it on the Approvals page, or with approvals_decide in the control plane.
  • Child run: nothing to do on this run. Resolve what the child is waiting for (an approval on the child run, say); the run continues on its own once every child has ended.

To stop a run instead, cancel it from the dashboard or with runs_cancel in the control plane.


Errors

Same envelope as the rest of the HTTP API:

CodeHTTPMeaning
UNAUTHENTICATED401Missing, invalid, or revoked key
VALIDATION_ERROR400Bad body, or the agent isn't hosted
FORBIDDEN403Key scoped to a different agent, or the agent is archived
AGENT_PAUSED403The agent is paused. Activate it, or pass test: true
WORKSPACE_SUSPENDED403The workspace is suspended
NOT_FOUND404Agent, parent_run_id, or session_id not found
NO_PLAN402The workspace has no active plan. Choose one in Backoffice → Billing
RATE_LIMITED429Over your plan's per-minute run limit. Wait for the Retry-After header

If the run itself fails, the response is 400 with one of these codes:

CodeMeaning
INVALID_AGENTThe agent can't run as configured (for example, it has no system prompt)
LLM_ERRORThe model provider returned an error
OUTPUT_PARSE_ERRORThe output didn't parse as JSON despite an output_schema
OUTPUT_TRUNCATEDThe output hit the agent's max tokens and was cut off
MAX_ITERATIONSThe agent hit its max iterations without a final answer
CANCELLEDThe run was cancelled

See the HTTP API reference for the exact endpoint, and Hosted vs non-hosted for when to invoke vs ingest.