Guided API flows
Practical server-side flows for customer subscriptions, payment events, and transactional email.
Guided API flows
These examples connect the endpoint reference into three common product journeys. Run them from a trusted backend with a key for the intended environment. All names, addresses, IDs, and domains are fictional placeholders. Replace IDs with values returned by your own company; never copy an ID from another company or environment.
Use the versioned base URL https://api.hub.donutwork.com/2026-02-01 and send Authorization: Bearer YOUR_API_KEY. Store the key in a server-side secret store. The examples assume that DONUTWORK_API_KEY is already available to the shell; do not commit or paste a real value into documentation. Read authentication and integration fundamentals before production use.
Flow 1: Onboard a customer and attach a plan
Goal: connect a CRM customer to a recurring plan. The key needs customers:write, customer_subscriptions:write, customer_subscriptions:read, recurring_subscriptions:read, and taxes:read.
- List available plans and tax profiles. Choose a plan and tax profile belonging to this company. The tax profile is required when attaching the plan.
curl 'https://api.hub.donutwork.com/2026-02-01/recurring-payments/subscriptions.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"
curl 'https://api.hub.donutwork.com/2026-02-01/taxes.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"- Create the customer. Save
customer.idfrom the response.externalIdis your own stable CRM identifier; a second create with the same value can return409, so look up the existing customer before retrying an ambiguous request.
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/customers.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"customer":{"company_name":"Example Studio","first_name":"Alex","last_name":"Rossi","email":"alex@example.com","externalId":"CRM-EXAMPLE-001","address":{"country":"IT","city":"Milano","address":"Via Esempio 1"}}}'- Attach the selected plan. Replace
CUSTOMER_ID,PLAN_ID, andTAX_IDwith the returned IDs. Read the customer subscription afterward to confirm the current state.
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/customers/CUSTOMER_ID/subscriptions.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"subscription":{"id":"PLAN_ID","taxes":"TAX_ID"}}'
curl 'https://api.hub.donutwork.com/2026-02-01/customers/CUSTOMER_ID/subscriptions.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"A 404 on attachment usually means the customer, plan, or tax profile is missing from this company. See the customer, recurring payments, and tax references for fields and lifecycle actions.
Flow 2: Receive payment events and reconcile a charge
Goal: receive billing changes and look up the charge's current state. The key needs webhooks:read, webhooks:write, charges:write, and charges:read. A captured charge requires a customer payment method and a valid tax profile.
- Fetch the supported event names, then register an HTTPS receiver with a valid certificate. Replace the example URL with a receiver you control. Save the generated webhook token privately; the example never includes a real token.
curl 'https://api.hub.donutwork.com/2026-02-01/webhooks/types.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/webhooks.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"webhook":{"name":"Billing updates","url":"https://example.com/webhooks/billing","events":["Charge.succeeded","Charge.failed"]}}'- Create a charge for a customer who already has a payment method. Replace
TAX_IDwith the profile selected for this company. Save the returnedideven whencapturedisfalse.
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/customers/CUSTOMER_ID/charges.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"charge":{"capture":true,"services":[{"name":"Example service","amount":25.00,"taxProfile":"TAX_ID"}]}}'- On an event or ambiguous timeout, read the charge by ID and use its current status to reconcile your own record. Do not assume that a successful create response means payment was captured. A missing payment method causes
412.
curl 'https://api.hub.donutwork.com/2026-02-01/customers/CUSTOMER_ID/charges/CHARGE_ID.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"See charges and webhooks. Register only event names returned by /webhooks/types.json.
For a payment that has already been collected by another system, follow external charge import. It records the payment and emits charge events without a second gateway capture; use its source transaction key to retry safely.
Flow 3: Send a transactional email
Goal: send a company template with safe example variables. The key needs email_templates:read and email_messages:write. Email Gateway must be configured for the company.
- List templates and choose an existing template ID. The template must have content and the variables it expects.
curl 'https://api.hub.donutwork.com/2026-02-01/email-gateway/templates.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY"- Send from the configured sender. Omit
fromto use the default; an explicitfrommust be a configured alternative sender. The recipient below is only an example.
curl -X POST 'https://api.hub.donutwork.com/2026-02-01/email-gateway/TEMPLATE_ID/send.json' \
-H "Authorization: Bearer $DONUTWORK_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"email":{"to":"recipient@example.com","subject":"Your account update","vars":{"first_name":"Alex"}}}'If the template is absent or empty, the endpoint returns 404. See the Email Gateway reference for template validation, preview, and delivery responses.
For AI, follow the AI Gateway guided examples. For more complex operations, use the workflow, AI Gateway, and AI Agents references. Each endpoint page gives the required permission and request contract.