Control plane

Manage your AgentOS workspace from code: agents, runs, approvals, evals, schedules and more.

Each method is one POST /api/v1/rpc/<method> call, with the same permissions as the dashboard and MCP.

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

const aos = new AgentOS({ apiKey: process.env.AGENTOS_WORKSPACE_KEY });

// Pause every agent that failed more than a third of its runs this week.
const fleet = await aos.fleet.health<{ agents: Array<{ agent_id: string; failure_rate: number }> }>(
  { days: 7 },
);
for (const agent of fleet.agents.filter((a) => a.failure_rate > 0.33)) {
  await aos.agents.setStatus({ agentId: agent.agent_id, status: "paused" });
}
import os

from agentos import AgentOS

aos = AgentOS(api_key=os.environ["AGENTOS_WORKSPACE_KEY"])

# Pause every agent that failed more than a third of its runs this week.
fleet = aos.fleet.health(days=7)
for agent in fleet["agents"]:
    if agent["failure_rate"] > 0.33:
        aos.agents.set_status(agent_id=agent["agent_id"], status="paused")
  • Keys. Use a workspace key (aos_ws_…), or a personal key (aos_user_…) with the workspace option (AGENTOS_WORKSPACE). Agent keys are refused: they're for reporting and invoking one agent.
  • Permissions. A personal key has your access, as in the dashboard: a member sees only the agents they created or whose folders they've been granted, changes them only with a manage grant, and can't change workspace settings. A workspace key acts as an admin but can't invite or remove people. Changes proposed by the Operator assistant can only be approved in the dashboard.
  • Names. TypeScript takes camelCase parameters (agentId), Python snake_case keywords (agent_id). Both send the wire's snake_case.
  • Results are the JSON the server returns. In TypeScript, pass a type to narrow it: aos.agents.list<Agent[]>().
  • Retries. Reads are retried after network errors; writes only after a 429, so nothing applies twice. Methods that wait for a run (runs.invoke, evals.runCase, reports.generate) use a 310 s timeout.
  • Errors come back as { data: null, error: { code, message } } and both SDKs raise them as an AgentOSError (or a subclass) carrying the code:
StatusCodeMeaning
400VALIDATION_ERRORThe parameters don't match the schema below.
401UNAUTHENTICATEDMissing, unknown or revoked key.
402NO_PLANThe workspace has no subscription, so agents can't run.
403FORBIDDENYour role or key type can't make this call.
403WORKSPACE_SUSPENDEDThe workspace is suspended.
404UNKNOWN_METHOD / NOT_FOUNDNo such method, or the record isn't in this workspace.
429RATE_LIMITEDOver the plan's run rate. Methods that run an agent or model (runs.invoke, evals.runCase, reports.generate) count toward it; wait for the Retry-After header.
  • MCP. The same tools are served to MCP clients at /api/mcp, with snake_case names (agents_list). MCP adds one tool: workspaces_create (name, slug), which needs a personal key. See MCP server to connect Claude Code, Claude Desktop or Cursor.
  • Always current. This page is generated from the server's schemas, so it lists exactly what the API accepts.

Agents

agents.create

Create a new hosted agent. A hosted agent runs on AgentOS: define its name, system prompt, model, and tools. Optionally gate tools behind a person's approval (tools_require_approval) and file it under a folder (folder_id from folders.list).

Python: aos.agents.create() · Wire: POST /api/v1/rpc/agents_create

ParameterTypeRequiredDescription
namestringYesShort display name.
rolestringNoOne-line role label, e.g. 'Email assistant'.
descriptionstringNoWhat this agent does.
systemPrompt / system_promptstringYesFull system prompt for the agent.
providerType / provider_type"anthropic" | "openai" | "google"NoModel provider. Default "anthropic".
modelstringNoModel id for the provider (e.g. 'claude-sonnet-4-6', 'gpt-4.1-mini', 'gemini-3.6-flash'). Any model the workspace's provider key can use is accepted. Defaults to the provider's default model.
toolsArray<string>NoTool names to enable. Mix and match: built-in names (tools.listBuiltin), workspace HTTP tools (tools.listWorkspace), and Composio actions (tools.listComposio, with names like 'composio_GITHUB_CREATE_ISSUE').
toolsRequireApproval / tools_require_approvalArray<string>NoThe tools, among tools, whose every call waits for a person's approval (approvals.list / approvals.decide). Pass [] to clear.
tagsArray<string>NoFree-form tags for grouping, e.g. ['email', 'sales']. At most 10 items.
temperaturenumberNoSampling temperature. Range 0 to 2.
maxTokens / max_tokensnumberNoMax output tokens per model call. Range 1 to 16384.
maxIterations / max_iterationsnumberNoMax model steps per run before the agent stops. Range 1 to 50. Default 10.
folderId / folder_idstringNoFolder UUID to file this agent under (from folders.list). Omit for uncategorized.
promptVariables / prompt_variablesRecord<string, { description?: string; value?: string }>NoNamed {{KEY}} placeholders in the system prompt. Object mapping KEY → { description?, value? }. Pass {} to clear.
inputSchema / input_schemaRecord<string, unknown>NoJSON Schema object (draft-07). Defines the shape of the agent's input/output.
outputSchema / output_schemaRecord<string, unknown>NoJSON Schema object (draft-07). Defines the shape of the agent's input/output.

agents.delete

Permanently delete an agent and its API keys.

Python: aos.agents.delete() · Wire: POST /api/v1/rpc/agents_delete

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.

agents.get

Get full configuration for a single agent, including system_prompt, model, tools, tools_require_approval, pinned_resource_ids, pinned_folder_ids, folder_id, and sampling params.

