DonutworkHelp Center
Documentazione Donutwork

Integration fundamentals

Production guidance for errors, retries, pagination, rate limits, observability, and safe API-key handling.

Integration fundamentals

Donutwork is a server-to-server JSON API. Build one small client layer that owns authentication, timeouts, error parsing, request correlation, and retry policy; keep business code independent from HTTP details.

Environments and versioning

Use the production origin and pin the API version in every URL:

https://api.hub.donutwork.com/2026-02-01

Never construct requests from an unversioned base URL. Keep staging and production API keys in separate secret stores, and never reuse resource IDs across environments. The 2026-02-01 contract is currently served by the compatible 2024-08-01 implementation; clients should still send the documented version so future migrations are explicit.

Request conventions

  • Send Authorization: Bearer YOUR_API_KEY on every request.
  • Send Content-Type: application/json when a JSON body is present.
  • Treat IDs as opaque strings. Do not infer type, creation time, or tenant from their shape.
  • Use UTC ISO 8601 timestamps unless an endpoint documents a date-only value.
  • Omit optional fields instead of sending empty strings unless clearing a value is explicitly supported.
  • Never place secrets, credentials, tokens, or sensitive customer content in metadata fields.

All lookups are scoped to the company attached to the API key. An identifier copied from another company is not a way to cross the tenant boundary and normally resolves as not found.

Success and error handling

Success responses are JSON unless an endpoint explicitly returns a different representation, such as a PDF. Error responses use this common envelope:

{
  "error": "Human-readable error or stable error token"
}

Some errors add machine-readable context. For example, a permission denial includes required_permission and granted_permissions; validation endpoints can add errors and warnings arrays. Copilot handlers use a structured error object with code and message; inspect the endpoint's envelope instead of assuming that every error is a string. A 204 response has no body, and a successful PDF response is binary.

StatusMeaningClient action
400Malformed request or missing envelopeFix serialization or required structure; do not retry unchanged.
401Missing, invalid, or revoked API keyStop and rotate or correct the key.
403Key is valid but lacks accessRequest the required scope; do not retry unchanged.
404Route or tenant-scoped resource not foundVerify version, ID, company, and environment.
409State or idempotency conflictRead current state before deciding whether to retry.
412A resource prerequisite is missingComplete the prerequisite, such as adding a payment method.
422Semantically invalid field or transitionSurface field/state feedback and correct the request.
429Daily API-key allowance exceededStop automatic retries until the rate-limit window resets.
5xxTemporary server-side failureRetry only safe or idempotent operations with backoff.

Log the request ID

Every response includes X-Request-Id. Persist it with method, route template, status, duration, and your own correlation ID. Share it with Donutwork support; never attach the bearer token or unredacted payload.

Rate limits

Authenticated responses expose the API-key allowance with:

  • X-RateLimit-Limit: configured daily request allowance;
  • X-RateLimit-CurrentUsage: requests counted in the current window;
  • X-RateLimit-Remaining: requests left;
  • X-RateLimit-Reset: Unix timestamp for the reset boundary.

Throttle before Remaining reaches zero. A 429 response is not evidence that a write failed safely; reconcile the target resource before resubmitting.

Retries and idempotency

Retry GET requests after network failures and selected 5xx responses with exponential backoff and jitter. Cap attempts and total elapsed time. Do not retry 400, 401, 403, 404, or 422 unchanged.

Use the idempotency mechanism documented for the specific operation. Some mutations use an Idempotency-Key header; subscription lifecycle actions use a body key, external charge imports use charge.source + charge.external_id, and audit events use source + event_id. Do not assume a generic header provides replay protection. Reuse a key only for the same logical request and payload, and store it with your local operation until reconciliation completes. Reusing a payload-bound key with different content returns 409.

When an endpoint does not advertise idempotency, a timeout after sending the body is ambiguous. Read the resource or search by your stable external identifier before creating it again.

Pagination

List endpoints generally accept page starting at 1 and size with an endpoint-specific maximum, commonly 100. Responses commonly include count, per_page or size, page metadata, and elements.

Do not assume all collections use identical envelope names. Follow the schema shown on each endpoint and stop when the current page reaches the reported maximum or returns no elements.

Production launch checklist

  1. Use a dedicated production key with only the documented read/write scopes.
  2. Keep the key in a managed server-side secret store and verify it never reaches browser bundles, mobile apps, logs, or analytics.
  3. Set connection and total request timeouts; bound concurrency and retry budgets.
  4. Persist Donutwork resource IDs plus your stable external IDs.
  5. Record X-Request-Id, HTTP status, and latency without sensitive bodies.
  6. Reconcile asynchronous payment, workflow, email, and scan operations instead of treating acceptance as completion.
  7. Register and monitor webhooks for lifecycle events your integration depends on.
  8. Exercise key rotation and incident revocation before launch.
  9. Validate your integration against the machine-readable OpenAPI document.

Machine-readable references

On this page