Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.natural.co/llms.txt

Use this file to discover all available pages before exploring further.

Idempotency ensures retries are safe for mutating requests. Retrying the same request with the same Idempotency-Key never executes side effects twice.

How it works

Include an Idempotency-Key header on mutation requests (POST, PUT, PATCH, DELETE where applicable):
response = await client.post(
    "https://api.natural.co/payments",
    headers={
        "Authorization": "Bearer sk_ntl_prod_abc123...",
        "Idempotency-Key": str(uuid.uuid4())
    },
    json={...}
)
Natural stores the key and response. On subsequent requests with the same key:
  • Same key + same request intent + completed -> Replays the original response.
  • Same key + different request intent -> Returns 409 Conflict.
  • Same key + request still in progress -> Returns 409 Conflict.
  • Different key -> Treated as a new mutation attempt.
Replayed responses include X-Idempotency-Replayed: true. Idempotency keys are scoped by caller namespace, and records are retained in a replay window (currently 48 hours). Reusing a key after expiration starts a new request.

Conflict reasons

When a request returns 409 Conflict because of idempotency, the error payload includes a reason value:
  • IDEMPOTENCY_KEY_REUSED: the same key was used with a different request intent.
  • IDEMPOTENCY_REQUEST_IN_PROGRESS: the original request is still executing.

Best practices

Do:
  • Use UUIDv4/UUIDv7 for keys.
  • Reuse the same key for network retries of the same submit intent.
  • Generate a new key only when the user starts a new logical operation.
Don’t:
  • Use a fresh random key per HTTP retry.
  • Reuse a key for different logical operations.
  • Put sensitive data in keys.

When to retry

ErrorAction
Network/timeoutRetry with same key, exponential backoff
5xx server errorRetry with same key, exponential backoff
409 + IDEMPOTENCY_REQUEST_IN_PROGRESSWait, then retry with same key
409 + IDEMPOTENCY_KEY_REUSEDFix request mismatch and use a new key
Other 4xxDon’t retry — fix request data first