LostChurn Docs
API Reference

API Reference

Complete reference for the LostChurn REST API v1 — payments, customers, recoveries, campaigns, analytics, webhooks, decline codes, email, AI, and more.

API v1 (Pre-release)

Complete endpoint reference for the LostChurn REST API v1.

Base URL: https://api.lostchurn.com/api/v1

This API is in pre-release. Endpoints, request/response shapes, and rate limits may change before general availability.

For key generation and rotation, see Authentication. For error codes and rate limits, see Errors & Rate Limits.


Authentication

All API requests require an API key passed via header:

Authorization: Bearer lc_live_your_api_key

Or alternatively:

X-API-Key: lc_live_your_api_key

Response Format

Success:

{
  "data": { ... },
  "meta": {
    "merchant_id": "m_abc123",
    "timestamp": "2026-03-29T12:00:00Z"
  }
}

Paginated (offset):

{
  "data": [ ... ],
  "meta": { ... },
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 142,
    "total_pages": 6
  }
}

Paginated (cursor):

{
  "data": [ ... ],
  "meta": { ... },
  "cursor": { "next": "eyJpZCI6..." }
}

Error:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "amount_cents must be a positive integer"
  }
}

Rate Limits

TypeLimit
Read endpoints (GET)200 requests/minute per API key
Write endpoints (POST, PUT, DELETE)50 requests/minute per API key

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.


Endpoint Summary

#MethodPathScopeDescription
1GET/v1/statusOptionalAPI connection check
2GET/v1/paymentsreadList payments
3GET/v1/payments/:idreadGet payment
4GET/v1/payments/:id/timelinereadPayment timeline
5POST/v1/payments/:id/retrywriteRetry payment
6POST/v1/payments/:id/pausewritePause recovery
7POST/v1/payments/:id/resumewriteResume recovery
8GET/v1/customersreadList customers
9GET/v1/customers/by-email/:emailreadLook up by email
10GET/v1/customers/:idreadGet customer
11GET/v1/customers/:id/paymentsreadCustomer payments
12GET/v1/customers/:id/recoveriesreadCustomer recoveries
13POST/v1/customers/:id/pause-allwritePause all recovery
14POST/v1/customers/:id/resume-allwriteResume all recovery
15DELETE/v1/customers/:idadminGDPR erasure
16GET/v1/recoveriesreadList recoveries
17GET/v1/recoveries/:idreadGet recovery
18POST/v1/recoveries/:id/dunningwriteTrigger dunning
19GET/v1/campaignsreadList campaigns
20GET/v1/campaigns/:idreadGet campaign
21POST/v1/campaignswriteCreate campaign
22PUT/v1/campaigns/:idwriteUpdate campaign
23POST/v1/campaigns/:id/activatewriteActivate campaign
24POST/v1/campaigns/:id/pausewritePause campaign
25GET/v1/campaigns/templatesreadList templates
26POST/v1/campaigns/from-templatewriteCreate from template
27POST/v1/campaigns/overlapreadCheck overlap
28POST/v1/campaigns/simulatereadSimulate campaign
29GET/v1/subscriptions/:idreadSubscription status
30GET/v1/subscriptions/:id/failed-invoicesreadFailed invoices
31GET/v1/invoices/:idreadInvoice status
32GET/v1/invoices/:id/timelinereadInvoice timeline
33GET/v1/analytics/recoveryanalyticsRecovery metrics
34GET/v1/analytics/campaignsanalyticsCampaign metrics
35GET/v1/analytics/revenueanalyticsRevenue metrics
36GET/v1/analytics/at-riskanalyticsAt-risk revenue
37GET/v1/analytics/decline-codesanalyticsDecline distribution
38GET/v1/analytics/recovery-breakdownanalyticsRecovery breakdown
39GET/v1/analytics/at-risk-customersanalyticsAt-risk customers
40POST/v1/analytics/at-risk-customers/:id/enrollwriteQuick-enroll customer
41GET/v1/analytics/email-healthanalyticsEmail health
42GET/v1/analytics/email-engagementanalyticsEmail engagement
43GET/v1/analytics/summaryanalyticsSummary (alias)
44GET/v1/webhooks/endpointswebhooksList endpoints
45POST/v1/webhooks/endpointswebhooksCreate endpoint
46PUT/v1/webhooks/endpoints/:idwebhooksUpdate endpoint
47DELETE/v1/webhooks/endpoints/:idwebhooksDelete endpoint
48POST/v1/webhooks/endpoints/:id/testwebhooksTest endpoint
49GET/v1/webhooks/eventswebhooksDelivery log
50GET/v1/decline-codesreadList decline codes
51GET/v1/decline-codes/categoriesreadDecline categories
52GET/v1/decline-codes/:codereadGet decline code
53GET/v1/settings/quiet-hoursreadGet quiet hours
54POST/v1/settings/quiet-hourswriteSet quiet hours
55GET/v1/settings/recovery-goalreadGet recovery goal
56POST/v1/settings/recovery-goalwriteSet recovery goal
57GET/v1/templates/preview/:idreadPreview template
58POST/v1/ingest/payment-eventwriteIngest event
59GET/v1/email/suppressionsemailList suppressions
60DELETE/v1/email/suppressions/:emailemailRemove suppression
61GET/v1/email/suppressions/statsemailSuppression stats
62POST/v1/email/ab-testwriteCreate A/B test
63GET/v1/email/ab-test/:campaign_idreadGet A/B test
64POST/v1/email/ab-test/:campaign_id/evaluatewriteEvaluate A/B test
65GET/v1/experimentsreadList experiments
66GET/v1/experiments/:idreadGet experiment
67GET/v1/experiments/:id/resultsreadExperiment results
68POST/v1/experiments/:id/promotewritePromote winner
69POST/v1/experiments/:id/stopwriteStop experiment
70GET/v1/experiments/assign/:customer_idreadGet assignment
71GET/v1/suggestions/recoveryreadRecovery suggestions
72POST/v1/suggestions/:id/applywriteApply suggestion
73POST/v1/suggestions/:id/dismisswriteDismiss suggestion
74POST/v1/win-back/:customerIdwriteWin-back campaign
75GET/v1/cancel-flowsreadList cancel flows
76POST/v1/cancel-flowswriteCreate cancel flow
77PUT/v1/cancel-flows/:idwriteUpdate cancel flow
78DELETE/v1/cancel-flows/:idwriteDelete cancel flow
79POST/v1/cancel-flows/:id/activatewriteActivate flow
80POST/v1/cancel-flows/:id/deactivatewriteDeactivate flow
81POST/v1/ai/generatewriteAI text generation
82GET/v1/ai/pingNoneAI health check
83POST/v1/scoring/retrywriteAI retry scoring
84POST/v1/vectors/embed-eventwriteEmbed event
85POST/v1/vectors/find-similarreadFind similar
86GET/v1/vectors/recommend-strategy/:idreadRecommend strategy
87POST/v1/integrations/shopify/registeradminRegister Shopify
88GET/v1/integrations/healthreadIntegration health
89GET/v1/integrations/:id/healthreadProvider health
90GET/v1/integrations/:id/errorsreadProvider errors

