Skip to main content
The developer API uses workspace keys from Workspace settings → API keys. Its base URL is https://app.cntillion.com/api/v2. Owners and members can create keys. Each key can access every agent in its workspace, with Full access, Monitor or Read only permissions and an optional expiration date. Monitor reads like Read only and can also use real-time monitoring. Send the key as Authorization: Bearer cl_api_.... A client that keeps that header for its own gateway can send X-API-Key: cl_api_... instead. Copy the key when it is created. Centillion stores only a hash and cannot show it again. Revoking or expiring a key stops new requests; a request already running may finish. Keep keys in server environment variables, never browser code. The workspace may have 20 active keys. These keys are separate from agent-specific Zapier connections.

First request

Copy an Agent ID from its General settings or the API keys page.
The response contains data.id, data.role, data.parts, and data.metadata. Text parts have type: "text" and text. Metadata includes conversationId, userMessageId, userId, finishReason, and usage. Send conversationId with the next message to continue. Centillion loads the stored history. Only API conversations can continue through this endpoint. userId is optional; when provided on a follow-up, it must match the stored user. The first request can include conversation_initiation_client_data with typed dynamic_variables and permitted agent overrides. Later requests omit it; voice and duration overrides are rejected for chat. This does not call an initiation webhook. See Personalization for the body and override permissions. Omit conversationId to start over. A UUID requestId can identify retries of the same chat request. Read-only keys cannot send chat messages.

Streaming

stream defaults to true. Read SSE events from the response body:
Append text-delta.delta to display the answer. Read the conversation ID from finish.messageMetadata. Failures emit an error event with code and errorText, followed by [DONE]. The API returns answer text. Internal tool arguments, tool results, and attachment storage paths are not exported.

Agents and settings

Create accepts name and optional role, websiteUrl, instructions, model, and temperature. Roles are customer-support, sales-agent, and shopping-assistant. Model defaults to google/gemini-3.5-flash-lite; use the model IDs shown in Centillion’s model picker. Temperature ranges from 0 to 1. If a supplied website cannot be added, creation still returns the new ID with pendingSteps: ["ADD_SOURCE"]; retry through the Sources endpoint. Updates accept name, instructions, model, temperature, guardrails, greeting, and defaultLanguage. Omitted fields stay unchanged. Set defaultLanguage to null to clear it. An explicit branch_id in the PUT/PATCH query or JSON body updates that branch’s published configuration and creates a new version automatically. This update starts from the published head, so it does not publish unrelated dashboard drafts. Optional revision detects a concurrent branch update; message labels the new version. A shared agent name can only be changed on Main. Published versions cannot be updated through version_id. A PUT/PATCH without a branch selector updates Main the same way and returns Main’s new configuration. Personal drafts keep their unpublished changes as the branch head moves. An open dashboard editor receives the new values for fields without personal edits; an editor on another branch keeps its work. A protected Main rejects updates from API keys. Agents created before version control, which have no Main yet, update their settings directly. Styles accept displayName, initialMessages, messagePlaceholder, footer, suggestedMessages, showSuggestedMessages, keepSuggestedMessages, theme, accentColor, accentEnabled, accentHeader, accentSend, radius, fontFamily, fontSize, bubblePosition, bubbleColor, bubbleIcon, showAgentBubble, collectFeedback, and copyMessage. Use the same values as the dashboard. Unknown properties are rejected. Clone accepts {} or an optional name. Each active branch starts with one new version containing that branch’s published configuration. Version history, personal drafts, archived branches, and traffic splits are not copied. Main receives 100% of the new agent’s traffic. Actions, evaluation criteria, tests, and voice configuration receive new agent-owned identities. Ready text, Q&A, file, and website sources remain shared workspace sources. Integrations, conversations, Notion connections, and phone routing are managed separately. The clone begins training automatically and checks the current per-agent knowledge storage limit. The copy’s Main answers with the new training as soon as it finishes.

Version control

