Recommended Free Tools
A retry creates a duplicate verification case when the provider cannot tell that the second request is the same intended operation as the first. A timeout does not mean the first request failed. The provider may have created the record and the response may have been lost on the way back. If your client then sends a fresh create call with nothing linking it to the original, the provider sees two operations. This article uses Persona’s documented behavior as a worked example and labels it as Persona-specific. It does not claim every KYC vendor works the same way.
The ambiguous-outcome problem
Suppose your service calls a “create verification” endpoint and the connection drops before a response arrives. Three things could have happened: the request never reached the provider, it reached the provider and failed, or it succeeded and only the response was lost. From the client’s side these look identical. A blind retry is safe in the first two cases. In the third it creates a second resource.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
Yubico - Security Key C NFC - Basic Compatibility - Multi-Factor authentication (MFA) Security Key... | $29.00 | Buy on Amazon |
As an Amazon Associate I earn from qualifying purchases.
Idempotency keys exist to remove that ambiguity. The client attaches a unique key to one logical create operation. The server uses the key to recognize a retransmission and does not perform the work twice. Persona documents exactly this use: a request to create an Inquiry that fails to respond can be retried with the same key, so that no more than one Inquiry is created (Persona, Idempotence, version dated 2025-10-27).
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall“Duplicate case” is not one thing: Inquiries, verifications and statuses
Before blaming retries, check which resource you actually have two of. In Persona’s model, an Inquiry is a single instance of an individual attempting to verify their identity, and it contains one or more verifications (see below).
#1 Best Overall
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
That link is not used; the sources are listed here instead. Persona’s Inquiries reference lists these Inquiry statuses: Created, Pending, Completed, Failed and Expired, plus the optional Needs Review, Approved and Declined. Its Verifications reference lists Initiated, Submitted, Passed, Requires Retry and Failed.
- Two Inquiries for one user attempt is the retry bug this article covers.
- One Inquiry with several verifications is a normal shape: a verification inside an existing flow can be retried without creating a new Inquiry.
- A Requires Retry or Pending state is a workflow state. By itself it is not a reason for your backend to call create again. Let the user continue or resubmit within the existing flow, as the provider’s lifecycle describes.
How Persona’s idempotency works
These details come from Persona’s idempotency page (version dated 2025-10-27). Confirm current endpoint-level requirements before relying on them.
- Scope: all POST requests accept idempotency keys. GET and DELETE are idempotent by definition, and keys have no effect on them.
- Replay: the first status code and response body are saved for a key, whether the request succeeded or failed. Later requests with the same key return that saved result.
- Parameter matching: incoming parameters are compared with the original, and an error is returned if they differ.
- Key format: use a UUID or another cryptographically random string, unique per endpoint and operation. Persona advises against using reference IDs as keys.
- Retention: keys may be pruned once they are at least 24 hours old. Reusing a pruned key generates a new request.
Two consequences matter in practice. First, a replayed response can be an error: Persona documents replay of the original status and body, including a 500. Resending the same key is not a request to try again from scratch, so a transient failure that was recorded may keep coming back. Second, a reference ID is a poor key because it identifies the user or business entity, not one attempt. Reusing it would conflate genuinely new attempts with retransmissions, and its parameters may legitimately change.
Decision table: what happens in each situation
These are behavior axes in your application and the provider’s contract, not different products. The outcomes describe Persona’s documented model; check your own vendor.
| Situation | Right client action | Expected provider behavior (Persona model) |
|---|---|---|
| Same operation, outcome ambiguous (timeout) | Resend with the same key and identical parameters | First result is created or replayed; at most one Inquiry |
| Same key, changed parameters | Do not do this; treat it as a bug | Error returned |
| Genuinely new user attempt | New logical operation, new key | New request processed |
| Retry after the key is at least 24 hours old | Do not assume the key still protects you; look up existing records first | Key may be pruned; reuse generates a new request |
| Recorded response was an error | Expect the same error on replay; decide whether it is a new operation | Saved status and body returned, including a 500 |
| Status check | GET; no key needed | Idempotent by definition |
The client-side invariant
These steps are engineering implications of the documented behavior, not a vendor-mandated procedure.
- Create a durable operation record first. Before calling the provider, write a row such as (operation ID, user, intent, generated idempotency key, request parameters, state “pending”) to your database.
- Generate the key once per logical create operation, as a random UUID, and persist it. Never generate it inside the retry loop.
- Send the request using the stored key and stored parameters. Build retries from the saved record so the parameters cannot drift.
- Retry only ambiguous or transient failures (timeouts, dropped connections, retryable server errors) with backoff, always reusing the same key and body.
- Store the provider’s resource ID when a response arrives and mark the operation complete. From then on, use GET to check status instead of creating again.
- Treat a new user attempt as a new operation with a new record and a new key, according to the provider’s contract.
Common ways retry logic still creates duplicates
- Key generated per attempt. A new UUID inside the retry loop makes every retry look like a new operation.
- Key lost on process restart. If the key lives only in memory, a crash and replay from a queue produces a new one.
- Parameters rebuilt on retry. Timestamps, regenerated fields or updated user data change the body and trigger a mismatch error, or push developers to drop the key.
- Layered retries. An HTTP client, a job queue and an application loop may each retry. Each layer must carry the same stored key.
- Late retries. Dead-letter queues or manual replays after more than 24 hours may meet a pruned key. Reconcile first using your operation record and any known provider resource ID, and only then decide to create.
- Using reference IDs as keys, which Persona advises against.
- Treating workflow states as failures. Reacting to Pending or Requires Retry by creating another Inquiry makes your own duplicates.
Reconciling when a key can’t help
If the key has aged out, or you never stored one, you cannot prove from the client whether the first call succeeded. Look for existing provider resources associated with the user in your own records, and use the provider’s retrieval endpoints where they exist, before creating anything. How you can search for existing Inquiries, for example by reference ID, depends on the provider’s API and should be checked in its current documentation.
What other APIs show, and the limits of that
Stripe’s idempotent requests reference describes a similar contract: it saves the first response, rejects parameter mismatches and allows keys to be pruned after at least 24 hours. That is evidence of Stripe’s contract, not proof that KYC vendors share it. Before integrating any provider, verify which endpoints accept keys, how keys are scoped, the retention period, how parameters are compared and how concurrent requests with the same key are handled. No published figure on how often retries cause duplicate KYC cases was found, so none is cited here.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteThe Bottom Line
Treat each logical create as one persisted operation with one stored key and one stored request body, and reuse both on every retransmission. Mint a new key only for a genuinely new attempt. Past the provider’s retention window, check your own records before you create anything.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