Status

Check API Connection

GET /v1/status

Returns API version, server time, and authentication status. No API key required, but if one is provided the response confirms it is valid.

Response:

{
  "data": {
    "status": "ok",
    "version": "1.0.0",
    "timestamp": "2026-03-29T12:00:00Z",
    "authenticated": true,
    "merchant_id": "m_abc123"
  }
}

Payments

List Payments

GET /v1/payments

Paginated list of payment events for the authenticated merchant.

Scopes: read or read:payments

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger25Items per page (max 100)
statusstringFilter: failed, recovered, terminal, pending
decline_categorystringFilter: soft_retry, hard_customer, terminal, unknown
created_afterdateYYYY-MM-DD
created_beforedateYYYY-MM-DD

Response:

{
  "data": [
    {
      "id": "pe_abc123",
      "external_id": "ch_1abc",
      "amount_cents": 4999,
      "currency": "usd",
      "status": "failed",
      "decline_code": "insufficient_funds",
      "decline_category": "soft_retry",
      "customer_id": "cust_xyz",
      "customer_email": "jane@example.com",
      "psp": "stripe",
      "created_at": "2026-03-28T10:30:00Z"
    }
  ],
  "pagination": { "page": 1, "per_page": 25, "total": 142, "total_pages": 6 }
}

Get a Payment

GET /v1/payments/:id

Returns full details for a single payment event.

Scopes: read or read:payments

ParameterInDescription
idpathPayment ID or PSP charge ID

Response:

{
  "data": {
    "id": "pe_abc123",
    "external_id": "ch_1abc",
    "amount_cents": 4999,
    "currency": "usd",
    "status": "failed",
    "decline_code": "insufficient_funds",
    "decline_category": "soft_retry",
    "retry_count": 2,
    "max_retries": 5,
    "customer_id": "cust_xyz",
    "customer_email": "jane@example.com",
    "psp": "stripe",
    "metadata": {},
    "created_at": "2026-03-28T10:30:00Z",
    "updated_at": "2026-03-29T08:00:00Z"
  }
}

Get Payment Timeline

GET /v1/payments/:id/timeline

