The RetainRabbit REST API, version 1. Base URL https://retainrabbit.com/api/v1. Every response is { "data": … } on success or { "error": "…" } on failure.
Authentication
Send a workspace API key (mint one in Integrations → API keys) as a bearer token. read keys cover every GET; read+write also allows POST /sessions. Keys are server-side only — never ship one in a browser bundle.
Authorization: Bearer rk_live_xxxxxxxx/flowsscope: readList the workspace's flows.
curl -H "authorization: Bearer rk_live_…" https://retainrabbit.com/api/v1/flows{ "data": [
{ "id": "…", "name": "Win-back", "slug": "win-back", "status": "active", "updatedAt": "2026-06-30T12:00:00Z" }
] }/flows/:idscope: readOne flow with its public step shape and the customer-facing hostedUrl.
curl -H "authorization: Bearer rk_live_…" https://retainrabbit.com/api/v1/flows/FLOW_ID{ "data": {
"id": "…", "name": "Win-back", "slug": "win-back", "status": "active", "updatedAt": "…",
"steps": [
{ "type": "survey", "label": "Why are you cancelling?", "config": { "options": ["Too expensive", "…"] } },
{ "type": "offer", "label": "A better price", "config": { "kind": "discount", "percentOff": 30 } },
{ "type": "confirmation", "label": "You're all set", "config": { "message": "…" } }
],
"hostedUrl": "https://retainrabbit.com/flow/WORKSPACE_ID/FLOW_ID"
} }Returns 404 if the flow isn't in your workspace.
/sessions/:idscope: readPoll a cancellation session's outcome (e.g. one you started via POST /sessions).
curl -H "authorization: Bearer rk_live_…" https://retainrabbit.com/api/v1/sessions/SESSION_ID{ "data": {
"id": "…", "customerId": "cus_…", "reason": "too expensive",
"outcome": "saved", "recoveredMrrCents": 2000, "createdAt": "…"
} }outcome is one of pending, saved, canceled.
/statsscope: readWorkspace recovery summary. Sandbox/test sessions are excluded.
curl -H "authorization: Bearer rk_live_…" https://retainrabbit.com/api/v1/stats{ "data": {
"recoveredMrrCents": 238000, "saveRate": 0.385,
"sessions": 1284, "saved": 494, "canceled": 790, "pending": 0, "window": "all"
} }saveRate is saved / (saved + canceled), or 0 before anything is decided.
/sessionsscope: read+writeStart a cancellation session programmatically (e.g. from your backend).
curl -X POST -H "authorization: Bearer rk_live_…" -H "content-type: application/json" \
-d '{"customerId":"cus_…","subscriptionId":"sub_…","reason":"too expensive"}' \
https://retainrabbit.com/api/v1/sessions{ "data": { "id": "…", "outcome": "pending" } }A read-only key here returns 403.
/sessionsscope: readThe 100 most recent non-test sessions for the workspace.
curl -H "authorization: Bearer rk_live_…" https://retainrabbit.com/api/v1/sessionsErrors
Errors are { "error": "<message>" } with a status:
400 — bad input401 — missing/invalid API key403 — read-only key on a write404 — not found in your workspaceFor workspace isolation, an id from another workspace returns 404 (never its data).