Skip to content

Retries and idempotency

Networks fail. A request can succeed on our side while your client times out. These two tools let you retry without creating duplicates.

Send your own id for a service job as external_ref on POST /v1/tickets. It is unique per organization.

SituationAnswer
First request201 with the new job.
Same external_ref again (from any caller in the organization)200 with the existing job. Nothing changes.
The external_ref belongs to a deleted job, or to a job on a board the key cannot open409.

Find a job by your reference with GET /v1/tickets?external_ref=crm-48213. Add archived=1 to include archived jobs.

Clients have their own external_ref, also unique per organization. Use it to link a client to your system and to open jobs for that client.

POST /v1/tickets/{id}/complete, POST /v1/tickets/{id}/create-invoice and POST /v1/tickets/{id}/cancel accept an optional Idempotency-Key header. Use a new random value (for example a UUID) per action, and reuse it only to retry that same action.

Terminal window
curl -X POST https://api.invoicing.proradius.co/v1/tickets/9a7c3e1f-2b4d-4e6f-8a1c-3d5e7f9b1c2d/complete \
-H "Authorization: Bearer $PRORADIUS_API_KEY" \
-H "Idempotency-Key: 6f1d2c3b-7a8e-4f90-a1b2-c3d4e5f60718" \
-H "Content-Type: application/json" \
-d '{ "outcome": "done" }'
  • A successful (200) answer is stored for 24 hours, per organization and key.
  • A retry with the same key within that time gets the stored answer and the header Idempotent-Replayed: true.
  • A retry while the first request is still running answers 409.
  • Error answers are not stored, so you can fix the request and send it again with the same key.

Even without the header, completing an already finished job does not bill twice. It answers 200 with completion.replayed: true and the same invoice.

Webhook deliveries can arrive more than once. Each event has an id that stays the same across retries. Store the ids you have processed and skip repeats. See Webhooks.