Quickstart
Integrate ChurnCut into your application in minutes and start retaining customers.
Prerequisites
- An active Stripe account with subscriptions (live or test)
- Your App ID and Secret Key from ChurnCut (available in Settings)
- Ability to add a JavaScript snippet to your web app
- A developer available for API integration

Step 1: Get Cancellation Session URL
Call the ChurnCut API from your backend to generate a session URL.
Node.js
const requests = require('requests');
async function getCancellationUrl(apiKey, appId, customerEmail) {
const expiration = Math.floor(Date.now() / 1000) + 3600;
const response = await requests.post(
'https://app.churncut.com/churncut-client-integration/get-cancellation-session-url',
{
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
json: {
churncut_app_id: appId,
expiration_date_timestamp: expiration,
customer_email: customerEmail
}
}
);
return response.json(); // Returns { url, hmac }
}Python
import requests
import time
def get_cancellation_url(api_key: str, app_id: str, customer_email: str):
expiration = int(time.time()) + 3600
response = requests.post(
"https://app.churncut.com/churncut-client-integration/get-cancellation-session-url",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"churncut_app_id": app_id,
"expiration_date_timestamp": expiration,
"customer_email": customer_email
}
)
return response.json() # Returns { url, hmac }Important: The API call must be made from your backend. Never expose your Secret Key on the client.
Step 2: Add the script
Include the ChurnCut script in your web application:
<script src="https://app.churncut.com/static/user_integration/js/integration_initiallizer.js"></script>Step 3: Start the cancellation flow
After getting the URL from Step 1, parse it and call starCancellationFromURl:
// After getting { url, hmac } from the API
starCancellationFromURl(url);Complete examples by framework
Choose your framework to see a complete example with cancel button:
import { useCallback } from 'react';
function CancelButton({ customerEmail }) {
const handleCancel = useCallback(async () => {
// 1. Get session URL and hmac from your backend
const res = await fetch('/api/churncut-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ customerEmail })
});
const { url } = await res.json();
// 2. Parse URL and start cancellation flow
const urlObj = new URL(url);
const params = new URLSearchParams(urlObj.search);
window.starCancellationFromURl(data.url);
}, [customerEmail]);
return (
<button onClick={handleCancel} className="cancel-btn">
Cancel subscription
</button>
);
}Cancel button with subscription preview
A common pattern is to show the user's subscription details with a cancel button. Here's a complete component you can adapt:
Pro Plan
$49/month · Renews Feb 28, 2026
import { useCallback, useState, useEffect } from 'react';
function SubscriptionSettings({ customerEmail }) {
const [subscription, setSubscription] = useState(null);
useEffect(() => {
// Fetch subscription details from your backend
fetch(`/api/subscription?email=${customerEmail}`)
.then(res => res.json())
.then(data => setSubscription(data));
}, [customerEmail]);
const handleCancel = useCallback(async () => {
// 1. Get session URL from your backend
const res = await fetch('/api/churncut-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ customerEmail })
});
const { url } = await res.json();
// 2. Parse URL and start cancellation flow
const urlObj = new URL(url);
const params = new URLSearchParams(urlObj.search);
// 3. ChurnCut handles the rest — shows personalized offers,
// collects feedback, and only cancels if the user confirms
window.starCancellationFromURl(data.url);
}, [customerEmail]);
if (!subscription) return <div>Loading...</div>;
return (
<div className="subscription-card">
<h3>{subscription.planName}</h3>
<p>${subscription.amount}/month · Renews {subscription.renewalDate}</p>
<div className="subscription-details">
<div><span>Status</span><span>{subscription.status}</span></div>
<div><span>Payment</span><span>•••• {subscription.last4}</span></div>
</div>
<div className="subscription-actions">
<button onClick={() => navigate('/change-plan')}>
Change plan
</button>
<button onClick={handleCancel} className="cancel-btn">
Cancel subscription
</button>
</div>
</div>
);
}Tip: ChurnCut handles showing personalized offers, collecting feedback, and only cancels if the user confirms. You just need to call starCancellationFromURl.
Alternative method: Cancellation with Stripe IDs
If you prefer to use Stripe IDs instead of customer email, use this variant:
{
"churncut_app_id": "your-app-uuid",
"expiration_date_timestamp": 1735689600,
"external_user_id": "stripe_customer_id",
"subscription_id": "stripe_subscription_id"
}Warning: When using Stripe IDs, make sure to provide a valid subscription_id as well.
