Chatfuel

Chatfuel Public API Quickstart

Create a personal API token, find your bot ID, create a virtual user and make your first Chatfuel Public API query and mutation in about ten minutes.

Last updated on

The quickstart takes you from no token to a working Chatfuel Public API call in five steps: create your personal API token, find the bot ID, create a virtual user, read contacts with the virtual user token, and change a contact. You need the Admin role in the bot, a terminal with curl and jq, and about ten minutes.

Step 1: Create your personal API token

The personal API token is called the CLI token in the Chatfuel dashboard. You use it only to manage virtual users and other account-level settings.

  1. Sign in to the Chatfuel dashboard at panel.chatfuel.com.
  2. Open the account menu (your name or avatar) and select CLI token. The page is also available directly at https://panel.chatfuel.com/integration/auth/token.
  3. Click Create token, then Copy token.
  4. Save the personal API token in a password manager or a secret store. Chatfuel shows the token only once.

Keep the personal API token in an environment variable for the rest of the quickstart:

export CHATFUEL_PERSONAL_TOKEN="paste-your-cli-token-here"

Anyone with the personal API token can act as you in every bot you can access. Never commit it to a repository or put it in client-side code.

Step 2: Find your bot ID

Every Public API operation works inside a bot. List the bots your account can access with the personal API token:

QUERY='query MyBots {
  currentUser {
    botsV2(first: 50) {
      edges { node { id title } }
    }
  }
}'

jq -n --arg query "$QUERY" '{query: $query}' |
curl -s https://panel.chatfuel.com/graphql \
  -H "Authorization: Bearer $CHATFUEL_PERSONAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @-

The bot ID is also visible in the dashboard address bar: it is the part after /automation/ when a bot is open. Save it:

export BOT_ID="your-bot-id"

Step 3: Create a virtual user

A virtual user is an API-only member of one bot. It gets its own token, which you use for all other calls. Create one with the createVirtualUser mutation and the personal API token:

QUERY='mutation CreateVirtualUser($botID: BotID!) {
  createVirtualUser(
    botID: $botID
    name: "Quickstart integration"
    role: { roleType: Editor, botPermissions: [] }
  ) {
    member { id role { roleTypeV2 } user { id name accountType } }
    authToken
  }
}'

jq -n --arg query "$QUERY" --arg botID "$BOT_ID" \
  '{query: $query, variables: {botID: $botID}}' |
curl -s https://panel.chatfuel.com/graphql \
  -H "Authorization: Bearer $CHATFUEL_PERSONAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @-

The response contains the new member and its token:

{
  "data": {
    "createVirtualUser": {
      "member": {
        "id": "6f1c…",
        "role": { "roleTypeV2": "Editor" },
        "user": { "id": "6f1b…", "name": "Quickstart integration", "accountType": "Virtual" }
      },
      "authToken": "3c9e…"
    }
  }
}

authToken is shown only in this response. Save it, together with member.id, which you need later to regenerate the token or remove the virtual user:

export CHATFUEL_VIRTUAL_USER_TOKEN="paste-authToken-here"

The role can be Editor or Agent. Virtual users explains what each role allows.

Step 4: Read contacts with the virtual user token

Switch to the virtual user token and read the bot title and the first ten contacts:

QUERY='query Contacts($botID: BotID!) {
  bot(id: $botID) {
    title
    contactsConnection(platforms: [whatsapp, instagram, facebook, tiktok, widget], first: 10) {
      edges { node { id name note updatedAt } }
      pageInfo { hasNextPage endCursor }
    }
  }
}'

jq -n --arg query "$QUERY" --arg botID "$BOT_ID" \
  '{query: $query, variables: {botID: $botID}}' |
curl -s https://panel.chatfuel.com/graphql \
  -H "Authorization: Bearer $CHATFUEL_VIRTUAL_USER_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @-

To get the next page, pass pageInfo.endCursor as the after argument. Making requests shows the full pagination pattern.

Step 5: Change a contact

Take a contact id from the previous response and set a note on it with contactSetNote:

export CONTACT_ID="a-contact-id-from-step-4"

QUERY='mutation SetNote($contactID: ContactID!, $note: String) {
  contactSetNote(id: $contactID, note: $note) { id note }
}'

jq -n --arg query "$QUERY" --arg contactID "$CONTACT_ID" --arg note "Synced from CRM" \
  '{query: $query, variables: {contactID: $contactID, note: $note}}' |
curl -s https://panel.chatfuel.com/graphql \
  -H "Authorization: Bearer $CHATFUEL_VIRTUAL_USER_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @-

The note now appears on the contact card in the dashboard, and the virtual user is listed in the bot's teammates with the API label. From here, browse the contacts reference and messaging reference, or read about tokens and authentication before going to production.

Common issues

"NotEnoughPermissions" when creating a virtual user

createVirtualUser works only with a personal API token of a user who has the Admin role in the bot. A virtual user token is always rejected for this mutation, even if the virtual user exists in the same bot.

"VirtualUserRoleNotAllowed"

The role must be Editor or Agent. Virtual users can't be Admins or have a Custom role.

"Unauthorized"

The token is missing, mistyped or revoked, or the header lacks the Bearer prefix. Send Authorization: Bearer <token> and check that the token was not regenerated in the meantime.

On this page