New agents start with Main, version 1, and 100% traffic on Main. Reading GET /agents/{agentId} returns Main’s published configuration. Select another branch with branch_id, a historical version with version_id, or the key creator’s personal branch draft with include_draft=true. A version ID cannot be combined with include_draft=true. Selecting a configuration does not change the dashboard editor.
Versioned agent reads include branchId, versionId, isDraft, and the full configuration snapshot alongside the agent settings. Stored request headers and signing secrets are redacted. Managed ticket and Notion source content is not returned. Read-only keys also redact action request bodies. Create a branch with name and optional description, fromBranchId, or versionId. Metadata updates accept name, description, and autoRebase. Main cannot be renamed or archived. Archive a branch only after its traffic allocation is zero. Branch configuration reads accept include_draft=true. History reads accept limit and cursor; agent history also accepts branch_id. Version comparison accepts against=previous or against=live. Saving a draft requires its branch revision and either settings containing submitted prompt, guardrail, greeting, model, temperature, or language fields, or a full configuration snapshot from a versioned read. Configuration IDs must belong to the agent or its workspace library. Redacted credentials are preserved when sent back unchanged. Changing a shared tool’s definition requires the key creator’s tool editing permission.
Publish with revision, optional message, and optional restoreVersionId. Restoration creates a new version and keeps the existing history. Traffic updates accept allocations: [{"branchId": "BRANCH_ID", "percent": 100}]; percentages must total 100. Merge accepts targetBranchId, optional force, and archiveSource, which defaults to true. Protected branches require a workspace owner to make changes in the dashboard. All writes require a full-access workspace key.

Knowledge sources

PUT can send only changed source fields. Source types and link URLs cannot be changed. Upload files with multipart fields file and optional name. Files may be up to 20 MB; text and Q&A sources allow 1 MB of extracted text. Existing workspace storage limits apply. Notion sources can be read and deleted but must be created or edited through the dashboard integration. Ticket sources use the tickets type in list responses, filters, and summaries. Their content is not returned. Configure the provider in the dashboard; cloning an agent does not attach ticket sources or copy their provider connections. These endpoints read and change Main’s knowledge, including pending API source changes. The branch open in the dashboard does not change their target. POST /agents/{agentId}/train also trains Main’s sources. Sources attached only to another branch or a personal draft are excluded. Writes queue training automatically. Poll the source for untrained, updated, trained, or failed, or poll the agent’s status and trainingError. Earlier trained content remains available during replacement training. When training finishes, Main gets a new version, “Knowledge updated through the API”, with Main’s sources and the finished training, so chat answers from them. Personal drafts keep their unpublished edits. Deleting a source removes it from Main before retraining starts and leaves other branches’ attachments in place. Retry failed training with POST /agents/{agentId}/train. The summary returns count and bytes for each source type, plus shouldRetrain, which is true while any source has changes its last training did not include.

Conversations and customer data

Pause with {"paused":true} and resume with {"paused":false}. Feedback accepts {"feedback":"positive"}, "negative", or null to clear it. Conversation lists accept startDate and endDate as ISO timestamps. Export accepts an optional conversationId.

Conversation analysis

GET /agents/{agentId}/analysis/{conversationId} returns the latest analysis and latest result for each criterion. Use the internal conversation ID shown in the dashboard or in an analysis webhook. For channel threads, pass ?source=CHANNEL_CONVERSATION; the default is CONVERSATION_LOG. A full-access or read-only workspace key can read results. data.analysis includes job status, error, completedAt and result. A completed result contains data (typed values, evidence and scope), sentiment (label, score, frustration, rationale and user-turn trajectory), and topics. It is null before analysis has been queued. Each entry in data.evaluations contains its criterion name, status, verdict or score, rationale and frozen scoring/model/scope configuration. Results may still be pending; use the status rather than treating a missing value as failure. The existing conversation detail endpoint also includes analysis for stored chat conversations. Its conversation ID remains the external session ID, as described above. Results from other workspaces are never returned.

WhatsApp templates

