Skip to content

docs(sca): document Strong Customer Authentication for EU customers - #683

Open
jklein24 wants to merge 2 commits into
mainfrom
feat/striga-sca-docs
Open

docs(sca): document Strong Customer Authentication for EU customers#683
jklein24 wants to merge 2 commits into
mainfrom
feat/striga-sca-docs

Conversation

@jklein24

@jklein24jklein24 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

A full, EU-scoped Strong Customer Authentication guide in the Mintlify docs, covering the SCA surface added in #558/#600 (both merged). What began as a single per-transaction snippet is now a dedicated guide section covering the whole SCA surface the API exposes, mirroring the structure of the reference docs it wraps (Striga's SCA docs).

What's added

A new "Strong Customer Authentication" group under the Get started tab (docs.json), with six pages under platform-overview/sca/:

  • overview — region scoping (EU / EUR / USDC), a "what SCA covers" table, factors + dynamic linking, a Mermaid flow diagram of the authorize loop, and lifetimes/limits + error tables.
  • per-transaction-authorization — reuses the existing snippets/sca/strong-customer-authentication.mdx as the single source (the three money-movement flow pages still import the same snippet, so they're unchanged): PENDING_AUTHORIZATION + scaChallenge, the status-driven authorize loop, inline vs. after-the-fact proof, resend, realtime-funding quotes, sandbox 123456.
  • factor-enrollment — TOTP + passkey enrollment (start/confirm), factor list/delete.
  • login-and-sessions — SCA login + the session it grants, plus account-security (record-event) signals and the lockout ladder.
  • trusted-beneficiaries — trust and untrust as start → confirm (keyed by externalAccountId).
  • two-factor-reset — liveness-gated start → poll → complete.

Refreshed for API drift (2026-08-28)

Rebased onto current main — the branch previously carried #600's spec commits, which are merged, so the PR is now docs-only — and updated for everything that landed on the SCA surface since the guide was written:

Review addressed

Incorporated the review on the guide:

  • Bounded the 2FA-reset poll loop (stop at expiresAt / client timeout; restart if the window closes before liveness passes).
  • Clarified the failed-login counter is cumulative and cleared only by RESET_PASSWORD_COMPLETED, not by a successful login.
  • Untrust is documented as start → confirm, backed by the startBeneficiaryUntrust endpoint from feat(sca): SCA management surface — enrollment, login/session, beneficiary trust, 2FA reset #600.
  • Fixed MD031/MD040 markdownlint violations on the new fenced code blocks.

Prose pass: em-dashes and AI-tell phrasing removed across the pages and the shared snippet.

Validation

  • make build — rebundled openapi.yaml / mintlify/openapi.yaml byte-match main; the PR carries no spec changes.
  • make lint (redocly + spectral) passes.
  • markdownlint (repo-pinned markdownlint-cli) passes clean on all SCA pages and the touched flow pages.
  • mint broken-links adds zero new broken links versus main.
  • Two adversarial-review rounds: no P0/P1 findings; P2s fixed (authorize-call label in the Mermaid diagram, suspension-vs-password-reset wording, PENDING_AUTHORIZATION guard in the conversion example, type/factor discriminator wording).

🤖 Generated with Claude Code

@vercel

vercelBot commented Jul 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
ProjectDeploymentActionsUpdated (UTC)
grid-flow-builderIgnoredIgnoredPreviewAug 29, 2026 1:03am
grid-wallet-demoIgnoredIgnoredPreviewAug 29, 2026 1:03am

Request Review

@jklein24Graphite App

jklein24 commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@jklein24

Copy link
Copy Markdown
ContributorAuthor

@greptile review

@greptile-apps

greptile-appsBot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

\m/ SCA documentation forged in EU steel \m/ ⚔ This PR adds a complete Strong Customer Authentication guide.

  • Adds six pages covering authorization, factors, sessions, beneficiaries, and resets.
  • Adds the SCA section to Mintlify navigation.
  • Reuses one shared authorization snippet across payment flows.
  • Guards realtime-funding instructions until quote authorization completes.
  • Documents quote-scoped authorization, resend behavior, errors, and expiry.

Confidence Score: 5/5

This looks safe to merge.

  • The pending quote example no longer reads withheld payment instructions.
  • Authorization and resend guidance matches the quote-scoped API contract.
  • No blocking issues remain in the updated documentation.

Important Files Changed

FilenameOverview
mintlify/ramps/conversion-flows/fiat-crypto-conversion.mdxGuards access to realtime-funding payment instructions while authorization is pending.
mintlify/snippets/sca/strong-customer-authentication.mdxProvides shared guidance for quote authorization, challenge loops, resend behavior, and expiry.
mintlify/platform-overview/sca/per-transaction-authorization.mdxDocuments authorization for prefunded and realtime-funded quotes.
mintlify/docs.jsonAdds the six SCA pages to the documentation navigation.

Reviews (4): Last reviewed commit: "docs(sca): refresh the guide for API dri..." | Re-trigger Greptile

Comment threadmintlify/snippets/sca/strong-customer-authentication.mdx Outdated
Comment threadmintlify/snippets/sca/strong-customer-authentication.mdx Outdated
jklein24 added a commit that referenced this pull request Jul 13, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24

Copy link
Copy Markdown
ContributorAuthor

@greptile review

Comment threadmintlify/snippets/sca/strong-customer-authentication.mdx Outdated
jklein24 added a commit that referenced this pull request Jul 13, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24

Copy link
Copy Markdown
ContributorAuthor

@greptile review

@jklein24
jklein24force-pushed the feat/striga-sca-management branch from af68ac7 to d71d44dCompareJuly 14, 2026 06:29
jklein24 added a commit that referenced this pull request Jul 14, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 14, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from b6d2de5 to 2280c96CompareJuly 14, 2026 06:29
@jklein24
jklein24force-pushed the feat/striga-sca-management branch from d71d44d to 7ddda22CompareJuly 14, 2026 06:37
jklein24 added a commit that referenced this pull request Jul 14, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 14, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 2280c96 to 36e9188CompareJuly 14, 2026 06:37
jklein24 added a commit that referenced this pull request Jul 14, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 14, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch 2 times, most recently from d61ee03 to 0d87524CompareJuly 14, 2026 08:23

@jklein24jklein24 left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes

Comment threadmintlify/platform-overview/sca/trusted-beneficiaries.mdx Outdated
Comment threadmintlify/platform-overview/sca/two-factor-reset.mdx Outdated
Comment threadmintlify/platform-overview/sca/login-and-sessions.mdx
Comment threadmintlify/platform-overview/sca/login-and-sessions.mdx
jklein24 added a commit that referenced this pull request Jul 14, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 14, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 78c7440 to a3a6b90CompareJuly 14, 2026 17:20
Comment threadmintlify/payouts-and-b2b/payment-flow/send-payment.mdx Outdated
jklein24 added a commit that referenced this pull request Jul 16, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 34c3e22 to be5713dCompareJuly 16, 2026 08:26
@jklein24
jklein24force-pushed the feat/striga-sca-management branch from b906634 to 94e5d2fCompareJuly 16, 2026 20:04
jklein24 added a commit that referenced this pull request Jul 16, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 16, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from be5713d to 4ea44c2CompareJuly 16, 2026 20:04
jklein24 added a commit that referenced this pull request Jul 17, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 17, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-management branch from 94e5d2f to b7f7e5bCompareJuly 17, 2026 17:24
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 4ea44c2 to 761678bCompareJuly 17, 2026 17:24
jklein24 added a commit that referenced this pull request Jul 17, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 17, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 761678b to 6bd7314CompareJuly 17, 2026 18:03
jklein24 added a commit that referenced this pull request Jul 17, 2026
Address Greptile review on #683:
- Document the quote resend endpoint (POST /quotes/{quoteId}/authorize/resend)
alongside the transaction one, since a realtime-funding quote's SMS challenge
exists before any transaction.
- Note that a realtime-funding 202 withholds paymentInstructions until the
challenge is authorized, so integrators authorize first, then read them.
Co-Authored-By: Claude <noreply@anthropic.com>
jklein24 added a commit that referenced this pull request Jul 17, 2026
…CA-pending quotes
The runnable displayPaymentInstructions example dereferenced
quote.paymentInstructions[0] unconditionally, which throws for an EU
realtime-funding quote returned as PENDING_AUTHORIZATION (instructions withheld
until the scaChallenge is authorized). Guard for the pending case and point at
the SCA section. Addresses Greptile P1 on #683.
Co-Authored-By: Claude <noreply@anthropic.com>
@jklein24
jklein24force-pushed the feat/striga-sca-docs branch from 6bd7314 to 332b681CompareJuly 17, 2026 18:07
@github-actions

github-actionsBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

✱ Stainless preview builds for grid

No changes were made to the SDKs.


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-08-29 01:03:47 UTC

Base automatically changed from feat/striga-sca-management to mainJuly 17, 2026 23:10
@jklein24

Copy link
Copy Markdown
ContributorAuthor

Implementation follow-ups from the Striga SCA parity review (docs-only corrections are in b66552e):

  1. Operation-aware factor support. Striga permits TOTP for non-dynamically-linked crypto withdrawals and trusted-beneficiary EUR/USDC sends, while dynamically linked debits require SMS/passkey. Grid needs to derive availableFactors from operation, destination, and trust state, expose a selectable factor where needed, and add contract tests for BTC/Lightning, trusted USDC, and untrusted regulated debits. Trust/untrust start must also accept a factor, or be documented and enforced as SMS-only; otherwise callers cannot initiate a passkey ceremony.

  2. 2FA reset lifecycle. Grid returning 204 from completion plus independent re-enrollment does not model Striga factor-specific completion results, such as new TOTP material or passkey creation options, or the transition to COMPLETED only after enrollment confirmation. Either expose that continuation or prove the alternate flow with contract tests and a coherent status model; include pending-reset reuse, enrolled-factor mismatch, suspended-user recovery, and session-revocation behavior.

  3. Strict proof contracts. Make authorization, login completion, and beneficiary-confirm schemas discriminated variants: exactly one proof, passkey requires assertion plus origin, and SMS requires challenge ID. Add negative validation tests so {} and invalid factor/proof combinations fail at schema validation.

  4. Session enforcement. Confirm or implement the 180-day EUR/USDC read session, fresh SCA for history older than 90 days, and prior-session revocation on login. Surface deterministic Grid errors on the affected read endpoints.

Reference: https://docs.striga.com/reference/strong-customer-authentication-sca and https://docs.striga.com/reference/sca-factors-implementation.

@mintlify

mintlifyBot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
Grid🟢 ReadyView PreviewJul 28, 2026, 7:15 AM

@ls-bolt
ls-boltBotforce-pushed the feat/striga-sca-docs branch from b66552e to 1e00e31CompareAugust 28, 2026 07:45
@ls-bolt

ls-boltBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Revision log — updated in place, latest first.

Revision 2

Rebased onto current main to clear merge conflicts: #877 ("Payout timing") and this PR both added a section after the status table in send-payment.mdx — resolved by keeping both sections (timing first, then SCA). Content is otherwise unchanged from the drift-refresh push; make build bundles still byte-match main, make lint and markdownlint pass.

Earlier revisions (1)

Revision 1

Rebased onto current main (dropped the already-merged #600 spec commits — the PR is now docs-only) and refreshed the guide for SCA-surface drift since the branch point:

Validation: make build bundles byte-match main, make lint passes, repo-pinned markdownlint clean on all touched pages, mint broken-links adds zero new broken links vs main.

jklein24and others added 2 commits August 29, 2026 01:02
A dedicated SCA guide section under the Get started tab covering the whole
SCA surface: overview, per-transaction authorization, factor enrollment,
login and sessions, trusted beneficiaries, and two-factor reset, plus a
shared snippet imported by the money-movement flow pages.
The SCA surface moved after this guide was written; bring it current:
- SCA login complete now requires `endUserIpAddress` and returns
`sessionExpiresAt` (#780); the session-scope guidance now tells
integrators to prompt re-login ahead of it.
- Quote authorize documents `409 SCA_SESSION_REQUIRED` and
`423 ACCOUNT_LOCKED` (#761); both join the error tables, and the
snippet notes authorizing requires an active login session.
- A challenge left to expire unsatisfied now fails the transaction with
`failureReason: SCA_NOT_COMPLETED` and no funds moved (#762).
- Trusted external accounts refuse `DELETE` with
`409 BENEFICIARY_TRUSTED`; untrust first (#770).
- The challenge lives on the quote, not the transaction — webhook
consumers route via the transaction's `quoteId` (#701).
- `POST /transfer-out` is deprecated in favor of `POST /quotes` with
`immediatelyExecute: true` (#856); the transfer-out tab now says so.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jklein24