IntegrationsapiCallstable

Call an API

Call an external API — either a saved integration (pick the integration, operation, and connection; credentials stay encrypted and never appear in flow JS…

What it does

Calls an external API. One node, two sources — pick with the Source (mode) toggle:

  • Saved integration (mode: "integration") — call a typed, audited, credential-managed integration spec. Pick the integration slug, the operation, and the connection (the per-org credential bundle), then map inputs from {{vars.x}} and outputs back into vars. Inputs render against the regular template scope plus {{conn.*}} (the connection's public config — base URLs, account ids) and {{secret.*}} (decrypted at run time, scrubbed from logs). Credentials are stored encrypted and never appear in flow JSON or run history. The node pins (integrationSlug, integrationVersion, operationKey, connectionId) so a republished spec cannot silently re-route a live flow. The response body lands in {{vars.integrationResult}} and the operation's mapped output fields are merged into vars. Optionally set When this succeeds, the call counts as (outcome): a standard call outcome (booked, lead_captured, ticket_filed, message_taken, transferred) or one of the org's own outcomes (Settings → Receptionist → Outcomes). When the operation succeeds the call is marked with it (call_outcome_marks), vars.callOutcome is set, and the call's outcome is derived through the same precedence the receptionist's tools use — so a work order created from a flow reports exactly like one the receptionist created. A failed run sets nothing.

  • Ad-hoc HTTP request (mode: "http") — configure a one-off request right on the node: URL, method, JSON body, extra headers, and simple auth (basic / bearer / custom header) and a timeout (1–25 seconds, default 10). The response is saved to {{vars.httpResult}} (or whatever you set under Response variable). URL, body, header values and the auth value all support {{vars.x}} / {{event.from}} templates.

Both modes run through the platform's SSRF guard and a bounded timeout.

This step's result

Every run records the step's own result, keyed by the node's id, apart from the response:

  • steps.<id>.status: the numeric HTTP status, 0 when no answer came back (timeout, network failure, SSRF block).
  • steps.<id>.ok: true for a 2xx answer.
  • steps.<id>.error: empty on success, else 4xx, 5xx, timeout, network or ssrf.

A later step reads them in a rule (in the variable picker: From 'Look up the customer' → succeeded / status code / error, which writes the path steps.<id>.ok) or a template ({{steps.<id>.status}}). Two API steps never overwrite each other's result. steps.* is read-only: a Set variable named steps.… is refused when you publish, and the platform ignores it at run time. The response body stays in the response variable exactly as the API returned it.

The node also still sets vars.integrationStatus, vars.integrationOk and vars.integrationErrorClass (ok on success). Those hold the last API call in the flow, whichever step made it; existing flows keep reading them.

Routing on the result

The node's routing panel (Where the call goes next) and its card list the outcomes in plain words, each with its own Go to:

  • When the request succeeds (any 2xx answer)
  • Not found / client error (4xx) (a 429 counts here)
  • Server error (5xx)
  • Times out
  • Can't connect
  • Otherwise: every other result (a rate limit, an SSRF block) and any outcome you leave unset.

+ Add a rule adds a custom rule for what an outcome can't say: one status code (From this step → status code equals 404) or a field of the response (response → status equals closed). Rules are checked before the outcomes, top to bottom; the first match wins.

Stored, each outcome is a case row on the node: vars.integrationOk == true for success, vars.integrationErrorClass == "<4xx|5xx|timeout|network>" for the others, after your own rules. A flow written by hand may instead key the outcome on on["outcome-<key>"] (or on["<key>"]); the runtime reads both, after the case rows and before Otherwise.

When to use it

  • Look up a caller in your CRM at connect time and pop the record on the agent's screen (pair with screenPop).
  • Centralize a third-party API across many flows so credentials live in one encrypted place (saved-integration mode).
  • Post to a webhook / Slack / your own API, or hit a one-off endpoint you don't want to formalize as a spec (ad-hoc HTTP mode).

Notes

  • Reach for saved integration when the credentials are sensitive or the API is reused across flows; reach for ad-hoc HTTP for quick, public, or one-off calls.
  • Output mappings (integration mode) land in vars per the operation's defaultOutputMappings and any transform, so {{vars.<field>}} resolves downstream — e.g. a screen-pop card.
  • This node replaces the former separate HTTP request and Integration call nodes; existing flows that still carry those types keep running.

See also