Funnel Lifecycle: Save, Publish & Go-Live
This guide covers the full lifecycle of a funnel managed through the API: duplicating an existing funnel, saving it (which mounts staging routes), previewing it, and publishing it to a production custom domain. It mirrors exactly what the CRM editor does when you click Save and Publish.If you’re creating your first funnel from scratch, start with the Funnel Orchestrator guide. This page focuses on the staging → production lifecycle.
The two environments of a funnel
Every funnel has two configurations:| Environment | Field | Served on | Updated by |
|---|---|---|---|
| Staging (draft) | config | {funnel-slug}--{storeId}.cdn.tagada.io | PUT /funnels/{funnelId} (Save) |
| Production (live) | productionConfig | Your custom domain (e.g. pay.example.com) | POST /funnels/{funnelId}/promote (Publish) |
config.id (its slug) and the store id. Example: a funnel with slug my-funnel on store_abc123 is served at https://my-funnel--store_abc123.cdn.tagada.io.
The golden workflow: Save, then Publish
The CRM editor always performs these two steps in order — and so should you:Save — PUT /funnels/{funnelId}
Persists the staging
config, mounts the staging routes on the CDN alias, computes URL → step mappings (including path remaps), and triggers page prebuilds.PUT replaces the entire config
PUT /funnels/{funnelId} is a full replace, not a patch. Sending a partial config (for example {"config": {"name": "New name"}}) will erase your funnel’s steps.
Always follow the read-modify-write pattern:
Duplicate an existing funnel
There is no dedicated duplicate endpoint — duplication is a read + create + save sequence:Sanitize the config
Before creating the copy:
- Change
config.id(the slug) — it determines the staging alias and must be unique per store - Change
config.name - Remove every
routeIdfrom node configs (they belong to the source funnel’s routes) - Reset every
mountPointId/urlon node configs (they point to the source funnel’s domains)
nodes[].config.stepConfig.payment.paymentFlowId on the checkout node before saving.
Preview the staging funnel
Create a preview session to test the staging environment without real payments:Publish to a production domain
| Field | Description |
|---|---|
customDomain | The production domain the funnel goes live on. Must already be attached to your store. |
acknowledgeConflict | Set true to confirm replacing routes another funnel currently owns on that domain. |
Troubleshooting
401 — Missing or invalid API key
401 — Missing or invalid API key
Every funnel endpoint requires your API key as a Bearer token:Watch out for an empty variable in shell scripts (
Authorization: Bearer with nothing after it) — it produces the same 401 as a missing header. Verify with echo ${#KEY} before calling.Legacy error: "Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware()"
Legacy error: "Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware()"
Older API versions returned this confusing 500 when the
Authorization header was missing, empty, or not a recognized key format. It never indicated a server problem — only that the API key didn’t reach the server. Current versions return a clear 401 explaining how to pass the key. Fix: send Authorization: Bearer YOUR_API_KEY with a non-empty, valid key.Staging alias returns 404
Staging alias returns 404
The funnel was created (and possibly promoted) but never saved, so no staging routes were mounted. Run
PUT /funnels/{funnelId} with the full config once, then retry.Production works on the internal path but 404s on the public path
Production works on the internal path but 404s on the public path
A step can declare a public
path (e.g. /checkout) remapped to an internal pagePath (e.g. /checkout-secure). The remap is materialized when staging routes are mounted (Save). If you promoted before ever saving, re-run Save then Publish to restore the remap.Doing this from an AI agent (MCP)
The CRM MCP server currently exposes funnels read-only (funnels.list, funnels.retrieve) — useful for diagnosing configuration. For mutations (create, save, promote), point your agent at the REST endpoints on this page with the same API key; they are designed to be safely scriptable.
Endpoint reference
| Endpoint | Method | Lifecycle role |
|---|---|---|
/funnels/{id} | GET | Read config (start of every read-modify-write) |
/funnels | POST | Create (or duplicate from a copied config) |
/funnels/{funnelId} | PUT | Save — persist staging config + mount staging routes |
/funnels/{funnelId}/promote | POST | Publish — copy staging routes to the production domain |
/funnels/{funnelId}/preview-session | POST | Test staging without real payments |
