{ "opencollection": "1.0.0", "info": { "name": "Grid Agent Management Strong Customer Authentication API", "version": "2025-10-13" }, "request": { "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "items": [ { "info": { "name": "Strong Customer Authentication", "type": "folder" }, "items": [ { "info": { "name": "List enrolled SCA factors", "type": "http" }, "http": { "method": "GET", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer whose factors are listed or enrolled." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "List the Strong Customer Authentication factors the customer has enrolled.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Start SCA factor enrollment", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer whose factors are listed or enrolled." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Begin enrolling an SCA factor for the customer. Enrollment covers the\nexplicit, opt-in factors a customer chooses to add — the request body's\n`type` selects `TOTP` or `PASSKEY`. Returns the factor-specific material\nneeded to finish via `POST /sca/factors/confirm`.\n\n`SMS_OTP` is implicit and is not enrolled through this endpoint. Every\ncustomer in an SCA-regulated region has a verified phone number from\ncustomer creation (via the Contact Verification flows —\n`POST /customers/{customerId}/verify-p" }, { "info": { "name": "Confirm SCA factor enrollment", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors/confirm", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer confirming a factor enrollment." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Finalize the factor enrollment started by `POST /sca/factors`. The request\nbody is discriminated by `type`: for `TOTP`, submit the shared `secret` from\nthe start call plus the first `code`; for `PASSKEY`, submit the WebAuthn\n`credential` the device produced plus the `origin` it was produced against.\nThe threaded secret/credential binds the confirmation to its enrollment, so\nno separate id is needed.\n\nA TOTP confirmation returns one-time recovery codes (shown once); a passkey\nconfirmation returns" }, { "info": { "name": "Delete an enrolled SCA factor", "type": "http" }, "http": { "method": "DELETE", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors/:credentialId", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer whose factor is being deleted." }, { "name": "credentialId", "value": "", "type": "path", "description": "The credential id of the enrolled factor to delete (from the factor's `credentialId`)." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Delete an enrolled SCA factor by its credential id. Today only `PASSKEY`\nfactors carry a `credentialId` and are deletable this way.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Start an SCA login", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/login/start", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer starting an SCA login." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Begin an SCA login for the customer with the chosen factor, opening the\nend-user SCA session (an exemption gating read / account access beyond the\nper-transaction window). Returns factor-specific material: `SMS_OTP`\ndispatches a code and returns a `challengeId` + `expiresAt`; `TOTP` returns\nonly the factor (the customer reads the code from their app); `PASSKEY`\nreturns WebAuthn `passkeyOptions`. Complete with\n`POST /sca/login/complete`.\n\nThis endpoint is only meaningful for customers in a region" }, { "info": { "name": "Complete an SCA login", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/login/complete", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer completing an SCA login." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Finalize an SCA login by submitting the proof for the started factor\n(`code` for `SMS_OTP` / `TOTP`, or `passkeyAssertion` + `origin` for\n`PASSKEY`), echoing the `challengeId` for `SMS_OTP`. Returns the\nreported session status.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n\nIn sandbox, the SMS/TOTP code is always `123456`.\n" }, { "info": { "name": "Record a security event", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/record-event", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer the security event is recorded for." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Record a client-side security-relevant event for the customer with Grid's risk engine (e.g. a sign-in, a sensitive view), to\nfeed adaptive-authentication signals.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Start a 2FA reset", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors/reset", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer resetting a factor." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Begin recovering a lost enrolled factor via a liveness-gated, poll-based\nflow. Opens the liveness check and returns a `resetId` plus the\nopaque liveness handles (`livenessAccessToken` / `verificationLink`) the end\nuser completes it with. Poll\n`GET /sca/factors/reset/{resetId}` until liveness\npasses, then call the complete endpoint.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Get 2FA reset status", "type": "http" }, "http": { "method": "GET", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors/reset/:resetId", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer whose reset status is polled." }, { "name": "resetId", "value": "", "type": "path", "description": "The reset handle returned by the start call." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Poll the status of an in-progress 2FA reset until it reaches the liveness-passed value, after which the reset can be completed.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Complete a 2FA reset", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/sca/factors/reset/:resetId/complete", "params": [ { "name": "customerId", "value": "Customer:019542f5-b3e7-1d02-0000-000000000001", "type": "query", "description": "The unique identifier of the customer completing the reset." }, { "name": "resetId", "value": "", "type": "path", "description": "The reset handle returned by the start call." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Complete a 2FA reset once liveness has passed, clearing the lost factor so\nthe customer can re-enroll.\n\nFor an `SMS_OTP` reset, supply the new `mobile` number in the body — completing\nthe reset enrolls it as the customer's number. Other factors need no body.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Start trusting a beneficiary", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts/:externalAccountId/trust", "params": [ { "name": "externalAccountId", "value": "", "type": "path", "description": "The unique identifier of the external account (beneficiary) being trusted." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Begin trusting (whitelisting) an external account so future sends to it can\nskip the per-transaction SCA ceremony. Returns the `scaChallenge` to satisfy\n(when one is issued). Complete with\n`POST /customers/external-accounts/{externalAccountId}/trust/confirm`.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Confirm trusting a beneficiary", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts/:externalAccountId/trust/confirm", "params": [ { "name": "externalAccountId", "value": "", "type": "path", "description": "The unique identifier of the external account (beneficiary) being trusted." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Finalize trusting a beneficiary (identified by the `externalAccountId` in the\npath) by submitting the SCA proof (`code` for `SMS_OTP` / `TOTP`, or\n`passkeyAssertion` + `origin` for `PASSKEY`), echoing the `challengeId` when\none was issued. Returns `trusted: true`.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n\nIn sandbox, the SMS/TOTP code is always `123456`.\n" }, { "info": { "name": "Start untrusting a beneficiary", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts/:externalAccountId/untrust", "params": [ { "name": "externalAccountId", "value": "", "type": "path", "description": "The unique identifier of the external account (beneficiary) being untrusted." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Begin untrusting (removing the trusted mark from) an external account, so\nfuture sends to it are dynamically linked and require the per-transaction SCA\nceremony again. Returns the `scaChallenge` to satisfy (when one is issued).\nComplete with\n`POST /customers/external-accounts/{externalAccountId}/untrust/confirm`.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n" }, { "info": { "name": "Confirm untrusting a beneficiary", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/customers/external-accounts/:externalAccountId/untrust/confirm", "params": [ { "name": "externalAccountId", "value": "", "type": "path", "description": "The unique identifier of the external account (beneficiary) being untrusted." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Finalize untrusting a beneficiary (identified by the `externalAccountId` in\nthe path) by submitting the SCA proof (`code` for `SMS_OTP` / `TOTP`, or\n`passkeyAssertion` + `origin` for `PASSKEY`), echoing the `challengeId` when\none was issued. Returns `trusted: false`.\n\nThis endpoint is only meaningful for customers in a region where SCA is required (e.g. EU). For customers outside SCA-regulated regions, this returns `409`.\n\nIn sandbox, the SMS/TOTP code is always `123456`.\n" }, { "info": { "name": "Authorize a quote's SCA challenge", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/quotes/:quoteId/authorize", "params": [ { "name": "quoteId", "value": "Quote:019542f5-b3e7-1d02-0000-000000000006", "type": "path", "description": "The unique identifier of the quote whose SCA challenge is being authorized." } ], "body": { "type": "json", "data": "{}" }, "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Satisfy the Strong Customer Authentication challenge carried by a quote in\n`PENDING_AUTHORIZATION` status by submitting an `ScaAuthorization` proof.\n\nThis is used for realtime-funding quotes: the quote is returned with an\n`scaChallenge` and **without** `paymentInstructions`; once authorized, the\nquote advances and its `paymentInstructions` are populated so the customer\ncan fund the transfer.\n\nAs with all SCA, a quote may require more than one authorization: after\nauthorizing, if the quote is sti" }, { "info": { "name": "Resend a quote's SCA challenge code", "type": "http" }, "http": { "method": "POST", "url": "https://api.lightspark.com/grid/2025-10-13/quotes/:quoteId/authorize/resend", "params": [ { "name": "quoteId", "value": "Quote:019542f5-b3e7-1d02-0000-000000000006", "type": "path", "description": "The unique identifier of the quote whose SCA challenge code should be re-sent." } ], "auth": { "type": "basic", "username": "{{username}}", "password": "{{password}}" } }, "docs": "Re-send the one-time code for a realtime-funding quote in\n`PENDING_AUTHORIZATION` status whose `scaChallenge.factor` is `SMS_OTP`. The\nexisting challenge is reused — no new challenge is issued, and its\n`scaChallenge.expiresAt` is **not** extended; once the challenge is past\n`expiresAt` it can no longer be authorized.\n\nOnly meaningful for customers in a region where SCA is required (e.g. EU);\na 409 is returned otherwise. `PASSKEY` challenges cannot be re-sent and return 409.\n\nIn sandbox, the code" } ] } ], "bundled": true }