ChurnCut/Docs

Endpoints

Detailed documentation for all ChurnCut API endpoints.

Customers

List customers

Get a list of customers with their churn risk status.

GET/v1/customers

Query parameters:

ParameterTypeDescription
limitintegerNumber of results (default: 20, max: 100)
offsetintegerOffset for pagination
risk_levelstringFilter: low, medium, high
statusstringFilter: active, churned, retained
bash
curl -X GET "https://api.churncut.com/v1/customers?risk_level=high&limit=10" \
  -H "Authorization: Bearer your-api-key"

Response:

json
{
  "success": true,
  "data": {
    "customers": [
      {
        "id": "cus_abc123",
        "email": "customer@example.com",
        "risk_level": "high",
        "churn_probability": 0.85,
        "status": "active",
        "subscription_id": "sub_xyz789",
        "factors": ["low_engagement", "support_tickets"],
        "created_at": "2024-01-15T10:30:00Z"
      }
    ],
    "total": 150,
    "has_more": true
  }
}

Get customer

Get detailed information about a specific customer.

GET/v1/customers/:id

Response:

json
{
  "success": true,
  "data": {
    "id": "cus_abc123",
    "email": "customer@example.com",
    "risk_level": "high",
    "churn_probability": 0.85,
    "status": "active",
    "subscription": {
      "id": "sub_xyz789",
      "plan": "pro",
      "amount": 4900,
      "currency": "usd",
      "current_period_end": "2024-02-15T00:00:00Z"
    },
    "factors": [
      { "type": "low_engagement", "weight": 0.4 },
      { "type": "support_tickets", "weight": 0.3 },
      { "type": "payment_failures", "weight": 0.15 }
    ],
    "history": [
      { "event": "cancellation_attempted", "date": "2024-01-20T14:30:00Z", "outcome": "retained" }
    ]
  }
}

Cancellation Flows

Start cancellation flow

Start a cancellation flow programmatically (alternative to JS widget).

POST/v1/cancellation-flows

Body:

json
{
  "customer_id": "cus_abc123",
  "subscription_id": "sub_xyz789",
  "reason": "too_expensive",
  "redirect_url": "https://your-app.com/subscription/cancelled"
}

Response:

json
{
  "success": true,
  "data": {
    "flow_id": "flow_123456",
    "flow_url": "https://app.churncut.com/flow/flow_123456",
    "expires_at": "2024-01-21T15:30:00Z"
  }
}

Get flow status

GET/v1/cancellation-flows/:id

Response:

json
{
  "success": true,
  "data": {
    "id": "flow_123456",
    "status": "completed",
    "outcome": "retained",
    "offer_accepted": {
      "type": "discount",
      "value": 50,
      "duration_months": 3
    },
    "completed_at": "2024-01-20T15:45:00Z"
  }
}

Analytics

Churn metrics

GET/v1/analytics/churn

Query parameters:

ParameterTypeDescription
start_datestringStart date (ISO 8601)
end_datestringEnd date (ISO 8601)
granularitystringday, week, month

Response:

json
{
  "success": true,
  "data": {
    "period": { "start": "2024-01-01", "end": "2024-01-31" },
    "summary": {
      "total_customers": 1000,
      "churned": 50,
      "churn_rate": 5.0,
      "mrr_lost": 24500
    },
    "by_period": [
      { "date": "2024-01-01", "churned": 12, "churn_rate": 1.2 },
      { "date": "2024-01-08", "churned": 15, "churn_rate": 1.5 }
    ]
  }
}

Retention metrics

GET/v1/analytics/retention

Response:

json
{
  "success": true,
  "data": {
    "period": { "start": "2024-01-01", "end": "2024-01-31" },
    "summary": {
      "cancellation_attempts": 120,
      "retained": 78,
      "retention_rate": 65.0,
      "mrr_saved": 38220
    },
    "by_offer_type": [
      { "type": "discount", "attempts": 80, "retained": 52, "rate": 65.0 },
      { "type": "pause", "attempts": 25, "retained": 18, "rate": 72.0 },
      { "type": "downgrade", "attempts": 15, "retained": 8, "rate": 53.3 }
    ]
  }
}

Webhooks

ChurnCut can send webhooks to your server when important events occur.

Available events

EventDescription
cancellation.startedUser started cancellation flow
cancellation.retainedUser was retained
cancellation.completedUser completed cancellation
offer.acceptedUser accepted an offer

Example payload

json
{
  "event": "cancellation.retained",
  "timestamp": "2024-01-20T15:45:00Z",
  "data": {
    "customer_id": "cus_abc123",
    "subscription_id": "sub_xyz789",
    "flow_id": "flow_123456",
    "offer": {
      "type": "discount",
      "value": 50,
      "duration_months": 3
    }
  }
}

Verify webhook signature

javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Important: Always verify webhook signatures before processing events.

API OverviewLast updated on January 26, 2026