Python: aos.agents.get() · Wire: POST /api/v1/rpc/agents_get

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.

agents.list

List all agents in the workspace with their status, model, enabled tools, tags and folder_id. Filter by status, by folder (folder_id='none' for uncategorized) or by tag (tag='pipeline' for AI pipeline orchestrators).

Python: aos.agents.list() · Wire: POST /api/v1/rpc/agents_list

ParameterTypeRequiredDescription
status"active" | "paused" | "archived"NoFilter by status. Omit to return all.
folderId / folder_idstringNoFilter by folder: a folder UUID (from folders.list), or 'none' for uncategorized agents. Omit to return all.
tagstringNoOnly those with this tag, e.g. 'pipeline' for pipeline orchestrators. Omit to return all.

agents.setStatus

Pause, unpause (active), or archive an agent. Pausing also turns its schedule off (schedule_disabled says so); unpausing never turns it back on.

Python: aos.agents.set_status() · Wire: POST /api/v1/rpc/agents_set_status

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.
status"active" | "paused" | "archived"Yes

agents.update

Update a hosted agent's config: name, system_prompt, model, tools, tools_require_approval, pinned_resource_ids, pinned_folder_ids, sampling params, or folder_id (pass null to un-file). Removing a tool removes its approval gate.

Python: aos.agents.update() · Wire: POST /api/v1/rpc/agents_update

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.
namestringNo
rolestringNo
descriptionstringNo
systemPrompt / system_promptstringNo
providerType / provider_type"anthropic" | "openai" | "google"No
modelstringNoModel id for the provider (e.g. 'claude-sonnet-4-6', 'gpt-4.1-mini'). Any model the workspace's provider key can use is accepted.
toolsArray<string>No
toolsRequireApproval / tools_require_approvalArray<string>NoThe tools, among tools, whose every call waits for a person's approval (approvals.list / approvals.decide). Pass [] to clear.
tagsArray<string>NoFree-form tags for grouping, e.g. ['email', 'sales']. At most 10 items.
temperaturenumberNoRange 0 to 2.
maxTokens / max_tokensnumberNoRange 1 to 16384.
maxIterations / max_iterationsnumberNoRange 1 to 50.
pinnedResourceIds / pinned_resource_idsArray<string>NoWorkspace resource IDs to pin into the system prompt. Pass [] to clear. At most 50 items.
pinnedFolderIds / pinned_folder_idsArray<string>NoResource folder IDs (from the Resources page) whose published brain files are loaded into the system prompt. Pass [] to clear. At most 20 items.
folderId / folder_idstring | nullNoFolder UUID to file this agent under (from folders.list). Pass null to un-file (move to uncategorized). Built-in agents can't be filed.
promptVariables / prompt_variablesRecord<string, { description?: string; value?: string }>NoNamed {{KEY}} placeholders in the system prompt. Object mapping KEY → { description?, value? }. Pass {} to clear.
inputSchema / input_schemaRecord<string, unknown>NoJSON Schema object (draft-07). Defines the shape of the agent's input/output.
outputSchema / output_schemaRecord<string, unknown>NoJSON Schema object (draft-07). Defines the shape of the agent's input/output.

Alerts

alerts.create

Create an alert rule. Alerts notify you when an agent fails, runs too slowly, errors too often, goes quiet, emits a given event, gets a worse Intelligence finding, or passes its monthly budget. Owner/admin only; needs a paid plan.

Python: aos.alerts.create() · Wire: POST /api/v1/rpc/alerts_create

ParameterTypeRequiredDescription
namestringYes
agentId / agent_idstringNoScope to a specific agent. Omit for workspace-wide.
scriptId / script_idstringNoScope to a specific script. Omit for workspace-wide.
conditionType / condition_type"run_failed" | "run_duration_exceeded" | "error_rate" | "no_activity" | "custom_event" | "intelligence_finding" | "spend_exceeded"Yes
conditionConfig / condition_config{ duration_ms?: number; threshold_pct?: number; window_runs?: number; hours_since_last_run?: number; event_type?: string; min_severity?: "warn" | "critical" }Norun_duration_exceeded: { duration_ms }. error_rate: { threshold_pct, window_runs } (defaults 10 and 20). no_activity: { hours_since_last_run } (default 24). custom_event: { event_type }. intelligence_finding: { min_severity: "warn" | "critical" } (default "warn").
channelsArray<"in_app" | "email" | "webhook">Yes
notificationConfig / notification_config{ email?: { recipients: Array<string> }; webhook?: { url: string } }No{ email?: { recipients: string[] }, webhook?: { url } }. Required for the email and webhook channels. Email alerts need a paid plan.

alerts.delete

Delete an alert rule. Owner/admin only.

Python: aos.alerts.delete() · Wire: POST /api/v1/rpc/alerts_delete

ParameterTypeRequiredDescription
alertId / alert_idstringYesAlert UUID.

alerts.list

List alert rules configured for this workspace.

Python: aos.alerts.list() · Wire: POST /api/v1/rpc/alerts_list

ParameterTypeRequiredDescription
activeOnly / active_onlybooleanNoOnly return active rules. Default false.

alerts.update

Update an alert rule: change its config, channels, or toggle active/inactive. Owner/admin only.

Python: aos.alerts.update() · Wire: POST /api/v1/rpc/alerts_update

