Skip to main content

Orby Assistant API

Orby is Orbit’s in-dashboard operator assistant. These endpoints power the Orby chat panel: you send a message, Orby streams back a response over Server-Sent Events (SSE), and — when a turn proposes an action that changes data (such as sending an SMS or reassigning a conversation) — it pauses for an explicit approval before running it. Orby is operator-facing. Every endpoint runs in the context of the signed-in dashboard user, scoped to that user’s organization and tenant. There is no server-to-server API-key path for Orby. Base path: /api/v1/orby

Using the SDKs

Prefer the typed client, but this page’s endpoint has no helper yet — the generic request() keeps auth/retries and the { data, meta } envelope identical:
Python (same call via the SDK’s escape hatch):
The Python SDK is core-scope — it wraps the 8 core resources (messaging, voice, contacts, campaigns, verify, numbers) and reaches everything else through the generic client.request() escape hatch above. See the Python SDK for install. Go, Ruby, and PHP ship the same untyped request method — call it the same way you would any untyped endpoint:
Samples below stay dependency-free so they run even before you vendor an SDK. Full SDK index at SDK quickstart.

Authentication

Orby uses the dashboard user (Bearer token) method, not an API key. Send the signed-in operator’s JWT:
A request authenticated with an API key — whether sent as X-API-Key or as a dv_* Bearer token — is rejected with 403 ORBY_SESSION_REQUIRED. There is no server-to-server path. When any ORBY_* code comes back, use Troubleshooting: Orby operator errors for the cause table and fix path per code. Every Orby endpoint requires one of these operator roles: owner, admin, developer, viewer, or billing. Two knowledge-base maintenance endpoints (POST /kb/reindex and GET /kb/status) additionally require super-admin and return 403 INSUFFICIENT_PERMISSIONS otherwise. A thread belongs to the operator who created it. You can only list, read, and post turns to your own threads — requesting another operator’s thread returns 404.

Rate limits

When you exceed the turn limit, POST /assistant returns 429 ORBY_RATE_LIMITED with a Retry-After header (seconds).

Run a turn

POST /api/v1/orby/assistant Start a new Orby conversation or continue an existing thread. The response is an SSE stream (Content-Type: text/event-stream), one event per token and per lifecycle step, terminated by a done event.
string
required
The operator’s message. 1–8000 characters.
string
Continue an existing thread. Omit to start a new one — the response stream reports the new thread_id in the final response event, and the thread is auto-titled from your first message.
object
Optional context describing the dashboard page the operator is on, so Orby can ground its answer. All fields are optional.
Pass an optional Idempotency-Key header to make a retried turn safe against double-execution of any tool it runs.

Stream events

Each SSE frame has an event: name and a JSON data: payload. Read them in order until you receive done (success) or error (failure); the connection then closes.
When Orby pauses on a tool_pending event, you can resume the same turn either by redeeming the pending action through the tool-actions endpoints, or by sending a follow-up turn on the same thread whose message is a plain confirm / yes / cancel. The chat reply and the explicit approve/reject button resolve through the same path, so the audit trail is identical.

Consume the stream (worked example)

A turn consumer does three jobs: open the connection, dispatch each named event, and handle tool_pending by holding the pending_action_id for approval or rejection. Register a listener per named event — the events listed above arrive as event: router, event: token, and so on, so a generic onmessage / message handler never sees them. State you track while the stream runs:
  • text — concatenate every token payload’s content in order. The response event then reports the full assembled answer, so you never have to re-assemble it client-side.
  • Pending actions — on tool_pending, store the pending_action_id with the tool name, input, and cost estimate, then render an approve/reject control (see Redeem a pending action below). A tool_end payload that arrives after approval reports the tool’s result.
  • Thread handle — hold the operator JWT in a variable; every request on this page carries it as Authorization: Bearer.
Both samples dispatch on the named events the Stream events table lists. Ignore any event name you do not handle — adding event types is backwards-compatible.

Redeem a pending action

