Donutwork Docs

Recurring Payments

Orchestrate billing cycles, recover failed renewals, and monitor subscription lifecycles.

Recurring Payments API

The Recurring Payments API provides the operational infrastructure for managing subscription-based revenue models. Failed renewals enter a three-day recovery lifecycle before cancellation, while expired subscriptions can be explicitly reactivated through the customer lifecycle API.

While a subscription is past_due, an operator can queue one immediate retry with PUT /customers/{customerId}/subscriptions/{subscriptionId}/lifecycle/retry-renewal.json. The manual retry preserves the original renewal boundary and is limited to one idempotent charge per cycle and calendar day.


Operational Configuration

Audit Recurring Settings

Retrieve the global operational parameters governing recurring billing. This includes the current retry logic for failed payments and the timing offsets for subsequent billing cycles.

GET
/2026-02-01/recurring-payments/settings.json
Required permissionrecurring_settings:read

Query Parameters

No query parameters required.

Responses

Operational settings successfully retrieved.

{
  "status": "success",
  "settings": {
    "retry_policy": "daily_recovery_window",
    "max_attempts": 3,
    "next_attempt_offset": "24 hours",
    "dunning_notifications": true
  }
}

Technical Implementation

curl --location --request GET \
'https://api.hub.donutwork.com/2026-02-01/recurring-payments/settings.json' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
try {
  const config = await sdk.recurringPayments.getSettings();
  console.log(`Billing Policy: ${config.settings.retry_policy} (Max Retries: ${config.settings.max_retries})`);
} catch (error) {
  console.error(`Fetch Failed: ${error.message}`);
}

Subscription Lifecycle Monitoring

Audit Active Subscriptions

Retrieve a comprehensive inventory of all subscriptions currently managed by the recurring payment engine. This endpoint provides crucial visibility into renewal dates, customer associations, and current billing health.

GET
/2026-02-01/recurring-payments/subscriptions.json
Required permissionrecurring_subscriptions:read

Query Parameters

sizeinteger
Maximum records per page.
pageinteger
Target page index.

Responses

Subscription inventory retrieved.

{
  "type": "RecurringSubscriptions",
  "count": 1250,
  "per_page": 100,
  "elements": [
    {
      "id": "67bdf...",
      "customerId": "66a15...",
      "subscription_reference": "sub_premium_9921",
      "status": "active",
      "next_renewal_date": "2026-04-01T00:00:00Z",
      "last_payment_status": "success"
    }
  ]
}

Implementation

const filters = { page: 1, size: 50 };
try {
  const activeSubs = await sdk.recurringPayments.listSubscriptions(filters);
  activeSubs.elements.forEach(sub => {
    console.log(`Subscription ${sub.id}: Renewal due on ${sub.next_renewal_date}`);
  });
} catch (error) {
  console.error(`Telemetry Error: ${error.message}`);
}

On this page