> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lightspark.com/llms.txt
> Use this file to discover all available pages before exploring further.

# External Accounts

> Configure external bank accounts and crypto wallets for ramp destinations

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

<Info>
  Customer external accounts often require some basic beneficiary information for compliance.
  Platform accounts are managed at the organization level.
</Info>

## Look up bank names with the Discoveries API

Some countries require a `bankName` when creating an external account — including the Philippines, Nigeria, South Africa, and others. The `bankName` value must match exactly what Grid expects.

Use the [Discoveries API](/api-reference/discoveries/list-available-receiving-institution-names) to retrieve the list of valid bank names for a given country and currency:

```bash cURL theme={null}
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/discoveries?country=PH&currency=PHP' \
  -H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
```

```json Response theme={null}
{
  "data": [
    {
      "bankName": "BDO Unibank",
      "displayName": "BDO Unibank",
      "country": "PH",
      "currency": "PHP"
    },
    {
      "bankName": "BPI",
      "displayName": "Bank of the Philippine Islands",
      "country": "PH",
      "currency": "PHP"
    }
  ]
}
```

Use `bankName` from the response as the `bankName` value when creating an external account. The `displayName` is a human-friendly label you can show to your users. You can filter the list on the client side as the user types to provide a bank search experience.

## Create external accounts by region or wallet

