POST /api/v1/funnels dispatches by operation. The trusted backend starts a Funnel with the current App/environment Key and retains requestId plus complete input; run operations use the returned runToken together with that Customer's Customer Token, so a browser cannot choose its Customer. Server start, decide and campaign commands name the Customer with customer: { type: "id" } is an Indiana Customer ID (also for Guests); { type: "externalUserId" } is your user ID, and a missing Customer is created with that request, optionally with creation-only customerData (name, email, registered stored attributes, fingerprint) that never overwrites an existing Customer. This needs customers:write on the Key. A server start returns customerId so you can issue the browser's Customer session. Standalone Paywall uses its own resolve/session API without a Funnel credential.
decide.attributes contains trusted server input for this decision. A Funnel Condition reads it at parameters.attributes.channel or parameters.attributes.is_new_paying_user; a root channel condition reads registered Customer attributes. Choose the source explicitly. Request input does not replace canonical Customer identity or subscription facts.
Server-evaluated Funnel nodes (Remote decisions and condition, Feature and Split steps in flows) may use GrowthBook definitions up to about 60 seconds old: Feature, Experiment and Saved group changes, including kill switches, take effect within about 60 seconds. Funnel publications, Customer attributes and request input are not delayed; Local rule downloads are rebuilt on each request.
| Operation | Contract |
|---|---|
| start | Explicit Funnel source, stable requestId, locale and optional parameters/commerce. A server Key names customer (and optional customerData); a Customer credential starts as itself. |
| get / resume | Read current state or resume the original accepted request; preserve pinned source/version. |
| submit | Submit the current nodeId, visit, revision and stable requestId with one typed input: screen, paywall_quote, paywall_confirm, paywall_cancel or client_action. Payment confirmation reads verified provider facts. |
| back | Move back only when allowed by the current graph and revision; replay an uncertain command with its original input and requestId. |
| shown / close | Record presentation or an explicit close; destroying UI alone does not close the run. |
| decide / read_decision | Evaluate a Remote Funnel for customer (Indiana ID or your externalUserId with optional creation-only customerData) or read its accepted decision. The decision returns both customerId and externalUserId. Continue a pending request with the original identity and input. |
| campaign_decide / campaign_start | Explicit backend campaign entries in matched SDK/server versions: reuse the original Customer/Funnel decision across requests, or suppress a new presentation using durable shown history and cooldownSeconds. A suppressed entry returns reason/retryAt without a Run. Ordinary decide/start do not apply these controls. |
| feature_config / configuration | Load Feature configuration or inspect the connection policy within the authenticated App/environment. Local rules require a Local connection. |
| report_used | Report consumption of an accepted decision with a stable event identity. This records caller_reported usage and does not prove a purchase. |
| signal / read_results | Send a declared scoped event or read declared results. Match the Run, event identity and current orchestration contract. |
| renew_run | Renew a Run credential only for its current authenticated Customer. Rotation preserves runExpiresAt and does not reopen a terminal Run. |
Calls and recovery
start
- Contract
- Explicit Funnel source, stable requestId, locale and optional parameters/commerce. A server Key names customer (and optional customerData); a Customer credential starts as itself.
get / resume
- Contract
- Read current state or resume the original accepted request; preserve pinned source/version.
submit
- Contract
- Submit the current nodeId, visit, revision and stable requestId with one typed input: screen, paywall_quote, paywall_confirm, paywall_cancel or client_action. Payment confirmation reads verified provider facts.
back
- Contract
- Move back only when allowed by the current graph and revision; replay an uncertain command with its original input and requestId.
shown / close
- Contract
- Record presentation or an explicit close; destroying UI alone does not close the run.
decide / read_decision
- Contract
- Evaluate a Remote Funnel for customer (Indiana ID or your externalUserId with optional creation-only customerData) or read its accepted decision. The decision returns both customerId and externalUserId. Continue a pending request with the original identity and input.
campaign_decide / campaign_start
- Contract
- Explicit backend campaign entries in matched SDK/server versions: reuse the original Customer/Funnel decision across requests, or suppress a new presentation using durable shown history and cooldownSeconds. A suppressed entry returns reason/retryAt without a Run. Ordinary decide/start do not apply these controls.
feature_config / configuration
- Contract
- Load Feature configuration or inspect the connection policy within the authenticated App/environment. Local rules require a Local connection.
report_used
- Contract
- Report consumption of an accepted decision with a stable event identity. This records caller_reported usage and does not prove a purchase.
signal / read_results
- Contract
- Send a declared scoped event or read declared results. Match the Run, event identity and current orchestration contract.
renew_run
- Contract
- Renew a Run credential only for its current authenticated Customer. Rotation preserves runExpiresAt and does not reopen a terminal Run.
The controller retains pendingCommand when acceptance is uncertain; retry replays the original command rather than creating another operation. runExpiresAt and credentialExpiresAt have separate meanings; credential rotation does not extend business lifetime. Use background waits, signal, external tasks and result reads only when enabled by the matching deployment; its request validation determines exact fields.
Related:Funnel integration·Standalone Paywall