ParameterTypeRequiredDescription
alertId / alert_idstringYesAlert UUID.
namestringNo
conditionConfig / condition_config{ duration_ms?: number; threshold_pct?: number; window_runs?: number; hours_since_last_run?: number; event_type?: string; min_severity?: "warn" | "critical" }Norun_duration_exceeded: { duration_ms }. error_rate: { threshold_pct, window_runs } (defaults 10 and 20). no_activity: { hours_since_last_run } (default 24). custom_event: { event_type }. intelligence_finding: { min_severity: "warn" | "critical" } (default "warn").
channelsArray<"in_app" | "email" | "webhook">No
notificationConfig / notification_config{ email?: { recipients: Array<string> }; webhook?: { url: string } }No{ email?: { recipients: string[] }, webhook?: { url } }. Required for the email and webhook channels. Email alerts need a paid plan.
activebooleanNoEnable or disable the alert rule.

API keys

apiKeys.create

Generate a new API key for an agent. Returns the plaintext key ONCE: surface it to the user immediately and instruct them to store it securely.

Python: aos.api_keys.create() · Wire: POST /api/v1/rpc/api_keys_create

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.
namestringYesDisplay name for this key, e.g. 'production', 'local-dev'.

apiKeys.list

List API keys for this workspace, optionally filtered to one agent or script. Plaintext is never returned, only id, name, prefix, agent_id, revoked, last_used_at.

Python: aos.api_keys.list() · Wire: POST /api/v1/rpc/api_keys_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
scriptId / script_idstringNoFilter by script. Omit for workspace-wide.
includeRevoked / include_revokedbooleanNoInclude revoked keys. Default false.

apiKeys.revoke

Revoke an API key by id. Subsequent requests using that key will be rejected. Revoking a workspace key (not tied to an agent) needs the owner or admin role.

Python: aos.api_keys.revoke() · Wire: POST /api/v1/rpc/api_keys_revoke

ParameterTypeRequiredDescription
keyId / key_idstringYesID of the key to revoke.

Approvals

approvals.decide

Approve or reject a pending tool call. Approving resumes the run; rejecting hands the refusal back to it. Returns the run's status after the decision: when it paused again (or other calls of the same turn wait), pending_approval_ids lists what to decide next; when it failed after the decision, error says why (the decision still stands).

Python: aos.approvals.decide() · Wire: POST /api/v1/rpc/approvals_decide

ParameterTypeRequiredDescription
approvalId / approval_idstringYesApproval UUID.
decision"approved" | "rejected"YesApprove or reject the pending tool call.
decisionNote / decision_notestringNoOptional note shown to the run log.

approvals.list

List pending approval requests for this workspace. Approvals are tool calls paused for human approval.

Python: aos.approvals.list() · Wire: POST /api/v1/rpc/approvals_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
scriptId / script_idstringNoFilter by script. Omit for workspace-wide.
limitnumberNoMax results to return. Default 20. Range 1 to 100.

Conversations

conversations.delete

Delete a conversation and its message history. Owner/admin only.

Python: aos.conversations.delete() · Wire: POST /api/v1/rpc/conversations_delete

ParameterTypeRequiredDescription
conversationId / conversation_idstringYesConversation UUID.

conversations.get

Get a conversation and its full message history.

Python: aos.conversations.get() · Wire: POST /api/v1/rpc/conversations_get

ParameterTypeRequiredDescription
conversationId / conversation_idstringYesConversation UUID.
messageLimit / message_limitnumberNoMax messages to return. Range 1 to 200. Default 50.

conversations.list

List conversation sessions for this workspace. Conversations persist multi-turn memory across runs.

Python: aos.conversations.list() · Wire: POST /api/v1/rpc/conversations_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
externalUserId / external_user_idstringNoFilter by external user ID passed at invoke time.
limitnumberNoMax results to return. Default 20. Range 1 to 100.

Evals

evals.createCase

Create an eval case for an agent. Define the input payload and a list of assertions (output_contains, tool_called, no_error, max_duration_ms, etc.) that must all pass for the case to succeed.

Python: aos.evals.create_case() · Wire: POST /api/v1/rpc/evals_create_case

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.
namestringYesShort label for this eval case, e.g. 'Handles missing invoice'.
inputRecord<string, unknown>YesInput payload passed to the agent when this case is run.
assertionsArray<{ type: "output_contains" | "output_equals" | "output_regex" | "tool_called" | "tool_not_called" | "no_error" | "max_duration_ms" | "max_cost_usd"; value?: string | number }>YesList of assertions to check after the run completes.

evals.deleteCase

Delete an eval case and all its run history.

Python: aos.evals.delete_case() · Wire: POST /api/v1/rpc/evals_delete_case

ParameterTypeRequiredDescription
evalCaseId / eval_case_idstringYesEval case UUID.

evals.getRun

Get the status and per-assertion results for an eval run. Each result includes assertion_type, passed, actual_value, and expected_value.

Python: aos.evals.get_run() · Wire: POST /api/v1/rpc/evals_get_run

ParameterTypeRequiredDescription
evalRunId / eval_run_idstringYesEval run UUID.

evals.listCases

List all eval cases for an agent, each with its most recent run status. Use to check what test coverage exists and whether cases are passing.

Python: aos.evals.list_cases() · Wire: POST /api/v1/rpc/evals_list_cases

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.

evals.runCase

Run an eval case now and wait for the verdict (up to 5 minutes). Returns eval_run_id, status, run_id, passed and total assertion counts, and the per-assertion results with failures first; error is set when the agent run itself failed. Fetch the result again later with evals.getRun.

Python: aos.evals.run_case() · Wire: POST /api/v1/rpc/evals_run_case

ParameterTypeRequiredDescription
evalCaseId / eval_case_idstringYesEval case UUID.

Fleet

fleet.health

