Skip to main content

AI API

A focused set of LLM-backed primitives that the Orbit platform uses internally — message analysis, reply suggestion, intent classification, summarization, content generation, and a small knowledge-base utility. All LLM requests route through Orbit’s partner-vetted Anthropic gateway — you don’t manage model-provider keys directly. Base path: /api/v1/ai Authentication: API key (X-API-Key) or session JWT. Service-to-service callers authenticate with X-Orbit-Signature (an HMAC-signed request) and get the developer role to cap blast radius. The legacy X-Internal-Token bearer header is still accepted only until 2026-09-01, after which requests using it will be rejected — internal callers should migrate to X-Orbit-Signature before that date. Response envelope: every route returns a { "data": <payload>, "meta": { "request_id", "timestamp" } } wrapper. The samples below show the full envelope once and then the inner data payload only. All endpoints except /kb/* share a 30-requests-per-minute LLM rate limit; KB reads sit behind a lighter authenticated-read limit.

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:
Raw curl in the body of this page works identically. Full SDK index at SDK quickstart.

Analysis & insight

Analyze

POST /api/v1/ai/analyze analyzes free text for sentiment, intent, detected language, and extracted topics. Feed it any customer-facing text — an inbound SMS body, an email snippet, a product review — and it returns a structured breakdown you can route on.
A body missing text returns 422 VALIDATION_ERROR.

Analyze a message by ID

POST /api/v1/ai/analyze-message/{id} loads one stored message, runs the same analysis, and persists the result into the message’s metadata so you get a durable audit trail.
A missing id returns 422; an unknown or body-less message returns 404 / 422.

Classify intent

POST /api/v1/ai/classify-intent classifies the dominant intent for a conversation (billing, support, sales, complaint, general inquiry, and so on) from its transcript, with a confidence score and a one-line rationale.
A conversation with no messages returns 422 with the message “Conversation has no messages.”

Summarize a conversation

POST /api/v1/ai/summarize-conversation collapses a thread into a one-paragraph summary, key topics, and the overall sentiment — the same digest the supervisor inbox uses.

Generation & rewriting

Suggest a reply

POST /api/v1/ai/suggest-reply reads the conversation transcript and returns 2–3 ready-to-send reply drafts, each tagged with a tone (professional, empathetic, concise) and a confidence score — the same inline copilot the agent inbox uses.
A missing conversation_id returns 422 VALIDATION_ERROR:

Generate content

POST /api/v1/ai/generate-content writes channel-appropriate message copy from a brief. The campaign composer and send dialogs both call this — pass a channel so the result fits the target (SMS length, WhatsApp formatting, email subject/body). The server-side grounding guard strips any offer, discount, price, or urgency claim the operator’s brief did not already make.

Improve text

POST /api/v1/ai/improve-text rewrites an existing message. Choose the action: improve (general polish), shorter, longer, change_tone, fix_grammar, or rephrase. If the model returns no usable rewrite the endpoint hands back your original text unchanged with a 200 — the AI-assist button never breaks the composer.

Translate

POST /api/v1/ai/translate translates free text into a target language, reporting the detected source language in the response.

Compose a campaign

POST /api/v1/ai/compose-campaign turns a plain-English goal into a full campaign blueprint: a name and description, per-channel message drafts, a visual journey graph (React Flow nodes and edges) ready to drop into the canvas, and an audience hint. The result is a draft — the operator still reviews it and clicks Launch.

Optimize channel

POST /api/v1/ai/optimize-channel scores a recipient’s delivery history, reachable identifiers, and cost to recommend the best channel (with fallbacks) for one message. Campaigns use this as the auto channel selector.

Inference building blocks

Two general-purpose endpoints let you run embeddings and chat inference on the same managed fleet — and the same wallet — as the rest of your Orbit comms. Both are OpenAI-compatible, so existing SDKs drop in by pointing their base URL at /api/v1/ai.
Both endpoints call a model provider on every request and are billed per token, metered to your workspace wallet. They share the same rate limit as the other AI routes.

Embeddings

POST /api/v1/ai/embeddings returns one vector per input. Send input as a single string, or as an array of up to 96 strings (each 1–10,000 characters) to embed a batch in one request.
The OpenAI-compatible envelope (object: "list", per-input embedding, usage) sits under data:
A malformed body (missing input, an empty string, or more than 96 items) returns 400.

Chat completions

POST /api/v1/ai/chat/completions is OpenAI-compatible. Point any OpenAI SDK at your /api/v1/ai base URL — the SDK appends /chat/completions — and send a messages array. OpenAI model ids are remapped to the platform’s managed model, so you don’t manage provider keys.
The OpenAI-style chat.completion envelope (choices, usage) sits under data:
A body missing messages (or with an out-of-range field) returns 400.

Node / OpenAI SDK snippet

The two inference endpoints are an OpenAI drop-in — set the base URL to /api/v1/ai, send any OpenAI model id, and it is remapped to the platform’s managed model. Either library style works:
Plain fetch works too — wrap the API in a helper that posts to the Orbit envelope and reads data:

Knowledge base

An embedded, org-wide knowledge base: ingest documents (upload, URL, markdown, or a bulk help-center import), keep them fresh with a staleness scorecard and per-document verification, and query them with raw semantic search or a grounded answer with citations. For a separately provisioned, per-knowledge-base store, use the Knowledge Bases API instead.

Mini-cookbook: ingest → poll → search → answer

The full KB lifecycle in four calls. Upload a markdown document, poll it until it is ready, run a raw semantic search, then get a grounded answer with citations. Like the rest of /api/v1/ai, these routes have no typed SDK helper today — the samples below pair each step’s curl with the Node SDK generic orbit.request escape hatch or plain fetch, and the Python SDK client.request (which prepends /api/v1) or plain requests, following the same pattern as the Verify factor suite.

1. Ingest a document

POST /api/v1/ai/kb/documents ingests a markdown document, uploads a file, or imports a public URL. One document at a time.
The response carries the new document record (id, name, source_type, status, chunk/token counts, timestamps) under data — every example above reads the same envelope, so curl, SDK, and fetch/requests stay interchangeable. It enters processing, generating a chunk index on the server. To upload a binary file instead, send multipart/form-data (10 MB max). For a public URL source, send { "source_type": "url", "source_url": "https://example.com/policy" }. For a bulk Zendesk Guide import, POST /kb/import/help-center queues one document per published article.

2. Poll until ready

GET /api/v1/ai/kb/documents/{id} checks the document status.
Same poll in code — Node SDK first, plain fetch below it; Python SDK client.request and requests take one-second sleep loops:
Wait for status: "ready" — only then will queries hit the document. A staleness block always accompanies the document detail; list endpoints page back with { documents, next_cursor }. POST /api/v1/ai/kb/search runs a raw semantic search across all ingested documents, returning the top matching chunks with their cosine/re-rank score, parent document, and chunk index.

4. Grounded answer

POST /api/v1/ai/kb/answers runs the knowledge base’s grounded QA loop — it retrieves the chunks above, then has the LLM synthesis an answer with citations and a confidence score. Call it (rather than raw search) from a customer-facing surface; the answer only counts as billable when the model is confident the source document covers the question.
answered: false means the KB does not cover the question — the answer comes back null with low confidence. Scope the search with knowledge_base_ids, threshold, min_confidence, or language; gating by audience ACLs is always enforced.

See also