-
Notifications
You must be signed in to change notification settings - Fork 6
idempotency
POST, PUT and PATCH on the authoring API (/api/contents and the rest of the bearer-token
surface) honour an Idempotency-Key header. Send one and a retried request will not be applied
twice. This is a different thing from the Idempotency-Key header a Webhook workflow action sends
on outbound deliveries (docs/webhooks.md); that one is generated by barakoCMS and identifies a
retry of our own delivery. This page is about the key a client sends us.
No other verb reads the header. A GET or DELETE sent with Idempotency-Key set is not
deduplicated; the header is ignored.
Set Idempotency-Key to a value your client generates once per logical write and reuses only when
retrying that same write:
POST /api/contents
Idempotency-Key: 6c1f6b2a-6e0a-4b1e-9f0a-6b1a2f6c1f6b
A GUID or ULID generated client side per operation is a good key. A constant, a timestamp, or the request body's hash is a bad one: a constant collides with itself on the next unrelated write, and a timestamp or body hash can collide across two genuinely different requests that happen to match to the second or produce the same JSON.
The key is scoped to the caller: it is namespaced internally by tenant and by user (falling back to the API caller's identity, or an anonymous bucket for an unauthenticated POST). Two different users, or the same user in two different tenants, can use the identical raw key without colliding. There is no length limit or format check: any non-empty header value is accepted and treated as a key. A missing header, or one that is empty or whitespace, is not an error either; the request just runs without idempotency protection, every time.
A second request with a key already in use gets:
HTTP/1.1 409 Conflict
Request with this Idempotency-Key already processed.
That is a fixed rejection message, not the first response replayed. If your client needs the id or body the first call returned, keep it on your side; a 409 here does not carry it.
A key that reached a successful response is kept indefinitely. There is no expiry or cleanup for a completed key, so reusing a key after a success is always a 409, not something that wears off.
A key claimed by a request that then failed (validation error, thrown exception, or any response
>= 400) is released as part of handling that failure, so the very next request with the same key
runs as a fresh attempt rather than being told it is a duplicate.
The one exception is a request that claims a key and then the process dies before it can succeed or fail, an in-progress claim with nothing to release it. That claim is treated as orphaned, and may be reclaimed, once it is more than 10 minutes old.
Send the same key on two requests at once and exactly one of them proceeds. The first to insert the key wins; the database's unique constraint on the key rejects the second insert, and that request gets the same 409 a genuine replay would. Neither request is queued behind the other or made to wait for the first to finish.
IdempotencyFilter (barakoCMS/Infrastructure/Filters/IdempotencyFilter.cs) claims the key before
the handler runs. IdempotencyFinalizer
(barakoCMS/Infrastructure/Filters/IdempotencyFinalizer.cs) completes or releases it afterwards. Both
are registered globally, so the behaviour above applies to every POST, PUT and PATCH on the
authoring API, not only content creation.
Generated from docs/idempotency.md by scripts/wiki-sync.sh. Edit the doc in the repository, not this page.
Releases
Start here
- Approval by configuration
- Configuring email
- Delivering a client project on barakoCMS
- Deploying barakoCMS on a VM
- Upgrading from 3.x to 4.0
Content
- Content type blueprints
- Public delivery API
- Event-sourced content types
- Image variants
- SEO fields
- URL redirects
Security and access
- Security and compliance posture
- Scanning uploads for malware
- Where the admin keeps your session, and why
Tenancy
Operations