---
title: "Pay a bank in Latin America or Asia"
description: "Bank payouts to Mexico, Brazil, Colombia, India and Hong Kong are not yet available. Learn what each route will need, and save payees now so they are ready."
---
Use this recipe to learn what each bank route in Mexico, Brazil, Colombia, India and Hong Kong will need, and to save payees now so they are ready when the route opens. These routes are not yet available.

**Who it is for.** A marketplace that wants to pay sellers in local currency in Mexico (CLABE), Brazil (PIX), Colombia, India or Hong Kong.

**Status.** Not yet available. Ask support to enable a country for your business. USD by SWIFT is a different route. See [Pay a supplier abroad by SWIFT](/recipes/bank-payouts/pay-a-supplier-abroad-by-swift).

## Money example: 100 USDC to Mexico, step by step

1. A seller in Guadalajara is owed 100.00 USD of sales. Your customer holds USDC in a Gravv wallet.
2. You save the seller as a payee with an 18-digit CLABE and a CURP.
3. You send 100.00 from the USDC wallet to that payee. Today the API returns `transfers to MX/MXN are not available at this time`, and Gravv debits nothing.
4. When support enables Mexico for your business, the same payee and the same request pay out in MXN.

## Before you start

There is nothing to check in advance. No call tells you whether a country is open, so the transfer's response is the check.

## Find out what is required

Each route checks these details when you send, not when you save the payee:

| Country | The payee needs | Fields |
| :-- | :-- | :-- |
| Mexico | An 18-digit CLABE, and a CURP or RFC | `payee_type` `bank_account` (always send it, because without it Gravv takes a CLABE for a US account and refuses it for MXN), `account_number`, `national_id`, `national_id_type` (`CURP` or `RFC`) |
| Brazil | A PIX key, and a CPF (person) or CNPJ (company) | `pix_key` (1 to 77 characters, no spaces), `national_id`, `national_id_type` |
| Colombia | An account number, the bank, the account type (savings or checking), and a CC or NIT | `account_number`, `institution_id`, `bank_account_type` (`checking` or `savings`), `national_id`, `national_id_type` |
| India | An account number (9 to 18 digits) and an IFSC | `account_number`, `routing_number` set to the IFSC |
| Hong Kong | An account number and the bank | `account_number`, `institution_id`. Hong Kong is also missing from `GET /v1/transfer/supported-countries` |
| All of them | The recipient's address | `address.address_line1` (4 to 34 characters), `address.city`, `address.country` |

## Steps

