> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: BINDING_REQUIRED / BINDING_MISMATCH on Verify

> Diagnose a /verify/send or /verify/check refused with the binding gates — PSD2 SCA dynamic-linking, SNA device tokens, passkey bindings — and fix the token pairing instead of retrying the call.

# Troubleshooting: BINDING\_REQUIRED / BINDING\_MISMATCH on Verify

A "binding" is the association between a verification factor run and the
device or token that must prove possession of it. Verify factors — passkey,
flashcall, SNA, and the PSD2 SCA dynamic-linking binding on OTP sends —
mint their challenge against a specific token, and the check will only pass
when that same token is replayed on the verify call. A binding gate refuses
the call at the 422 layer; it does not consume an attempt and it is not a
transient failure — you fix the pairing, not retry.

This page covers the two codes that surface the gate. The OTP-delivery and
factor-enforcement gates that sit around them are on the [Verify OTP](/troubleshooting/verify-otp)
and [Verify factor suite](/troubleshooting/verify-factor-suite) pages.

## What a binding is

A binding is the device/token association a factor run must carry across
its full life — enroll → send → check. Each factor has its own canonical
binding, and the gate rejects any run that loses it:

* **Passkey** — the enrolled public key for the relying party. The verify
  challenge is issued against the enrollment; any other key, origin, or
  `rpId` mismatches the binding.
* **Flashcall / SNA** — a device-bound network token. The SIM possession
  proof is anchored at send time, and /check must come back through the
  same device token.
* **PSD2 SCA dynamic-linking** — the `sca_binding` object (`amount`,
  `payee`, optional `transaction_id`) you pass on `POST /api/v1/verify/send`.
  The send stores its hash; `POST /api/v1/verify/check` must replay the
  exact same object or it refuses.

## BINDING\_REQUIRED — a binding the route needs was not supplied

`BINDING_REQUIRED` fires when a binding-bearing route is called without
its binding. The two shapes:

| Surface                                                                                     | What is missing                                                                 | Fix                                                                                                                                                                                                                                      |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /api/v1/verify/send` for an SNA / device-bound factor                                 | The device network token (`device_token`) that anchors the SIM possession-proof | Mint a fresh device token on the handset and pass it on the send. Do not reuse a token that was issued for a different send                                                                                                              |
| `POST /api/v1/verify/check` on a verification that was minted with a PSD2 SCA `sca_binding` | The `sca_binding` object                                                        | Replay the exact same `sca_binding` (amount, payee, and any `transaction_id`) you passed on `/verify/send`. If you have it stored, send it now; if you never captured it, mint a fresh verification with the binding and re-run the flow |

A legacy row — one minted before the binding gate existed, or one you sent
without a binding — carries no stored hash and passes `/check` unchanged.
The gate only arms when the send itself carried the binding.

Sample envelope:

```json theme={null}
{
  "error": {
    "code": "BINDING_REQUIRED",
    "message": "This verification was minted with a PSD2 SCA dynamic-linking binding; /check must replay the original sca_binding (amount, payee, transaction_id).",
    "status": 400
  }
}
```

## BINDING\_MISMATCH — the replayed token does not match the stored one

`BINDING_MISMATCH` fires when a binding is supplied but does not match the
one the verification was minted with. The common cause is a token that
drifted between the send and the check: a regenerated device token, a
different `rpId` or origin on the passkey ceremony, or a replayed
`sca_binding` whose `amount`, `payee`, or `transaction_id` differs from
what the send stored — even when the numeric value looks the same, a
reformatted `amount` (10.5 vs 10.50) or a re-cased `payee` still hashes
differently.

The fix is the same in both cases: pass the stable token. For PSD2 SCA,
store the exact `sca_binding` your server sent and replay it verbatim —
never recompute it from a parsed copy, because the parse can normalize
whitespace or key order and change the hash. For device tokens, reuse the
same device identifier between factor runs; rotating the device id at
the check stage trips the mismatch. For a passkey, keep the relying party
(`rpId`, origin) identical between enrollment and verification.

Sample envelope:

```json theme={null}
{
  "error": {
    "code": "BINDING_MISMATCH",
    "message": "Submitted sca_binding does not match the binding this verification was minted with. The OTP is invalidated under PSD2 RTS Article 5(2).",
    "status": 400
  }
}
```

Both codes are deterministic: the gate rejects the same inputs identically
every time, and it does not time out. Do not retry the same body — re-mint
the verification with the stable token first, or drop the binding from the
send if you do not actually need to link it.

## Deterministic — do not retry without fixing the pairing

The binding gates are taxonomy-side honour codes. Fix the pairing once and
the check passes; retry the same body and the gate keeps refusing. If you
are deliberately not on the PSD2 SCA flow, omit `sca_binding` from
`/verify/send` and the gate does not arm — but once a send carries one,
every check against that row must carry it too.

## See also

* [Verify OTP](/troubleshooting/verify-otp) — the send and check gates around the binding codes.
* [Verify factor suite](/troubleshooting/verify-factor-suite) — the TOTP, push, passkey, and backup-code factors the binding belongs to.
* [Verify API reference](/api-reference/endpoints/verify) — the full request shape for `sca_binding` and `device_token`.
* [Error codes reference](/reference/error-codes) — the platform-wide enum where `BINDING_REQUIRED` and `BINDING_MISMATCH` live.
