Skip to main content
Applies only to customers in an SCA-required region (EU). Every endpoint here returns 409 for other customers.
SMS_OTP needs no enrollment; a code is sent to the customer’s verified phone. TOTP and PASSKEY must be enrolled before a customer can authenticate with them. Enrolled factors then appear in scaChallenge.availableFactors and can be requested per transaction (see per-transaction authorization). Enrollment is two calls, both discriminated by a type field (TOTP or PASSKEY):
  • POST /sca/factors — start enrollment; returns the factor-specific material.
  • POST /sca/factors/confirm — finish enrollment with the factor-specific proof.
All paths below are relative to https://api.lightspark.com/grid/2025-10-13.

Enroll a TOTP authenticator

1

Start enrollment

Returns the shared secret and an otpauth:// provisioning URI. Render totpUri as a QR code (or show secretBase32Encoded for manual entry) so the customer can add it to their authenticator app.
2

Confirm enrollment

Submit the secret from the start call plus the first code the app produces. Grid returns one-time recovery codes; surface them to the customer once and don’t store them server-side.
A wrong or expired code returns 400. In sandbox, the code is always 000000.

Enroll a passkey

Passkey enrollment is a standard WebAuthn registration ceremony. Grid issues the options, the customer’s device produces the credential, and you hand it back.
A customer may have up to two passkeys. With two enrolled, starting another returns 409 (PASSKEY_ALREADY_ENROLLED). Delete one first (see below). To replace a passkey, enroll the new one before deleting the old one.
1

Start enrollment

Pass options unmodified to the device’s WebAuthn API (navigator.credentials.create). The ceremony must run against one of allowedOrigins.
2

Confirm enrollment

Submit the credential the device produced and the origin it ran against.
Returns the enrolled factor (an ScaFactorView, including the credentialId you’ll use to delete it later). An invalid credential or origin returns 400.

List enrolled factors

credentialId is populated only for PASSKEY factors.

Delete a factor

Returns 204. Use the credentialId from the factor list (or the confirm response). Today only passkeys carry a credentialId, so this is how you remove an enrolled passkey.