# Traps

> The cross-domain sharp edges of the Chatfuel API — identity and selection, schema and introspection, deprecated fields, pagination, and data semantics — in full.

Page: https://sdk.chatfuel.com/docs/reference/chatfuel-api/traps
Markdown: https://sdk.chatfuel.com/docs/reference/chatfuel-api/traps.md

These bite in every domain, and none of them is visible from a type signature alone.

## Identity and selection [#identity-and-selection]

| Trap                                                                        | What to do                                                                                                                                                                                                                                                                                                                         |
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Conversation.id` is the contact id.                                        | The backend's primary key for a conversation is `Conversation.ContactID`, exposed as an alias on `id`. Every `conversationID` argument takes a contact id; there is no separate conversation identity, and passing one is not a bug to fix.                                                                                        |
| Not selecting `__typename` on `Contact` and `Conversation` produces errors. | A known backend bug, CFN-1289, called out in the schema's own doc comments. Select `__typename` on both — and, as cheap insurance, on every interface and union selection you write.                                                                                                                                               |
| Interface field names are disambiguated per platform.                       | One field name must map to one type across every implementer, so the same concept gets different names: `whatsappStatus` on a WhatsApp message against plain `status` on a widget one, and `waReferral` / `fbReferral` / `igReferral` for the referral. Never assume a field from one platform's message type exists on another's. |
| `__typename` in a mutation's variables is rejected.                         | The server refuses unknown input fields. If you round-trip a fetched object into a mutation input, strip `__typename` recursively first.                                                                                                                                                                                           |

<Callout type="warn">
  A message's `clientId` must be a fresh UUID per message and unique across every client of the
  account, your app and the Chatfuel dashboard included — both merge messages by `clientId`, so a
  collision corrupts your UI and the customer's dashboard at the same time, with no error anywhere.
  `Message.id` is nullable; `clientId` is the reliable key.
</Callout>

## Schema and introspection [#schema-and-introspection]

| Trap                                                             | What to do                                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Introspection is disabled in production.                         | Use the bundled SDL and validate operations against it before running them.                                                                                                                                                                                                                                                                                                                                              |
| The bundle is not the whole dashboard schema.                    | Billing, Albato, A/B-experiment and debug surfaces are dropped, along with every field, argument and union member that referred to a dropped name. What is missing is missing on purpose.                                                                                                                                                                                                                                |
| Every legacy `fuelyConfig*` behaviour setter is dead.            | Agent name, language, greeting, message length, emoji, respond-to-sources, switch-to-human, summarize-chat, comment reply rules V1 and V2, and `fuelyConfigBookingSetAIAutonomyLevel` are deprecated and always return `BotMigratedToNewFuelySettings`. The per-scope `fuelyAutomation*` settings replaced them. The business-info, hours, FAQ and booking-notification setters are *not* deprecated — the family split. |
| `GetDefinedErrorCodes` always errors.                            | It is a stub that exists only to union the error enum across subgraphs, and the schema says so. Never query it.                                                                                                                                                                                                                                                                                                          |
| Error lists in doc comments hide under three different headings. | `DefinedErrorCodes:`, `DefinedErrCodes:` and `errors:` all appear. Grep for all three when hunting the codes a mutation can return.                                                                                                                                                                                                                                                                                      |
| Mutation casing is inconsistent.                                 | `whatsAppTextMessageSend` sits next to `whatsappAttachmentMessageSend`; `tiktokTextMessageSend` returns `TikTokOutTextMessage`. Copy names character for character from the schema instead of deriving them.                                                                                                                                                                                                             |

## Deprecated, and what replaced it [#deprecated-and-what-replaced-it]

| Deprecated                                                    | Use                                                                                                 |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| root `searchContacts`                                         | `bot.contactsConnection`                                                                            |
| root `countContacts`                                          | `bot.contactsCount`                                                                                 |
| `bot.contactChatsCount`                                       | `bot.contactChatsCountV2(filter:)`                                                                  |
| `bot.contactDealsTotalsByStages`                              | `bot.contactDealsByStages(filter:)`                                                                 |
| `updateFCMTokenForCurrentMobileDevice`                        | `updateFCMTokenForCurrentDevice`                                                                    |
| `bot.commentReplyRulesV2Connection`, `bot.commentReplyRuleV2` | `bot.fuelyAutomations`. These two do not error — they return an empty connection and an empty rule. |

## Pagination [#pagination]

| Trap                                                                                 | What to do                                                                                                                                                                                                                                                                                       |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Bot.whatsAppTemplates` accepts `first`, `after` and `before` and ignores all three. | It returns the full list every time, and the field is nullable. The same absence, more honestly stated, applies to `goodsCatalog`, `specialists`, `contactScopes`, `members`, `invites`, `bookingsV2`, `Workspace.bots` and `currentUser.workspaces`, which have no pagination arguments at all. |
| Message history flips direction.                                                     | No cursor or `after` gives newest-first descending; `before` gives ascending. `first` is required on the contact-ish connections and optional on `messages`. The rules are on [the pagination page](/docs/reference/chatfuel-api/pagination).                                                    |

## Data semantics [#data-semantics]

| Trap                                                                 | What to do                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "Deleted or inaccessible" is modelled three different ways.          | Union branches (`DeletedGoodsService`, `DeletedSpecialist`), boolean flags (`PublicUserAccount.isUnknown`, `TikTokPost.isUnknown` — when true, ignore every other field), and stub types (`UnavailableContact`, which means no permission and holds empty data; `UnavailableTaskData`). Handle all three; there is no single shape to check. |
| `File.status == Expired` means the file is gone.                     | Do not request and do not render any other field of it.                                                                                                                                                                                                                                                                                      |
| Datetime *attribute values* are not RFC3339.                         | An attribute whose `AttributeDataType` is `datetime` carries a millisecond-timestamp string, like `"1720456863000"`. Only the `Time` scalar uses RFC3339.                                                                                                                                                                                    |
| `Task.statuses` is a history.                                        | The current status is the entry with the latest `startedAt`, and a task past its `deadline` has failed even with no `Failed` status. See [files and tasks](/docs/reference/chatfuel-api/files-and-tasks).                                                                                                                                    |
| `contactsCount` and `contactsTotalCount` answer different questions. | `contactsCount` respects the caller's assignee visibility restrictions and is what a contacts table should show; `contactsTotalCount` ignores them and is what a broadcast size estimate wants. Pick deliberately — both return an `Int!` and neither says which it is.                                                                      |

The transport-level traps live with their subjects: an `Unauthorized` arriving inside an HTTP 200
and a subgraph code nested one level down are on [errors](/docs/reference/chatfuel-api/errors); a
socket that replays nothing on reconnect and the 25-requests-a-second ceiling are on
[transport and auth](/docs/reference/chatfuel-api/transport-auth); uploads never going through
GraphQL is on [files and tasks](/docs/reference/chatfuel-api/files-and-tasks).
