REST API Reference
The Declined REST API is available at https://app.declined.io/api. All endpoints accept and return JSON unless noted. List endpoints support cursor pagination via limit and starting_after query parameters.
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /v1/events | Ingest billing and recovery events (idempotent) |
| GET | /v1/customers | List customers with recovery context |
| GET | /v1/recoveries | List recovery attempts |
| POST | /v1/recoveries/:id/mark-recovered | Mark a recovery attempt recovered |
| GET | /v1/sequences | List dunning sequences |
| GET | /v1/webhooks | List outbound webhook endpoints |
| GET | /v1/incentives | List incentive offers |
| GET | /v1/analytics | Recovery analytics summary |
HTTP status codes
| Code | Meaning |
|---|---|
| 200 | Duplicate event (same event_id already ingested) |
| 201 | Event accepted and processed |
| 401 | Missing, invalid, or revoked API key |
| 422 | Validation error (malformed payload or unknown event type) |
| 429 | Rate limited — retry after Retry-After seconds |
Pagination
json
{
"data": [ ... ],
"has_more": true,
"next_cursor": "ra_abc123"
}Idempotency
POST /v1/events requires a stable event_id per logical occurrence. Duplicate submissions return HTTP 200:
json
{
"status": "duplicate",
"event_id": "evt_unique_001",
"inbound_event_id": "ie_existing"
}Marking recoveries
See the dedicated Recoveries guide for POST /v1/recoveries/:id/mark-recovered and the payment_recovered event type.
Rate limits
Event ingestion is optimized for high throughput. If you exceed workspace limits, responses include 429 with a Retry-After header. Implement exponential backoff with jitter on retries.