### 1. Save the Mexican payee

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/external-accounts \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: aa5afdef-78eb-4d44-9ac6-61bd16c95002' \
     --data '
{
  "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
  "payee_type": "bank_account",
  "currency": "MXN",
  "account_name": "Diego Hernandez",
  "account_number": "002180000123456789",
  "institution_country_iso_code": "MX",
  "national_id": "GODE561231HDFRRN09",
  "national_id_type": "CURP",
  "address": {
    "address_line1": "Av Vallarta 1520",
    "city": "Guadalajara",
    "country": "MX"
  }
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/external-accounts", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "aa5afdef-78eb-4d44-9ac6-61bd16c95002",
  },
  body: JSON.stringify({
    "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
    "payee_type": "bank_account",
    "currency": "MXN",
    "account_name": "Diego Hernandez",
    "account_number": "002180000123456789",
    "institution_country_iso_code": "MX",
    "national_id": "GODE561231HDFRRN09",
    "national_id_type": "CURP",
    "address": {
      "address_line1": "Av Vallarta 1520",
      "city": "Guadalajara",
      "country": "MX"
    }
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/external-accounts",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "aa5afdef-78eb-4d44-9ac6-61bd16c95002",
    },
    json={
        "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
        "payee_type": "bank_account",
        "currency": "MXN",
        "account_name": "Diego Hernandez",
        "account_number": "002180000123456789",
        "institution_country_iso_code": "MX",
        "national_id": "GODE561231HDFRRN09",
        "national_id_type": "CURP",
        "address": {
            "address_line1": "Av Vallarta 1520",
            "city": "Guadalajara",
            "country": "MX",
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response (HTTP 200)"
{
  "data": {
    "id": "2ce0729d-3b00-4b22-8967-58f801966ffc",
    "payee_type": "bank_account",
    "account_number": "002180000123456789",
    "account_name": "DIEGO HERNANDEZ",
    "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
    "currency": "MXN",
    "institution_country_iso_code": "MX",
    "address": {
      "city": "Guadalajara",
      "address_line1": "Av Vallarta 1520",
      "country": "MX"
    },
    "status": "active",
    "date_created": "2026-10-13T13:01:12.300Z",
    "national_id_type": "CURP",
    "national_id_masked": "**************RN09"
  },
  "error": null
}
```

Gravv never returns the full `national_id`, only `national_id_masked`.

### 2. Add missing details to a payee you already have

To complete a Brazilian payee saved earlier without a PIX key and CPF, use [`PATCH /v1/external-accounts/{external_account_id}`](/api-reference/external-accounts/patch-v1-external-accounts-external-account-id). A field you leave out keeps its value, and `null` clears a field. This call does not need an `Idempotency-Key`, and it returns HTTP 202.

<CodeGroup>
```bash title="cURL"
curl --request PATCH \
     --url https://api.gravv.xyz/v1/external-accounts/8e65cb04-10e2-4faa-b365-e1e03942b846 \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --data '
{
  "pix_key": "maria.souza@example.com",
  "national_id": "529.982.247-25",
  "national_id_type": "CPF",
  "address": {
    "address_line1": "Rua Augusta 1200",
    "city": "Sao Paulo",
    "country": "BR"
  }
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/external-accounts/8e65cb04-10e2-4faa-b365-e1e03942b846", {
  method: "PATCH",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "pix_key": "maria.souza@example.com",
    "national_id": "529.982.247-25",
    "national_id_type": "CPF",
    "address": {
      "address_line1": "Rua Augusta 1200",
      "city": "Sao Paulo",
      "country": "BR"
    }
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.patch(
    "https://api.gravv.xyz/v1/external-accounts/8e65cb04-10e2-4faa-b365-e1e03942b846",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
    },
    json={
        "pix_key": "maria.souza@example.com",
        "national_id": "529.982.247-25",
        "national_id_type": "CPF",
        "address": {
            "address_line1": "Rua Augusta 1200",
            "city": "Sao Paulo",
            "country": "BR",
        },
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

Read the payee back to confirm `national_id_type` and `national_id_masked`. Gravv never returns the PIX key.

### 3. Try the transfer

This example sends from the customer's USDC wallet, as in the money example. You can also skip this step until support confirms the country.

<CodeGroup>
```bash title="cURL"
curl --request POST \
     --url https://api.gravv.xyz/v1/transfer \
     --header 'Api-Key: <API_KEY>' \
     --header 'Content-Type: application/json' \
     --header 'Idempotency-Key: d440eeab-474f-4c59-9bf5-301c1e3e2ef7' \
     --data '
{
  "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
  "source": {
    "source_type": "internal_crypto_wallet",
    "id": "3a8f1c2d-5b7e-4d9a-8c6f-0e2b4d6f8a15",
    "crypto_asset": "USDC"
  },
  "destination": {
    "destination_type": "external_account",
    "id": "2ce0729d-3b00-4b22-8967-58f801966ffc"
  },
  "amount": "100.00",
  "description": "Seller payout October",
  "client_reference": "mkt-mx-payout-5521"
}
'
```
```javascript title="Node"
const response = await fetch("https://api.gravv.xyz/v1/transfer", {
  method: "POST",
  headers: {
    "Api-Key": process.env.GRAVV_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "d440eeab-474f-4c59-9bf5-301c1e3e2ef7",
  },
  body: JSON.stringify({
    "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
    "source": {
      "source_type": "internal_crypto_wallet",
      "id": "3a8f1c2d-5b7e-4d9a-8c6f-0e2b4d6f8a15",
      "crypto_asset": "USDC"
    },
    "destination": {
      "destination_type": "external_account",
      "id": "2ce0729d-3b00-4b22-8967-58f801966ffc"
    },
    "amount": "100.00",
    "description": "Seller payout October",
    "client_reference": "mkt-mx-payout-5521"
  }),
});
console.log(response.status, await response.json());
```
```python title="Python"
import os

import requests

response = requests.post(
    "https://api.gravv.xyz/v1/transfer",
    headers={
        "Api-Key": os.environ["GRAVV_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "d440eeab-474f-4c59-9bf5-301c1e3e2ef7",
    },
    json={
        "customer_id": "30c9ae51-00ce-4616-8eb4-e4d189afa159",
        "source": {
            "source_type": "internal_crypto_wallet",
            "id": "3a8f1c2d-5b7e-4d9a-8c6f-0e2b4d6f8a15",
            "crypto_asset": "USDC",
        },
        "destination": {
            "destination_type": "external_account",
            "id": "2ce0729d-3b00-4b22-8967-58f801966ffc",
        },
        "amount": "100.00",
        "description": "Seller payout October",
        "client_reference": "mkt-mx-payout-5521",
    },
)
print(response.status_code, response.json())
```
</CodeGroup>

```json title="Response (HTTP 400)"
{
  "data": null,
  "error": "transfers to MX/MXN are not available at this time"
}
```

Brazil, Colombia, India and Hong Kong return the same error, with their own country and currency. Gravv debits nothing.

## What can go wrong

| Response | Why | Fix |
| :-- | :-- | :-- |
| 400 `transfers to MX/MXN are not available at this time` (or `BR/BRL`, `CO/COP`, `IN/INR`, `HK/HKD`), or `… are not supported at this time` | The route is not yet available | Contact support to enable it, and keep the payee |
| 400 `the payee is missing required information for this transfer type — please update the payee details` | The route cannot pay this payee yet | Contact support with the payee `id` |
| 400 `MXN not supported for ach/wire external accounts: invalid input` | You sent a CLABE without `payee_type`, so Gravv took it for a US account | Send `"payee_type": "bank_account"` |
| 400 `CLABE checksum invalid (expected check digit X, got Y): invalid input` | The CLABE is mistyped | Enter the 18 digits again |
| 400 `national id type CPF is not accepted for MX payees (expected CURP, RFC)` | The id type is wrong for the country | Send CURP or RFC for Mexico |
| 400 `national id is not a valid CPF (11 digits with valid check digits)` | The CPF is mistyped | Fix it. Gravv removes dots and dashes for you |
| 400 `national id and national id type must be provided together` | You sent only one of the two | Send both |
| 400 `pix key cannot contain whitespace or control characters` | The key has spaces | Remove the spaces |
| 400 `this payee is missing details required for this transfer (<list>); update the payee and retry` | The route is enabled, but a detail from the table is missing | PATCH the payee with the listed fields, then send again with a new key |
| … `cannot be changed on this payee; create a new payee with the complete details and retry` | The missing field cannot be changed on this payee | Save a new payee |
| 409 `the address of payee … cannot be changed: it is already registered for payouts; create a new payee with the new address` | The address is locked | Save a new payee |

## Webhooks you will receive

You receive `external_account.created` for each payee. You receive no transfer events, because Gravv creates no transfer while the route is closed.

## Testing in sandbox

In sandbox, saving payees for Mexico, Brazil, India and Hong Kong works as described, and so does the PATCH.

- Brazil and Hong Kong return `not available at this time`.
- Mexico and India return `the payee is missing required information for this transfer type — please update the payee details` instead.

Either error means you cannot pay the payee yet, and Gravv debits nothing.

## Reference

- [Add an external account](/api-reference/external-accounts/post-v1-external-accounts)
- [Update an external account](/platform/external-accounts/update-an-external-account)
- [Payments and supported countries](/getting-started/payments-and-supported-countries#pay-out-coverage)