Per-agent health for the whole fleet over the last N days, worst first: run counts, failure rate, open-finding severity, and a 0-100 health score with its value at the start of the window so you can see the trend. Reads the daily rollup, so it agrees with the dashboard and costs one query. Prefer this over listing runs when the question is 'what needs attention?'.

Python: aos.fleet.health() · Wire: POST /api/v1/rpc/fleet_health

ParameterTypeRequiredDescription
daysnumberNoHow many days back to summarise. Default 7. Range 1 to 30.

Folders

folders.create

Create a new agent folder. Name must be unique in the workspace. File agents into it via agents.update(folder_id) or agents.create(folder_id).

Python: aos.folders.create() · Wire: POST /api/v1/rpc/folders_create

ParameterTypeRequiredDescription
namestringYesFolder display name. Must be unique within the workspace.

folders.delete

Delete an agent folder. Its agents are moved to uncategorized (folder_id cleared), not deleted.

Python: aos.folders.delete() · Wire: POST /api/v1/rpc/folders_delete

ParameterTypeRequiredDescription
folderId / folder_idstringYesFolder UUID to delete. Its agents are moved to uncategorized, not deleted.

folders.list

List the workspace's agent folders with each folder's agent count. Use a folder's id with agents.list(folder_id) or agents.update(folder_id).

Python: aos.folders.list() · Wire: POST /api/v1/rpc/folders_list

Human Input

humanInput.list

List questions runs are waiting on (ask_human), oldest first: request_id, run_id, agent_id, question and any options. Answer one with humanInput.reply.

Python: aos.human_input.list() · Wire: POST /api/v1/rpc/human_input_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
scriptId / script_idstringNoFilter by script. Omit for workspace-wide.
limitnumberNoMax results to return. Default 20. Range 1 to 100.

humanInput.reply

Answer a question a run is waiting on (ask_human) and resume the run, as replying on its run page does. Returns the run's status after the reply: when it paused again, pending_approval_ids, awaiting_input (the next question) or awaiting_child say what it waits on; when it failed after the reply, error says why (the answer still stands). A question already answered, or cancelled with its run, is refused.

Python: aos.human_input.reply() · Wire: POST /api/v1/rpc/human_input_reply

ParameterTypeRequiredDescription
requestId / request_idstringYesThe question's request_id (humanInput.list, or runs.invoke's answer).
answerstringYesYour answer, handed to the run as the reply to its question.

Integrations

integrations.list

List third-party integrations and their connection status (Gmail, Google Sheets, GitHub, Slack, etc., all via Composio). Read-only: connect them at /integrations in the dashboard (owner/admin only).

Python: aos.integrations.list() · Wire: POST /api/v1/rpc/integrations_list

Marketplace

marketplace.install

Install a marketplace template into the target workspace as a regular agent (status='paused' so you can review before activating). Generates a default API key shown once in the response. Returns agent_id, the plaintext api_key, and the template's setup_notes (steps the user still has to complete, such as connecting Gmail, filling placeholders or pinning resources).

Python: aos.marketplace.install() · Wire: POST /api/v1/rpc/marketplace_install_template

ParameterTypeRequiredDescription
templateId / template_idstringYesTemplate id (slug), e.g. 'welcome-onboarding'. Use marketplace.listTemplates first to discover available ids.

marketplace.listTemplates

List the marketplace's agent templates with their id, description, category, model and tools, to install with marketplace.install.

Python: aos.marketplace.list_templates() · Wire: POST /api/v1/rpc/marketplace_list_templates

Members

members.invite

Invite a user to the workspace by email. Sends an invite email and returns an invite link. Owner/admin only, and only with a personal key (aos_user_…): a workspace key is refused. 'member' role requires Team/Enterprise plan.

Python: aos.members.invite() · Wire: POST /api/v1/rpc/members_invite

ParameterTypeRequiredDescription
emailstringYesEmail address to invite.
role"admin" | "member"YesRole to grant. 'member' requires Team/Enterprise plan.

members.list

List workspace members (with email and role) and pending invites. Useful for auditing who has access.

Python: aos.members.list() · Wire: POST /api/v1/rpc/members_list

members.remove

Remove a member from the workspace. Cannot remove the last owner. Owner/admin only, and only with a personal key (aos_user_…): a workspace key is refused.

Python: aos.members.remove() · Wire: POST /api/v1/rpc/members_remove

ParameterTypeRequiredDescription
memberId / member_idstringYesWorkspace member row UUID (from members.list).

Notifications

notifications.list

List recent workspace notifications (agent failures, approvals, system events). Filter to unread_only to process the inbox.

Python: aos.notifications.list() · Wire: POST /api/v1/rpc/notifications_list

ParameterTypeRequiredDescription
unreadOnly / unread_onlybooleanNoReturn only unread notifications. Default false.
limitnumberNoMax results to return. Default 20. Range 1 to 100.

notifications.markRead

Mark notifications as read. Pass notification_id to mark a single one, or omit to mark all unread notifications in the workspace as read.

Python: aos.notifications.mark_read() · Wire: POST /api/v1/rpc/notifications_mark_read

ParameterTypeRequiredDescription
notificationId / notification_idstringNoID of a specific notification to mark read. Omit to mark ALL unread notifications in the workspace as read.

Orchestration

orchestration.get

The workspace's orchestration map for a period: every active or paused agent and script as a node (kind, folder, schedule, how it was started, runs, failed runs, tokens, a status with its reason, approval counts), and every call between them as an edge (declared by the caller's prompt or code, observed in runs, or both, with calls, failed calls and tokens). Each script node lists the Resources files its code reads and writes, and files names the ones that one runnable writes and another uses, which join them without a call. Built-in agents are left out. Use it for 'what runs here and how do the pieces fit together?'.

