Intuify

Intuify

Documentation

Logic & flow9 min read

Web Service Block

Call an external API mid-flow — push answers out to another system, or pull data back into survey variables (and auto-answer questions from them).

On this page (14 sections)

The Web Service block lets a survey call an external HTTP API in the middle of the flow — to push responses out to another system (Zapier, Make, a CRM, a webhook) or to pull data back into the survey and save it to variables.

Add it from the Flow tab → Add a New ElementWeb Service, then configure it in the block's Options panel. It sits alongside branches, randomizers, and end-of-survey elements in the Flow Editor.

Requests always run on our server. The respondent's browser never makes the outbound call and never sees your secrets. An internal-host guard blocks requests to private/loopback addresses.

You can open this guide any time from inside the builder: Flow tab → the Web Service block → Guide button in the panel header.


The editor at a glance#

The panel is grouped into cards:

  1. Request — Method, Endpoint URL, Query parameters, Headers.
  2. Request body — only for POST / PUT / PATCH; what to send.
  3. Authentication — None / Basic / API key / Bearer (inline secrets).
  4. Response — Fire-and-forget, Save response fields to variables, Test.
  5. Advanced — Timeout, Retries, Continue-on-error.

There is no saved-credential store: you supply secrets inline on the block (or reference a global variable), and they are injected server-side.


Configuration reference#

SettingNotes
MethodGET / POST / PUT / PATCH / DELETE.
Endpoint URLThe endpoint to call. May contain tokens in the path/query (not the host — see Security).
Query parametersAppended to the URL. Values support tokens.
HeadersArbitrary request headers. Values support tokens.
Request bodyOnly for POST / PUT / PATCH. Modes below.
AuthenticationNone / Basic / API key / Bearer. Secrets are entered inline or referenced from a global variable. No native OAuth (see below).
Fire and forgetWhen on, the survey does not wait for a reply; response mapping is disabled. Ideal for "notify and move on".
Save response fields to variablesMap dot-paths in the JSON reply (e.g. weather.tempF) to survey global variables. Hidden in fire-and-forget mode.
Timeout (ms)500–20000 (hard cap 20 s).
Retries0–3 (only on 5xx / 429 / network — a 4xx is not retried).
Continue the survey if this request failsWhen off, a failed non-fire-and-forget call stops the survey.

Request body modes#

ModeWhat it sends
Don't send a bodyNo body.
Build fields (recommended)Your key → value rows, wrapped in the response envelope (below).
Send all answersThe whole response envelope — every answered question.
Write raw JSON (advanced)A raw JSON string you author, with tokens substituted.
Send as form dataapplication/x-www-form-urlencoded key=value pairs.

Use "+ Add a whole question" in Build fields to include a question's full answer, and mix in literals or tokens for the rest.


Inserting dynamic values#

Anywhere a value is accepted — Endpoint URL, query params, headers, Build-fields values, form params, raw JSON, and auth secrets — there is an emerald variable button (the same Variable icon used by the Global Variables panel). It opens the shared piping menu, so you insert the same tokens the same way as in question text or logic:

