API Reference
Programmatic access to your DunningDog workspace data.
Getting Started
The DunningDog API lets you read recovery data, manage dunning sequences, and access workspace settings from your own applications. API access is available on the Scale plan.
Base URL: https://dunningdog.com/api
To get started:
- Make sure you're on the Scale plan
- Go to Settings → API Keys in your dashboard
- Create a new API key with the scopes you need
- Copy the key immediately — it's only shown once
Authentication
Authenticate API requests by including your API key in the x-api-key header:
curl https://dunningdog.com/api/dashboard/summary \
-H "x-api-key: dd_live_your_key_here"API keys use the prefix dd_live_ followed by 48 hexadecimal characters. They are hashed on our servers — we never store the raw key.
Scopes
Each API key has one or more scopes that control which endpoints it can access. Requests to an endpoint without the required scope will receive a 403 error.
| Scope | Access | Endpoints |
|---|---|---|
read:dashboard | Dashboard metrics | GET /api/dashboard/summary |
read:recoveries | Recovery data & export | GET /api/dashboard/recoveriesGET /api/dashboard/export |
read:sequences | Read sequences | GET /api/dunning/sequences |
write:sequences | Create & update sequences | POST /api/dunning/sequencesPATCH /api/dunning/sequences/:id |
read:settings | Workspace settings | GET /api/settings/brandingGET /api/settings/notifications |
Security: API keys grant access to your workspace data. Keep them secret. Never expose them in client-side code, public repositories, or browser requests. Use API keys exclusively from server-side applications.
Error Format
All errors follow the RFC 7807 Problem+JSON format:
{
"type": "https://docs.dunningdog.com/errors/AUTH_FORBIDDEN",
"title": "Insufficient API key permissions",
"status": 403,
"code": "AUTH_FORBIDDEN",
"detail": "This API key lacks the required scope(s): read:dashboard.",
"instance": "/api/dashboard/summary",
"traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"meta": {}
}Common Error Codes
| Status | Code | Description |
|---|---|---|
| 401 | AUTH_UNAUTHORIZED | Invalid or missing API key |
| 403 | AUTH_FORBIDDEN | API key lacks required scope or plan feature |
| 403 | FEATURE_NOT_AVAILABLE | Feature not included in your billing plan |
| 403 | TRIAL_EXPIRED | Workspace trial has ended |
| 400 | VALIDATION_REQUEST_BODY_INVALID | Request body failed validation |
| 404 | AUTH_FORBIDDEN | Resource not found or not accessible |
Rate Limits
API requests are rate-limited to 100 requests per minute per API key. If you exceed this limit, you'll receive a 429 response with a Retry-After header indicating how many seconds to wait.
{
"type": "https://docs.dunningdog.com/errors/RATE_LIMIT_EXCEEDED",
"title": "Rate limit exceeded",
"status": 429,
"code": "RATE_LIMIT_EXCEEDED",
"detail": "Too many requests. Retry after 12 seconds."
}Endpoint Reference
Get Dashboard Summary
/api/dashboard/summaryReturns aggregated recovery metrics for your workspace, including failed and recovered revenue, recovery rate, active sequences, and at-risk subscriptions.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
window | string | Time window. One of 7d, 30d, 90d, month, lifetime. Default: month. |
Example Request
curl https://dunningdog.com/api/dashboard/summary?window=30d \
-H "x-api-key: dd_live_your_key_here"Example Response
{
"workspaceId": "ws_abc123",
"window": "30d",
"failedRevenueCents": 125000,
"recoveredRevenueCents": 87500,
"recoveryRate": 0.7,
"atRiskCount": 3,
"activeSequences": 2,
"generatedAt": "2026-03-04T12:00:00.000Z",
"latestSnapshot": {
"id": "snap_1",
"workspaceId": "ws_abc123",
"periodStart": "2026-02-01T00:00:00.000Z",
"periodEnd": "2026-03-01T00:00:00.000Z",
"failedRevenueCents": 200000,
"recoveredRevenueCents": 140000,
"recoveryRate": 0.7,
"atRiskCount": 5,
"generatedAt": "2026-03-01T00:05:00.000Z"
},
"atRiskPreview": []
}List Recovery Attempts
/api/dashboard/recoveriesReturns a paginated list of recovery attempts for your workspace. Each item includes the recovery attempt details and the latest outcome.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: pending, recovered, failed, or abandoned. |
limit | integer | Number of results (1–100). Default: 20. |
Example Request
curl "https://dunningdog.com/api/dashboard/recoveries?status=recovered&limit=5" \
-H "x-api-key: dd_live_your_key_here"Example Response
{
"items": [
{
"attempt": {
"id": "ra_1",
"workspaceId": "ws_abc123",
"stripeInvoiceId": "in_1abc",
"stripeCustomerId": "cus_xyz",
"declineType": "soft",
"status": "recovered",
"amountDueCents": 4999,
"recoveredAmountCents": 4999,
"startedAt": "2026-02-15T10:00:00.000Z",
"endedAt": "2026-02-17T08:30:00.000Z"
},
"latestOutcome": {
"id": "ro_1",
"workspaceId": "ws_abc123",
"recoveryAttemptId": "ra_1",
"outcome": "recovered",
"reasonCode": null,
"occurredAt": "2026-02-17T08:30:00.000Z"
}
}
],
"nextCursor": null
}Export Recoveries (CSV)
/api/dashboard/exportDownloads recovery attempts as a CSV file. Useful for importing data into spreadsheets or BI tools.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
startDate | string | ISO 8601 date (e.g. 2026-01-01). Defaults to 30 days before endDate. |
endDate | string | ISO 8601 date. Defaults to today. |
status | string | Filter by status: pending, recovered, failed, or abandoned. |
Example Request
curl "https://dunningdog.com/api/dashboard/export?startDate=2026-02-01&endDate=2026-03-01" \
-H "x-api-key: dd_live_your_key_here" \
-o recoveries.csvThe response has Content-Type: text/csv and a Content-Disposition header with the filename.
List Dunning Sequences
/api/dunning/sequencesReturns all dunning sequences for your workspace, including their steps ordered by position.
Example Request
curl https://dunningdog.com/api/dunning/sequences \
-H "x-api-key: dd_live_your_key_here"Example Response
{
"items": [
{
"id": "seq_1",
"workspaceId": "ws_abc123",
"name": "Default Recovery",
"isEnabled": true,
"steps": [
{
"id": "step_1",
"delayHours": 0,
"subjectTemplate": "Your payment failed",
"bodyTemplate": "Hi {{customerName}}, we couldn't process your payment...",
"status": "scheduled"
},
{
"id": "step_2",
"delayHours": 72,
"subjectTemplate": "Reminder: update your payment method",
"bodyTemplate": "Hi {{customerName}}, this is a friendly reminder...",
"status": "scheduled"
}
],
"createdAt": "2026-01-15T09:00:00.000Z",
"updatedAt": "2026-02-20T14:30:00.000Z"
}
]
}Create Dunning Sequence
/api/dunning/sequencesCreates a new dunning sequence with one or more email steps. The maximum number of steps depends on your plan.
Request Body
| Parameter | Type | Description |
|---|---|---|
workspaceIdrequired | string | Your workspace ID. |
namerequired | string | Name for the sequence. |
isEnabledrequired | boolean | Whether the sequence should be active. |
stepsrequired | array | Array of step objects, each with delayHours (integer, hours after previous step), subjectTemplate (string), and bodyTemplate (string). |
Example Request
curl -X POST https://dunningdog.com/api/dunning/sequences \
-H "x-api-key: dd_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"workspaceId": "ws_abc123",
"name": "Gentle Recovery",
"isEnabled": true,
"steps": [
{
"delayHours": 0,
"subjectTemplate": "Action needed: payment failed",
"bodyTemplate": "Hi {{customerName}}, your payment of {{amount}} could not be processed..."
},
{
"delayHours": 48,
"subjectTemplate": "Reminder: please update your payment method",
"bodyTemplate": "Hi {{customerName}}, we still need your updated payment details..."
}
]
}'Example Response (201)
{
"id": "seq_new1",
"workspaceId": "ws_abc123",
"name": "Gentle Recovery",
"isEnabled": true,
"steps": [
{
"id": "step_a",
"delayHours": 0,
"subjectTemplate": "Action needed: payment failed",
"bodyTemplate": "Hi {{customerName}}, your payment of {{amount}} could not be processed...",
"status": "scheduled"
},
{
"id": "step_b",
"delayHours": 48,
"subjectTemplate": "Reminder: please update your payment method",
"bodyTemplate": "Hi {{customerName}}, we still need your updated payment details...",
"status": "scheduled"
}
],
"createdAt": "2026-03-04T10:00:00.000Z",
"updatedAt": "2026-03-04T10:00:00.000Z"
}Update Dunning Sequence
/api/dunning/sequences/:idUpdates an existing dunning sequence. You can change the name, enabled status, or replace the steps entirely. All fields are optional.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | string | Sequence ID. |
Request Body
| Parameter | Type | Description |
|---|---|---|
name | string | New name. |
isEnabled | boolean | Enable or disable. |
steps | array | Replace all steps. Each object: id (optional, for existing steps), delayHours, subjectTemplate, bodyTemplate. |
Example Request
curl -X PATCH https://dunningdog.com/api/dunning/sequences/seq_1 \
-H "x-api-key: dd_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "isEnabled": false }'Get Workspace Branding
/api/settings/brandingReturns the branding settings for your workspace, including company name, logo URL, accent color, and email footer text.
Example Request
curl https://dunningdog.com/api/settings/branding \
-H "x-api-key: dd_live_your_key_here"Example Response
{
"companyName": "Acme Inc",
"logoUrl": "https://example.com/logo.png",
"accentColor": "#10b981",
"footerText": "Acme Inc - Powered by DunningDog"
}List Notification Channels
/api/settings/notificationsReturns the configured notification channels (Slack or Discord webhooks) for your workspace.
Example Request
curl https://dunningdog.com/api/settings/notifications \
-H "x-api-key: dd_live_your_key_here"Example Response
[
{
"id": "nc_1",
"workspaceId": "ws_abc123",
"type": "slack",
"label": "Recovery alerts",
"webhookUrl": "https://hooks.slack.com/services/T.../B.../xxx",
"events": ["recovery_started", "recovery_succeeded", "recovery_failed"],
"createdAt": "2026-02-01T12:00:00.000Z"
}
]Need help? Contact us at info@dunningdog.com.