Skip to content
SarvexDocs
Esc
↑↓navigate↵open⌘Jpreview

Discovery-to-checkout funnel stage counts and derived rates

Stage counts are monotonically non-increasing through the funnel (a session cannot reach checkout without reaching cart). Rates are derived at read time from the stored counts, never stored as percentages. Max range 92 days.

GET/channel/funnel
Authorization
AuthorizationBearer token (JWT) · headerrequired

JWT issued by the external IdP via the OAuth 2.0 authorization-code flow (Kinde in production; a simulator in test). The client obtains it and sends it as a Bearer token on every authenticated call. Sarvex's services verify it — issuer, audience, signature (IdP JWKS), expiry — and read identity and tenant from its claims. Sarvex does not issue or revoke these tokens. merchant_id/store_id are read from the verified claims (and the merchant→store mapping), never from the URL. The operator scope is required for /operator/*. Operators acting on a specific merchant pass the X-Operate-As header, which is recorded in the audit log.

Query parameters
fromstring<date>

yyyy-MM-dd, inclusive. Defaults to 29 days before to. Range with to is capped at 92 days.

tostring<date>

yyyy-MM-dd, inclusive. Defaults to today (UTC). Range with from is capped at 92 days.

surfacechannel_surface

Restrict to one surface. Omit for the all-surfaces combined rollup.

Allowed:google_ai_modegoogle_geminiopenai_chatgptother_agentunknown
store_idstring
Responses
200

Funnel stage counts and derived rates for the range.

fromstring<date>
tostring<date>
surfacechannel_surface_or_all

channel_surface's domain plus the literal "all", used only on the combined-across-surfaces row (channel_summary, channel_funnel). Distinct from channel_surface because the query parameter and channel_daily_entry never emit "all" — a daily row is always one real surface.

Allowed:google_ai_modegoogle_geminiopenai_chatgptother_agentunknownall
sessionsinteger
sessions_confirmedinteger

sessions minus sessions_inferred.

sessions_inferredinteger
sessions_reached_cartinteger
sessions_reached_checkoutinteger
checkouts_initiatedinteger
checkouts_completedinteger
currencystring | null

Same absent/currency_mixed rule as channel_summary.currency.

currency_mixedboolean
rateschannel_rates

Derived at read time from stored counts (R7) — never itself stored.

Show properties
cart_ratenumber<double>

sessions_reached_cart / sessions.

checkout_ratenumber<double>

sessions_reached_checkout / sessions_reached_cart.

completion_ratenumber<double>

checkouts_completed / checkouts_initiated.

aov_minorinteger

revenue_minor / checkouts_completed, zero-safe.

403

Authenticated but not permitted (e.g. non-operator on an operator route).

errorobjectrequired
Show properties
codestringrequired
messagestringrequired
detailsobject | null
422

Request body failed validation.

errorobjectrequired
Show properties
codestringrequired
messagestringrequired
detailsobject | null
Try it
Server
Authorization
Parameters
Request
curl -X GET "https://api.sarvex.example.com/v1/channel/funnel" \
  -H "Authorization: Bearer YOUR_TOKEN"
Response
{
  "from": "2019-08-24",
  "to": "2019-08-24",
  "surface": "google_ai_mode",
  "sessions": 0,
  "sessions_confirmed": 0,
  "sessions_inferred": 0,
  "sessions_reached_cart": 0,
  "sessions_reached_checkout": 0,
  "checkouts_initiated": 0,
  "checkouts_completed": 0,
  "currency": "string",
  "currency_mixed": true,
  "rates": {
    "cart_rate": 0.1,
    "checkout_rate": 0.1,
    "completion_rate": 0.1,
    "aov_minor": 0
  }
}