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.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:
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. ReadingGET /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.
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.
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
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.
tois the customer’s number with its country code.fromis a sender’sphoneNumberIdorphoneNumber. Omit it when the agent has one WhatsApp number.template.languagecan be omitted when the template is approved in one language.variablesgives 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.customerNamenames the conversation when this is the first message to the number.
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 acceptlimit, 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.