Data Points
A data point is a named piece of information the AI can use during a conversation — the order status, the number of days since delivery, the customer's default address. Flows reference data points by name, either as an objective the AI works through or as passive context injected for the whole conversation (see Flows).
There are three kinds:
- useData — fetches or derives a value the AI can read (no side effect).
- useOptions — fetches a list of choices to present to the customer for selection (see useOptions).
- executeAction — performs a side effect against an external system (create a ticket, cancel an order) and can expose a result.
Both live in the Data Library so they can be defined once and reused across flows. Build and change them conversationally with the Copilot.
Where a data point gets its value
Every data point has a source that says where its value comes from:
| Source | Where the value comes from |
|---|---|
| Order | The current order — its status, fulfillment, tracking, dates, line items. Backed by your order-detail source (see Custom APIs → Source APIs). |
| Customer | The customer record — contact details, address, order history. |
| Order list | The customer's orders, used for selecting which order the conversation is about. |
| Custom API | A Custom API endpoint you've configured — anything with an API. |
| Google Sheet | A row looked up in (or written to) a connected Google Sheet. |
| Standalone | A pure computation from values already collected — no external call. |
Built-in data points
Alongside the data points you configure, Flowcall ships a small set of always-available data points. Reference them by their exact key — no setup needed. Several represent information only the customer can provide, so when you use one as an objective it must be set to ask the customer.
| Key | What it holds | Asks the customer |
|---|---|---|
customerName | The customer's name, from customer context or the conversation. | — |
customerPhone | The customer's phone number. | Yes |
customerEmail | The customer's email address. | Yes |
selectedOrderName | The order the customer selected. May also hold the informational order-source marker ECOMMERCE or OFFLINE. | Yes |
shopifyOrderId | The Shopify order ID for the selected order, when available from order context. | — |
isProvidedOrderInvalid | "yes" when the customer provided a concrete order ID in extracted information and the order-detail lookup found no order, including after source-reference mapping. Returns null otherwise: no ID, an order was found, an OFFLINE/ECOMMERCE source marker, or a lookup error. | — |
selectedLineItemTitle (alias selectedLineItem) | Title of the single order line item the customer selected. | Yes |
selectedLineItemsTitle (aliases selectedLineItems, selectedLineItemTitles) | Comma-separated titles of one or more selected line items. | Yes |
imageUrls | Image URLs the customer shared in the conversation. | Yes |
pdfUrl | The most recent PDF/document URL the customer shared. | Yes |
pdfUrls | All PDF/document URLs the customer shared, as a comma-separated list. | Yes |
The order- and line-item selection keys are paired with an options_data_point that supplies the list to choose from, and are usually marked required so the flow can't proceed until a concrete selection is made. Use imageUrls / pdfUrl / pdfUrls only to collect the attachment itself — to pull a value out of an image or PDF (a serial number, an address on an invoice), use a plain inferred objective instead.
Beyond these always-available keys, order and customer values — order status, delivery dates, tracking, addresses, order history — are configured data points backed by your order and customer sources. Because they read from your order-detail source, they work the same whatever system your orders live in.
Ticket context
Data points and execute actions can also read values from the current ticket without the flow having to collect them. These keys are available as inputs whenever a data point or execute action needs ticket details:
| Key | What it holds |
|---|---|
ticketId | The ticket's ID. |
ticketName | The ticket's name. |
ticketSummary | The ticket's summary. |
ticketResolution | The resolution recorded on the ticket. |
ticketCustomerId | The customer the ticket belongs to. |
ticketTaskId | The flow that created the ticket. |
ticketDispositionData | The ticket's disposition field values. |
ticketMoods | The customer sentiment/mood signals on the ticket. |
These aren't Data Library items and don't need to be asked for — map them into a data point or execute action's inputs when the call needs them (for example, passing ticketId to an execute action that updates the ticket in Freshdesk).
Custom-API-backed data points
When the value or action comes from a Custom API, the data point maps the flow's values into the API's inputs:
- API input mappings — each of the API's input fields is fed by a data point or objective value collected in the conversation. For a phrase like "pass
pincodetoservice_address_pincode," the conversation valuepincodesupplies the API fieldservice_address_pincode. - Fixed inputs — constant values sent on every call (an account ID, a channel name).
- Required inputs — inputs the flow must collect before the data point can run.
- Possible values — the bounded set of values the data point can return, which conditions and transitions can branch on.
Changing an input mapping (which conversation value feeds an API field) is a change to the data point. Changing the API field itself, or how a value is formatted before it's sent, is a change to the Custom API — a distinction the Copilot is careful about.
useOptions
A useOptions data point supplies the list of choices an objective asks the customer to pick from — available appointment slots, serviceable branches, eligible return reasons. It's configured exactly like a custom-API-backed data point (same sources, input mappings, fixed inputs, required inputs); the only difference is what it returns.
Instead of a single value, it returns a list of items, each with two parts:
| Field | What it is |
|---|---|
label | The text shown to the customer. |
id | The value stored when that option is selected. Usually the same as the label — differ only when the stored value shouldn't match what's presented. |
An objective points at a useOptions data point as its options data point, and the options are then presented as part of asking that objective's question.
How the options are presented
The option values are deliberately kept out of the AI's prompt — the AI writes the question, and the exact list is attached afterwards, verbatim:
- Two or more options — attached as an option list/dropdown, one row per item. The AI is told how many options exist but not what they are, so it can't paraphrase, reorder, or invent them.
- Exactly one option — no list is rendered; the single label is appended to the message text instead.
- No options — no list is rendered and the AI is told nothing is available, so it can tell the customer and the flow can branch on the empty result.
Because the list never passes through the model, labels stay exactly as your API returned them — useful for slot times, addresses, IDs, and anything else that must not be reworded.
How a selection is stored
When the customer picks an option — by tapping a row, or by typing the label or the id as free text — the selection is resolved back to the option's id and stored as the objective's value. Matching is forgiving about case, punctuation, and &/and, so a typed answer that's close to a label still resolves. Conditions and transitions branch on the stored id.
Execute actions
An execute action is a data point that does something rather than just reading a value — update a Freshdesk ticket, cancel an order, submit a rating. It's configured like a custom-API-backed data point (input mappings, fixed inputs, required inputs), and because it changes an external system, its calls are recorded in API Logs. Execute actions can also draw on ticket context — the ticket's ID, name, summary, resolution, and more — without the flow having to collect it.
Execute actions can also run after a delayed Event Hook. An Event Hook can map built-in values such as customerPhone, or compatible Data Library values, from the selected ticket's shared state into the action's API inputs.
Related
- Flows — how objectives use data points and execute actions.
- Event Hooks — run an execute action after a new conversation session using the closest ticket.
- Custom APIs — the endpoints that back data points, and the source APIs behind built-in order data.
- Workflows → Data Library — where data points are managed.
- Copilot — create and change data points by chatting.
- Testing → Mocking — mock data point values so tests stay evergreen.
Ticket-linked email identifiers
Use these built-in data points for an external case lookup:
ticketEmailMessageId: Provider message ID of the latest inbound support email linked to this ticket, falling back to the nearest linked parent. Not the original RFC Message-ID.ticketEmailReferenceMessageId: Original RFC Message-ID header of the latest inbound ticket-linked support email. Use to match the same email in external systems such as Sprinklr; never substitute the Gmail/provider message ID.ticketEmailThreadId: Provider thread ID for the same latest inbound ticket-linked support email.ticketEmailMailbox: Connected mailbox owner email for the same ticket-linked inbound email. Use to scope external case matching; null when mailbox identity is ambiguous.ticketEmailProvider: Email provider (gmail or outlook) for the same ticket-linked inbound email.
During email ticket creation, these values use the server-supplied incoming support thread even before the ticket is saved. For saved tickets, these values are resolved at runtime from the latest inbound email in the ticket’s linked support threads or explicitly linked messages. A child without email links uses its nearest linked parent. Outbound messages and vendor threads are excluded. Lookup is scoped to the account and customer; missing links or ambiguous mailbox identity return null. The original header is not replaced with a provider message ID when missing.
For a disposition closure action, map the required inputs of an API-backed case lookup to ticketEmailReferenceMessageId and ticketEmailMailbox. Map that lookup’s result into the update execute action, together with helper data points extracting fields from ticketDispositionData. Attach the action to a disposition field using executeAction:<action-key>. Match within the configured external environment/source account before choosing the latest case; preserve both case ID and number if the update API needs them. Do not update on no match or ambiguity. Copilot can draft these mappings and preview them with sample inputs.