Docs·Funnels

GET/api/v1/event/analytics/funnels/:funnelId

Get funnel conversion

How people moved through one saved funnel in the date range: how many reached each step, the share lost between steps, and what they spent. Each step is one of your goals.

The funnel follows the people who completed its first step in the range. Each then has the funnel's conversion window to complete the later steps in order, even past the end of the range, but never past now. Identified people count once across all their devices; anonymous visitors count per browser. With strictOrder on (the Exact order switch), no later step may come early; other pages in between do not matter either way.

page, event_name and goal_id conditions in filter return a 400. A funnel id that is not in this audience returns a 404.

Keys: an account key. Getting started explains both kinds.

Parameters

PropInTypeNotes
funnelIdpathstringThe id of a saved funnel in this audience.
contactListIdquerystringThe id of the audience (the tracked site) to read, a UUID: anything else returns a 400. You must be a member of the workspace the audience belongs to, or the call returns a 401. An id that matches no audience is not an error: the call returns no data.
startDatequerystringStart of the date range, read as UTC: a date such as 2026-09-01 (from midnight), or an exact time such as 2026-09-01T09:30:00Z. Use one of these two forms.
endDatequerystringEnd of the date range, read as UTC. A date such as 2026-09-30 includes that whole day; an exact time such as 2026-09-30T18:00:00Z ends the range right before that moment. If the workspace has gone past its plan's event allowance this billing period, the range is cut short at the moment the allowance ran out.
filter?querystringNarrows the results: a URL-encoded JSON array of conditions, each [key, values, operator], where a missing operator means is. Example: [["country",["US","GB"]],["page",["/pricing"],"startsWith"]] keeps visits from the US or the UK that viewed a page starting with /pricing. Every condition must match, and each key can appear once (a second condition on the same key replaces the first). A condition matches any of its values, except that isNot, notContains and notRegex rule out all of them. Operators: is and isNot (exact), contains, notContains, startsWith and endsWith (ignoring case), regex and notRegex (RE2 syntax, so no lookarounds; a pattern that does not compile returns a 400), and isNull and isNotNull (the value is not set, or is set; send [] as the values). Keys: channel, referrer_source, referrer, utm_source, utm_medium, utm_campaign, utm_term, utm_content, country (a two-letter code), region, city, browser, browser_version, os, os_version, screen_size (Desktop, Mobile or Tablet), hostname, entry_page, exit_page, page and event_name (visits that viewed such a page or sent such an event), identified (["true"] or ["false"]), goal_id (people who completed the goal in the range) and cohort_id (members of a segment). The last two take ids and only is or isNot. Unknown keys, and a filter that is not valid JSON, are ignored rather than refused. page, event_name and goal_id are refused here with a 400, because they would clash with the funnel's own steps.

Response

PropTypeNotes
completionRatenumberPeople who reached the last step divided by those who reached the first: a fraction from 0 to 1 with four decimals.
stepsFunnelReportStep[]One entry per step, in order: stepOrder, goalId, goalName, visitors, dropOffRate, revenuePerVisitor, topSources and topCountries.
strictOrderbooleantrue when Exact order is on.
windowSecondsnumberThe conversion window in seconds: how long after the first step people have to finish every step.
namestringThe funnel's name.
funnelIdstringThe funnel id.

Each item in steps

PropTypeNotes
topCountriesFunnelStepBreakdown[]Up to three countries of these people's first session in the range, as { name, share, countryCode } with two-letter codes. Unknown countries are left out.
topSourcesFunnelStepBreakdown[]Up to three sources these people came from on their first session in the range, as { name, share }, where share is a fraction of visitors and Direct means no source.
revenuePerVisitornumberEverything this step's people paid from entering the funnel to the end of their window, net, in the audience's reporting currency (Settings → Revenue), divided by visitors. Two decimals.
dropOffRatenumberShare of the previous step's people who did not reach this one: a fraction from 0 to 1 with four decimals, 0 on the first step.
visitorsnumberPeople who reached at least this step, in order, within the window.
goalNamestringThat goal's name.
goalIdstringThe goal this step is.
stepOrdernumberPosition of the step, from 1.

Request

curl 'https://app.spreelytics.com/api/v1/event/analytics/funnels/:funnelId?contactListId=…&startDate=…&endDate=…' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const url = new URL('https://app.spreelytics.com/api/v1/event/analytics/funnels/:funnelId');
url.searchParams.set('contactListId', '…');
url.searchParams.set('startDate', '…');
url.searchParams.set('endDate', '…');

const res = await fetch(url, {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
const data = await res.json();
import requests

res = requests.get(
    "https://app.spreelytics.com/api/v1/event/analytics/funnels/:funnelId",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"contactListId": "…", "startDate": "…", "endDate": "…"},
)
data = res.json()

Response

{
  "completionRate": 0,
  "steps": [
    {
      "topCountries": [
        {
          "countryCode": null,
          "share": null,
          "name": null
        }
      ],
      "topSources": [
        {
          "countryCode": null,
          "share": null,
          "name": null
        }
      ],
      "revenuePerVisitor": 0,
      "dropOffRate": 0,
      "visitors": 0,
      "goalName": "string",
      "goalId": "string",
      "stepOrder": 0
    }
  ],
  "strictOrder": true,
  "windowSeconds": 0,
  "name": "string",
  "funnelId": "string"
}

See your own numbers today.

Free up to 100k events a month · no credit card

Contact

Tell us what you need.

A real person reads these. We usually reply within one working day.

Or email us directly at contact@spreelytics.com.