Returns a chronological timeline of retry attempts and status changes for a payment.

Scopes: read or read:payments

Response:

{
  "data": {
    "payment_id": "pe_abc123",
    "events": [
      {
        "type": "payment_failed",
        "timestamp": "2026-03-28T10:30:00Z",
        "details": { "decline_code": "insufficient_funds" }
      },
      {
        "type": "retry_scheduled",
        "timestamp": "2026-03-28T14:00:00Z",
        "details": { "retry_number": 1 }
      },
      {
        "type": "retry_succeeded",
        "timestamp": "2026-03-28T14:01:00Z",
        "details": { "amount_cents": 4999 }
      }
    ]
  }
}

Retry a Payment

POST /v1/payments/:id/retry

Schedule a retry attempt for a failed payment. Returns 202 Accepted.

Scopes: write or write:payments

Response (202):

{
  "data": {
    "payment_id": "pe_abc123",
    "retry_scheduled": true,
    "retry_number": 3,
    "scheduled_at": "2026-03-29T14:00:00Z"
  }
}

Pause Recovery

POST /v1/payments/:id/pause

Pause all recovery activity (retries and dunning emails) for a specific payment.

Scopes: write or write:payments

Response:

{
  "data": {
    "payment_id": "pe_abc123",
    "status": "paused"
  }
}

Resume Recovery

POST /v1/payments/:id/resume

Resume previously paused recovery for a payment.

Scopes: write or write:payments

Response:

{
  "data": {
    "payment_id": "pe_abc123",
    "status": "active"
  }
}

Customers

List Customers

GET /v1/customers

Paginated list of customers with optional search.

Scopes: read or read:customers

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger25Items per page (max 100)
searchstringSearch by name or email

Response:

{
  "data": [
    {
      "id": "cust_xyz",
      "email": "jane@example.com",
      "name": "Jane Doe",
      "total_payments": 12,
      "failed_payments": 2,
      "recovered_payments": 1,
      "total_revenue_cents": 59988,
      "created_at": "2025-06-15T00:00:00Z"
    }
  ],
  "pagination": { "page": 1, "per_page": 25, "total": 1024 }
}

Look Up Customer by Email

GET /v1/customers/by-email/:email

Find a customer by email address with recovery stats.

Scopes: read or read:customers

ParameterInDescription
emailpathURL-encoded email address

Response:

{
  "data": {
    "id": "cust_xyz",
    "email": "jane@example.com",
    "name": "Jane Doe",
    "recovery_stats": {
      "total_failed": 3,
      "total_recovered": 2,
      "recovery_rate": 0.667,
      "total_recovered_cents": 9998
    }
  }
}

Get a Customer

GET /v1/customers/:id

Get customer by internal ID or Stripe customer ID (cus_*).

Scopes: read or read:customers

List Customer Payments

GET /v1/customers/:id/payments

Returns all payment events for a specific customer.

Scopes: read or read:customers

List Customer Recoveries

GET /v1/customers/:id/recoveries

Returns all recovery records for a specific customer.

Scopes: read or read:customers

Pause All Recovery for a Customer

POST /v1/customers/:id/pause-all

Pauses recovery on all active payments for a customer.

Scopes: write or write:customers

Resume All Recovery for a Customer

POST /v1/customers/:id/resume-all

Resumes recovery on all paused payments for a customer.

Scopes: write or write:customers

Delete Customer Data (GDPR Erasure)

DELETE /v1/customers/:id

Permanently erases all customer data per GDPR Article 17. This action is irreversible.

Scopes: admin or admin:customers

Response:

{
  "data": {
    "deleted": true,
    "customer_id": "cust_xyz"
  }
}

Recoveries

List Recoveries

GET /v1/recoveries

Paginated list of recovery records.

Scopes: read

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger25Items per page (max 100)
statusstringFilter: active, recovered, terminal, paused
campaign_idstringFilter by campaign

Response:

{
  "data": [
    {
      "id": "rec_abc123",
      "payment_id": "pe_abc123",
      "customer_id": "cust_xyz",
      "campaign_id": "camp_def",
      "status": "active",
      "current_step": 2,
      "total_steps": 5,
      "amount_cents": 4999,
      "currency": "usd",
      "created_at": "2026-03-28T10:30:00Z"
    }
  ],
  "pagination": { "page": 1, "per_page": 25, "total": 87 }
}

Get a Recovery

GET /v1/recoveries/:id

Returns full details for a single recovery including campaign steps and timeline.

Scopes: read

Trigger Dunning Email

POST /v1/recoveries/:id/dunning

Manually trigger a dunning email for a recovery, bypassing the campaign schedule.

Scopes: write

Request body:

