REST API Reference
The Declined REST API is available at https://dev.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 |
| GET | /v1/customers | List customers with recovery context |
| GET | /v1/recoveries | List recovery attempts |
| POST | /v1/recoveries/:id/mark-recovered | Mark a recovery attempt as successfully 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 | Success (including idempotent event replays) |
| 201 | Resource created |
| 400 | Invalid request body or query parameters |
| 401 | Missing or invalid API key |
| 403 | Authenticated but not allowed for this resource |
| 404 | Resource not found in this workspace |
| 409 | Conflict (e.g. duplicate non-idempotent create) |
| 429 | Rate limited — retry with backoff |
| 500 | Unexpected server error |
| 0 / network | The request never reached Declined (DNS, CORS, offline, or aborted). Retry from Sandbox after checking connectivity. |
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.