## One key for the same intent

Send `Idempotency-Key` when creating a transaction. The contract makes the header optional, but using it is recommended to tolerate a lost connection after the server receives your request. Generate and persist the key before the first POST; reuse it only for the same creation and payload.

```http
Idempotency-Key: onboarding-demo-0001
```

## A lost response does not mean a lost creation

Suppose your server sends a request and receives a timeout. The transaction may already exist. Retrying with a new key can create a second journey. Repeating the same POST with the same key and payload can recover the idempotent creation; its documented response remains `201`.

Use `external_id` for business correlation, without treating it as an automatic replacement for the header. Preserve the relationship between key, attempt and transaction in your system.

## Handle conflicts explicitly

Using the same key with a different payload returns `409` with code `idempotency_conflict`. Do not bypass this result by silently changing the key. Determine whether the customer changed the data or your application reconstructed the request inconsistently.

A genuinely new intent gets a new key. A technical retry preserves the previous intent. Do not assume an undocumented key-retention window.

Creation idempotency does not replace [webhook](/en/developers/kyc/webhooks-and-events) deduplication. Use `event_id` for events and make business side effects idempotent as well.
