Pay a bank in Latin America or Asia

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.

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

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"
}
}
'
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());
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())
{
  "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}. 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.

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"
}
}
'
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());
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())

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.

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"
}
'
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());
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())
{
  "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

Was this page helpful?