FieldTypeRequiredDescription
template_idstringNoOverride the default template
subjectstringNoCustom subject line

Response:

{
  "data": {
    "sent": true,
    "recovery_id": "rec_abc123",
    "message_id": "msg_xyz"
  }
}

Campaigns

List Campaigns

GET /v1/campaigns

Paginated list of recovery campaigns.

Scopes: read or read:campaigns

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger25Items per page (max 100)
statusstringFilter: draft, active, paused, completed, archived
triggerstringFilter: payment_failed, card_expiring, card_expired, manual, pre_dunning, soft_decline, repeated_failure, high_value_churn, any_decline

Get a Campaign

GET /v1/campaigns/:id

Returns campaign details with all steps.

Scopes: read or read:campaigns

Create a Campaign

POST /v1/campaigns

Create a new recovery campaign.

Scopes: write or write:campaigns

Request body:

FieldTypeRequiredDescription
namestringYesCampaign name (1-200 chars)
triggerstringNoTrigger type (default: payment_failed)
stepsarrayYesArray of campaign step objects (min 1)
filters_jsonstringNoJSON string of campaign filters

Response (201):

{
  "data": {
    "id": "camp_new123",
    "name": "Soft Decline Recovery",
    "status": "draft",
    "trigger": "payment_failed",
    "steps": [ ... ],
    "created_at": "2026-03-29T12:00:00Z"
  }
}

Update a Campaign

PUT /v1/campaigns/:id

Update campaign name, trigger, or filters. Campaign must be in draft or paused status.

Scopes: write or write:campaigns

Activate a Campaign

POST /v1/campaigns/:id/activate

Activate a draft or paused campaign so it begins processing enrollments.

Scopes: write or write:campaigns

Pause a Campaign

POST /v1/campaigns/:id/pause

Pause an active campaign. Existing enrollments are paused.

Scopes: write or write:campaigns

List Campaign Templates

GET /v1/campaigns/templates

Returns pre-built campaign templates that can be used as starting points.

Scopes: read or read:campaigns

Create Campaign from Template

POST /v1/campaigns/from-template

Create a new campaign using a pre-built template.

Scopes: write or write:campaigns

Request body:

FieldTypeRequiredDescription
template_idstringYesTemplate ID from the templates list
namestringNoOverride the template name

Check Campaign Overlap

POST /v1/campaigns/overlap

Check whether a campaign's filters overlap with existing active campaigns.

Scopes: read or read:campaigns

Request body:

FieldTypeRequiredDescription
triggerstringYesTrigger type
filters_jsonstringNoJSON filter criteria
exclude_campaign_idstringNoExclude a campaign from overlap check

Simulate Campaign

POST /v1/campaigns/simulate

Simulate a campaign against historical data to estimate impact before activating.

Scopes: read or read:campaigns

Request body:

FieldTypeRequiredDescription
triggerstringYesTrigger type
filters_jsonstringNoJSON filter criteria
lookback_daysintegerNoDays of historical data to simulate (default: 30)

Subscriptions & Invoices

Get Subscription Status

GET /v1/subscriptions/:id

Returns the current status and metadata for a subscription.

Scopes: read

List Failed Invoices

GET /v1/subscriptions/:id/failed-invoices

Returns all failed invoices for a subscription.

Scopes: read

Get Invoice Status

GET /v1/invoices/:id

Returns status and payment details for a single invoice.

Scopes: read

Get Invoice Timeline

GET /v1/invoices/:id/timeline

Returns retry and status change history for an invoice.

Scopes: read


Analytics

Recovery Analytics

GET /v1/analytics/recovery

Summary of failed, recovered, and terminal payments with decline category breakdown.

Scopes: analytics or read

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
group_bystringdayhour, day, week, month
pspstringFilter by PSP provider
decline_categorystringsoft_retry, hard_customer, terminal, unknown
currencystringusdISO 4217 currency code

Response:

{
  "data": {
    "summary": {
      "total_failed": 150,
      "total_recovered": 95,
      "total_terminal": 30,
      "recovery_rate": 0.633
    },
    "by_category": {
      "soft_retry": { "count": 80, "recovered": 65, "rate": 0.812 },
      "hard_customer": { "count": 45, "recovered": 20, "rate": 0.444 },
      "terminal": { "count": 25, "recovered": 10, "rate": 0.400 }
    },
    "meta": { "start_date": "2026-02-27", "end_date": "2026-03-29", "group_by": "day" }
  }
}

Campaign Analytics

GET /v1/analytics/campaigns

Per-campaign recovery rate and session counts. Uses cursor-based pagination.

Scopes: analytics or read

