SCA-protected transactions
Carefully read the Strong Customer Authentication (SCA) mapping section to understand what requirements apply to your specific workflow
Initiate
The initiate endpoint is the same one you already call to start a transaction - SCA adds a single optional field, verificationMethod. If omitted, the application's default (SMS) is used.
POST /wallets/send/initiate/bank
Authorization: <HMAC>
{
"userId": "<uuid>",
"sourceAccountId": "<accountId>",
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"amount": "10000",
"verificationMethod": "passkey"
}Other initiate variants share the same verificationMethod field:
| Operation | Endpoint |
|---|---|
| SEPA payout | POST /wallets/send/initiate/bank |
| Onchain withdrawal | POST /wallets/send/initiate/onchain |
| Lightning payment | POST /wallets/send/initiate/lightning |
| Intra-ledger transfer | POST /wallets/send/intra/initiate |
| Inter-ledger transfer | POST /wallets/send/inter/initiate |
Response (shape illustrative; transaction fields vary by endpoint):
{
"challengeId": "<uuid>",
"dateExpires": "<ISO date>",
"transaction": { /* ... */ }
}For passkey, the response also includes the WebAuthn assertion request the user agent needs to perform the ceremony. For TOTP, no server challenge is issued — the user reads the code from their authenticator app.
Confirm
POST /wallets/transaction/confirm
Authorization: <HMAC>
{
"userId": "<uuid>",
"challengeId": "<uuid>",
"verificationMethod": "sms" | "totp" | "passkey",
"ip": "203.0.113.42",
// SMS or TOTP:
"verificationCode": "123456",
// Passkey:
"origin": "https://app.example.com",
"passkeyAssertion": { /* WebAuthn assertion serialised */ }
}On success the transaction is executed and the response carries the standard transaction shape (id, status, amount, …). On a Dynamic Linking mismatch, all sibling challenges sharing this challengeId are cancelled and the call fails with 30031. The challenge counter caps at 5 attempts; exceeding it returns TooMany2FAAttemptsError.
Resend
POST /wallets/transaction/resend-otp
Authorization: <HMAC>
{ "userId": "<uuid>", "challengeId": "<uuid>" }SMS only. Calling resend with a challenge issued for passkey returns 31100.

