The Chatfuel API
The mental model behind the GraphQL API a generated app talks to — the hierarchy every operation traverses, the two automation surfaces that are not the same thing, and why the schema ships as a file.
The supergraph has twelve root query fields, so you reach almost everything by traversing
bot(id:) and currentUser rather than by asking for an entity by its own name.
The hierarchy
| Level | What it is | How you reach it |
|---|---|---|
UserAccount | The Chatfuel login the token belongs to. | currentUser |
Workspace | The billing container. It holds bots and carries a botsLimit. | currentUser.workspaces, currentUser.workspace(id:) |
Bot | One Chatfuel project. Almost every field in the schema hangs off it, and almost every argument list opens with a botID. | bot(id: BotID!), Workspace.bots |
ContactScope | One connected channel. The interface carries an id and nothing else; five types implement it — web widget, WhatsApp phone, Instagram account, TikTok account, Facebook page. | bot.contactScopes |
Contact | A person inside one scope. | bot.contactsConnection |
Conversation | The thread with that contact. | bot.conversation(conversationID:), Contact.conversation |
Conversation.id is the contact's id. Every conversationID argument in the schema takes a
contact id, and there is no separate conversation identity to look up.
Automations and Flows are two different surfaces
| Automations | Flows | |
|---|---|---|
| What it configures | How the AI behaves. | Scripted logic on a canvas. |
| The chain | Bot → FuelyAutomation → FuelySetting | Bot → Flow → Block → BlockElement |
| Scoping | One base automation per scope, plus custom ones. A scope is a channel and an entry point together — InstagramPostComments, WhatsAppClickFromAds, FacebookDirectMessages — and a setting can inherit from another automation in the same bot. | Per flow. Blocks carry canvas positions and are joined by Connections; a flow names its startingPointBlock and its entryPoints. |
| Typing | FuelySetting is an interface with one concrete type per setting. | Strongly typed per plugin. There are no JSON configs. |
| Real time | fuelyAutomationUpdated(botID:). | None. The Subscription type carries no flow or block field, so you reconcile from mutation results. |
Everything sendable branches on platform
enum Platform {
widget
facebook
instagram
whatsapp
tiktok
}Message types, send mutations and some fields exist per platform, so you branch on
Conversation.platform or on __typename before you read a message. Field names are
disambiguated per platform for the same reason — see the traps.
One endpoint per environment, not per account
Production is https://panel.chatfuel.com/graphql for every account; the botID inside the
operation selects the project. The addresses, the header and the socket are on
transport and auth.
The schema is a file, not an introspection query
Introspection is not available, so the bundled SDL is the schema. The snapshot lives at
content/schema/schema.graphql — a generated subset of the Chatfuel dashboard's own schema,
carrying names and types only: no descriptions, no deprecated members. Its first three lines say
so, and name the date it was generated.
One file, three readers. Codegen reads it here and inside a generated app; the operation validator
builds from it; and the scaffold writes two copies from it — references/schema.graphql inside the
chatfuel-core skill your coding agent reads, and src/vendor/schema/ inside the app, because a
skill directory may have been installed to your home directory where the app cannot reach it.
Grepping any of the three answers the same question.
Two validate passes keep the snapshot honest. One re-derives possible-types.json — the
interface and union implementations a normalized cache has to be told about — from the SDL beside
it and fails if the derivation does not reproduce. The other walks the schema from Query,
Mutation and Subscription and fails on any declaration nothing can reach, which is what a
trimmed subset leaves behind when a root field is cut and its subtree is not.
The rest of this section
| Page | What it holds |
|---|---|
| Transport and auth | The three endpoints, how the token travels on each, what the token is and what it may do, the WebSocket client's behaviour, and rate limiting. |
| Errors | The envelope, the DefinedErrorCode family, and the rules that catch people. |
| Pagination | Relay cursors with per-connection scalars, the direction flip on message history, and the connections that take pagination arguments and ignore them. |
| Files and tasks | REST upload then FileID, the File lifecycle, and Task progress tracking. |
| Traps | The cross-domain sharp edges, in full. |
Generated operations
The eleven generated document families, what each covers, how the names are formed, and what happens when you add an operation.
Transport and auth
The three endpoints, how the Chatfuel token travels on each of them, what the token is and what it may do, how the WebSocket client behaves, and how rate limiting is handled.