Signing in with SSO proves the user authenticated with your identity provider. For a small set of high-risk operations that isn’t enough. Those need a factor bound to the user’s own device, held by that user and not by any system in between. That factor is a passkey.
Enrol every SSO user in a passkey. Treat it as part of onboarding, not an optional extra. A user without a passkey can’t complete the operations below, and passkey is the only method accepted on an SSO session. PIN and TOTP don’t work here.

Which operations need it

For secure card details, use the POST form above. It’s the only one that can carry a passkey confirmation. On an SSO session the legacy GET form is refused.

The flow

Step 1: enrol the user (once per device)

An SSO user registers a passkey with the ordinary add-a-passkey endpoints, authenticated with the token they already hold. One extra step applies only to SSO: the user confirms a code emailed to them before the passkey challenge is issued.
1

Start. A code is emailed.

Start adding a passkey with Authorization: Bearer <access_token> and an optional friendly_name (for example "My iPhone"). On an SSO program this doesn’t return publicKey yet. It emails the user a verification code and responds with:
2

Start again, with the code.

Collect the code from the user and call the same endpoint again, same body plus email_code:
Once the code checks out you get the normal response, a session_token and publicKey creation options, and continue as any other program would.
3

On the device

Pass publicKey to navigator.credentials.create() on the web, or the platform credential API on iOS and Android. The OS asks the user for Face ID, Touch ID, or their screen lock.
4

Finish

Finish adding a passkey with the session_token and the attestation the device produced.
The email check runs on every SSO passkey registration. No grace period, no “already verified” shortcut. A user adding a second device gets a fresh code. Build the code-entry screen as a normal part of enrolment, not a one-off.It’s there so a passkey can only be added by someone who can read the account’s email. That’s what makes the passkey a real second factor on top of your identity provider.
The code goes to the email on the user’s Orenda account. If your identity provider changes a user’s email, the code still goes to the address we hold, not the new one.
Users can hold several passkeys. List them with List passkeys and let users add one per device. Prompt for enrolment at a calm moment in your app, not in the middle of a payment.

Step 2: get a challenge

Right before the sensitive call, request a step-up passkey challenge:
The challenge is short-lived. Request it when the user acts, not at screen load.

Step 3: unlock on the device

Convert the base64url fields to byte arrays, call navigator.credentials.get() (or the native equivalent), and encode the result back to base64url. The mechanics are the same as passkey login.

Step 4: send the confirmation

Add a confirmation object to the operation’s request body:
This is the same confirmation shape every other step-up in the API uses. See Confirming a sensitive action.

Errors

Both are 422, with the code in the response body:
The SCA_MISSING message names the accepted method: "Authentication is required (passkey)" on an SSO session, versus "Authentication is required (passkey, TOTP, or PIN)" elsewhere. Branch on the code, not the message text.

Building for it

1

Ship enrolment with your first release

Add a passkey screen and prompt existing users. Without enrolled users, payees, international payments, batches, invites, and card details are all unreachable.
2

Handle 422 as a prompt, not a failure

Treat SCA_MISSING as “ask the user to confirm”, run the challenge, and retry the same call. Don’t show it as an error.
3

Check device support

Passkeys need WebAuthn. Detect support before you offer it (PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()) and tell users which of their devices can enrol.
4

Ask us if you get stuck

Contact the team if enrolment or step-up doesn’t behave as described here.