Skip to main content
Retrying a render with the same idempotency key, within the same project, returns the original render instead of creating a duplicate. This makes at-least-once delivery — an offline-first app that resubmits a sign-off on reconnect — safe.

Supplying a key

Send an Idempotency-Key header (preferred), or a jobId in the body. If both are present the header wins. Renders with no key are never deduplicated.
curl -X POST https://api.craftkit.dev/v1/templates/charter-handover/render \
  -H "Authorization: Bearer $CRAFTKIT_API_KEY" \
  -H "Idempotency-Key: handover-BK-12345-checkout" \
  -H "Content-Type: application/json" \
  -d '{ "data": { "...": "..." } }'

Behavior

  • First call with a key creates the render and returns 202.
  • Repeat call with the same key returns the existing render with its current state (status, downloadUrl, …) and 200. So a retry after completion returns the finished render and its download URL.
  • Scope is per project — the same key in two different projects creates two renders.
  • A concurrent double-submit races safely: a unique constraint ensures only one render is created; the loser receives the winner’s render.
Use a key derived from the business event, not a random UUID per attempt — e.g. handover-{bookingCode}-{checkin|checkout}. The whole point is that all retries of the same event share one key.

Important: failures are not retried by the same key

Idempotency returns the stored render regardless of its status — including failed. Retrying a failed render with the same key returns the failed render; it does not trigger a fresh attempt. To deliberately re-render after a failure, submit with a new idempotency key.
200 (idempotent replay) vs 202 (newly queued) lets you tell the two apart in client code if you need to.