API Reference

REST API for programmatic access to your Retainly workspace. All endpoints return JSON. Base URL: https://getretainly.app

Looking for the SDK? The SDK is for client-side cancel flows. This API is for server-to-server access (analytics, exports, configuration). See Integration Guide for SDK docs.

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.

ScopeAccess
analytics:readRead analytics, sessions, recovery data
*Full access (all read + write operations)

Analytics

GET/api/v1/analytics

Returns key retention metrics for your workspace: save rate, recovery rate, MRR saved, sessions count.

Auth: X-API-Key header (analytics:read or *)
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
}
GET/api/v1/analytics/revenue

Monthly MRR saved + payments recovered breakdown. Up to 24 months of history.

Auth: X-API-Key header (analytics:read or *)
curl "https://getretainly.app/api/v1/analytics/revenue?months=3" \
  -H "X-API-Key: rk_sk_xxx"
GET/api/v1/sessions

Paginated list of cancel sessions. Filter by outcome, date range.

Auth: X-API-Key header (analytics:read or *)
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.

POST/api/flows/start

Starts a cancel flow session. Returns session ID and active flow configuration.

Auth: X-Workspace-Key header (rk_pub_… public key)
// 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": [...]
  }
}
POST/api/flows/save

Records an accepted save offer and executes it in Stripe (discount, pause, downgrade, or annual switch).

Auth: X-Workspace-Key header
// 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
}
POST/api/flows/cancel

Records a confirmed cancellation.

Auth: X-Workspace-Key header
// Request body
{ "session_id": "sess_uuid", "reason": "too_expensive" }
POST/api/flows/event

Records a flow event (e.g. offer_shown, step_viewed) for analytics.

Auth: X-Workspace-Key header
// 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.

POST/api/webhooks (your endpoint)

Retainly POSTs to your endpoint when retention events occur. Always verify the X-Retainly-Signature header.

Auth: Verify X-Retainly-Signature: sha256=… (HMAC-SHA256)
// 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

GET/api/exports/sessions

All cancel sessions (last 5,000). Fields: id, email, reason, outcome, offer_type, offer_accepted, started_at, completed_at.

Auth: Session cookie (logged-in user) or X-API-Key header
curl https://getretainly.app/api/exports/sessions \
  -H "X-API-Key: rk_sk_xxx" \
  -o sessions-export.csv
GET/api/exports/recovery

All payment recovery attempts (last 5,000). Fields: id, email, amount_eur, status, decline_code, attempted_at.

Auth: Session cookie (logged-in user) or X-API-Key header
curl https://getretainly.app/api/exports/recovery \
  -H "X-API-Key: rk_sk_xxx" \
  -o recovery-export.csv
GET/api/exports/saves

All save events (last 5,000). Fields: id, event_type, mrr_impact_eur, occurred_at.

Auth: Session cookie (logged-in user) or X-API-Key header
curl https://getretainly.app/api/exports/saves \
  -H "X-API-Key: rk_sk_xxx" \
  -o saves-export.csv

Error codes

HTTP statusMeaning
200OK
400Bad request — invalid payload, missing required field
401Unauthorized — missing or invalid API key
403Forbidden — valid key but insufficient scope or wrong workspace
404Not found — resource does not exist
429Rate limited — >60 requests/minute per key; retry after 60 seconds
500Server error — contact hello@getretainly.app with the request ID