Docs › API reference › Idempotency
Idempotency keys: never post twice by mistake
Add an Idempotency-Key to create-a-post so a retry after a timeout never sends the same post twice.
If a request to create a post times out, you cannot tell whether OmniPosts received it. Sending it again could post
twice. The Idempotency-Key header removes the doubt: send the same key and the same request again and you get
the original post back instead of a second one.
Use it
Send the header on POST /v1/groups. It also works on POST /v1/ideas/{id}/promote, which creates a post
the same way.
- The key is any string of 1 to 255 characters. A UUID, or an id from your own database, works well. Anything
else gets
400 invalid_request. - The header is optional, but send it every time. Without it, a retry is a new post.
- A key is scoped to your organization. Two organizations can use the same key.
- Use a new key for each different post. Reuse a key only to retry the very same request.
curl https://omniposts.dev/v1/groups \
-H "Authorization: Bearer omniposts_..." \
-H "Idempotency-Key: 6f1c2a52-launch-post-1" \
-H "Content-Type: application/json" \
-d '{"body": "We shipped.", "targets": [{"channelId": "CHANNEL_ID"}]}'
What a replay looks like
If the key and the request both match an earlier call, OmniPosts creates nothing. It answers 200 with the
header Idempotent-Replayed: true, and the body is the post as it is now (so its statuses may have moved on
since the first call):
The first call answers 201 (all channels accepted) or 207 (some rejected). A replay is always 200 and carries rejections too. Check the Idempotent-Replayed header to tell a replay
from a first answer.
HTTP/1.1 200 OK
Idempotent-Replayed: true
Same key, different request
If you reuse a key with a request that differs, OmniPosts refuses it so it cannot guess which one you meant:
The status is 409. Pick a new key for the new request.
{
"error": {
"code": "idempotency_conflict",
"message": "This Idempotency-Key was already used for a different request."
}
}
What counts as the same request
OmniPosts compares a SHA-256 fingerprint of these parts of the request:
bodymediaIdsscheduledForandtimezonequeue, when it istrue- the draft being published, when you call
POST /v1/ideas/{id}/promote targets, in the order you sent them, with each target'schannelId,body,mediaIdsandsettings
So changing the text, adding a channel, reordering the targets, or moving the time makes it a different
request. A missing top-level body or mediaIds counts the same as an empty one. On a target, leaving out mediaIds (use the post's media) is different from sending [] (no media).
The Idempotency-Key itself is not part of the fingerprint, and neither are headers such as
Authorization. Sending the same JSON with a different key is a new post.
A 422 does not use up the key
The key is saved only when a post is actually created. If the request is refused, nothing is saved, so you can
fix the problem and send again with the same key. This covers nothing_to_publish, plan_limit_reached,
queue_empty and queue_full, and any 400.
A 207 is different. It means a post was created and some channels were rejected, so the key is used. To
resend those channels, use retry, or create a new post with a new key.
Two requests at once
If two requests with the same key arrive at the same moment, one creates the post and the other gets the replay. You still end up with one post.