<Tabs>
  <Tab title="United States">
    **ACH, Wire, RTP**

    ```bash cURL theme={null}
    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": "USD_ACCOUNT",
          "accountNumber": "123456789",
          "routingNumber": "021000021",
          "bankAccountType": "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"
            }
          }
        }
      }'
    ```

    <Note>
      Category must be `CHECKING` or `SAVINGS`. Routing number must be 9 digits.
    </Note>
  </Tab>

  <Tab title="Mexico">
    **CLABE/SPEI**

    ```bash cURL theme={null}
    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": "MXN_ACCOUNT",
          "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"
            }
          }
        }
      }'
    ```
  </Tab>

  <Tab title="Brazil">
    **PIX**

    ```bash cURL theme={null}
    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": "BRL_ACCOUNT",
          "pixKey": "user@email.com",
          "pixKeyType": "EMAIL",
          "bankName": "Nubank",
          "taxId": "12345678900",
          "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"
            }
          }
        }
      }'
    ```

    <Tip>Key types: `CPF`, `CNPJ`, `EMAIL`, `PHONE`, or `RANDOM`</Tip>
  </Tab>

  <Tab title="Colombia">
    **Bank Transfer or Mobile Money (Nequi, Daviplata)**

    Colombia supports two payment rails: bank transfer and mobile money.

    **Bank Transfer:**

    ```bash cURL theme={null}
    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": "COP",
        "platformAccountId": "co_bank_001",
        "accountInfo": {
          "accountType": "COP_ACCOUNT",
          "bankName": "Bancolombia",
          "accountNumber": "1234567890",
          "bankAccountType": "CHECKING",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "Juan Carlos García",
            "birthDate": "1988-03-15",
            "nationality": "CO",
            "documentType": "CC",
            "documentNumber": "1234567890",
            "address": {
              "line1": "Carrera 7 #45-23",
              "city": "Bogotá",
              "postalCode": "110111",
              "country": "CO"
            }
          }
        }
      }'
    ```

    **Mobile Money (Nequi, Daviplata):**

    ```bash cURL theme={null}
    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": "COP",
        "platformAccountId": "co_mobile_001",
        "accountInfo": {
          "accountType": "COP_ACCOUNT",
          "bankName": "Nequi",
          "phoneNumber": "+573001234567",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "María López",
            "birthDate": "1992-07-20",
            "nationality": "CO",
            "documentType": "CC",
            "documentNumber": "9876543210",
            "address": {
              "line1": "Calle 100 #15-30",
              "city": "Medellín",
              "postalCode": "050021",
              "country": "CO"
            }
          }
        }
      }'
    ```

    <Note>
      Bank transfer requires `bankName`, `accountNumber`, and `bankAccountType` (CHECKING or SAVINGS).
      Mobile money requires `phoneNumber` in international format (e.g., +573001234567).
      Most Colombian banks require `documentType` and `documentNumber` for KYC matching.
      Document types: `CC` (Cédula de Ciudadanía), `CE` (Cédula de Extranjería), `TI` (Tarjeta de Identidad), `NIT` (Número de Identificación Tributaria), `PP` (Passport).
    </Note>
  </Tab>

  <Tab title="El Salvador">
    **Bank Transfer or Mobile Money (Tigo Money)**

    El Salvador supports two payment rails: bank transfer and mobile money.

    **Bank Transfer:**

    ```bash cURL theme={null}
    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": "sv_bank_001",
        "accountInfo": {
          "accountType": "SLV_ACCOUNT",
          "bankName": "Banco Cuscatlan",
          "accountNumber": "0123456789",
          "bankAccountType": "CHECKING",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "Carlos Morales",
            "birthDate": "1990-05-20",
            "nationality": "SV",
            "address": {
              "line1": "Colonia Escalon 123",
              "city": "San Salvador",
              "postalCode": "01101",
              "country": "SV"
            }
          }
        }
      }'
    ```

    **Mobile Money (Tigo Money):**

    ```bash cURL theme={null}
    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": "sv_mobile_001",
        "accountInfo": {
          "accountType": "SLV_ACCOUNT",
          "phoneNumber": "+50312345678",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "Ana Martinez",
            "birthDate": "1985-08-15",
            "nationality": "SV",
            "address": {
              "line1": "Avenida Roosevelt 456",
              "city": "San Salvador",
              "postalCode": "01101",
              "country": "SV"
            }
          }
        }
      }'
    ```

    <Note>
      Bank transfer requires `bankName`, `accountNumber`, and `bankAccountType` (CHECKING or SAVINGS).
      Mobile money requires `phoneNumber` in international format (e.g., +50312345678).
    </Note>
  </Tab>

  <Tab title="Europe">
    **IBAN/SEPA**

    ```bash cURL theme={null}
    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": "EUR_ACCOUNT",
          "iban": "DE89370400440532013000",
          "swiftCode": "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"
            }
          }
        }
      }'
    ```
  </Tab>

  <Tab title="Philippines">
    **PHP Bank Transfer**

    ```bash cURL theme={null}
    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": "PHP",
        "platformAccountId": "ph_bank_001",
        "accountInfo": {
          "accountType": "PHP_ACCOUNT",
          "bankName": "BDO Unibank",
          "accountNumber": "001234567890",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "Maria Santos",
            "birthDate": "1995-04-10",
            "nationality": "PH",
            "address": {
              "line1": "123 Rizal Avenue",
              "city": "Manila",
              "state": "Metro Manila",
              "postalCode": "1000",
              "country": "PH"
            }
          }
        }
      }'
    ```

    <Note>
      Account number must be 8-16 digits.
    </Note>
  </Tab>

  <Tab title="United Kingdom">
    **GBP Faster Payments**

    ```bash cURL theme={null}
    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": "GBP",
        "platformAccountId": "gb_bank_001",
        "accountInfo": {
          "accountType": "GBP_ACCOUNT",
          "sortCode": "123456",
          "accountNumber": "12345678",
          "beneficiary": {
            "beneficiaryType": "INDIVIDUAL",
            "fullName": "James Smith",
            "birthDate": "1985-09-03",
            "nationality": "GB",
            "address": {
              "line1": "10 Downing Street",
              "city": "London",
              "postalCode": "SW1A 2AA",
              "country": "GB"
            }
          }
        }
      }'
    ```

    <Note>
      Sort code must be 6 digits. Account number must be 8 digits. Address is required for GBP individual beneficiaries.
    </Note>
  </Tab>

  <Tab title="India">
    **UPI**

    ```bash cURL theme={null}
    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": "INR_ACCOUNT",
          "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"
            }
          }
        }
      }'
    ```
  </Tab>

  <Tab title="Nigeria">
    **NGN Bank Transfer**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Account number must be exactly 10 digits.
    </Note>
  </Tab>

  <Tab title="South Africa">
    **ZAR Bank Transfer**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Account number must be 9-13 digits.
    </Note>
  </Tab>

  <Tab title="Kenya">
    **KES Mobile Money (M-PESA)**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+254XXXXXXXXX` (9 digits after country code). Provider must be `M-PESA`.
    </Note>
  </Tab>

  <Tab title="Tanzania">
    **TZS Mobile Money**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+255XXXXXXXXX` (9 digits after country code). Providers: `AIRTEL` or `VODACOM`.
    </Note>
  </Tab>

  <Tab title="Zambia">
    **ZMW Mobile Money**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+260XXXXXXXXX` (9 digits after country code). Providers: `TNM`, `AIRTEL`, `ZAMTEL`, or `MTN`.
    </Note>
  </Tab>

  <Tab title="Rwanda">
    **RWF Mobile Money**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+250XXXXXXXXX` (9 digits after country code). Providers: `MTN` or `AIRTEL`.
    </Note>
  </Tab>

  <Tab title="Malawi">
    **MWK Mobile Money**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+265XXXXXXXXX` (9 digits after country code). Providers: `AIRTEL` or `TNM`.
    </Note>
  </Tab>

  <Tab title="Uganda">
    **UGX Mobile Money**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Phone number must be in format `+256XXXXXXXXX` (9 digits after country code). Providers: `MTN` or `AIRTEL`.
    </Note>
  </Tab>

  <Tab title="West Africa">
    **XOF Mobile Money (Senegal, Benin, Ivory Coast)**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Supported countries and phone formats:

      * Senegal (+221): `+221XXXXXXXXX` (9 digits after country code)
      * Ivory Coast (+225): `+225XXXXXXXXXX` (10 digits after country code)
      * Benin (+229): `+229XXXXXXXX` or `+229XXXXXXXXX` (8–9 digits after country code)
    </Note>
  </Tab>

  <Tab title="Canada">
    **CAD Bank Transfer**

    ```bash cURL theme={null}
    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"
            }
          }
        }
      }'
    ```

    <Note>
      Bank code is 3 digits, branch code is 5 digits, account number is 7-12 digits.
    </Note>
  </Tab>

  <Tab title="Cryptocurrency">
    **Bitcoin Lightning (Spark Wallet)**

    ```bash cURL theme={null}
    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"
        }
      }'
    ```

    <Note>
      Spark wallets don't require beneficiary information as they are self-custody wallets.
    </Note>
  </Tab>
</Tabs>

<Tip>Use `platformAccountId` to tie your internal id with the external account.</Tip>

**Sample Response:**

```json theme={null}
{
  "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": "USD_ACCOUNT",
    "accountNumber": "123456789",
    "routingNumber": "021000021",
    "bankAccountType": "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:

```json theme={null}
{
  "currency": "USD",
  "platformAccountId": "acme_corp_account",
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "accountInfo": {
    "accountType": "USD_ACCOUNT",
    "accountNumber": "987654321",
    "routingNumber": "021000021",
    "bankAccountType": "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"
      }
    }
  }
}
```

## Minimum required beneficiary fields

The following tables show the minimum required fields for individual and business beneficiaries. All other fields are optional but recommended for faster compliance review.

### Individual beneficiaries

| Country              | Required Fields                          | Required Address Fields                  |
| -------------------- | ---------------------------------------- | ---------------------------------------- |
| US (USD)             | `beneficiaryType`, `fullName`            | `line1`, `city`, `postalCode`, `country` |
| Mexico (MXN)         | `beneficiaryType`, `fullName`            | None (address optional)                  |
| Brazil (BRL)         | `beneficiaryType`, `fullName`            | None (address optional)                  |
| Philippines (PHP)    | `beneficiaryType`, `fullName`            | None (address optional)                  |
| United Kingdom (GBP) | `beneficiaryType`, `fullName`, `address` | `line1`, `city`, `postalCode`, `country` |
| Europe (EUR)         | `beneficiaryType`, `fullName`, `address` | `line1`, `city`, `postalCode`, `country` |

<Info>
  While only the fields listed above are strictly required, providing additional information like `birthDate`, `nationality`, and `address` can reduce the likelihood of false positive compliance checks and increase transaction success rates.
</Info>

### Business beneficiaries

For business beneficiaries, the required fields vary by destination currency:

| Currency                                                   | Required fields                                       |
| ---------------------------------------------------------- | ----------------------------------------------------- |
| USD                                                        | `legalName`, `address`                                |
| MXN                                                        | `legalName`, `address`                                |
| EUR                                                        | `legalName`, `address`, `registrationNumber`          |
| GBP, INR, BRL, DKK, PHP, HKD, IDR, MYR, SGD, THB, VND, AED | `legalName`, `address`                                |
| NGN, ZAR, KES, TZS, RWF, ZMW, UGX, BWP, MWK, XOF, XAF      | `legalName`, `address`, `registrationNumber`, `taxId` |

<Note>
  When sending to GBP, INR, BRL, DKK, PHP, HKD, IDR, MYR, SGD, THB, VND, or AED, business senders (originators) must also provide `registrationNumber`.
</Note>

<Info>
  `registrationNumber` is the business's official registration or incorporation number (e.g., EIN in the US, CNPJ in Brazil, company registration number in the UK). `taxId` is the business's tax identification number where it differs from the registration number.
</Info>

## 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                         |
| -------------- | ----------------------------------- |
| `PENDING`      | Created, awaiting verification      |
| `ACTIVE`       | Verified and ready for transactions |
| `UNDER_REVIEW` | Additional review required          |
| `INACTIVE`     | Disabled, cannot be used            |

## Listing external accounts

### List customer accounts

```bash theme={null}
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'
```

### List platform accounts

For platform-wide operations, list all platform-level external accounts:

```bash theme={null}
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/platform/external-accounts' \
  -H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET'
```

<Info>
  Platform external accounts are used for platform-wide operations like
  depositing funds from external sources.
</Info>

## Best practices

<AccordionGroup>
  <Accordion title="Validate account information">
    Validate account details before submission:

    ```javascript theme={null}
    // US accounts: 9-digit routing, 4-17 digit account number
    if (!/^\d{9}$/.test(routingNumber)) {
      throw new Error("Invalid routing number");
    }

    // CLABE: exactly 18 digits
    if (!/^\d{18}$/.test(clabeNumber)) {
      throw new Error("Invalid CLABE number");
    }

    // NGN: exactly 10-digit account number
    if (!/^\d{10}$/.test(ngnAccountNumber)) {
      throw new Error("Invalid Nigerian account number");
    }

    // CAD: 3-digit bank code, 5-digit branch code, 7-12 digit account number
    if (!/^\d{3}$/.test(bankCode)) {
      throw new Error("Invalid bank code");
    }
    if (!/^\d{5}$/.test(branchCode)) {
      throw new Error("Invalid branch code");
    }
    if (!/^\d{7,12}$/.test(cadAccountNumber)) {
      throw new Error("Invalid Canadian account number");
    }

    // PHP: 8-16 digit account number
    if (!/^\d{8,16}$/.test(phpAccountNumber)) {
      throw new Error("Invalid Philippine account number");
    }

    // GBP: 6-digit sort code, 8-digit account number
    if (!/^\d{6}$/.test(sortCode)) {
      throw new Error("Invalid sort code");
    }
    if (!/^\d{8}$/.test(gbpAccountNumber)) {
      throw new Error("Invalid UK account number");
    }

    // ZAR: 9-13 digit account number
    if (!/^\d{9,13}$/.test(zarAccountNumber)) {
      throw new Error("Invalid South African account number");
    }

    // African mobile money phone numbers
    if (!/^\+254\d{9}$/.test(kesPhoneNumber)) {
      throw new Error("Invalid Kenyan phone number");
    }
    if (!/^\+255\d{9}$/.test(tzsPhoneNumber)) {
      throw new Error("Invalid Tanzanian phone number");
    }
    if (!/^\+260\d{9}$/.test(zmwPhoneNumber)) {
      throw new Error("Invalid Zambian phone number");
    }
    if (!/^\+250\d{9}$/.test(rwfPhoneNumber)) {
      throw new Error("Invalid Rwandan phone number");
    }
    if (!/^\+265\d{9}$/.test(mwkPhoneNumber)) {
      throw new Error("Invalid Malawian phone number");
    }
    if (!/^\+256\d{9}$/.test(ugxPhoneNumber)) {
      throw new Error("Invalid Ugandan phone number");
    }
    // West African (XOF): Senegal (+221), Ivory Coast (+225), Benin (+229)
    if (!/^\+(221\d{9}|225\d{10}|229\d{8,9})$/.test(xofPhoneNumber)) {
      throw new Error("Invalid West African phone number");
    }
    ```
  </Accordion>

  <Accordion title="Check account status">
    Verify status before sending payments:

    ```javascript theme={null}
    if (account.status !== "ACTIVE") {
      throw new Error(`Account is ${account.status}, cannot process payment`);
    }
    ```
  </Accordion>

  <Accordion title="Secure account data">
    Never expose full account numbers. Display only masked info:

    ```javascript theme={null}
    function displaySafely(account) {
      return {
        id: account.id,
        bankName: account.accountInfo.bankName,
        lastFour: account.accountInfo.accountNumber.slice(-4),
        status: account.status,
      };
    }
    ```
  </Accordion>
</AccordionGroup>

## 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

<Tip>
  Spark wallets are the recommended destination for on-ramps due to instant
  settlement and minimal fees.
</Tip>

### 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

<Warning>
  Off-ramp destinations require complete beneficiary information for compliance.
  Ensure all required fields are provided.
</Warning>

## Crypto wallet destinations

### Spark wallet addresses

The primary destination type for on-ramps:

```bash theme={null}
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:**

```json theme={null}
{
  "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"
}
```

<Check>
  Spark wallet external accounts are immediately `ACTIVE` and ready for on-ramp
  conversions.
</Check>

### Validate Spark addresses

Before creating external accounts, validate Spark wallet addresses:

```javascript theme={null}
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,
  },
});
```

<Note>
  Spark addresses are case-insensitive and follow the bech32 format starting
  with `spark1`.
</Note>

## Bank account destinations

For off-ramp flows, create external bank accounts with full beneficiary information:

### Example: US bank account for off-ramp

```bash theme={null}
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": "USD_ACCOUNT",
      "accountNumber": "123456789",
      "routingNumber": "021000021",
      "bankAccountType": "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"
        }
      }
    }
  }'
