Skip to main content

AI assistants

An assistant is an Orbit AI agent: a named system prompt, model, and tool set that you bind to a channel when you deploy it. This page is the worked reference for the assistant lifecycle — create, list, fetch, update, deploy, undeploy, and delete — with one assistant_id carried across the whole sequence. Field-level reference lives in the Agents API; this page walks the sequence end to end. Base path: /api/v1/agents Authentication: API key (X-API-Key) or session JWT. Create, update, deploy, undeploy, and delete require an owner, admin, or developer role; list and fetch are open to any authenticated role. Every response below carries the full { data, meta } envelope — meta.request_id and meta.timestamp on the success path, a labelled error envelope on the failure path — the same floor as SDK sample coverage policy.

Using the SDKs

The assistant lifecycle has no typed helpers yet, so the Node.js samples on this page route through the generic orbit.request() escape hatch — auth, retries, and the { data, meta } envelope stay identical to the typed client:
Python samples use plain requests, and Go, Ruby, and PHP use the plain standard-library HTTP form — deliberately dependency-free per the SDK language policy and Writing compliant API samples. Full SDK index at SDK quickstart.

Lifecycle worked sequence

Create the assistant once, reuse its assistant_id for everything afterward. Nothing seeds channel binding on create — the agent lands as a draft, and deploy flips it active.

1. Create the assistant

Response 201:
Carry the returned assistant_id (agt_8f2e41abcc9d70) through the rest of this page — it is the same id you pass to fetch, update, deploy, undeploy, and delete.

2. Deploy the assistant to a channel

deploy binds a channel and moves the assistant out of draft into active. The channel name is one of webhook, sms, whatsapp, voice, or rcs; webhook_url is required only for webhook channels, and a phone_number is required only for SMS / WhatsApp / voice.
Response 200 — status is active and config.deployment carries the channel binding:

3. List to confirm the assistant is live

Response 200 — the envelope’s meta.pagination carries the cursor and has_more pair you use to walk the full list:

4. Fetch one assistant by id

The same { data, meta } envelope as the list, without pagination. Use this form when you already know the id — there is no separate “assistant detail” resource.

5. Update the system prompt, tools, or safety config in place

PATCH rewrites only the fields you send. Bump the prompt or safety configuration without redeploying.
Response 200:

6. Undeploy, then delete

undeploy drops the channel binding and flips status back to draft. Delete the assistant only when it is no longer needed — conversation history stays on the tenant.
Undeploy returns 200 with the same envelope. Delete returns 204 No Content with an empty body.

Error envelopes

An unknown id — whether passed to fetch, update, deploy, undeploy, or delete — answers 404 with a labelled error envelope, not a bare status:
404 Error
Validation failures on create come back as 422 VALIDATION_ERROR — one entry per field, with the same meta block. A cross-tenant id returns the same 404 NOT_FOUND as one that never existed, so existence cannot be probed across organizations. If you receive a 403 INSUFFICIENT_PERMISSIONS, the caller’s role is below developer; only owner, admin, and developer may write assistants.

Language coverage per the SDK sample policy

Every operation on this page shows the compliant six-form block — cURL, Node.js (TypeScript), Python, Go, Ruby, and PHP inside one <CodeGroup> — the same per-operation floor the SDK sample coverage policy sets and Writing compliant API samples operationalizes. Node.js runs the orbit.request() escape hatch; Python uses plain requests; Go, Ruby, and PHP use the plain standard-library HTTP forms, so no sample depends on a typed helper that may not exist yet. For routes outside this lifecycle — or when the anchor id you need is outside the worked sequence — each public SDK still ships an untyped request method that reaches any endpoint. The route shape above applies verbatim; the per-language escape-hatch names (client.request in Java and Ruby, client.RequestAsync in C#, $client->request in PHP) are catalogued in the SDK language policy escape-hatch table. See also Agents API for the full field catalogue and Agent templates for the pre-built-into-assistant flow.