POST /v1/social/posts landed. SmartlyQ has two independent layers so a retry is always safe.
Layer 1: idempotency keys
Send anX-Idempotency-Key header (X-Request-Id is accepted as an alias) with a fresh value per logical post - generate a UUID v4 in your code. If the call fails ambiguously (timeout, 5xx, connection reset), retry it with the same key:
- First call creates the post and returns
201. - A retry with the same key returns
200with the original post andidempotent_replay: true- nothing new is created:
Replay response (200)
A-Z a-z 0-9 . _ : -), and permanently identify their post - there is no expiry window to race against. Deleting the post frees its key. Concurrent retries are safe: a unique database constraint guarantees only one post can ever own a key.
Works on POST /social/posts and POST /social/posts/schedule (including queue scheduling).
Layer 2: duplicate-content guard
Independent of headers, creating identical content in the same workspace within 24 hours returns409 DUPLICATE_CONTENT with the existing post’s id:
409 response
"allow_duplicates": true in the body. Posts that ended failed or were unpublished never block a re-post.
How the layers interact
- Same idempotency key seen before → 200 replay of the original post (wins over the duplicate guard - a retry is not a duplicate).
- No (or new) key, identical content within 24h → 409 DUPLICATE_CONTENT.
- Otherwise → the post is created normally.