```

## Listing external accounts

### List customer external accounts

```bash theme={null}
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

```bash theme={null}
curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001&currency=BTC' \
  -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 |
| -------------- | -------------------------- | ----------------------- |
| `PENDING`      | Verification in progress   | ❌                       |
| `ACTIVE`       | Verified and ready         | ✅                       |
| `UNDER_REVIEW` | Additional review required | ❌                       |
| `INACTIVE`     | Manually disabled          | ❌                       |

<Info>
  Spark wallet accounts are immediately `ACTIVE`. Bank accounts may require
  verification (typically instant to a few hours).
</Info>

## Best practices for ramps

<AccordionGroup>
  <Accordion title="Validate addresses before creation">
    Always validate wallet addresses and bank account details before creating external accounts:

    ```javascript theme={null}
    // 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;
    }
    ```
  </Accordion>

  <Accordion title="Use platform account IDs for tracking">
    Map external accounts to your internal system using `platformAccountId`:

    ```javascript theme={null}
    const externalAccount = await createExternalAccount({
      customerId,
      currency: "BTC",
      platformAccountId: `${userId}_spark_primary`, // Your internal ID
      accountInfo: {
        accountType: "SPARK_WALLET",
        address: sparkAddress,
      },
    });

    // Store mapping in your database
    await db.userWallets.create({
      userId,
      gridAccountId: externalAccount.id,
      internalId: `${userId}_spark_primary`,
    });
    ```
  </Accordion>

  <Accordion title="Handle multiple destinations per customer">
    Support multiple wallets or bank accounts for flexibility:

    ```javascript theme={null}
    // 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 },
    });
    ```
  </Accordion>

  <Accordion title="Implement address verification for crypto">
    For crypto destinations, implement additional verification:

    ```javascript theme={null}
    // 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({
        /* ... */
      });
    }
    ```
  </Accordion>
</AccordionGroup>

## 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

<Warning>
  Always verify account details before initiating large off-ramp conversions.
  Test with small amounts first.
</Warning>

## Next steps

* [Fiat-to-Crypto Conversion](/ramps/conversion-flows/fiat-crypto-conversion) - Build conversion flows
* [Self-Custody Wallets](/ramps/conversion-flows/self-custody-wallets) - Advanced wallet integration
* [Webhooks](/ramps/platform-tools/webhooks) - Handle account status updates

## Related resources

* [Platform Configuration](/ramps/onboarding/platform-configuration) - Configure supported account types
* [Sandbox Testing](/ramps/platform-tools/sandbox-testing) - Test with mock accounts
* [API Reference](/api-reference) - Complete API documentation