Python: aos.orchestration.get() · Wire: POST /api/v1/rpc/orchestration_get

ParameterTypeRequiredDescription
period"24h" | "7d" | "30d" | "90d"NoHow far back the numbers go. Default 7d.

Providers

providers.list

List the model providers this workspace holds a key for (anthropic, openai, google, openai_compatible, anthropic_compatible), each with the model AgentOS picks on it, or null. Never a key. Owner/admin only.

Python: aos.providers.list() · Wire: POST /api/v1/rpc/providers_list

Records

records.count

Count the records of a collection, or those matching where: { count }.

Python: aos.records.count() · Wire: POST /api/v1/rpc/records_count

ParameterTypeRequiredDescription
collectionstringYesThe collection's name: lowercase letters, digits and underscores, starting with a letter, up to 60 characters.
whereRecord<string, unknown>NoCount only records whose top-level fields match these values. A string, number or boolean must be the same; a list or object matches when the record's contains it; null matches a field that is null, not one that is absent.

records.create

Add a record to a collection; a collection exists once it has a record. With key, the record is the only one of its collection with that key: a second create with the same key is refused, and the refusal names the record that has it. Returns the record with its id. Limits: 32 KB a record, 50,000 records a workspace. Needs the owner or admin role.

Python: aos.records.create() · Wire: POST /api/v1/rpc/records_create

ParameterTypeRequiredDescription
collectionstringYesThe collection's name: lowercase letters, digits and underscores, starting with a letter, up to 60 characters.
keystringNoA name for the record that is unique in its collection, e.g. an email address: up to 320 characters, stored as given and never changed.
dataRecord<string, unknown>YesThe record: a JSON object of at most 32 KB.

records.delete

Delete one record by id: { deleted: true, id }. With if, the record is deleted only while its top-level fields still match those values; the answer is { deleted: true, id } or { deleted: false, matched: false }. Needs the owner or admin role.

Python: aos.records.delete() · Wire: POST /api/v1/rpc/records_delete

ParameterTypeRequiredDescription
idstringYesRecord UUID.
if / if_Record<string, unknown>NoTop-level fields and the values they must still match for the record to be deleted. A string, number or boolean must be the same; a list or object matches when the record's contains it; null matches a field that is null, not one that is absent.

records.get

Read one record, by id or by collection and key: its id, collection, key, data, created_at and updated_at.

Python: aos.records.get() · Wire: POST /api/v1/rpc/records_get

ParameterTypeRequiredDescription
idstringNoRecord UUID.
collectionstringNoWith key: the collection the record is in.
keystringNoWith collection: the key the record was created with.

records.list