Send an approved WhatsApp template from your own systems, for example when an application needs more information or a payment bounced. A template is the only way to message someone who has not written to your number in the last 24 hours. Create templates in Meta’s WhatsApp Manager; Centillion lists the ones Meta has approved. The listing returns senders, each with phoneNumberId, phoneNumber, displayName, status, and wabaId, and templates, each with name, language, category, wabaId, its header, body, and footer text, the variables each component takes, and sendable. A template with an image, video, or document header, or with a button that takes a value, has sendable: false and an unsupportedReason. When Meta cannot be read for a business account, complete is false and unavailableWabaIds names it.
  • to is the customer’s number with its country code.
  • from is a sender’s phoneNumberId or phoneNumber. Omit it when the agent has one WhatsApp number.
  • template.language can be omitted when the template is approved in one language.
  • variables gives each placeholder’s value by component and key: "1" for {{1}}, or the name of a named placeholder. Every placeholder needs a value. Header values may be up to 60 characters and body values up to 1,024, with no line breaks, tabs, or five spaces in a row.
  • customerName names the conversation when this is the first message to the number.
A sent template returns 201 with data.id, data.status (accepted), data.providerMessageId, the body as the customer sees it, and data.channelConversationId. Replies arrive in that conversation, where the agent answers them like any WhatsApp message while the number’s automatic replies are on. A conversation a teammate has taken over stays with them. Every send needs an Idempotency-Key header, unique to the message you mean to send. Retrying with the same key and body returns the first result with Idempotent-Replayed: true and never messages the customer twice. Reusing the key with another body returns 409 IDEMPOTENCY_KEY_REUSED. When Centillion cannot confirm whether Meta sent the message, it returns 502 DELIVERY_UNCONFIRMED, and retries with that key return 409 DELIVERY_UNCONFIRMED: check the conversation before sending again with a new key. Read the delivery status afterwards. status moves from accepted to sent, delivered, and read, or to failed with Meta’s error code in error.code. Centillion does not send to a customer who sent STOP to any of the agent’s WhatsApp numbers. A customer who turned off marketing messages from your business in WhatsApp still gets utility and authentication templates, but not marketing ones. Sending needs a plan that includes API access, and Meta bills each template to your WhatsApp Business account.

Agent testing

Use the testing API to create reusable workspace tests, attach them to agents, run suites against selected configurations, and read transcripts, verdicts, and grouped failure reasons. Runs support idempotent requests and explicit message-credit opt-in. The JavaScript client and CLI can use these results as a CI release check.

Helpdesk

Workspace keys also authenticate the Helpdesk API. Any key can read tickets. Creating and updating tickets needs a Full access key and a plan that includes Helpdesk. A ticket’s history shows changes made with a key as made by the API. Attachment and image links in ticket responses still need a signed-in dashboard session.

Pagination and errors

List endpoints accept limit, from 1 to 100, default 20, and an opaque cursor. The response is {"data":[...],"pagination":{"cursor":null,"hasMore":false,"total":0}}. Pass the returned cursor with the same filters to fetch the next page. Message pages contain chronological messages, paging backward from the newest. PUT endpoints also accept PATCH. All writes require a full-access key. Every resource query is scoped to the key’s workspace; inaccessible resources return 404. Workspace keys do not authenticate the voice APIs. GET /health needs no key and returns {"data":{"status":"ok"}}. Every response includes x-request-id and Cache-Control: no-store. Authenticated requests include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, a Unix timestamp in milliseconds. Each key permits 100 requests per 10-second sliding window. A 429 response includes Retry-After in seconds. Agent message limits and workspace credits still apply. Errors use {"error":{"code":"UNAUTHORIZED","message":"..."}}: Configure event deliveries in Agent settings → Webhooks. For client-side embedding and identity, use the website guide or mobile SDKs.

Batch calls

Create, schedule and manage phone or WhatsApp voice batches with the batch calling API. It supports inline recipients, resumable imports, paginated results and the same controls as Outbound.
Last modified on November 1, 2026