Stellar (USDC)
Hold USDC on Stellar, receive it, buy it with Pix and pay Pix from it — without ever holding XLM.
Stellar is available for USDC. Each account (and each sub-account) gets its own Stellar wallet, ready to receive USDC the moment it is created: Hodle activates the account on-chain and opens its USDC trustline for you, and pays every network fee. Your users never need XLM.
Stellar is enabled per account. Ask your Hodle contact to enable it for your API key; until then
network: "stellar"answers403. Sandbox support (Stellar testnet, test USDC) is coming soon.
How it works
| Step | Endpoint | What happens |
|---|---|---|
| 1. Create the wallet | POST /api/wallet/create | A Stellar account is created and activated with its USDC trustline. Returns the G… address. |
| 2. Receive USDC | — | Send USDC on Stellar to the G… address from any wallet or exchange. |
| 3. Buy USDC with Pix | POST /api/deposit/asset | asset: "USDC", network: "stellar": the buyer pays a Pix and the USDC arrives on the wallet. |
| 4. Read the balance | GET /api/wallet | addresses.stellar and the USDC / XLM rows for network: "stellar". |
| 5. Pay a Pix | POST /api/wallet/payout/stellar | Pays a Pix key or a Pix QR code from the wallet's USDC. |
1. Create the wallet
The key is protected by the account's wallet PIN, like every other Hodle wallet. Creating it again returns the same wallet.
curl --request POST \
--url https://api.hodle.com.br/api/wallet/create \
--header "Authorization: Bearer $API_KEY" \
--header "Content-Type: application/json" \
--data '{ "network": "stellar", "walletPin": "123456" }'const res = await fetch('https://api.hodle.com.br/api/wallet/create', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.HODLE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ network: 'stellar', walletPin: '123456' }),
})
const { data } = await res.json()
// data.address → "G…"| Field | Type | Required | Description |
|---|---|---|---|
network | string | yes | "stellar" |
walletPin | string | yes | The account's 6-digit wallet PIN. |
subAccountId | string | no | Create the wallet for a customer sub-account. |
isDefault | boolean | no | Make it the default wallet of its scope. |
Response 201
{
"success": true,
"data": {
"id": "6ad96f9124b1c5b037ec6fed",
"address": "GCHZCGL3DQ4BBVK2UCDRTIBSAJPGBQJZMDVZHPXVNRA6X5IWT7Y33ZJD",
"network": "stellar",
"balance": 0
}
}| Status | Meaning |
|---|---|
400 | Missing or invalid field. |
403 | Stellar is not enabled for this account, or the PIN is wrong. |
429 | The wallet is already being created, or the account reached its Stellar wallet limit. |
503 | The on-chain activation did not confirm yet. Call again with the same body: it resumes on the same address. |
2. Receive USDC
Send USDC on Stellar (the official USDC asset, issuer GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN) to the wallet's G… address. No memo is needed. Other Stellar assets are not credited.
3. Buy USDC with Pix
Use Deposit Asset with asset: "USDC" and network: "stellar". The account (or sub-account) must already have its Stellar wallet; the USDC is delivered to it.
{ "asset": "USDC", "network": "stellar", "value": 10000 }4. Read the balance
Wallet Get includes the Stellar wallet:
{
"addresses": { "stellar": "GCHZ…ZJD" },
"balances": [
{ "network": "stellar", "asset": "USDC", "amount": "25.00" },
{ "network": "stellar", "asset": "XLM", "amount": "0.00" }
]
}Balances are cached for 30 seconds; pass sync: true for a fresh read. POST /api/wallet/list lists the wallet with type: "STELLAR_CLIENT_GENERATED" and its address.
5. Pay a Pix
POST /api/wallet/payout/stellar pays a Pix key or a Pix QR code in BRL from the wallet's USDC. It runs every check Wallet Payout runs (limits, third-party rules, rate limit, duplicates) and answers 202 while the payout settles.
Payouts from Stellar are being rolled out. While they are not enabled for your account the endpoint answers
403.
curl --request POST \
--url https://api.hodle.com.br/api/wallet/payout/stellar \
--header "Authorization: Bearer $API_KEY" \
--header "Content-Type: application/json" \
--data '{ "value": 1000, "pixKey": "[email protected]", "walletPin": "123456", "externalId": "order-123" }'| Field | Type | Required | Description |
|---|---|---|---|
value | integer | yes | BRL the recipient receives, in cents (minimum 500). |
pixKey | string | one of | The recipient's Pix key. |
qrCode | string | one of | A Pix QR code (copia e cola). Send pixKey or qrCode, never both. |
walletPin | string | yes | The account's wallet PIN. |
subAccountId | string | no | Pay from a customer sub-account's Stellar wallet. |
externalId | string | no | Your idempotency key. Repeating it returns the same payout (200, alreadyProcessed: true). |
taxId | string | no | The recipient's CPF/CNPJ, for the third-party rules. |
Response 202
{
"success": true,
"data": {
"id": "6ad9…",
"trackId": "1dbf…",
"stage": "SENT",
"amountInRaw": "19230000",
"txHash": "aa…"
}
}amountInRaw is the USDC debited, with 7 decimals (19230000 = 1.923 USDC). Follow the payout with GET /api/wallet/payout/:transactionId and the PAYOUT_SUCCESSFUL / PAYOUT_FAILED webhooks.
| Status | Meaning |
|---|---|
400 | Invalid body, or both / neither of pixKey and qrCode. |
403 | Not enabled, wrong PIN, KYC or limits refused. |
409 | Another payout from the same wallet is in progress. |
429 | Rate limited. |
503 | Temporarily unavailable; nothing was debited. Retry with the same externalId. |