Integrations API
The Clarflow Integrations API lets an automation platform subscribe to quiz completions on a funnel and receive each completion as an HTTP POST. It powers Clarflow's Zapier and Make apps, and you can build against it directly.
A machine-readable OpenAPI 3.1 specification for everything on this page is published at www.clarflow.com/openapi.yaml.
- Base URL —
https://www.clarflow.com - Format — JSON request and response bodies throughout
- Authentication — bearer session token (below)
Use the
www.host. The apexclarflow.comredirects towww.clarflow.com, and many HTTP clients drop theAuthorizationheader when a redirect crosses hosts.
Authentication
Every endpoint except sign-in expects a bearer token:
Authorization: Bearer <session token>
You get a token by exchanging a Clarflow email and password once. Clarflow never stores the password — the token is a signed, self-contained credential.
Scope. Tokens carry a single scope, integrations:listen. A token can list funnels and manage webhook subscriptions for one workspace. It cannot create API keys, modify funnels, change billing, or alter the account in any way.
Lifetime. Tokens last 90 days. They are bound to a fingerprint of the account's current password, so changing the Clarflow password immediately revokes every outstanding token. That is the revocation mechanism — there is no separate token management screen.
On a 401, sign in again to mint a fresh token and retry.
The flow at a glance
- Sign in to get a token.
- List funnels so the user can pick one.
- Subscribe your webhook URL to that funnel; keep the returned
id. - Clarflow POSTs to your URL on every completion.
- Delete the subscription when the automation is switched off.
Sign in
POST /api/integrations/session
Exchanges credentials for a token. No authentication required.
Request
{
"email": "jane@example.com",
"password": "…"
}
Response — 200
{
"token": "eyJzdWIiOiJ1c2Vy…",
"workspaceId": "9d3f7c21-4b8e-4a10-9c55-2f1a6b0e77d2",
"workspaceName": "Acme Supplements"
}
workspaceName falls back to "Clarflow workspace" when the workspace is unnamed.
Errors
| Status | Meaning |
|---|---|
400 | email or password missing |
401 | Invalid credentials |
404 | The account has no workspace |
Accounts that sign in with Google have no password and cannot use this endpoint — they return 401. Every failure returns the same generic 401 message on purpose, so the endpoint cannot be used to discover which email addresses are registered.
Test the connection
GET /api/zapier/me
Validates the token and returns the workspace it is scoped to. This is the cheapest way to check whether a token is still good.
Response — 200
{
"workspaceId": "9d3f7c21-4b8e-4a10-9c55-2f1a6b0e77d2",
"workspaceName": "Acme Supplements"
}
List funnels
GET /api/zapier/funnels
Returns every funnel in the connected workspace — use it to populate a funnel picker.
Response — 200
[
{ "id": "f1e2d3c4-b5a6-4789-9012-3456789abcde", "name": "Skincare Finder Quiz" },
{ "id": "0fedcba9-8765-4321-a098-765432100000", "name": "Protein Powder Match" }
]
Pass id as funnelId when subscribing.
Fetch sample data
GET /api/zapier/responses?funnelId=<funnel id>
Returns a single representative completion payload so users can map fields before any real completion has happened.
The sample is generated by the same code that builds live events, so its shape is guaranteed to match what your webhook will receive. The values are fictional.
Response — 200 — an array containing exactly one payload. The array wrapper matches the polling convention automation platforms expect.
Errors
| Status | Meaning |
|---|---|
400 | funnelId query parameter missing |
404 | No such funnel in this workspace |
Subscribe a webhook
POST /api/zapier/subscriptions
Registers a URL to receive every completion of a funnel. Call this when the user turns their automation on.
Request
{
"funnelId": "f1e2d3c4-b5a6-4789-9012-3456789abcde",
"hookUrl": "https://hooks.zapier.com/hooks/standard/123456/abcdef/"
}
targetUrl is accepted as an alias for hookUrl; supply one or the other.
Response — 201
{ "id": "7c2b1a09-5e4d-4c3b-8a19-0f6e5d4c3b2a" }
Store this id — it is required to unsubscribe.
Errors
| Status | Meaning |
|---|---|
400 | funnelId or the webhook URL missing, or the URL is not on a supported host |
404 | No such funnel in this workspace |
Webhook URLs must be hosted at hooks.zapier.com or hook.<region>.make.com. This restriction is deliberate: Clarflow only ever delivers to URLs registered through this endpoint, never to a URL supplied at delivery time, so the public delivery endpoint cannot be turned into an open forwarding proxy.
Unsubscribe
DELETE /api/zapier/subscriptions/{id}
Stops delivery. Call this when the user turns their automation off.
Response — 200
{ "success": true }
This endpoint is idempotent: deleting a subscription that does not exist, or one belonging to another workspace, still returns 200. Teardown never fails, and repeated calls are safe.
The webhook payload
Each time a visitor completes a subscribed funnel, Clarflow POSTs JSON to your registered URL.
Delivery is fire-and-forget with a 5-second timeout per webhook. A slow or failing endpoint never blocks the visitor, and one failing webhook never affects the others. Return any 2xx to acknowledge; the response body is ignored. Failed deliveries are not currently retried.
{
"primary_goal": "Lose weight",
"email": "jane@example.com",
"country": "United States",
"_meta": {
"funnelId": "f1e2d3c4-b5a6-4789-9012-3456789abcde",
"funnelTitle": "Skincare Finder Quiz",
"sessionId": "sample-session-0001",
"submittedAt": "2026-01-01T00:00:00.000Z",
"email": "jane@example.com",
"phone": "+15551234567"
},
"_responses": {
"questions": [
{
"key": "step-1_0",
"stepId": "step-1",
"questionText": "What is your primary goal?",
"selectedOptions": ["opt-1"],
"selectedLabels": ["Lose weight"]
}
],
"inputs": [
{
"key": "step-2_0",
"stepId": "step-2",
"label": "Email",
"value": "jane@example.com",
"inputType": "email"
}
],
"dropdowns": [
{
"key": "step-3_0",
"stepId": "step-3",
"label": "Country",
"value": "United States",
"optionId": "us"
}
]
}
}
Answers appear twice, deliberately.
Flat answer keys (top level)
Every answer is flattened to the top level so each question becomes a first-class, mappable field. Key names come from the author-defined variable name where one exists, and from a sanitised question or input label otherwise:
- lowercased, with every non-alphanumeric character collapsed to
_ - trimmed of leading and trailing underscores, then truncated to 50 characters
- colliding names get a numeric suffix —
goal,goal_2,goal_3— so no answer is ever silently dropped - leading underscores are stripped, so an answer can never shadow
_metaor_responses
Multi-select answers are joined into one comma-separated string. Password inputs are never forwarded.
Because these keys derive from the funnel's own content, they differ from funnel to funnel. Fetch a sample from GET /api/zapier/responses to discover the keys for a specific funnel.
_meta
| Field | Type | Notes |
|---|---|---|
funnelId | string | |
funnelTitle | string | |
sessionId | string | null | The visitor's session, when available |
submittedAt | string | ISO-8601 timestamp |
email | string | null | Present when the funnel collected one |
phone | string | null | Present when the funnel collected one |
_responses
Every answer in full structural detail, grouped into questions, inputs, and dropdowns. Use this when you need step ids and option ids rather than display labels. Each entry carries a key formatted {stepId}_{elementIndex}.
Errors
Errors return the relevant status code and a JSON body:
{ "error": "Invalid or missing session token" }
| Status | Meaning |
|---|---|
400 | Malformed request — a required field or parameter is missing or invalid |
401 | Token missing, malformed, expired, wrong scope, or invalidated by a password change |
404 | The funnel or account does not exist in this workspace |
500 | Unexpected server error |
A note on paths
These endpoints live under /api/zapier/* for historical reasons. They are platform-neutral and shared by the Zapier app, the Make app, and generic webhook consumers alike — only the host of the registered webhook URL differs.
Support
Questions about the API: support@clarflow.com.