Call an API from a Flow
Flows are great at collecting answers (Ask / Send / Buttons). The Call API node adds the missing piece: reading and writing your own backend during the chat. With it you can build order lookups, live pricing, and real transactions directly in the Flow builder instead of a separate bot.
Add the node
Section titled “Add the node”In the Flow builder, open the palette → Data category → Call API. It has two output handles:
- success — the request returned
2xx - error — non-
2xx, a timeout, or any failure
Connect a fallback message to the error handle so the customer always gets a reply.
Fields
Section titled “Fields”| Field | Notes |
|---|---|
| Method | GET / POST / PUT / PATCH / DELETE |
| URL | Supports {{variable}} — e.g. https://api.example.com/orders?phone={{phone}} |
| Headers | Key/value list. Each value is either a literal (with {{variable}}) or a 🔒 secret referenced by name (see below) |
| Body | JSON with {{variable}} interpolation (shown for POST/PUT/PATCH/DELETE) |
| Response mapping | response path → variable. Dot/JSON-path (e.g. data.orders.0.id). Lists become newline-joined text — handy for a following Send message |
| Timeout | Milliseconds (default 10000, capped at 30000) |
After the call, two variables are always set:
{{_http_status}}— the HTTP status code{{_http_error}}— a short reason on the error branch (e.g.HTTP 404,request failed: ConnectTimeout)
Secrets (never put API keys in the graph)
Section titled “Secrets (never put API keys in the graph)”Store credentials once at Settings → Flow Secrets (a name + value, e.g.
infracart_api). In a header, switch the value to 🔒 secret and pick the name.
- The raw value is write-only — it’s never returned by the API and never appears in the exported flow graph JSON.
- The engine resolves the secret to its value only at run time, server-side.
Graph / JSON shape
Section titled “Graph / JSON shape”Flows are authored by PATCH-ing draft_graph. A Call API node looks like:
{ "id": "fetch_orders", "type": "http_request", "position": { "x": 600, "y": 140 }, "data": { "method": "GET", "url": "https://api.example.com/orders?phone={{phone}}", "headers": [{ "key": "X-Api-Key", "secretRef": "infracart_api" }], "body": null, "responseMap": { "orders": "orders_text" }, "timeoutMs": 10000 }}Edges branch on sourceHandle: "success" and sourceHandle: "error":
[ { "id": "e1", "source": "fetch_orders", "sourceHandle": "success", "target": "show_orders" }, { "id": "e2", "source": "fetch_orders", "sourceHandle": "error", "target": "fallback_msg" }]A header with an inline value instead of a secret:
{ "key": "Content-Type", "value": "application/json" }Examples
Section titled “Examples”Order status — buyer taps My orders:
Ask Buttons ("My orders") → Call API GET /orders?phone={{phone}} map: orders → {{orders_text}} success → Send "Your orders:\n{{orders_text}}" error → Send "Couldn't load your orders right now — try again."Live rate:
Ask Text ("Which material?", save as material) → Call API GET /rate?product={{material}} map: price → {{rate}} success → Send "Today's {{material}} rate: ₹{{rate}}" error → Send "Rates are unavailable at the moment."Submit a real bid:
… collect rfq + amount … → Call API POST /bids body: {"rfq":"{{rfq}}","amt":{{amount}}} header X-Api-Key = 🔒 infracart_api map: rfq_no → {{rfq_no}} success → Send "Quote submitted for {{rfq_no}} ✅" error → Send "We couldn't submit your quote — please retry."Behaviour & limits
Section titled “Behaviour & limits”- Never breaks the flow. Any failure/timeout/non-
2xxroutes to the error handle — the run never crashes. - Interpolation applies to URL, header values, and body via
{{variable}}. Unknown variables are left as-is. - Body must be valid JSON after interpolation; otherwise it’s sent without a body.
- Response mapping reads up to ~200 KB of JSON. A mapped list is joined into newline-separated text; an object is stored as compact JSON; scalars pass through.
- Timeout is capped at 30 s so a slow API can’t hang the conversation.
Security notes
Section titled “Security notes”- Secret headers are stored at the workspace level and referenced by name — never the raw value in the graph.
- Only fields you map end up in flow variables; nothing else from the response is stored.