Building Flows
Create and configure cancel flows using the visual flow builder — add steps, set up conditional branching, and test before going live.
The cancel flow builder is a visual editor for designing the experience subscribers see when they click "Cancel". You add steps in sequence, configure each one, and connect cancellation reasons to targeted offers.
Creating a New Flow
- Navigate to Cancel Flows in the left sidebar
- Click New Flow
- Give your flow a name (e.g., "Default Cancel Flow" or "Enterprise Tier Cancellation")
- The builder opens with an empty canvas
Each flow needs at least one step to be useful. Most effective flows include three steps: a survey, an offer, and a confirmation.
Step Types
Every step in a cancel flow has a type that determines what the subscriber sees:
| Step Type | Purpose |
|---|---|
| Survey | Collect the cancellation reason via multiple choice or free text |
| Offer | Present a retention offer (pause, downgrade, discount, or extension) |
| Confirm | Final confirmation before processing the cancellation |
Steps execute in the order you define them. You can reorder steps by dragging them in the builder.
Adding Steps
Click Add Step below the last step in your flow. Choose the step type, then configure it:
Survey Step
Select from pre-built survey templates or create custom questions. See Survey Steps for full configuration details.
Offer Step
Choose the offer type and configure its parameters. Each offer type has its own settings:
- Pause — Set pause duration. See Pause Offers.
- Downgrade — Select the target plan. See Downgrade Offers.
- Discount — Set discount amount and duration. See Discount Offers.
- Extension — Set extension length. See Extension Offers.
Confirm Step
Configure the final confirmation message. This step shows when the subscriber declines all offers and proceeds with cancellation. Customize the headline, body copy, and CTA text.
Conditional Branching
The most effective cancel flows present different offers based on why the subscriber is leaving. You can set up conditional branching to map survey responses to specific offer steps.
Example configuration:
| Cancellation Reason | Offer Presented |
|---|---|
| Too expensive | 20% discount for 3 months |
| Not using it enough | Pause for 1 month |
| Missing features | Downgrade to a lower tier |
| Switching to competitor | 30% discount + feature comparison |
| Other | Pause for 1 month |
To configure branching:
- Add a Survey step as your first step
- Add multiple Offer steps after it
- In each offer step, set the Trigger Reason — the survey answer that activates this offer
- If a subscriber's reason doesn't match any specific trigger, the default offer is shown
Preview and Testing
Before activating a flow, test it to make sure the experience works as intended.
Preview Mode
Click Preview in the top-right corner of the builder. This opens a simulation of the cancel flow as your subscribers will see it. Walk through each step, select different survey answers, and verify that the correct offers appear.
Test with a Sandbox Subscription
For a full end-to-end test:
- Create a test subscription in your payment processor's sandbox/test mode
- Set your cancel flow to Active
- Trigger a cancellation on the test subscription
- Verify the session appears in Cancel Flows > Sessions with the correct status
Things to Check
- Survey options are clear and cover the most common reasons
- The right offer appears for each cancellation reason
- Offer details (discount amount, pause duration) are correct
- The confirmation step copy is accurate
- The flow creates a session record with the correct status after completion
Session Management at the Edge
Cancel flow sessions run entirely at the edge using Cloudflare KV, delivering sub-millisecond step transitions with no database round-trip during the flow. This means the cancel experience feels instant to your subscribers, regardless of their location.
How It Works
When a subscriber initiates a cancellation:
- Session created in KV — The edge worker creates a session record in Cloudflare KV containing the flow definition, current step, and subscriber context.
- Step transitions at the edge — As the subscriber moves through survey questions and offers, each transition reads and writes to KV directly. No database call is made during the flow.
- Auto-expiry — Sessions that are abandoned (subscriber closes the page without completing) automatically expire after 1 hour. Expired sessions are cleaned up by KV's built-in TTL mechanism.
- Final persistence — When the subscriber completes the flow (either canceling or accepting an offer), the final outcome is persisted to the database for analytics, reporting, and integration with your payment processor.
Because sessions live at the edge, a KV outage does not prevent cancellations. The worker falls back to a direct database session if KV is unavailable, preserving the full cancel flow experience with slightly higher latency.
Token-Based Session Access
Each session is identified by a UUID token returned when the session is created. This token is the only way to access or advance the session -- it acts as both an identifier and an access credential. Tokens are generated using crypto.randomUUID() and are separate from the internal session ID.
- The token is returned to the caller on session creation and should be included in subsequent requests
- Tokens are not stored in any persistent database -- they exist only in KV with the session TTL
- No PII is stored in the session record (customer ID is a UUID, not an email or name)
Session State Machine
Every session follows a defined state machine:
| State | Description |
|---|---|
in_progress | Session is active; subscriber is moving through steps |
saved | Subscriber accepted a retention offer (session completed successfully) |
completed | Session finished normally (used for non-retention completions) |
churned | Subscriber declined all offers and confirmed cancellation |
State transitions:
in_progress → saved (subscriber accepts an offer)
in_progress → churned (subscriber confirms cancellation)
in_progress → [expired] (abandoned — KV TTL removes the record after 1 hour)Once a session reaches saved or churned, it is persisted to SpacetimeDB and the KV record is deleted. Expired sessions leave no trace -- they are silently removed by KV's TTL mechanism.
Response Accumulation
As a subscriber advances through each step, their responses are accumulated in the session record:
- Each advance appends a response object containing the
step_type,response_json, and optionally anaccepted_offeridentifier - The full response history travels with the session in KV, so no database reads are needed mid-flow
- On completion, the entire response array is persisted to SpacetimeDB as part of the
cancel_feedbackrecord - This accumulated data powers the Measuring Saves analytics, showing which survey answers and offers are most effective
What SpacetimeDB Handles
While KV owns the session lifecycle, SpacetimeDB is still used for:
- Cancel flow configuration — Flow definitions and step configs (
cancel_flowandcancel_flow_steptables) are read from SpacetimeDB when the session starts and when step config is requested - Outcome persistence — On completion, the worker calls a reducer to insert a
cancel_feedbackrow, emit arecovery_event, and update subscription status if the outcome ischurned - Analytics — All completed session data lives in SpacetimeDB for reporting and cohort analysis
For the full cancel session API reference, see Cancel Sessions API.
Activating Your Flow
When you are satisfied with the flow:
- Click Activate in the builder toolbar
- The flow becomes live immediately for new cancellation attempts
- Only one flow can be active per merchant at a time — activating a new flow deactivates the previous one
You can deactivate a flow at any time from the cancel flows list. In-progress sessions will complete using the flow that was active when they started.
Managing Multiple Flows
While only one flow can be active at a time, you can create multiple flows for different scenarios and switch between them:
- Seasonal flows — Use a more aggressive retention offer during renewal periods
- Segment-specific flows — Build different flows for different plan tiers and activate the appropriate one
- A/B testing — Create two flow variants, run each for a set period, and compare results in Measuring Saves
Next Steps
- Survey Steps — Design effective cancellation surveys
- Discount Offers — Configure discount and coupon offers
- Measuring Saves — Track flow performance