Intercept cancel clicks, capture reasons, and fire save offers automatically. Works on Starter, Growth, and Pro.
chsk_live_ API key. Generate one in Integrations › Cancellation Recovery. You'll also need to point your cancel button at our mint-token endpoint before redirecting. Need help? Talk to the founder.Your cancel button calls our mint-token endpoint server-side to get a short-lived signed token, then redirects the customer to cancel.chaser.cash/<workspaceId>?token=<token>.
The customer sees a branded cancel page with your logo. They select a reason, optionally leave a comment, and see a save offer if one of your rules matches their reason and MRR.
If the customer accepts an offer, Chaser applies the coupon or pause to their Stripe subscription. If they confirm cancellation, Chaser sets cancel_at_period_end: true. Everything is logged to your Cancellation Insights dashboard.
Go to Integrations › Cancellation Recovery and enable the toggle. Select "Via a cancel button in my app" as your setup path.
Under Save Rules, add rules to intercept cancellations with a matching offer. Rules are evaluated in priority order, first match wins. You can match on cancellation reason, minimum MRR, or both.
Open the Branding accordion in the Cancellation Recovery tab to configure:
Theme: Dark or Light Logo: PNG, JPG, WEBP, or SVG up to 2MB Accent color: #RRGGBB hex, buttons and selections Background: #RRGGBB hex, page background Card color: #RRGGBB hex, form card background
Use Generate with AI to write a branded headline and subheadline in your tone. Four tones available: Founder-Style, Standard Corporate, Direct & Urgent, Concierge.
Open the Cancellation reasons accordion to add reasons specific to your product. Custom reasons appear after the seven default reasons. Click Suggest with AI to get product-specific suggestions. Max 20 custom reasons.
Host your cancel page on your own subdomain instead of chaser.cash. Requires a DNS CNAME record.
When your customer clicks cancel, call this endpoint from your backend:
POST https://chaser.cash/api/public/cancel/mint-token
Authorization: Bearer chsk_live_YOUR_KEY
Content-Type: application/json
{ "customerId": "cus_stripe_customer_id" }
Response:
{
"token": "eyJ...",
"publicWorkspaceId": "ws_xxx",
"expiresAt": "2026-06-21T21:00:00Z",
"ttlSeconds": 1800
}Redirect your customer to:
https://cancel.chaser.cash/<publicWorkspaceId>?token=<token>
The token expires in 30 minutes and is single-workspace scoped. Never expose your API key client-side.
The Cancellation Recovery tab has a live preview panel on the right. It updates instantly as you change branding, reasons, and copy. Toggle between Mobile and Desktop views using the device switcher at the top of the preview panel.
If you have a verified custom domain, click Open test page next to the Verified badge. This mints a real HMAC token and opens your cancel page in a new tab with your actual rules active.
Without a custom domain, use the preview URL to see the cancel page without a real customer token:
https://chaser.cash/cancel/{workspaceId}?token=previewThe preview token loads your real branding, logo, and custom reasons but does not process a real cancellation.
Every cancellation attempt is logged to Cancellation Insights regardless of which flow fired: branded cancel page or Stripe Billing Portal. Each event records:
source: branded_page | stripe_portal
reason_code: normalized reason (too_expensive,
missing_features, switched_competitor,
technical_issues, unused,
temporary_pause, other, unknown)
reason_raw: original reason string
save_attempted: whether an offer was shown
outcome: no_offer | offered | accepted |
declined | canceled
mrr_cents: subscription value at cancellationSave rate is calculated as accepted divided by accepted plus canceled across all cancellation attempts. MRR kept tracks the subscription value of saved customers. MRR lost tracks the value of customers who canceled despite an offer or with no offer shown.
When using the Stripe Billing Portal path, Chaser captures cancellation reasons via webhook automatically. No cancel page is shown. Reasons are mapped from Stripe's feedback enum to the normalized reason_code taxonomy.
Tokens expire after 30 minutes. If a customer lands on an expired token they see a "This link has expired" message. Mint a fresh token and redirect again.
If the Stripe customer ID has no active subscription, the cancel page returns a 404. Check that you are passing the correct stripe_customer_id, not an internal user ID.
Check that your save rule is enabled and that the customer's reason and MRR match the rule conditions. Use the Cancellation Insights dashboard to see what outcome was logged for the attempt.