Skip to main content

Agents API

Build AI-powered conversational and task agents. Create agents with custom tools and guardrails, deploy them to messaging and voice channels, run conversations programmatically, and access interaction history. Base path: /api/v1/agents

CRUD Operations

Create Agent

POST /api/v1/agents
string
required
Agent display name
string
default:"custom"
Agent type. One of custom, chatbot, router, voice, workflow. Optional — defaults to custom when omitted.
string
default:"claude-sonnet-4-6"
Anthropic Claude model id. Orbit is Anthropic-only. Supported values: claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5-20251001, claude-fable-5. Note: claude-fable-5 is temporarily unavailable (export-suspended); requests pinned to it fall back to claude-opus-4-7. This list can change as models are added or availability shifts — call GET /api/v1/agents/models for the live, authoritative set.Optional. When you omit model, the agent record is created with claude-sonnet-4-6 stored as its model — this is the create-time field default, and it is the model that agent runs on.Do not confuse this with the platform default model, which the runtime resolves separately (admin pin → auto-discovery → boot fallback) for agents left on the platform default rather than pinned here. That chain can settle on a different id, so the model serving a platform-default agent need not match this field’s default. See Agent model selection.
string
System instructions that define the agent’s behavior and personality. Optional.
object[]
Tool definitions the agent can invoke
Channel binding is not set at create time. POST /api/v1/agents does not accept a channels field — pass it and it is silently ignored. Bind an agent to channels when you activate it via Deploy Agent.
object
Guardrail configuration enforced by Orbit’s agent runtime. There is no separate guardrails endpoint — send this on create or update.
object[]
Conditions that hand a conversation off to a human. Each entry is one of { "type": "keyword", "value": "<string>" }, { "type": "sentiment_below", "value": <0–1> }, or { "type": "turn_count_above", "value": <positive integer> }.
string[]
IDs of knowledge bases (Qdrant collections) to attach for RAG
number
default:"0.7"
LLM temperature (0.0–2.0)
integer
default:"4096"
Maximum tokens per LLM response

List Agents

GET /api/v1/agents Retrieve all agents with cursor-based pagination.
string
Cursor for pagination
integer
default:"25"
Results per page (max 200)
string
Filter by status: draft, active, paused, archived

Get Agent

GET /api/v1/agents/{id} Retrieve full configuration of an agent including tools, guardrails, and deployment status.

Update Agent

PUT /api/v1/agents/{id} Update an agent’s configuration. Changes take effect for new conversations immediately.

Delete Agent

DELETE /api/v1/agents/{id} Delete an agent. Active conversations are terminated gracefully. Response: 204 No Content

Deploy

Deploy Agent

POST /api/v1/agents/{id}/deploy Activate an agent and make it available on its configured channels. The agent must have a valid system_prompt.
string
required
Agent ID
string
required
The channel to deploy the agent to. One of webhook, sms, whatsapp, voice, rcs.
string
HTTPS callback URL for the webhook channel. Must be a valid HTTPS URL. An empty string is ignored and leaves any previously set URL unchanged.
string
E.164 phone number to bind the agent to. Required when channel is voice.

Undeploy Agent

POST /api/v1/agents/{id}/undeploy Remove an agent’s channel deployment. This clears the config.deployment metadata and sets the agent’s status to paused. For a voice deployment it also releases the bound phone number, so that number becomes available to deploy to another agent. No request body is required. To bring the agent back, call Deploy Agent again — redeploying flips the status back to active regardless of its previous state. This is distinct from pausing an agent: pausing stops new conversations but keeps the channel binding, whereas undeploying removes the binding entirely. This endpoint is rate limited to 5 requests per minute per API key, the same budget as Deploy Agent.
string
required
Agent ID

Pause / Resume Agent

There are no dedicated pause or resume endpoints. An agent’s lifecycle is controlled through its status field via Update Agent. To pause an agent, send PUT /api/v1/agents/{id} with { "status": "paused" }. Existing conversations are completed but no new ones are started. To resume a paused agent, send PUT /api/v1/agents/{id} with { "status": "active" }. To fully remove an agent’s channel deployment (rather than just pause it), use Undeploy Agent above. Valid status values are draft, active, paused, and archived.

Chat

Send Chat Message