ParameterTypeDefaultDescription
cursorstringPagination cursor
limitinteger50Items per page (max 200)

Revenue Analytics

GET /v1/analytics/revenue

Returns revenue recovered and MRR impact for a date range.

Scopes: analytics or read

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
currencystringusdISO 4217 code

Response:

{
  "data": {
    "revenue_recovered": 475000,
    "revenue_at_risk": 275000,
    "payments_recovered": 95,
    "payments_failed": 150,
    "currency": "usd",
    "period": { "start_date": "2026-02-27", "end_date": "2026-03-29" }
  }
}

At-Risk Revenue

GET /v1/analytics/at-risk

Returns aggregate at-risk revenue across all active recoveries.

Scopes: analytics or read

Decline Code Distribution

GET /v1/analytics/decline-codes

Returns decline code frequency distribution for a date range.

Scopes: analytics or read

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
pspstringFilter by PSP

Recovery Breakdown

GET /v1/analytics/recovery-breakdown

Detailed recovery breakdown with time series data, segmented by decline category and PSP.

Scopes: analytics or read

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
group_bystringdayhour, day, week, month
segment_bystringdecline_category, psp, campaign

At-Risk Customers

GET /v1/analytics/at-risk-customers

List of customers at risk of churn, segmented by cohort.

Scopes: analytics or read

ParameterTypeDefaultDescription
cohortstringallall, expiring_card, repeat_failure, high_value
pageinteger1Page number
per_pageinteger25Items per page (max 100)

Quick-Enroll At-Risk Customer

POST /v1/analytics/at-risk-customers/:id/enroll

Enroll an at-risk customer directly into a specific campaign.

Scopes: write

Request body:

FieldTypeRequiredDescription
campaign_idstringYesTarget campaign ID

Email Health

GET /v1/analytics/email-health

Email deliverability health metrics including bounce rate, spam complaints, and domain reputation.

Scopes: analytics or email

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
group_bystringdayhour, day, week, month

Email Engagement

GET /v1/analytics/email-engagement

Email engagement metrics: open rate, click rate, and unsubscribe rate.

Scopes: analytics or email

ParameterTypeDefaultDescription
start_datedate30 days agoYYYY-MM-DD
end_datedateTodayYYYY-MM-DD
campaign_idstringFilter by campaign

Analytics Summary

GET /v1/analytics/summary

Alias for /v1/analytics/recovery. Returns the same recovery summary response.

Scopes: analytics or read


Webhooks (Outbound)

List Webhook Endpoints

GET /v1/webhooks/endpoints

Returns all registered webhook endpoints. Uses cursor-based pagination.

Scopes: webhooks or read

ParameterTypeDefaultDescription
cursorstringPagination cursor
limitinteger50Items per page (max 200)

Create a Webhook Endpoint

POST /v1/webhooks/endpoints

Register a new webhook endpoint URL.

Scopes: webhooks

Request body:

FieldTypeRequiredDescription
urlstring (URI)YesHTTPS URL to receive webhook events
eventsstring[]NoEvent types to subscribe to (default: all events)
descriptionstringNoHuman-readable description

Response (201):

{
  "data": {
    "id": "we_abc123",
    "url": "https://example.com/webhooks",
    "events": ["payment.recovered", "payment.failed"],
    "signing_secret": "whsec_abc123...",
    "created_at": "2026-03-29T12:00:00Z"
  }
}

Update a Webhook Endpoint

PUT /v1/webhooks/endpoints/:id

Update an existing webhook endpoint URL, events, or description.

Scopes: webhooks

Request body:

FieldTypeRequiredDescription
urlstring (URI)NoUpdated HTTPS URL
eventsstring[]NoUpdated event subscriptions
descriptionstringNoUpdated description
enabledbooleanNoEnable or disable the endpoint

Delete a Webhook Endpoint

DELETE /v1/webhooks/endpoints/:id

Permanently removes a webhook endpoint.

Scopes: webhooks

Test a Webhook Endpoint

POST /v1/webhooks/endpoints/:id/test

Sends a test event to the specified webhook endpoint and returns the delivery result.

Scopes: webhooks

Response:

{
  "data": {
    "success": true,
    "status_code": 200,
    "response_time_ms": 142,
    "endpoint_id": "we_abc123"
  }
}

Webhook Delivery Log

GET /v1/webhooks/events

Returns recent webhook delivery attempts with status and response codes.

Scopes: webhooks

ParameterTypeDefaultDescription
cursorstringPagination cursor
limitinteger50Items per page (max 200)
endpoint_idstringFilter by endpoint
statusstringFilter: delivered, failed, pending

Decline Codes

List Decline Codes

GET /v1/decline-codes

Paginated list of 268 decline codes across 13 PSPs.