On tool_pending, hold the pending_action_id and redeem it through the tool-actions endpoints. The approve call can race a second click or arrive after the 5-minute expiry window, so retry 409 responses whose error_code is PENDING_ACTION_RACE or PENDING_ACTION_EXPIRED after refreshing the action state.
To cancel instead, POST to /tool-actions/{id}/reject; the same pattern applies.

Poll the pending action and render the countdown

While an approval control is on screen, poll GET /tool-actions/{id} (120 requests per minute per tenant — once every few seconds is enough) and count down to expires_at. When the window elapses, disable the control: the next poll reports the action as cancelled with error_code: PENDING_ACTION_EXPIRED.

Threads

List threads

GET /api/v1/orby/threads Return the operator’s most recent threads (up to 50, newest first) for the “Past chats” panel.
403 ORBY_SESSION_REQUIRED

Create a thread

POST /api/v1/orby/threads Pre-allocate an empty thread before the first message (the chat panel uses this to reserve a thread id up front). You can also let POST /assistant create the thread implicitly by omitting thread_id.
string
Optional thread title (max 200 chars). Left empty, the thread is auto-titled from the first message.
object
Optional page context stored on the thread.
422 Validate — missing search text

Get thread messages

GET /api/v1/orby/threads/{id}/messages Replay a thread’s persisted messages (oldest-first) to re-render history on reload.
string
required
Thread id.
404 THREAD_NOT_FOUND

Tool confirmations

When a turn proposes an action that changes data, Orby does not run it immediately. It emits a tool_pending event carrying a pending_action_id and waits. Approve to execute, or reject to cancel. A pending action expires 5 minutes after it is created; an expired action returns 409 PENDING_ACTION_EXPIRED.

Approve an action

POST /api/v1/orby/tool-actions/{id}/approve Execute the pending action. Returns the tool’s result once it runs.
string
required
The pending_action_id from the tool_pending event.
409 PENDING_ACTION_NOT_APPROVABLE

Reject an action

POST /api/v1/orby/tool-actions/{id}/reject Cancel the pending action without running it.
string
required
The pending_action_id.
409 PENDING_ACTION_EXPIRED

Poll an action

GET /api/v1/orby/tool-actions/{id} Read the current state of a pending action, including its expires_at so you can render a countdown. A pending action whose window has elapsed is reported as cancelled with error_code: PENDING_ACTION_EXPIRED.
string
required
The pending_action_id.
404 NOT_FOUND
Action states are pending, executing, done, undone, failed, and cancelled. Only a pending action can be approved or rejected — acting on any other state returns 409 PENDING_ACTION_NOT_APPROVABLE, and a concurrent second approve returns 409 PENDING_ACTION_RACE. Both approve and reject are idempotent in effect: the action runs (or cancels) exactly once. A done action moves to undone when the operator reverses it within the tool’s undo window — for example, a sent message rolled back inside its 30-second grace period. Treat undone as a terminal state whose side effect has been undone; it differs from cancelled, which marks an action that was rejected (or expired) before it ever ran.

Orby can search the Orbit product documentation so operators can answer “where do I configure X” without leaving the dashboard. These endpoints sit under /api/v1/orby/kb.

Search docs

GET /api/v1/orby/kb/search Hybrid search over the Orbit docs index. Available to any authenticated operator role.
string
required
Search text. 1–500 characters.
integer
default:"10"
Results to return (max 50).
string
Restrict to a docs section.
string
Restrict to a docs category.
422 VALIDATION_ERROR

Find a setting

POST /api/v1/orby/kb/find-setting Map a plain-language description to the dashboard route where the setting lives. Available to any authenticated operator role.
string
required
What the operator wants to configure. 1–500 characters.
integer
default:"10"
Matches to return (max 20).
422 VALIDATION_ERROR

Reindex and status (super-admin)

POST /api/v1/orby/kb/reindex triggers a rebuild of the docs index and returns immediately with { "scheduled": true } (or { "ran_inline": true } when the corpus is available in-process). GET /api/v1/orby/kb/status returns a health snapshot: total and stale chunk counts, the last run timestamp, the current version, and cache hit rate. Both require the super-admin role and return 403 INSUFFICIENT_PERMISSIONS otherwise.
403 INSUFFICIENT_PERMISSIONS