POST /api/v1/agents/{id}/chat Send a message to an agent and receive a response. Supports both stateless single-turn and stateful multi-turn conversations.
string
required
Agent ID
string
required
User message text
string
Existing conversation ID to append onto, for multi-turn. Omit to start a new conversation.
object[]
Optional conversation history to seed the agent, additive on top of any persisted state. Each item is { "role": "user" | "assistant" | "system", "content": string }. Use this to inject prior turns or context instead of a separate context field.
boolean
default:"false"
Run the message in sandbox mode (does not persist the conversation).
string
Associate the conversation with a contact record.
string
Channel the message originates from (e.g., whatsapp, sms, web).
Streaming is a separate endpointPOST /api/v1/agents/{id}/chat/stream — not a stream: true flag on this request. See Streaming Responses below.

Streaming Responses

POST /api/v1/agents/{id}/chat/stream Streaming uses a dedicated endpoint rather than a flag on the chat request. It accepts the same request body as POST /api/v1/agents/{id}/chat (message, conversationId, history, sandbox, contactId, channel) and returns the response as Server-Sent Events (SSE) with Content-Type: text/event-stream. The runtime emits six event types as the turn progresses, each carrying a single JSON data payload:
  • event: status — a progress update while the turn runs (for example, retrieval or routing). data is { "status": "...", "detail": "..." }; detail may be omitted.
  • event: token — one incremental fragment of the assistant response. data is { "content": "..." }. Concatenate every content value in order to reconstruct the streamed reply.
  • event: tool_start — the agent invoked a tool. data is { "tool": "...", "input": { ... } }.
  • event: tool_end — a tool returned. data is { "tool": "...", "input": { ... }, "output": ... }, where output is the tool result (a string or JSON value).
  • event: response — the completed turn. data is { "response": "...", "tokensUsed": <number>, "promptTokensUsed": <number>, "completionTokensUsed": <number>, "apiCallsUsed": <number>, "escalated": <boolean>, "conversation_id": "..." }. tokensUsed is the scalar total token count for the turn; promptTokensUsed and completionTokensUsed split it, and conversation_id is the id to reuse for follow-up turns.
  • event: error — a terminal failure (upstream reset, timeout, provider error). data is { "code": "...", "message": "..." }. Treat this as stream completion.
The status, token, tool_start, and tool_end events are progress frames and may arrive zero or more times in any order as the turn runs. The stream terminates with exactly one response (success) or error (failure) event, after which the connection closes.
On failure:

