> ## Documentation Index
> Fetch the complete documentation index at: https://ramps-feat-striga-sca-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Trusted beneficiaries

> Whitelist a payee so future sends skip the per-transaction ceremony

<Note>
  Applies only to customers in an SCA-required region (EU). Every endpoint here
  returns **`409`** for other customers.
</Note>

Trusting a beneficiary is a one-time, SCA-gated step that whitelists an external
account. Only **USDC addresses** can be trusted today. Once trusted, future sends
to that payee are no longer dynamically linked; they drop to a lighter
authentication instead of a full per-transaction challenge. Use it for recurring
payouts to known destinations.

The beneficiary is identified end-to-end by its **`externalAccountId`** in the
path, so there is no separate whitelist handle to track. All paths below are
relative to `https://api.lightspark.com/grid/2025-10-13`.

## Trusting a beneficiary

<Steps>
  <Step title="Start the trust">
    ```bash theme={null}
    POST /customers/external-accounts/{externalAccountId}/trust
    ```

    Returns the `scaChallenge` to satisfy:

    ```json theme={null}
    { "scaChallenge": { "id": "…", "factor": "SMS_OTP", "expiresAt": "2025-10-03T12:05:00Z", "availableFactors": ["SMS_OTP"] } }
    ```

    <Note>
      `scaChallenge` may be **omitted** when no challenge is issued. In that case,
      confirm directly without a `challengeId`.
    </Note>
  </Step>

  <Step title="Confirm the trust">
    Submit the proof for the factor Grid returned in `scaChallenge`: `code` for
    `SMS_OTP` / `TOTP`, or `passkeyAssertion` + `origin` for `PASSKEY`. Echo
    `challengeId` when start issued one. Do not assume a factor is available unless
    it appears in `scaChallenge.availableFactors`.

    ```bash theme={null}
    POST /customers/external-accounts/{externalAccountId}/trust/confirm

    { "challengeId": "…", "code": "123456" }
    ```

    ```json theme={null}
    { "trusted": true }
    ```

    An invalid or expired proof returns `400`. **In sandbox, the code is always
    `123456`.**
  </Step>
</Steps>

## Untrusting a beneficiary

Untrusting mirrors trusting: a start call issues the challenge, then confirm
submits the proof.

<Steps>
  <Step title="Start the untrust">
    ```bash theme={null}
    POST /customers/external-accounts/{externalAccountId}/untrust
    ```

    Returns the `scaChallenge` to satisfy, omitted when no challenge is issued (the
    caller then confirms without a `challengeId`).
  </Step>

  <Step title="Confirm the untrust">
    Submit the proof for the factor Grid returned in `scaChallenge`: `code` for
    `SMS_OTP` / `TOTP`, or `passkeyAssertion` + `origin` for `PASSKEY`. Echo
    `challengeId` when start issued one. Returns `trusted: false`.

    ```bash theme={null}
    POST /customers/external-accounts/{externalAccountId}/untrust/confirm

    { "challengeId": "…", "code": "123456" }
    ```
  </Step>
</Steps>

Once untrusted, sends to that beneficiary are dynamically linked again and each
one requires a full per-transaction challenge.