Scopes: read

ParameterTypeDefaultDescription
pspstringFilter by PSP: stripe, braintree, adyen, checkout_com, etc.
categorystringsoft_retry, hard_customer, terminal, unknown
subcategorystringFilter by subcategory
cursorstringPagination cursor
limitinteger50Items per page (max 200)

Response:

{
  "data": [
    {
      "code": "insufficient_funds",
      "psp": "stripe",
      "category": "soft_retry",
      "subcategory": "balance",
      "description": "The card has insufficient funds to complete the purchase.",
      "recommended_action": "Retry in 24-48 hours",
      "recovery_rate": 0.72
    }
  ]
}

List Decline Code Categories

GET /v1/decline-codes/categories

Returns the 4 decline categories with subcategories and expected recovery rates.

Scopes: read

Response:

{
  "data": [
    {
      "category": "soft_retry",
      "description": "Temporary issues that are likely to resolve",
      "expected_recovery_rate": 0.75,
      "subcategories": ["balance", "limit", "processing_error"]
    },
    {
      "category": "hard_customer",
      "description": "Customer action required to resolve",
      "expected_recovery_rate": 0.35,
      "subcategories": ["expired", "stolen", "closed"]
    }
  ]
}

Get a Decline Code

GET /v1/decline-codes/:code

Returns details for a specific decline code including PSP-specific variations.

Scopes: read

ParameterInDescription
codepathDecline code string (e.g. insufficient_funds)

Settings

Get Quiet Hours

GET /v1/settings/quiet-hours

Returns the merchant's quiet hours configuration. During quiet hours, no retry attempts or dunning messages are sent.

Scopes: read

Response:

{
  "data": {
    "start_hour": 22,
    "end_hour": 8,
    "timezone": "America/New_York",
    "enabled": true
  }
}

Set Quiet Hours

POST /v1/settings/quiet-hours

Configure quiet hours for the merchant.

Scopes: write

Request body:

FieldTypeRequiredDescription
start_hourintegerYesHour to begin quiet period (0-23)
end_hourintegerYesHour to end quiet period (0-23)
timezonestringYesIANA timezone (e.g. America/New_York)

Get Recovery Goal

GET /v1/settings/recovery-goal

Returns the merchant's recovery rate target and current progress.

Scopes: read

Set Recovery Goal

POST /v1/settings/recovery-goal

Set a target recovery rate goal.

Scopes: write

Request body:

FieldTypeRequiredDescription
target_ratenumberYesTarget recovery rate (0.0-1.0)
periodstringNoGoal period: monthly, quarterly, annual

Templates

Preview Dunning Template

GET /v1/templates/preview/:id

Returns a rendered preview of a dunning email template with sample data substituted into all placeholders.

Scopes: read

Response:

{
  "data": {
    "id": "tmpl_abc123",
    "name": "Soft Decline - First Touch",
    "subject": "Your payment of $49.99 could not be processed",
    "html_preview": "<html>...</html>",
    "text_preview": "Hi Jane Doe, your payment of $49.99...",
    "placeholders": [
      "{{customer_name}}",
      "{{amount}}",
      "{{currency}}",
      "{{decline_reason}}",
      "{{retry_date}}",
      "{{update_payment_url}}"
    ]
  }
}

Email

List Email Suppressions

GET /v1/email/suppressions

Paginated list of suppressed email addresses (hard bounces, spam complaints).

Scopes: email or read

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger25Items per page (max 100)
searchstringSearch by email address
reasonstringFilter by suppression reason
active_onlystringtruetrue or false

Remove Email Suppression

DELETE /v1/email/suppressions/:email

Lift a suppression to allow emails to the address again.

Scopes: email or write

ParameterInDescription
emailpathEmail address to unsuppress

Email Suppression Stats

GET /v1/email/suppressions/stats

Returns aggregate suppression statistics.

Scopes: email or read

Create Email A/B Test

POST /v1/email/ab-test

Create a new A/B test for email subject lines or templates within a campaign.

Scopes: write

Request body:

FieldTypeRequiredDescription
campaign_idstringYesCampaign to run the test on
variantsarrayYesArray of variant objects with name, subject, and template_id
traffic_splitnumberNoPercentage of traffic for the test (default: 0.5)

Get Email A/B Test

GET /v1/email/ab-test/:campaign_id

Returns A/B test configuration and current results for a campaign.

Scopes: read

Evaluate Email A/B Test

POST /v1/email/ab-test/:campaign_id/evaluate

Evaluate the A/B test results and optionally promote the winning variant.

Scopes: write


Experiments

List Experiments

GET /v1/experiments

Returns all recovery experiments (retry timing, email cadence, etc.).