List the records of a collection (the workspace's structured data, as JSON objects): { records, next }, each record with its id, collection, key, data, created_at and updated_at. Newest first by default, 100 a page at most; a page of large records ends early. Pass next as after for the following page; null means there is none.

Python: aos.records.list() · Wire: POST /api/v1/rpc/records_list

ParameterTypeRequiredDescription
collectionstringYesThe collection's name: lowercase letters, digits and underscores, starting with a letter, up to 60 characters.
whereRecord<string, unknown>NoOnly records whose top-level fields match these values, e.g. { "status": "open" }. A string, number or boolean must be the same; a list or object matches when the record's contains it; null matches a field that is null, not one that is absent.
order"newest" | "oldest"NoBy creation time. Default newest.
limitnumberNoRecords a page. Default 100.
afterstringNoThe next of the page before.

records.update

Change a record: set is laid over its top-level fields, and a null removes a field. With if, the change happens only while the record's top-level fields still match those values; the answer is { matched: true, record } or { matched: false }, so of two callers taking the same item one succeeds. Needs the owner or admin role.

Python: aos.records.update() · Wire: POST /api/v1/rpc/records_update

ParameterTypeRequiredDescription
idstringYesRecord UUID.
setRecord<string, unknown>YesTop-level fields to write. A null value removes the field.
if / if_Record<string, unknown>NoTop-level fields and the values they must still match for the change to happen. A string, number or boolean must be the same; a list or object matches when the record's contains it; null matches a field that is null, not one that is absent.

Reports

reports.delete

Delete a report. Owner/admin only.

Python: aos.reports.delete() · Wire: POST /api/v1/rpc/reports_delete

ParameterTypeRequiredDescription
reportId / report_idstringYesReport UUID.

reports.generate

Generate an AI report synchronously and return its report_id when complete. run_summary requires run_id and is available on every plan. The period reports (agent_daily, agent_weekly, workspace_weekly, on_demand) require agent_id, period_start and period_end, and need a paid plan.

Python: aos.reports.generate() · Wire: POST /api/v1/rpc/reports_generate

ParameterTypeRequiredDescription
type"run_summary" | "agent_daily" | "agent_weekly" | "workspace_weekly" | "on_demand"YesReport type. 'run_summary' requires run_id. Period types (agent_daily, agent_weekly, workspace_weekly, on_demand) require agent_id + period_start + period_end.
agentId / agent_idstringNoAgent UUID. Required for period reports.
runId / run_idstringNoRun UUID. Required for run_summary.
periodStart / period_startstringNoISO 8601 start of the period. Required for period reports.
periodEnd / period_endstringNoISO 8601 end of the period. Required for period reports.

reports.get

Get a single report including full markdown content (content_md). Use after reports.list or reports.generate.

Python: aos.reports.get() · Wire: POST /api/v1/rpc/reports_get

ParameterTypeRequiredDescription
reportId / report_idstringYesReport UUID.

reports.list

List AI-generated reports for the workspace. Filter by agent, status, or limit. Returns id, type, status, summary, and period; use reports.get for full markdown content.

Python: aos.reports.list() · Wire: POST /api/v1/rpc/reports_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
status"generating" | "ready" | "failed"NoFilter by status. Omit for all.
limitnumberNoMax results to return. Default 20. Range 1 to 100.

Resources

resources.create

Upload a text resource (content) or an image (content_base64: png, jpeg, webp, gif) into the workspace. Returns the saved filename. Pin it on an agent via agents.update.pinned_resource_ids to inject the content into that agent's system prompt. brain marks it as workspace brain; folder files it in a Resources folder by name (a Brain section is one).

Python: aos.resources.create() · Wire: POST /api/v1/rpc/resources_create

ParameterTypeRequiredDescription
brain"draft" | "published" | nullNoMark the file as workspace brain: 'draft' (nobody reads it yet) or 'published' (pinned folders and the Operator read it), or null to make it an ordinary resource. Omit to keep what an existing file has.
folderstring | nullNoThe Resources folder to file it in, by name (any case), e.g. 'Voice and brand'; the Brain's sections are folders. It must exist. null takes the file out of its folder. Omit to keep what an existing file has; a new file is in none. A brain file is read through its folder.
filenamestringYesSimple filename (no path separators), e.g. 'prospects.csv'.
contentstringNoText content of the file. Max 10 MB after UTF-8 encoding. Give this or content_base64.
contentBase64 / content_base64stringNoAn image's bytes, base64-encoded (png, jpeg, webp or gif). Max 10 MB decoded. Give this or content.
mimeType / mime_type"text/plain" | "text/markdown" | "text/csv" | "text/html" | "application/json" | "image/png" | "image/jpeg" | "image/webp" | "image/gif"NoContent mime type. Inferred from filename extension when omitted.

resources.delete

Delete a workspace resource by filename. Removes the file from storage and any pinned references resolve as missing on next agent run.

Python: aos.resources.delete() · Wire: POST /api/v1/rpc/resources_delete

ParameterTypeRequiredDescription
filenamestringYesFilename to delete (must already exist in this workspace).

resources.get

Read one workspace resource by filename: its metadata and, for a text file, its content (the first 256 KB; truncated says when there is more). An image returns metadata with content null.

Python: aos.resources.get() · Wire: POST /api/v1/rpc/resources_get

ParameterTypeRequiredDescription
filenamestringYesFilename to read, as resources.list returns it.

resources.list

List workspace resource files (uploaded text/markdown/csv/json/html documents that agents can read at runtime), each with its brain flag ('draft', 'published' or null) and folder. Filter with brain.

Python: aos.resources.list() · Wire: POST /api/v1/rpc/resources_list

ParameterTypeRequiredDescription
brain"draft" | "published" | nullNoOnly the workspace brain's 'draft' or 'published' files, or null for the ordinary resources. Omit for all.

Runs

runs.cancel

Cancel a run that is running or waiting. Its active child runs are cancelled with it and listed in cancelled_child_run_ids.

Python: aos.runs.cancel() · Wire: POST /api/v1/rpc/runs_cancel

ParameterTypeRequiredDescription
runId / run_idstringYesRun UUID.

runs.events

Get the event log for a run: tool calls, LLM steps, errors. Use for debugging.

Python: aos.runs.events() · Wire: POST /api/v1/rpc/runs_get_events

ParameterTypeRequiredDescription
runId / run_idstringYesRun UUID.
limitnumberNoMax events to return. Range 1 to 200. Default 50.

runs.get

Get full detail for a single run, including output, timing, its own token usage, runnable_kind (agent, script or pipeline: an agent or script tagged pipeline), parent_run_id, child_run_ids, subagent_tokens (what its child runs and their descendants spent) and when (its start on the workspace's clock as it read that day; started_at is UTC).

Python: aos.runs.get() · Wire: POST /api/v1/rpc/runs_get

ParameterTypeRequiredDescription
runId / run_idstringYesRun UUID.

runs.invoke

Invoke a hosted agent synchronously and return the result. Use to test agents or trigger them manually. Waits up to 5 minutes. The answer's status says whether it finished: a run that paused returns 'awaiting_approval' (approval_ids), 'awaiting_input' (request_id, question) or, when a child run it started paused, 'awaiting_child' (child_run_ids; it resumes on its own once they end). Optionally use conversation memory: pass start_session=true on the first turn (the response returns session_id), then pass that session_id on later turns. Or pass history[] for stateless multi-turn. Pass at most one of session_id, start_session, history.

Python: aos.runs.invoke() · Wire: POST /api/v1/rpc/runs_invoke

ParameterTypeRequiredDescription
agentId / agent_idstringYesAgent UUID.
inputRecord<string, unknown>NoInput passed to the agent. Shape depends on the agent.
promptVariables / prompt_variablesRecord<string, string>NoValues for the agent's prompt_variables. Each key matches a {{KEY}} placeholder in the system prompt.
sessionId / session_idstringNoResume a stateful conversation. The id must already exist: an unknown id is an error, not a new session.
startSession / start_sessionbooleanNoBegin a new stateful conversation. The response returns the server-assigned session_id to pass on later turns.
historyArray<{ role: "user" | "assistant"; content: string }>NoStateless multi-turn: prior user/assistant turns prepended before this input. AgentOS persists nothing. At most 50 items.
externalUserId / external_user_idstringNoOpaque end-user identifier (e.g. a Firebase uid), recorded on the conversation. Only meaningful with session_id or start_session.

runs.list

List recent runs for a specific agent or script, or workspace-wide, newest first; kind narrows to agents, scripts or pipelines, and since to the runs started from a time ('today' or an instant). Each row's runnable_kind and runnable_name say what ran it, and when is its start on the workspace's clock as it read that day (started_at is UTC). Pass parent_run_id for the child runs one run started.

Python: aos.runs.list() · Wire: POST /api/v1/rpc/runs_list

ParameterTypeRequiredDescription
agentId / agent_idstringNoFilter by agent. Omit for workspace-wide.
scriptId / script_idstringNoFilter by script. Omit for workspace-wide.
kind"agent" | "script" | "pipeline"NoOnly runs of this kind of runnable: an agent, a script or a pipeline (an agent or a script tagged pipeline; a script pipeline is not a script here).
status"running" | "completed" | "failed" | "cancelled" | "awaiting_approval" | "awaiting_input" | "awaiting_child"No
parentRunId / parent_run_idstringNoOnly the child runs this run started (scripts and agents it called).
sincestringNoOnly runs started at or after this: "today" (since midnight in the workspace's timezone) or an ISO 8601 instant.
limitnumberNoMax results to return. Default 20, or 100 with since: to count runs, pass since and leave this out.

Schedules

schedules.delete

Remove an agent's or a script's schedule (agent_id or script_id, exactly one). It is no longer invoked on a recurring basis (manual / SDK invokes still work).

Python: aos.schedules.delete() · Wire: POST /api/v1/rpc/schedules_delete

ParameterTypeRequiredDescription
agentId / agent_idstringNoAgent UUID. Give agent_id or script_id, exactly one.
scriptId / script_idstringNoScript UUID. Give agent_id or script_id, exactly one.

schedules.get

Get the schedule configured for an agent or a script (agent_id or script_id, exactly one; one schedule each at most). Returns null when no schedule exists. A calendar schedule carries its run_dates, and a null next_run_at once none is left.

Python: aos.schedules.get() · Wire: POST /api/v1/rpc/schedules_get

ParameterTypeRequiredDescription
agentId / agent_idstringNoAgent UUID. Give agent_id or script_id, exactly one.
scriptId / script_idstringNoScript UUID. Give agent_id or script_id, exactly one.

schedules.upsert

Create or update an agent's or a script's schedule (agent_id or script_id, exactly one). Supports hourly, daily, weekly, monthly and calendar frequency. Hourly runs on the hour and ignores the time fields; daily, weekly and monthly take an optional hour_of_day (0-23), minute_of_hour (0-59), and IANA timezone (e.g. 'America/New_York'), defaulting to 00:00 UTC. Weekly needs day_of_week, monthly needs day_of_month (1-28). Calendar runs once at each entry of run_dates (a date and an hour, in the timezone) and has no next run after the last; saving the list never runs an entry already past. The dispatcher runs the agent or script with the configured input JSON.

Python: aos.schedules.upsert() · Wire: POST /api/v1/rpc/schedules_upsert

ParameterTypeRequiredDescription
agentId / agent_idstringNoAgent UUID. Give agent_id or script_id, exactly one.
scriptId / script_idstringNoScript UUID. Give agent_id or script_id, exactly one.
frequency"hourly" | "daily" | "weekly" | "monthly" | "calendar"Yes
dayOfWeek / day_of_weeknumber | nullNo0=Sunday … 6=Saturday. Required when frequency='weekly'.
dayOfMonth / day_of_monthnumber | nullNoDay of the month, 1 to 28. Required when frequency='monthly'.
runDates / run_datesArray<{ date: string; hour: number }> | nullNoThe dates and hours to run on. Required when frequency='calendar', and not accepted otherwise. No two alike; an entry already past does nothing.
hourOfDay / hour_of_daynumberNoLocal hour (0-23) at which the schedule fires. Defaults to 0 (midnight).
minuteOfHour / minute_of_hournumberNoLocal minute (0-59) offset within the hour. Defaults to 0.
timezonestringNoIANA timezone name, e.g. 'America/New_York', 'Europe/Lisbon'. Defaults to 'UTC'.
inputRecord<string, unknown>NoInput passed to the agent or script on each run. JSON object.
enabledbooleanNoSet false to keep the schedule but stop it firing. Default true.

Scripts

scripts.create

Create a script: JavaScript that runs in a sandbox with no model, and spends no tokens. It can reach nothing but the tools you enable on it. Pass tags: ['pipeline'] to create a script pipeline: a fixed sequence of agents (tools.invoke_agent({ agent_name, input })) and scripts, listed on Pipelines. Returns script_id and the tool name agents call it by.

Python: aos.scripts.create() · Wire: POST /api/v1/rpc/scripts_create

ParameterTypeRequiredDescription
namestringYesShort display name.
descriptionstringNoWhat this script does.
scriptCode / script_codestringYesJavaScript module: export default async function run(input, tools) \{ ... \}. No imports, network or timers: everything goes through tools.
inputSchema / input_schemaRecord<string, unknown> | nullNoJSON Schema (draft-07) of the input. Also the parameters an agent sees when the script is its tool.
toolsArray<string>NoTools the script may call, by id. Not ask_human, not control-plane (cp_*) tools. At most 50 items. Default [].
toolsRequireApproval / tools_require_approvalArray<string>NoThe tools, among tools, whose every call waits for an approval. At most 50 items. Default [].
folderId / folder_idstring | nullNoFolder UUID (from folders.list) to file the script under.
tagsArray<string>NoFree-form tags for grouping, e.g. ['email', 'sales']. 'pipeline' lists the script on Pipelines. At most 10 items.

scripts.delete

Permanently delete a script, its versions and its API keys.

Python: aos.scripts.delete() · Wire: POST /api/v1/rpc/scripts_delete

ParameterTypeRequiredDescription
scriptId / script_idstringYesScript UUID.

scripts.get

Get a script in full: its code, input_schema, tools and which of them wait for an approval. Its slug names it as a tool: an agent that enables the script calls it as script_<slug>.

Python: aos.scripts.get() · Wire: POST /api/v1/rpc/scripts_get

ParameterTypeRequiredDescription
scriptId / script_idstringYesScript UUID.

scripts.list

List the scripts in the workspace with their status, slug, enabled tools, tags and folder_id. A script is JavaScript that runs with no model and calls only its enabled tools. Filter by status, by folder (folder_id='none' for unfiled) or by tag (tag='pipeline' for script pipeline orchestrators).

Python: aos.scripts.list() · Wire: POST /api/v1/rpc/scripts_list

ParameterTypeRequiredDescription
status"active" | "paused" | "archived"NoFilter by status. Omit to return all.
folderId / folder_idstringNoFilter by folder: a folder UUID (from folders.list), or 'none' for unfiled scripts. Omit to return all.
tagstringNoOnly those with this tag, e.g. 'pipeline' for pipeline orchestrators. Omit to return all.

scripts.run

Run a script with an input and wait for it: its code executes in the sandbox, calling only its enabled tools, and spends no tokens. Returns the run id and the script's output; a call that waits for an approval returns 'awaiting_approval' with the approval ids, and one whose child run paused returns 'awaiting_child' with the child run ids (the run resumes on its own once the child ends).

Python: aos.scripts.run() · Wire: POST /api/v1/rpc/scripts_run

ParameterTypeRequiredDescription
scriptId / script_idstringYesScript UUID.
inputRecord<string, unknown>NoInput passed to the script, the object its code receives.
idempotencyKey / idempotency_keystringNoRuns the script at most once per key: a repeated call with the same key returns that first run as it stands now (replayed: true) instead of starting another; the first call's input is the one that ran. Use it for retries and webhooks that may deliver twice.

scripts.setStatus

Pause, unpause (active), or archive a script. Pausing also turns its schedule off (schedule_disabled says so); unpausing never turns it back on. An archived script does not count against the plan.

Python: aos.scripts.set_status() · Wire: POST /api/v1/rpc/scripts_set_status

ParameterTypeRequiredDescription
scriptId / script_idstringYesScript UUID.
status"active" | "paused" | "archived"Yes

scripts.update

Change a script's name, description, code, input_schema, tools, approval gates or tags. Send only what changes. Each config change is saved as a new version (tags are not config: a tags-only update makes none); a run already waiting keeps the version it started on. Tag a script 'pipeline' to list it on Pipelines as a script orchestrator.

Python: aos.scripts.update() · Wire: POST /api/v1/rpc/scripts_update

ParameterTypeRequiredDescription
scriptId / script_idstringYesScript UUID.
namestringNoShort display name.
descriptionstringNoWhat this script does.
scriptCode / script_codestringNoJavaScript module: export default async function run(input, tools) \{ ... \}. No imports, network or timers: everything goes through tools.
inputSchema / input_schemaRecord<string, unknown> | nullNoJSON Schema (draft-07) of the input. Also the parameters an agent sees when the script is its tool.
toolsArray<string>NoAt most 50 items.
toolsRequireApproval / tools_require_approvalArray<string>NoAt most 50 items.
tagsArray<string>NoFree-form tags for grouping, e.g. ['email', 'sales']. 'pipeline' lists the script on Pipelines. At most 10 items.

Tools

tools.create

Create a custom HTTP tool that hosted agents can call.

Python: aos.tools.create() · Wire: POST /api/v1/rpc/tools_create_workspace

ParameterTypeRequiredDescription
namestringYesUnique tool name, e.g. 'fetch_invoice'.
descriptionstringNoWhat this tool does. The AI uses it to decide when to call it.
method"GET" | "POST"Yes
urlstringYesAbsolute URL the tool will call.
authSecret / auth_secretstringNoOptional Bearer token. Stored encrypted.

tools.delete

Delete a custom workspace tool.

Python: aos.tools.delete() · Wire: POST /api/v1/rpc/tools_delete_workspace

ParameterTypeRequiredDescription
toolId / tool_idstringYesTool UUID.

tools.listBuiltin

List all built-in tools available to hosted agents (e.g. web_search, read_url, read_resource). Provider-specific actions (Gmail, Sheets, GitHub, etc.) come from Composio toolkits.

Python: aos.tools.list_builtin() · Wire: POST /api/v1/rpc/tools_list_builtin

tools.listComposio

List Composio-backed actions available to this workspace, grouped by toolkit (e.g. github, slack). Each action's tool_name is the exact value to put into agents.tools[] (e.g. 'composio_GITHUB_CREATE_ISSUE'). Returns empty toolkits if no Composio apps are connected; direct the user to /integrations to connect one (owner/admin only).

Python: aos.tools.list_composio() · Wire: POST /api/v1/rpc/tools_list_composio

tools.listWorkspace

List custom HTTP tools configured for this workspace.

Python: aos.tools.list_workspace() · Wire: POST /api/v1/rpc/tools_list_workspace

ParameterTypeRequiredDescription
enabledOnly / enabled_onlybooleanNoOnly return enabled tools. Default true.

Workspaces

workspaces.list

List the workspaces this key can access. A personal key sees every workspace you belong to, with your role; a workspace key sees its own.

Python: aos.workspaces.list() · Wire: POST /api/v1/rpc/workspaces_list