Legacy streaming (POST //stream)

POST /api/v1/agents/{id}/stream A compatibility shim for SDK runtimes that cannot consume the preferred POST /api/v1/agents/{id}/chat/stream endpoint. It runs the same blocking turn as POST /api/v1/agents/{id}/chat, then replays the completed response over Server-Sent Events word by word, with a short gap between words, so a client gets a token-by-token render without the runtime producing true incremental tokens. Prefer chat/stream for new integrations; reach for this endpoint only when your client already expects a token / done SSE shape. It accepts the same request body as POST /api/v1/agents/{id}/chat (message, conversationId, history, sandbox, contactId, channel) and returns Content-Type: text/event-stream. The endpoint is rate limited to 20 requests per minute per tenant, the same budget as chat/stream. Three event types are emitted:
  • event: token — one fragment of the response. data is { "text": "..." }. The response is split on whitespace and each word and each run of whitespace is sent as its own token event, so concatenating every text value in order reconstructs the original response, spacing included.
  • event: done — the turn completed. data is { "totalTokens": <number>, "costCents": <number>, "conversationId": "..." }. Read conversationId to continue a multi-turn conversation.
  • event: error — a terminal failure. data is { "code": "...", "message": "..." }. No further events follow.
Every successful stream ends with a single done event after the last token; a failed stream ends with one error event instead. The connection then closes. If the client disconnects mid-stream, the server stops sending tokens.
On failure:

Conversations

List Conversations

GET /api/v1/agents/{id}/conversations Retrieve conversation history for an agent.
string
Cursor for pagination
integer
default:"25"
Results per page (max 200)
string
Search conversations by message content (case-insensitive substring match, max 200 characters)

Get Conversation Messages

GET /api/v1/agents/{id}/conversations/{conversationId}/messages Retrieve the full message history of a specific conversation.

MCP Servers

Register your own Model Context Protocol (MCP) servers so an agent can discover and call tools you host, without Devotel adding a built-in integration for each one. At inference time the agent runtime fetches each enabled server, lists its tools, and adds them to the agent’s tool catalog alongside built-in tools. Servers are scoped to a single agent and to your organization. Management endpoints require the owner, admin, or developer role; listing a server’s configuration is available to any authenticated member.

Register MCP Server

POST /api/v1/agents/{agentId}/mcp-servers
string
required
Agent ID the server is registered against.
string
required
Display name for the server. Must be unique within the agent — registering a second server with the same name returns 409 MCP_SERVER_NAME_CONFLICT.
string
required
The server’s endpoint. Must be a public https:// URL. URLs that resolve to private, loopback, link-local, or cloud-metadata addresses are rejected with 422 INVALID_MCP_SERVER_URL.
string
required
Transport. Only http_sse is supported.
string
A static bearer token or API key sent to your server, stored encrypted at rest. Mutually exclusive with oauth2.
object
An OAuth2 grant the runtime exchanges for a live access token before calling your server. Mutually exclusive with auth_credentials. The interactive authorization-code (browser redirect) flow is not supported.
string[]
Restrict which of the server’s tools the agent can see and call. Omit to expose every discovered tool. Pass an array to expose only those tool names. Pass [] to expose none without removing the server.
object
Free-form key/value metadata stored with the server.
boolean
default:"true"
Whether the agent loads tools from this server.
Credentials are never returned over the wire. Responses expose only a has_auth_credentials boolean and auth_type (bearer, oauth2, or none).

List MCP Servers

GET /api/v1/agents/{agentId}/mcp-servers
string
required
Agent ID.
string
Cursor for the next page. Pass back the meta.pagination.cursor value from the previous response; omit for the first page.
integer
default:"100"
Results per page (max 200).
Returns the servers registered for the agent, newest first, with cursor-based pagination. Each entry carries id, organization_id, agent_id, name, server_url, server_type, metadata, enabled, created_at, updated_at, has_auth_credentials, and tool_allowlist (null when no allowlist is set). Use meta.pagination.cursor with has_more: true to fetch the next page.

Update MCP Server

PATCH /api/v1/agents/{agentId}/mcp-servers/{id} Change a registered server’s tool allowlist and/or enabled state. Send at least one field.
string
required
Agent ID.
string
required
MCP server ID.
string[] | null
An array replaces the allowlist ([] exposes no tools); null clears it so every discovered tool is exposed again; omit to leave it unchanged.
boolean
Toggle the server on or off without deleting it.

Delete MCP Server

DELETE /api/v1/agents/{agentId}/mcp-servers/{id} Remove a registered server. The call is idempotent: deleting an id that no longer exists returns 200 with deleted: 0 rather than a 404, so retries are safe.
string
required
Agent ID.
string
required
MCP server ID.

Probe MCP Server

POST /api/v1/agents/{agentId}/mcp-servers/probe Test a candidate URL and credentials before registering. The probe runs the same tools/list request the runtime uses at discovery time, so a successful probe predicts the server will register cleanly. Nothing is persisted.
string
required
Agent ID.
string
required
Server endpoint to probe. Same https://-only, public-address validation as on register.
string
Transport. http_sse if provided.
string
Static bearer token to test. Mutually exclusive with oauth2.
object
OAuth2 grant to test (same shape as on register). Mutually exclusive with auth_credentials.
The response reports the outcome. status is one of ok, ssrf_blocked, timeout, unreachable, auth_failed, http_error, or protocol_error. On success tools lists the discovered tool names; otherwise error carries a short, safe explanation.

Test MCP Server

POST /api/v1/agents/{agentId}/mcp-servers/{id}/test Health-check an already-registered server using its stored credentials, and save the result so the dashboard can show a health status without re-probing.
string
required
Agent ID.
string
required
MCP server ID.
The response uses the same verdict fields as the probe (ok, status, tool_count, tools, http_status, error, checked_at), plus the server id and agent_id.

Agent Statuses

Examples

Node.js

A first-party Python SDK is on the roadmap but not yet shipped. Call the REST endpoints above with requests / httpx / any HTTP client.