TokenResolves to
${gv://Field/name}a global variable / embedded data field
${q://QID/SelectedValue} (and other sub-keys)a question's answer
${m://ResponseID} (and other metadata)session metadata — see below

${m://…} metadata (filled by the server)#

The browser cannot see server-side data, so these are filled authoritatively by the server:

TokenValue
${m://ResponseID}the response / session id
${m://SurveyID}the survey id
${m://RecipientEmail}respondent's email (non-anonymous surveys; empty otherwise)
${m://StartDate} / ${m://EndDate} / ${m://Duration}response timestamps
${m://IPAddress} / ${m://UserAgent}stored request metadata
${m://DisplayLanguage}response language

Valid JSON reminder: in the raw-JSON body, wrap string tokens in quotes — {"email": "${m://RecipientEmail}"}, not {email: ${m://RecipientEmail}}.


The response envelope (Send all answers / Build fields)#

Both Send all answers and Build fields ship the same JSON envelope, so a consumer sees one stable contract:

json
{
  "surveyId":       "SV_abc123",
  "sessionId":      "RSP_xyz789",
  "recipientEmail": "[email protected]",
  "submittedAt":    "2026-07-14T12:00:00Z",
  "values":    { "Q1": 2, "Q9_1": 3, "NPS_Score": 9 },
  "labels":    { "Q1": "Option 2", "Q9_1": "Disagree", "NPS_Score": 9 },
  "questions": { "Q1": "Pick one", "Q9": "Rate the statements", "NPS_Score": "How likely?" },
  "choices":   { "Q1": { "2": "Option 2" }, "Q9": { "1": "Statement 1" } }
}
  • values — machine codes: choice/row/column recode values, numbers, or text, keyed by a stable export tag (matrix rows as tag_row, grid cells as tag_row_col, multi-answer as an array). Unanswered questions are omitted.
  • labels — human-readable text, keyed identically to values.
  • questions — question wording (plain text).
  • choices — per choice-based question, { recode: label } for the selected options.
  • surveyId / sessionId / submittedAt — stamped by the server.
  • recipientEmail — added only for non-anonymous responses.

Variables: in Send all answers, every global variable is folded into labels (an answer with the same key wins). In Build fields the payload is filtered — only the rows you add are sent (reference a variable explicitly with ${gv://Field/name} to include it).

The snapshot is assembled when the block fires, so place the block where you want that snapshot taken — usually near the end of the flow.


Authentication & OAuth#

TypeFieldsInjected as
Nonenothing
Basicusername, passwordAuthorization: Basic base64(user:pass)
BearertokenAuthorization: Bearer <token>
API keyvalue, placement (header/query), paramName (default X-API-Key)header or query param

A blank secret means no auth header is attached. Any secret may itself be a ${gv://Field/name} token so it isn't hard-coded in the survey.

OAuth is not natively supported — there's no token-endpoint / auto-refresh flow. If you already hold an access token, paste it as the Bearer token (optionally via a variable). A client-credentials flow can be approximated with two chained blocks (fetch token → map access_token to a variable → use ${gv://Field/access_token}).


Pulling data back (response → variables)#

For lookups (weather, enrichment, eligibility), leave Fire and forget off:

  1. Configure a GET/POST to the API.
  2. Click Send a test request — the editor lists the reply's JSON fields (test calls use sample metadata).
  3. Click a field to auto-create a mapping (response.path → variable), or add mappings manually under Save response fields to variables.

Mapped variables become survey global variables and can drive display logic, branching, quotas, piping into question text, and auto-answering a question (see below). The block also writes status variables keyed by its Section Label (spaces → underscores): ws_<label>_ok, ws_<label>_status, ws_<label>_error, ws_<label>_response. Give each block a unique label if you need to inspect more than one.

Auto-answering / skipping a question from a mapped variable#

A mapped variable can pre-fill a question's answer so the respondent never sees it. On the question's Logic tab:

  • Under Auto-Answer Question Rules, add a rule with the condition <variable> Is Not Empty, and set Default answer text to the variable token — use the emerald variable button on that field to insert ${gv://Field/name}.
  • When the variable is set, the question is hidden and recorded with the resolved value (e.g. the real name), not the literal token. When the variable is empty, the question is shown normally.

When the block runs (placement matters)#

Web Service blocks — like all flow blocks — execute when the respondent completes the section just before the block in the flow, not in the middle of a page and not any earlier. A block placed after Section 3 does not call the service until Section 3 is finished. So a pulled variable is available to questions in a later section, not to a question shown on the same first screen.

If you need the pulled data before the very first question (for example, to skip it), give the survey a lead-in section — such as a short "welcome" Text/Graphic page — and put the consuming question in the next section. A block placed before the first section won't run until a section is completed. Verify the end-to-end behaviour on the live survey link (a real session).


Chaining calls#

Multiple Web Service blocks in one flow step execute in order, and each block's response variables feed the next block's tokens. So you can fetch an OAuth token in block A (map access_token → a variable) and send ${gv://Field/access_token} as the Bearer secret in block B — within the same navigation step. Fire-and-forget blocks return immediately and don't contribute variables.


Walkthrough: send survey responses to Zapier#

Goal: POST answers to a Zapier Catch Hook when the respondent reaches a point in the flow.

  1. In Zapier, create a Zap with Webhooks by Zapier → Catch Hook and copy the URL, e.g. https://hooks.zapier.com/hooks/catch/123456/abcdef/.

  2. Add a Web Service block and set Method POST, Endpoint URL to the hook URL, Authentication None, Fire and forget on.

  3. Request bodyBuild fields. Add rows (left = JSON key, right = a literal or token via the variable button):

    Field nameValue
    email${m://RecipientEmail} (non-anonymous) or a question
    nps"+ Add a whole question" → your NPS question
    sourcesurvey-app (literal)
  4. (Optional) Send a test request — Zapier shows the payload in its Catch Hook test panel.


Security & limits#

  • Server-side only. The outbound request is made by the backend, not the browser. Only the resolved token values and the assembled envelope are sent from the client.
  • Internal-host guard. Private / loopback / non-global hosts are rejected. Only https is allowed by default.
  • Host is never templated. A token may appear in the path, query, headers, or body — but not the host. On a cross-host redirect the credential (Authorization header and any query-placed API key) is stripped.
  • Injection-safe. Token values spliced into a URL are percent-encoded and those in a raw-JSON body are JSON-escaped, so a respondent answer can't inject params or forge JSON keys. ${m://…} metadata is server-owned.
  • Inline vs. variable. Inline secrets are stored in the survey definition; reference a global variable instead if that's a concern.
  • Hard limits. 20 s timeout cap, ≤ 3 retries, ≤ 3 redirects, 256 KB response cap, rate-limited per session.

Was this page helpful?