Steerd API

Idempotency

Make writes safe to retry with an Idempotency-Key.

Unsafe writes (POST, PATCH, DELETE) honor an Idempotency-Key request header, so a retried request runs the operation at most once.

curl -X POST https://app.steerd.io/api/public/v1/contacts \
  -H "Authorization: Bearer strd_YOUR_KEY" \
  -H "Idempotency-Key: 9f1c2b7e-4a6d-4c2e-8b1a-3d5e7f9a0c11" \
  -H "Content-Type: application/json" \
  -d '{ "firstName": "Jane", "lastName": "Doe", "email": "jane@example.com" }'

Behavior

  • Repeating a request with the same key and the same body replays the original response. The operation runs once.
  • Reusing a key with a different body returns 422 idempotency_key_conflict.
  • A key whose original request is still in flight returns 409 conflict; retry shortly.
  • A replay whose caller's permissions have narrowed since the original request returns 409 idempotency_authorization_changed. Retry without the key, or with a new one, to get a correctly-authorized answer. Gaining a permission never affects a replay.
  • Keys are retained for 24 hours, scoped to { key, method, path }.

Generate a fresh UUID per logical write, and reuse the same value when retrying after a network failure. That way a request that succeeded on the server but whose response you never received will not create a duplicate on retry.

Idempotency covers the transport-level retry problem; a lost response, a dropped connection. It is scoped per method and path, so the same UUID on a different endpoint is a different logical operation.

File uploads are covered too. POST /files and POST /attachments honor Idempotency-Key like every other write. Because the body of a multipart request is not the file, what the key is matched against is a digest of the uploaded bytes plus the filename, type and size (and, for an attachment, the entity it is bound to). So a retry with the same key and the same file replays the original response, and the same key with a different file returns 422 idempotency_key_conflict rather than quietly handing back the first file's response.

On this page