Scopes: read

Get Experiment

GET /v1/experiments/:id

Returns experiment configuration and status.

Scopes: read

Get Experiment Results

GET /v1/experiments/:id/results

Returns statistical results for an experiment including confidence intervals.

Scopes: read

Promote Experiment Winner

POST /v1/experiments/:id/promote

Promote the winning variant to be the default for all future recoveries.

Scopes: write

Stop Experiment

POST /v1/experiments/:id/stop

Stop a running experiment early.

Scopes: write

Get Customer Assignment

GET /v1/experiments/assign/:customer_id

Returns which experiment variant a customer is assigned to.

Scopes: read


AI Suggestions

Get Recovery Suggestions

GET /v1/suggestions/recovery

Returns AI-powered recovery strategy suggestions based on recent payment patterns.

Scopes: read

Apply a Suggestion

POST /v1/suggestions/:id/apply

Apply an AI suggestion (e.g. adjust retry timing, change campaign trigger).

Scopes: write

Dismiss a Suggestion

POST /v1/suggestions/:id/dismiss

Dismiss a suggestion so it no longer appears.

Scopes: write


Win-Back

Trigger Win-Back Campaign

POST /v1/win-back/:customerId

Initiate a win-back campaign for a churned customer.

Scopes: write

Request body:

FieldTypeRequiredDescription
campaign_idstringNoSpecific win-back campaign (uses default if omitted)
offer_typestringNodiscount, pause, downgrade, custom
offer_valuestringNoOffer details (e.g. 20%, 1_month_free)

Cancel Flows

List Cancel Flows

GET /v1/cancel-flows

Returns all cancel flows with steps and session statistics.

Scopes: read or read:cancel-flows

Create a Cancel Flow

POST /v1/cancel-flows

Create a new cancel flow (starts as an inactive draft).

Scopes: write or write:cancel-flows

Request body:

FieldTypeRequiredDescription
namestringYesFlow name (1-200 chars)
stepsarrayNoArray of step objects

Each step object:

FieldTypeDescription
step_typestringsurvey, offer, confirm, or custom
titlestringStep title
bodystringStep body text
optionsarrayArray of { value, label } objects
button_labelstringCTA button text

Update a Cancel Flow

PUT /v1/cancel-flows/:id

Replace all steps for a cancel flow.

Scopes: write or write:cancel-flows

Delete a Cancel Flow

DELETE /v1/cancel-flows/:id

Delete an inactive cancel flow.

Scopes: write or write:cancel-flows

Activate a Cancel Flow

POST /v1/cancel-flows/:id/activate

Activate a cancel flow. Deactivates all other flows (only one can be active).

Scopes: write or write:cancel-flows

Deactivate a Cancel Flow

POST /v1/cancel-flows/:id/deactivate

Deactivate the currently active cancel flow.

Scopes: write or write:cancel-flows


AI & Vectors

AI Text Generation

POST /v1/ai/generate

Generate AI-powered text (dunning emails, retry explanations, customer communications).

Scopes: write

Request body:

FieldTypeRequiredDescription
prompt_templatestringYesTemplate: retry_explanation, dunning_email, win_back, report_summary
contextobjectYesTemplate variables (payment details, customer info, etc.)
max_tokensintegerNoMaximum output tokens (default: 500)

Response:

{
  "data": {
    "text": "Hi Jane, we noticed your payment of $49.99 was declined...",
    "model": "qwen3-30b",
    "tokens_used": 142,
    "cost_usd": 0.0003
  }
}

AI Health Check

GET /v1/ai/ping

Returns AI service availability. No authentication required.

AI Retry Scoring

POST /v1/scoring/retry

Score a failed payment to determine optimal retry timing and likelihood of success.

Scopes: write

Request body:

FieldTypeRequiredDescription
payment_idstringYesPayment to score
decline_codestringYesCurrent decline code
amount_centsintegerYesPayment amount
currencystringYesISO 4217 code
retry_countintegerYesNumber of previous retries

Response:

{
  "data": {
    "score": 0.73,
    "recommended_delay_hours": 24,
    "confidence": 0.85,
    "reasoning": "Soft decline with 72% historical recovery rate for this code"
  }
}

Embed Recovery Event

POST /v1/vectors/embed-event

Store a recovery event as a vector embedding for similarity search.

Scopes: write or write:vectors

Request body:

FieldTypeRequiredDescription
idstringYesRecovery event ID
decline_codestringYesDecline code
amount_centsintegerYesAmount
currencystringYesCurrency
customer_segmentstringYesCustomer segment
recovery_outcomestringYesOutcome: recovered, terminal

Find Similar Recoveries

