API Reference
REST API for programmatic access to your Retainly workspace. All endpoints return JSON. Base URL: https://getretainly.app
Authentication
Create API tokens at Dashboard → API Tokens. Include the token in every request:
curl https://getretainly.app/api/v1/analytics \
-H "X-API-Key: rk_sk_your_token_here"Tokens are SHA-256 hashed — we never store the raw value. Copy it when created; you cannot retrieve it again.
| Scope | Access |
|---|---|
| analytics:read | Read analytics, sessions, recovery data |
| * | Full access (all read + write operations) |
Analytics
/api/v1/analyticsReturns key retention metrics for your workspace: save rate, recovery rate, MRR saved, sessions count.
curl https://getretainly.app/api/v1/analytics \
-H "X-API-Key: rk_sk_xxx"{
"workspace_id": "ws-uuid",
"period": "last_30_days",
"cancel_sessions": 142,
"saves": 44,
"save_rate_pct": 31.0,
"failed_payments": 28,
"recoveries": 17,
"recovery_rate_pct": 60.7,
"mrr_saved_cents": 184200,
"mrr_lost_cents": 96000
}/api/v1/analytics/revenueMonthly MRR saved + payments recovered breakdown. Up to 24 months of history.
curl "https://getretainly.app/api/v1/analytics/revenue?months=3" \
-H "X-API-Key: rk_sk_xxx"/api/v1/sessionsPaginated list of cancel sessions. Filter by outcome, date range.
curl "https://getretainly.app/api/v1/sessions?outcome=saved&limit=20" \
-H "X-API-Key: rk_sk_xxx"Params: limit (max 200), offset, outcome (saved|canceled|abandoned), since, until (ISO 8601 dates)
Cancel Flows (SDK endpoints)
These endpoints are called by the Retainly SDK. You don't call them directly — include them here for reference if you're building a custom SDK or debugging.
/api/flows/startStarts a cancel flow session. Returns session ID and active flow configuration.
// Request body
{
"subscription_id": "sub_xxx",
"customer_id": "cus_xxx",
"email": "user@example.com",
"metadata": {}
}
// Response
{
"session_id": "sess_uuid",
"flow": {
"id": "flow-uuid",
"steps": [...]
}
}/api/flows/saveRecords an accepted save offer and executes it in Stripe (discount, pause, downgrade, or annual switch).
// Request body
{
"session_id": "sess_uuid",
"offer_accepted": "discount",
"offer_value": { "percent": 30, "duration_months": 3 }
}
// Response
{
"success": true,
"stripe": { "success": true },
"saved_mrr_cents": 19900
}/api/flows/cancelRecords a confirmed cancellation.
// Request body
{ "session_id": "sess_uuid", "reason": "too_expensive" }/api/flows/eventRecords a flow event (e.g. offer_shown, step_viewed) for analytics.
// Request body
{ "session_id": "sess_uuid", "event_type": "offer_shown", "data": {} }Webhooks
Configure outgoing webhooks at Dashboard → Webhooks. See Integration Guide for event payload schemas and signature verification.
/api/webhooks (your endpoint)Retainly POSTs to your endpoint when retention events occur. Always verify the X-Retainly-Signature header.
// Example: cancel.saved
{
"id": "evt_uuid",
"type": "cancel.saved",
"timestamp": "2026-05-01T10:00:00Z",
"workspace_id": "ws-uuid",
"data": {
"session_id": "sess_uuid",
"customer_id": "cus_xxx",
"email": "user@example.com",
"offer": "discount",
"offer_value": { "percent": 30, "duration_months": 3 },
"saved_mrr_cents": 19900,
"cancel_reason": "too_expensive"
}
}CSV Exports
/api/exports/sessionsAll cancel sessions (last 5,000). Fields: id, email, reason, outcome, offer_type, offer_accepted, started_at, completed_at.
curl https://getretainly.app/api/exports/sessions \
-H "X-API-Key: rk_sk_xxx" \
-o sessions-export.csv/api/exports/recoveryAll payment recovery attempts (last 5,000). Fields: id, email, amount_eur, status, decline_code, attempted_at.
curl https://getretainly.app/api/exports/recovery \
-H "X-API-Key: rk_sk_xxx" \
-o recovery-export.csv/api/exports/savesAll save events (last 5,000). Fields: id, event_type, mrr_impact_eur, occurred_at.
curl https://getretainly.app/api/exports/saves \
-H "X-API-Key: rk_sk_xxx" \
-o saves-export.csvError codes
| HTTP status | Meaning |
|---|---|
| 200 | OK |
| 400 | Bad request — invalid payload, missing required field |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — valid key but insufficient scope or wrong workspace |
| 404 | Not found — resource does not exist |
| 429 | Rate limited — >60 requests/minute per key; retry after 60 seconds |
| 500 | Server error — contact hello@getretainly.app with the request ID |