External accounts are bank accounts, cryptocurrency wallets, or payment destinations outside Grid where you can send funds. Grid supports two types:
Customer external accounts - Scoped to individual customers, used for withdrawals and customer-specific payouts
Platform external accounts - Scoped to your platform, used for platform-wide operations like receiving funds from external sources
Customer external accounts often require some basic beneficiary information for compliance.
Platform accounts are managed at the organization level.
Create external accounts by region or wallet
United States
Mexico
Brazil
Europe
India
Nigeria
South Africa
Kenya
Tanzania
Zambia
Rwanda
Malawi
Uganda
West Africa
Canada
Cryptocurrency
ACH, Wire, RTP curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "USD",
"platformAccountId": "user_123_primary_bank",
"accountInfo": {
"accountType": "US_ACCOUNT",
"accountNumber": "123456789",
"routingNumber": "021000021",
"accountCategory": "CHECKING",
"bankName": "Chase Bank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "John Doe",
"birthDate": "1990-01-15",
"nationality": "US",
"address": {
"line1": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}
}
}'
Category must be CHECKING or SAVINGS. Routing number must be 9 digits.
CLABE/SPEI curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "MXN",
"platformAccountId": "mx_beneficiary_001",
"accountInfo": {
"accountType": "CLABE",
"clabeNumber": "123456789012345678",
"bankName": "BBVA Mexico",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "María García",
"birthDate": "1985-03-15",
"nationality": "MX",
"address": {
"line1": "Av. Reforma 123",
"city": "Ciudad de México",
"state": "CDMX",
"postalCode": "06600",
"country": "MX"
}
}
}
}'
PIX curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "BRL",
"platformAccountId": "br_pix_001",
"accountInfo": {
"accountType": "PIX",
"pixKey": "user@email.com",
"pixKeyType": "EMAIL",
"bankName": "Nubank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "João Silva",
"birthDate": "1988-07-22",
"nationality": "BR",
"address": {
"line1": "Rua das Flores 456",
"city": "São Paulo",
"state": "SP",
"postalCode": "01234-567",
"country": "BR"
}
}
}
}'
Key types: CPF, CNPJ, EMAIL, PHONE, or RANDOM
IBAN/SEPA curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "EUR",
"platformAccountId": "eu_iban_001",
"accountInfo": {
"accountType": "IBAN",
"iban": "DE89370400440532013000",
"swiftBic": "DEUTDEFF",
"bankName": "Deutsche Bank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Hans Schmidt",
"birthDate": "1982-11-08",
"nationality": "DE",
"address": {
"line1": "Hauptstraße 789",
"city": "Berlin",
"state": "Berlin",
"postalCode": "10115",
"country": "DE"
}
}
}
}'
UPI curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "INR",
"platformAccountId": "in_upi_001",
"accountInfo": {
"accountType": "UPI",
"vpa": "user@okbank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Priya Sharma",
"birthDate": "1991-05-14",
"nationality": "IN",
"address": {
"line1": "123 MG Road",
"city": "Mumbai",
"state": "Maharashtra",
"postalCode": "400001",
"country": "IN"
}
}
}
}'
NGN Bank Transfer curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "NGN",
"platformAccountId": "ng_bank_001",
"accountInfo": {
"accountType": "NGN_ACCOUNT",
"accountNumber": "0123456789",
"bankName": "First Bank of Nigeria",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Chukwuemeka Okonkwo",
"birthDate": "1990-06-20",
"nationality": "NG",
"address": {
"line1": "15 Marina Street",
"city": "Lagos",
"state": "Lagos",
"postalCode": "100001",
"country": "NG"
}
}
}
}'
Account number must be exactly 10 digits.
ZAR Bank Transfer curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "ZAR",
"platformAccountId": "za_bank_001",
"accountInfo": {
"accountType": "ZAR_ACCOUNT",
"accountNumber": "1234567890",
"bankName": "Standard Bank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Thabo Mbeki",
"birthDate": "1985-04-12",
"nationality": "ZA",
"address": {
"line1": "42 Nelson Mandela Drive",
"city": "Johannesburg",
"state": "Gauteng",
"postalCode": "2000",
"country": "ZA"
}
}
}
}'
Account number must be 9-13 digits.
KES Mobile Money (M-PESA) curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "KES",
"platformAccountId": "ke_mpesa_001",
"accountInfo": {
"accountType": "KES_ACCOUNT",
"phoneNumber": "+254712345678",
"provider": "M-PESA",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Wanjiku Kamau",
"birthDate": "1990-08-20",
"nationality": "KE",
"address": {
"line1": "Kenyatta Avenue 15",
"city": "Nairobi",
"postalCode": "00100",
"country": "KE"
}
}
}
}'
Phone number must be in format +254XXXXXXXXX (9 digits after country code). Provider must be M-PESA.
TZS Mobile Money curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "TZS",
"platformAccountId": "tz_mobile_001",
"accountInfo": {
"accountType": "TZS_ACCOUNT",
"phoneNumber": "+255712345678",
"provider": "VODACOM",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Juma Hassan",
"birthDate": "1988-02-14",
"nationality": "TZ",
"address": {
"line1": "Samora Avenue 28",
"city": "Dar es Salaam",
"postalCode": "11101",
"country": "TZ"
}
}
}
}'
Phone number must be in format +255XXXXXXXXX (9 digits after country code). Providers: AIRTEL or VODACOM.
ZMW Mobile Money curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "ZMW",
"platformAccountId": "zm_mobile_001",
"accountInfo": {
"accountType": "ZMW_ACCOUNT",
"phoneNumber": "+260971234567",
"provider": "MTN",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Mwila Chanda",
"birthDate": "1992-11-05",
"nationality": "ZM",
"address": {
"line1": "Cairo Road 100",
"city": "Lusaka",
"postalCode": "10101",
"country": "ZM"
}
}
}
}'
Phone number must be in format +260XXXXXXXXX (9 digits after country code). Providers: TNM, AIRTEL, ZAMTEL, or MTN.
RWF Mobile Money curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "RWF",
"platformAccountId": "rw_mobile_001",
"accountInfo": {
"accountType": "RWF_ACCOUNT",
"phoneNumber": "+250781234567",
"provider": "MTN",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Uwimana Diane",
"birthDate": "1995-06-30",
"nationality": "RW",
"address": {
"line1": "KN 5 Avenue",
"city": "Kigali",
"postalCode": "00100",
"country": "RW"
}
}
}
}'
Phone number must be in format +250XXXXXXXXX (9 digits after country code). Providers: MTN or AIRTEL.
MWK Mobile Money curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "MWK",
"platformAccountId": "mw_mobile_001",
"accountInfo": {
"accountType": "MWK_ACCOUNT",
"phoneNumber": "+265991234567",
"provider": "AIRTEL",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Chimwemwe Banda",
"birthDate": "1993-03-18",
"nationality": "MW",
"address": {
"line1": "Kamuzu Procession Road",
"city": "Lilongwe",
"postalCode": "00100",
"country": "MW"
}
}
}
}'
Phone number must be in format +265XXXXXXXXX (9 digits after country code). Providers: AIRTEL or TNM.
UGX Mobile Money curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "UGX",
"platformAccountId": "ug_mobile_001",
"accountInfo": {
"accountType": "UGX_ACCOUNT",
"phoneNumber": "+256701234567",
"provider": "MTN",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Nakato Sarah",
"birthDate": "1990-07-25",
"nationality": "UG",
"address": {
"line1": "Kampala Road 45",
"city": "Kampala",
"postalCode": "00100",
"country": "UG"
}
}
}
}'
Phone number must be in format +256XXXXXXXXX (9 digits after country code). Providers: MTN or AIRTEL.
XOF Mobile Money (Senegal, Benin, Ivory Coast) curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "XOF",
"platformAccountId": "xof_mobile_001",
"accountInfo": {
"accountType": "XOF_ACCOUNT",
"phoneNumber": "+221781234567",
"provider": "ORANGE",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Mamadou Diallo",
"birthDate": "1988-11-12",
"nationality": "SN",
"address": {
"line1": "Avenue Cheikh Anta Diop",
"city": "Dakar",
"postalCode": "10000",
"country": "SN"
}
}
}
}'
Supported countries: Senegal (+221), Benin (+229), and Ivory Coast (+225). Phone formats vary by country.
CAD Bank Transfer curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "CAD",
"platformAccountId": "ca_bank_001",
"accountInfo": {
"accountType": "CAD_ACCOUNT",
"bankCode": "001",
"branchCode": "00012",
"accountNumber": "1234567",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "Emily Thompson",
"birthDate": "1988-09-12",
"nationality": "CA",
"address": {
"line1": "456 Queen Street West",
"city": "Toronto",
"state": "ON",
"postalCode": "M5V 2B3",
"country": "CA"
}
}
}
}'
Bank code is 3 digits, branch code is 5 digits, account number is 7-12 digits.
Bitcoin Lightning (Spark Wallet) curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"currency": "BTC",
"platformAccountId": "btc_spark_001",
"accountInfo": {
"accountType": "SPARK_WALLET",
"address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
}
}'
Spark wallets don’t require beneficiary information as they are self-custody wallets.
Use platformAccountId to tie your internal id with the external account.
Sample Response:
{
"id" : "ExternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965" ,
"customerId" : "Customer:019542f5-b3e7-1d02-0000-000000000001" ,
"status" : "ACTIVE" ,
"currency" : "USD" ,
"platformAccountId" : "user_123_primary_bank" ,
"accountInfo" : {
"accountType" : "US_ACCOUNT" ,
"accountNumber" : "123456789" ,
"routingNumber" : "021000021" ,
"accountCategory" : "CHECKING" ,
"bankName" : "Chase Bank" ,
"beneficiary" : {
"beneficiaryType" : "INDIVIDUAL" ,
"fullName" : "John Doe" ,
"birthDate" : "1990-01-15" ,
"nationality" : "US" ,
"address" : {
"line1" : "123 Main Street" ,
"city" : "San Francisco" ,
"state" : "CA" ,
"postalCode" : "94105" ,
"country" : "US"
}
}
}
}
Business beneficiaries
For business accounts, include business information:
{
"currency" : "USD" ,
"platformAccountId" : "acme_corp_account" ,
"customerId" : "Customer:019542f5-b3e7-1d02-0000-000000000001" ,
"accountInfo" : {
"accountType" : "US_ACCOUNT" ,
"accountNumber" : "987654321" ,
"routingNumber" : "021000021" ,
"accountCategory" : "CHECKING" ,
"bankName" : "Chase Bank" ,
"beneficiary" : {
"beneficiaryType" : "BUSINESS" ,
"businessInfo" : {
"legalName" : "Acme Corporation, Inc." ,
"taxId" : "EIN-987654321"
},
"address" : {
"line1" : "456 Business Ave" ,
"city" : "New York" ,
"state" : "NY" ,
"postalCode" : "10001" ,
"country" : "US"
}
}
}
}
Account status
Beneficiary data may be reviewed for risk and compliance. Only ACTIVE accounts can receive payments. Updates to account data may trigger account re-review.
Status Description PENDINGCreated, awaiting verification ACTIVEVerified and ready for transactions UNDER_REVIEWAdditional review required INACTIVEDisabled, cannot be used
Listing external accounts
List customer accounts
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
For platform-wide operations, list all platform-level external accounts:
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/platform/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
Platform external accounts are used for platform-wide operations like
depositing funds from external sources.
Best practices
Validate account information
Verify status before sending payments: if ( account . status !== "ACTIVE" ) {
throw new Error ( `Account is ${ account . status } , cannot process payment` );
}
Never expose full account numbers. Display only masked info: function displaySafely ( account ) {
return {
id: account . id ,
bankName: account . accountInfo . bankName ,
lastFour: account . accountInfo . accountNumber . slice ( - 4 ),
status: account . status ,
};
}
Using external accounts for ramps
External accounts serve as destinations for ramp conversions:
For on-ramps (Fiat → Crypto)
External accounts represent crypto wallet destinations:
Spark wallets : Lightning Network wallets for instant Bitcoin delivery
Self-custody : User-controlled wallets for full ownership
No beneficiary required : Crypto wallets don’t need compliance information
Spark wallets are the recommended destination for on-ramps due to instant
settlement and minimal fees.
For off-ramps (Crypto → Fiat)
External accounts represent bank account destinations:
Traditional bank accounts : ACH, wire, SEPA, CLABE, PIX, UPI, etc.
Beneficiary required : Full compliance information needed for fiat destinations
Multiple currencies : Support for USD, EUR, MXN, BRL, INR, and more
Off-ramp destinations require complete beneficiary information for compliance.
Ensure all required fields are provided.
Crypto wallet destinations
Spark wallet addresses
The primary destination type for on-ramps:
curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
"currency": "BTC",
"platformAccountId": "user_wallet_001",
"accountInfo": {
"accountType": "SPARK_WALLET",
"address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
}
}'
Response:
{
"id" : "ExternalAccount:wallet001" ,
"customerId" : "Customer:019542f5-b3e7-1d02-0000-000000000001" ,
"status" : "ACTIVE" ,
"currency" : "BTC" ,
"platformAccountId" : "user_wallet_001" ,
"accountInfo" : {
"accountType" : "SPARK_WALLET" ,
"address" : "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
},
"createdAt" : "2025-10-03T14:00:00Z"
}
Spark wallet external accounts are immediately ACTIVE and ready for on-ramp
conversions.
Validate Spark addresses
Before creating external accounts, validate Spark wallet addresses:
function isValidSparkAddress ( address ) {
// Spark addresses start with 'spark1' and are 87 characters
return address . startsWith ( "spark1" ) && address . length === 87 ;
}
const walletAddress =
"spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu" ;
if ( ! isValidSparkAddress ( walletAddress )) {
throw new Error ( "Invalid Spark wallet address format" );
}
// Create external account
await createExternalAccount ({
customerId ,
currency: "BTC" ,
accountInfo: {
accountType: "SPARK_WALLET" ,
address: walletAddress ,
},
});
Spark addresses are case-insensitive and follow the bech32 format starting
with spark1.
Bank account destinations
For off-ramp flows, create external bank accounts with full beneficiary information:
Example: US bank account for off-ramp
curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
"currency": "USD",
"platformAccountId": "user_bank_usd_001",
"accountInfo": {
"accountType": "US_ACCOUNT",
"accountNumber": "123456789",
"routingNumber": "021000021",
"accountCategory": "CHECKING",
"bankName": "Chase Bank",
"beneficiary": {
"beneficiaryType": "INDIVIDUAL",
"fullName": "John Doe",
"birthDate": "1990-01-15",
"nationality": "US",
"address": {
"line1": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}
}
}'
Creating accounts inline with quotes
For one-time conversions, create external accounts inline using externalAccountDetails:
curl -X POST 'https://api.lightspark.com/grid/2025-10-13/quotes' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' \
-H 'Content-Type: application/json' \
-d '{
"source": {
"customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
"currency": "USD"
},
"destination": {
"externalAccountDetails": {
"customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
"currency": "BTC",
"accountInfo": {
"accountType": "SPARK_WALLET",
"address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu"
}
}
},
"lockedCurrencySide": "SENDING",
"lockedCurrencyAmount": 10000
}'
Use externalAccountDetails for one-time destinations. The external account
will be automatically created and can be reused for future quotes using its
returned ID.
Listing external accounts
List customer external accounts
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
Filter by currency
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001¤cy=BTC' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
Filter by account type
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001&accountType=SPARK_WALLET' \
-H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
Account status and verification
External accounts move through verification states:
Status Description Can Use for Conversions PENDINGVerification in progress ❌ ACTIVEVerified and ready ✅ FAILEDVerification failed ❌ DISABLEDManually disabled ❌
Spark wallet accounts are immediately ACTIVE. Bank accounts may require
verification (typically instant to a few hours).
Best practices for ramps
Validate addresses before creation
Always validate wallet addresses and bank account details before creating external accounts: // Validate Spark address format
function validateSparkAddress ( address ) {
if ( ! address . startsWith ( "spark1" )) {
throw new Error ( "Spark address must start with spark1" );
}
if ( address . length !== 87 ) {
throw new Error ( "Spark address must be 87 characters" );
}
// Additional validation logic
return true ;
}
Use platform account IDs for tracking
Handle multiple destinations per customer
Support multiple wallets or bank accounts for flexibility: // Primary Spark wallet for on-ramps
await createExternalAccount ({
customerId ,
currency: "BTC" ,
platformAccountId: ` ${ userId } _spark_primary` ,
accountInfo: { accountType: "SPARK_WALLET" , address: primaryWallet },
});
// Secondary wallet for larger amounts
await createExternalAccount ({
customerId ,
currency: "BTC" ,
platformAccountId: ` ${ userId } _spark_savings` ,
accountInfo: { accountType: "SPARK_WALLET" , address: savingsWallet },
});
Implement address verification for crypto
For crypto destinations, implement additional verification: // Verify Spark wallet is reachable (optional)
async function verifySparkWallet ( address ) {
try {
// Use Lightning Network tools to verify wallet exists
const probe = await lightningClient . probeWallet ( address );
return probe . reachable ;
} catch ( error ) {
console . error ( "Wallet verification failed:" , error );
return false ;
}
}
// Only create external account after verification
if ( await verifySparkWallet ( sparkAddress )) {
await createExternalAccount ({
/* ... */
});
}
Ramp-specific considerations
On-ramp destinations
Instant delivery : Spark wallets receive Bitcoin within seconds
No KYC required : Self-custody wallets don’t need beneficiary info
Reusable addresses : Store and reuse Spark addresses for multiple conversions
No minimum : Send any amount supported by Lightning Network
Off-ramp destinations
Full compliance : Bank accounts require complete beneficiary information
Verification delays : Bank account verification may take a few hours
Settlement times : Vary by destination (instant for RTP/PIX, 1-3 days for ACH)
Amount limits : Check minimum and maximum amounts per destination currency
Always verify account details before initiating large off-ramp conversions.
Test with small amounts first.
Next steps