Safe retries and conditional updates

Retry writes with idempotency keys and update safely with ETags.

Network errors and timeouts can leave you unsure whether a write went through. API V2 gives you two tools to handle that safely.

Idempotency keys for POST requests

Send a unique Idempotency-Key header with each intended POST operation, and send the same key again if you retry that operation:

curl -X POST "https://api.lingohub.com/v2/branches/$BRANCH_ID/exports" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"language_codes": ["de", "fr"]}'
  • If the first request succeeded, a retry with the same key returns the original response with Idempotent-Replayed: true instead of running the operation again. Successful responses are kept for 24 hours by default.
  • If the first request is still running, you get 409 idempotency_key_in_use with a Retry-After header.
  • If the outcome of the first request is unknown, you get 409 idempotency_outcome_unknown. Check the affected resource before you start a new operation with a new key.
  • Reusing a key with a different request returns 422 idempotency_key_mismatch.
  • A 4xx rejection releases the key, so you can fix the request and retry with the same key.

This protection is best effort, not exactly-once execution. Never blindly retry an uncertain write with a new key: look at the resource first.

Conditional updates with ETags

Many resources return an ETag header. Send it back in If-Match to make sure you only change what you last read:

# 1. Read the segment and note its ETag
curl -i "https://api.lingohub.com/v2/segments/$SEGMENT_ID" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY"

# 2. Update it only if nobody changed it in the meantime
curl -X PATCH "https://api.lingohub.com/v2/segments/$SEGMENT_ID" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY" \
  -H "If-Match: $SEGMENT_ETAG" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{"description": "Label on the sign-in button"}'
  • Send the complete quoted ETag. Weak ETags never match.
  • 412 precondition_failed means the resource changed since you read it. Read it again and decide whether your change still applies; don't overwrite it automatically.
  • PUT responses don't include an ETag. Read the resource again to get the current one.
  • ETags are for write preconditions. API V2 doesn't use them for conditional GET caching.
  • An operation that doesn't support If-Match rejects the header.

Shared content

Some edits reach further than one place. A segment holds the text that one or more keys share, so editing a segment's text or description changes it for every key that uses it. Use GET /v2/segments/{segmentId}/keys to see which keys use a segment before you edit it.


Did this page help you?