Supported currencies
Prerequisites
- The account holder already has an internal account in the same currency. Funds go there when a sweep can’t be completed.
- The account holder is verified. For a platform-owned account, your platform’s own customer record must be verified.
- The sweep destination exists. It can be an external account or another internal account, but not another rule-based account.
Create a rule-based account
CallPOST /internal-accounts with type: RULE_BASED, the currency, and a sweepRule. Omit customerId to create an account owned by your platform.
- USD
- USDC
Sweep every incoming dollar payment to the customer’s external bank account over ACH:
fundingPaymentInstructions with the payer: a bank account number for USD, or one wallet address per network for USDC and USDT. If the account’s status is PENDING, wait for ACTIVE before sharing them.
USDC response
USDC response
Configure the sweep rule
When you read the account,
sweepRule.minimumAmount and sweepRule.maximumAmount show the range the route to the destination can carry, in the rule-based account’s currency.
Track sweeps
Each sweep appears as a transaction withruleBasedAccountId set to the rule-based account that received the deposit. Its source describes the depositor when it’s known.
A sweep that can’t be completed fails with one of these reasons, and the funds move to the account holder’s own internal account in the same currency:
SWEEP_AMOUNT_OUT_OF_RANGE: The amount is belowminimumAmountor abovemaximumAmount.SWEEP_QUOTE_FAILED: Grid couldn’t price the sweep.
QUOTE_EXECUTION_FAILED, the same as any other payment. Include it alongside the SWEEP_* reasons when you monitor for failed sweeps.
To list an account holder’s rule-based accounts, filter internal accounts with type=RULE_BASED.
EU customers
For customers in a region where Strong Customer Authentication (SCA) is required, a rule-based account converts every deposit and sends the result to its destination. The sweep runs without any further action once the account holder has authorized it.
A same-currency destination isn’t supported, and neither are
remittanceInformation or purposeOfPayment on the sweep rule. A customer can hold up to 10 rule-based accounts.
Authorize the account
The create request returns202 with the account in PENDING_AUTHORIZATION and an scaChallenge. The account holder authorizes it once, and later sweeps run without further authorization:
1
Confirm an SCA session
Make sure the customer has an active SCA login session. A missing session returns
409 SCA_SESSION_REQUIRED.2
Trust an external destination
For an external destination, start beneficiary trust with
POST /customers/external-accounts/{externalAccountId}/trust, then submit the customer’s proof to POST /customers/external-accounts/{externalAccountId}/trust/confirm. Check that the response contains trusted: true before creating the account. An untrusted destination returns 409 BENEFICIARY_NOT_TRUSTED.3
Create the account
Call
POST /internal-accounts with an Idempotency-Key. Pass scaFactor to choose SMS_OTP (default), TOTP, or PASSKEY.4
Authorize the challenge
Call
POST /internal-accounts/{id}/authorize with the customer’s proof, then check the returned account. If it is still PENDING_AUTHORIZATION, authorize its next scaChallenge and repeat until it advances. Once the account is ACTIVE, Grid sends INTERNAL_ACCOUNT.STATUS_UPDATED.Idempotency-Key to receive a new challenge. An account that is never authorized moves to FAILED.
Funds a sweep couldn’t deliver
If a payout is refused after the conversion (for example, by the destination bank or a compliance check), the converted funds stay with the account holder. They are listed in the account’sstrandedBalances. Move them to the account holder’s own internal account in that currency with POST /internal-accounts/{id}/stranded-funds/transfer, which returns a quote to authorize like any other SCA-protected transfer.
Test in sandbox
In sandbox, account numbers and addresses are generated locally. CallPOST /sandbox/internal-accounts/{accountId}/fund on a rule-based account to simulate a settled deposit. It triggers the sweep exactly as a real deposit would. Fund a very small amount to test the SWEEP_AMOUNT_OUT_OF_RANGE path.