Skip to main content
This applies only to customers in a region where Strong Customer Authentication is required, in practice customers in the EU (EUR / USDC). For every other customer none of this appears: money-movement calls complete as usual, no scaChallenge is returned, the authentication endpoints return 409, and you can skip this section.
Under PSD2, EU e-money and e-money-token (EUR / USDC) money movement must be confirmed by the end user with Strong Customer Authentication (SCA). Grid wraps SCA so you satisfy it through the same resources you already use. There is no separate product to integrate, and the same request shapes work for every customer whether or not SCA applies. This section covers the whole surface:

Per-transaction authorization

Authorize a money movement that came back PENDING_AUTHORIZATION. This is the flow you hit most often.

Factor enrollment

Enroll and manage a customer’s TOTP and passkey factors.

Login & sessions

The end-user SCA login and the session it grants for reads.

Trusted beneficiaries

Whitelist a payee once so future sends to it skip the per-transaction ceremony.

Two-factor reset

Recover a customer who has lost their factors, gated by an identity (liveness) check.

What SCA covers

SCA gates debits on EU-regulated balances. EUR / USDC reads are covered by an active SCA login session, while non-EUR/USDC accounts do not require SCA. “Dynamic linking” means the authorization is cryptographically bound to the transaction’s amount and payee (PSD2 Article 97(2)); it forces a fresh, transaction-specific challenge, and it’s the reason some flows can’t use TOTP (see Authentication factors).

Authentication factors

The scaChallenge.availableFactors field tells you which factors a customer may use; scaChallenge.factor is the one in use (default SMS_OTP). TOTP is barred from dynamically-linked debits because an authenticator code is derived only from a clock and a shared secret, so it can’t be bound to this amount and payee. It stays valid for flows that don’t require dynamic linking: login, trusting a beneficiary, sends to an already-trusted beneficiary, and eligible on-chain or Lightning withdrawals. Always use the factors in scaChallenge.availableFactors; that field, not the operation name, is the source of truth for the challenge Grid issued.

The authorization flow

For an SCA-required customer, a money-movement call that would otherwise complete instead returns the resource in status PENDING_AUTHORIZATION carrying an scaChallenge, and the transfer is not released until the challenge is satisfied. A single money movement can require more than one challenge in sequence, so loop on status rather than assuming one authorization releases the transfer. Per-transaction authorization covers the mechanics: authorizing the quote, the multi-step loop, resending an expired code, and the realtime-funding-quote nuance.

Lifetimes & limits

Errors you’ll encounter

Calling a customer outside SCA-regulated regions

Every authentication endpoint returns 409 for customers outside SCA-regulated regions (non-EU), and no scaChallenge is ever attached to their transactions. You don’t need to branch on region. Handle scaChallenge when it’s present and treat its absence as nothing to do.