An API integration connects Chatonio to one of your backend services so the AI can call it as a tool during a conversation — look up an order, check a balance, create a ticket, anything your API can do. Each integration owns a base URL and an auth config; one integration can expose many tools (one per endpoint you want the AI to be able to call).
When to add an API integration
- The customer’s answer depends on data that lives in your system (order id, subscription status, account balance).
- You want the AI to do something on the customer’s behalf — issue a refund, cancel a booking, mark a ticket resolved.
- For pure FAQ knowledge, prefer KB articles instead — integrations are for live, per-customer data.
Step 1 — Open the Integrations page
From the operator dashboard, go to Admin → Projects → [your project] → Integrations. You need ADMIN or MANAGER role on the project. The page lists every integration in the project, each with its tools nested underneath.
Step 2 — Create the integration
Click + Add above the integrations list. The form runs in two short steps — Connection then Auth & scope — and asks for:
- Name — internal label (e.g.
Stripe,OrderService). - Base URL — the root of every endpoint, no trailing slash (e.g.
https://api.example.com). - Auth type — pick one of
none,api_key,bearer, orbasic. - Available on — All channels by default, meaning every channel in the project. Switch it to Specific channels to scope the integration — Telegram bots, Telegram group chats, web chat widgets, email addresses, or your helpdesk portal.
Step 3 — Configure auth
Auth credentials are encrypted at rest — you only ever see them once at entry. Pick the right shape:
API key (custom header)
{
"type": "api_key",
"header": "X-API-Key",
"value": "sk_live_…"
}Sent as X-API-Key: sk_live_… on every call. Pick any header name your API expects.
Bearer token
{
"type": "bearer",
"token": "eyJhbGciOi…"
}Sent as Authorization: Bearer eyJhbGciOi….
Basic auth
{
"type": "basic",
"username": "service-user",
"password": "…"
}Custom headers
{
"type": "headers",
"headers": {
"API-LOGIN": "…",
"API-KEY": "…"
}
}For an API that needs more than one credential header at once — a separate login and key, for example. Each row is sent as its own request header. Use this instead of API key when a single header is not enough.
Step 4 — Add tools (the actual endpoints)
An integration is dormant until you add at least one tool. A tool is one HTTP endpoint the AI can call. Select the integration in the list on the left — the Tools column appears on the right — then click + Add tool and work through the three steps — What it does, How to call it, Try it:
- Name — short, action-oriented, snake_case (
get_order_status,cancel_subscription). The AI sees this name. - Description — one sentence explaining when to use it. The AI reads this to decide. Be precise: “Returns the current shipping status for an order id. Use when the customer asks where their order is.”
- HTTP method —
GET,POST,PUT, orPATCH. - Endpoint path — appended to the integration’s base URL. Supports
{placeholder}tokens that get filled from the parameters schema (e.g./orders/{order_id}/status). - Parameters — what the AI must pull out of the conversation before it can call the tool. Add one row per value and give each a name, a type, whether it is required, a description and an optional pattern. Each row shows a badge saying where the value actually travels — in path when its name appears in braces in the endpoint path, otherwise in query for
GETand in body for the rest. Under the hood this is still a JSON Schema:
{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The customer-facing order number, e.g. ORD-12345"
}
},
"required": ["order_id"]
}- Requires confirmation — under Advanced settings on the last step. Turn it on for any write or destructive operation (cancel, refund, delete). The AI will quote the parameters back to the customer and wait for an explicit “yes” before firing.
- Confirmation message template — optional, supports the same
{placeholder}tokens as the path.
Request body format
For POST, PUT and PATCH you choose how the parameters are sent:
- JSON (default) — the body is a JSON object. This is what almost every modern API expects.
- Form-encoded — the body is sent like an HTML form (
application/x-www-form-urlencoded). Older PHP APIs that read$_POSTneed this.
This one is worth a moment's care, because getting it wrong often does not produce an error. An API that cannot read a JSON body may simply ignore your parameters and answer 200 with some default record — so the assistant receives a complete, plausible answer about the wrong thing. If a tool returns data that looks valid but always describes the same record no matter what you ask for, switch this setting. The field appears only for non-GET methods; on GET, parameters always ride the query string.
Step 5 — Test the tool
Every tool has a Test action — on the tool row, and as the last step of the tool wizard. Fill in sample values for the parameters you declared and press Run test. Chatonio issues the real request through exactly the same code the AI uses, then shows you both halves of it:
- the assembled request — method, final URL, headers with credentials masked, and the body or query string;
- the upstream response — status code, selected headers and the body;
- a plain-language verdict, and the address the request went out from.
That last detail matters more than it looks. If your API restricts access by IP and our address is not on the allowlist, the refusal is a 403 that looks exactly like a wrong API key. Seeing “we sent this from 64.7.198.218” next to it turns a long debugging session into a one-line fix.
A failed test never blocks saving. An API that is temporarily down, or a credential you have not been issued yet, should not stop you finishing the tool.
The reachability check is not a tool test
The integration itself has a separate Reachability check button, in its Auth and scope step. It sends a plain request to the base URL and confirms the host answers — nothing more. It does not use your endpoint path, method or parameters, so it can report a healthy 200 while every tool call is failing. Use it to sanity-check a base URL; use Test to check a tool.
What happens when your API returns an error
Chatonio reads the status code and splits failures into two kinds, because they need opposite responses:
- The customer’s details don’t match —
400,404,409,410,422. The AI relays this and asks the customer to re-check what they gave you. Nobody is paged: a mistyped order number is an ordinary support moment, not an outage. - Something is wrong on our side —
401,403,429,5xx, timeouts and DNS failures. The AI is told explicitly that the fault is not the customer’s and must not ask them to re-check anything, and the conversation is escalated so a human picks it up.
This is worth designing your API around. If your endpoint answers an unknown order number with 403 instead of 400 or 404, every customer typo will page an operator.
Step 6 — Watch it work
Open a real conversation. When the customer asks a question whose answer needs the integration, the AI will:
- Decide which tool fits.
- Extract the parameters from the conversation (and ask the customer if anything is missing).
- Either call immediately, or — if requires confirmation is on — quote the parameters and wait for “yes”.
- Use the response to ground its reply.
Allowlisting our IP
Chatonio calls your API from one fixed address:
64.7.198.218
If your API restricts access by IP — common for exchange and payment backends — add that address alongside your API key. Calls made by the AI during a conversation, the tool Test and the Reachability check all originate there.
Tips
- One tool per intent. Don’t try to make one endpoint serve five workflows — the AI picks better when each tool has a narrow, clear job.
- Description quality matters more than name. The AI routes on the description.
- Always require confirmation for writes. Cheap insurance against the AI over-acting on an ambiguous message.
- Keep responses small. Return only the fields the AI needs to answer; tool output is capped at 16 KB and noisy responses dilute the model’s focus.