POST /v1/vectors/find-similar

Query the vector index for similar past recoveries to inform strategy.

Scopes: read or read:vectors

Request body:

FieldTypeRequiredDescription
decline_codestringYesDecline code to match
amount_centsintegerYesAmount
currencystringYesCurrency
top_kintegerNoNumber of results (default: 5)

Recommend Recovery Strategy

GET /v1/vectors/recommend-strategy/:id

Returns an AI-recommended recovery strategy based on similar past recoveries.

Scopes: read or read:vectors

ParameterInDescription
idpathPayment ID to get recommendations for

Integrations

Register Shopify Store

POST /v1/integrations/shopify/register

Creates or updates a merchant's Shopify store association during app installation.

Scopes: admin

Request body:

FieldTypeRequiredDescription
shop_domainstringYesShopify domain (e.g. mystore.myshopify.com)

Integration Health Overview

GET /v1/integrations/health

Returns health status for all configured integrations.

Scopes: read

Provider Health

GET /v1/integrations/:id/health

Returns detailed health status for a specific integration provider.

Scopes: read

Provider Errors

GET /v1/integrations/:id/errors

Returns recent error log for a specific integration provider.

Scopes: read


Ingest

Ingest Payment Event

POST /v1/ingest/payment-event

Generic payment event ingestion for PSPs without native webhook support (BigCommerce, WooCommerce, custom).

Scopes: write or admin

Request body:

FieldTypeRequiredDescription
event_typestringYespayment_failed, payment_succeeded, subscription_cancelled, payment_method_updated, charge_refunded
amount_centsintegerYesAmount in smallest currency unit
currencystringYesISO 4217 code (e.g. usd, eur)
customer_emailstringYesCustomer email address
decline_codestringNoPSP-specific decline code
metadataobjectNoArbitrary key-value metadata

Supported currencies: usd, eur, gbp, cad, aud, jpy, chf, nzd, sek, nok, dkk, pln, czk, huf, ron, bgn, hrk, brl, mxn, inr

Response:

{
  "data": {
    "event_id": "pe_new123",
    "status": "processed",
    "recovery_initiated": true
  }
}

On this page

API v1 (Pre-release)AuthenticationResponse FormatRate LimitsEndpoint SummaryStatusCheck API ConnectionPaymentsList PaymentsGet a PaymentGet Payment TimelineRetry a PaymentPause RecoveryResume RecoveryCustomersList CustomersLook Up Customer by EmailGet a CustomerList Customer PaymentsList Customer RecoveriesPause All Recovery for a CustomerResume All Recovery for a CustomerDelete Customer Data (GDPR Erasure)RecoveriesList RecoveriesGet a RecoveryTrigger Dunning EmailCampaignsList CampaignsGet a CampaignCreate a CampaignUpdate a CampaignActivate a CampaignPause a CampaignList Campaign TemplatesCreate Campaign from TemplateCheck Campaign OverlapSimulate CampaignSubscriptions & InvoicesGet Subscription StatusList Failed InvoicesGet Invoice StatusGet Invoice TimelineAnalyticsRecovery AnalyticsCampaign AnalyticsRevenue AnalyticsAt-Risk RevenueDecline Code DistributionRecovery BreakdownAt-Risk CustomersQuick-Enroll At-Risk CustomerEmail HealthEmail EngagementAnalytics SummaryWebhooks (Outbound)List Webhook EndpointsCreate a Webhook EndpointUpdate a Webhook EndpointDelete a Webhook EndpointTest a Webhook EndpointWebhook Delivery LogDecline CodesList Decline CodesList Decline Code CategoriesGet a Decline CodeSettingsGet Quiet HoursSet Quiet HoursGet Recovery GoalSet Recovery GoalTemplatesPreview Dunning TemplateEmailList Email SuppressionsRemove Email SuppressionEmail Suppression StatsCreate Email A/B TestGet Email A/B TestEvaluate Email A/B TestExperimentsList ExperimentsGet ExperimentGet Experiment ResultsPromote Experiment WinnerStop ExperimentGet Customer AssignmentAI SuggestionsGet Recovery SuggestionsApply a SuggestionDismiss a SuggestionWin-BackTrigger Win-Back CampaignCancel FlowsList Cancel FlowsCreate a Cancel FlowUpdate a Cancel FlowDelete a Cancel FlowActivate a Cancel FlowDeactivate a Cancel FlowAI & VectorsAI Text GenerationAI Health CheckAI Retry ScoringEmbed Recovery EventFind Similar RecoveriesRecommend Recovery StrategyIntegrationsRegister Shopify StoreIntegration Health OverviewProvider HealthProvider ErrorsIngestIngest Payment Event