Full integration guide

The complete path — from API key to a settled PIX payout, covering subaccounts, KYC, wallets, on-ramp and off-ramp.

This is the golden path. Follow it top to bottom once and you'll have a working integration: create a subaccount for your user, verify them, give them a wallet, fund it, pay out to PIX, and reconcile. Each step explains what you call, why, and what comes back.

Identity model. A subAccountId is the single identifier for an end-user across KYC, wallets, deposits and payouts. Create one first — every other call references it.

Prerequisites

  • An API key from the Hodle team. Production keys start with hodle_live_, sandbox with hodle_test_.
  • A server that can receive webhooks (recommended) — or you can poll.
  • Test against the sandbox first: https://sandbox-api.hodle.com.br.

Every request carries your key:

Authorization: Bearer YOUR_API_KEY

Step 1 — Create a subaccount

A subaccount is the segregated account for one of your end-users (or a business unit). It's the identity everything else hangs off.

curl -X POST https://api.hodle.com.br/api/subaccount \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "João da Silva" }'
201 Created
{ "success": true, "data": { "subAccountId": "5b9f...e21a" } }

Store subAccountId against your user. List or fetch them any time:

curl https://api.hodle.com.br/api/subaccount      -H "Authorization: Bearer $API_KEY"   # list
curl https://api.hodle.com.br/api/subaccount/5b9f...e21a -H "Authorization: Bearer $API_KEY"   # one

Step 2 — Run KYC

Money can't move for a subaccount until it's APPROVED. Submit the person's data plus two uploaded image ids (selfie + document).

curl -X POST https://api.hodle.com.br/api/kyc \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subAccountId": "5b9f...e21a",
    "fullName": "João da Silva",
    "dateOfBirth": "1990-05-21",
    "taxIdNumber": "12345678901",
    "countryOfTaxId": "BRA",
    "email": "joao@example.com",
    "country": "BRA",
    "state": "SP",
    "city": "São Paulo",
    "zipCode": "01310-100",
    "streetAddress": "Av. Paulista, 1000",
    "uploadedSelfieId": "sel_...",
    "uploadedDocumentId": "doc_..."
  }'
202 Accepted
{ "success": true, "data": { "attemptId": "kyc_8a2f...", "status": "PENDING" } }

Then wait for approval — by webhook (preferred) or by polling:

curl https://api.hodle.com.br/api/kyc/kyc_8a2f... -H "Authorization: Bearer $API_KEY"
{ "success": true, "data": { "status": "APPROVED" } }

States: PENDING → APPROVED | REJECTED | EXPIRED. On APPROVED you also receive the KYC_APPROVED webhook. A subaccount that isn't APPROVED gets 403 from deposit and payout. Full field reference: KYC.

Step 3 — Provision a wallet

Create a wallet protected by the PIN the account holder established on the platform. The API verifies that PIN and returns fresh keys protected by it. See Wallet Keys for PIN setup and wallet selection.

curl -X POST https://api.hodle.com.br/api/wallet/create \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "subAccountId": "5b9f...e21a", "network": "polygon", "walletPin": "123456" }'
201 Created
{ "success": true, "data": { "id": "6a4d263d4cc67674bf72a3c9", "address": "0x4b1f...c9a2", "network": "polygon", "chainId": 137, "balance": 0, "protectedSymmetricKey": "<new wallet protected key>" } }

Save data.id as walletId and cache its protectedSymmetricKey. Creation provisions the requested network. Calling create again creates another wallet.

Read this wallet with /api/wallet/get using walletId and subAccountId. Pass walletId, walletPin and this wallet's protectedSymmetricKey in transfers and payouts. A transfer uses fromSubAccountId to identify the source subaccount; a payout uses subAccountId.

Step 4 — Fund the wallet (on-ramp)

Turn BRL into crypto credited to the wallet. Two ways:

  • PIX on-rampPOST /api/deposit/asset returns a PIX charge; once the payer pays, Hodle credits the wallet in the chosen asset.
  • External transfer — send USDT/USDC to the wallet address from Step 3; Hodle indexes the inbound transfer and credits the subaccount automatically.
curl -X POST https://api.hodle.com.br/api/deposit/asset \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subAccountId": "5b9f...e21a",
    "value": 5000,
    "asset": "USDT",
    "network": "polygon"
  }'

value is in BRL cents (5000 = R$50,00). asset is one of LIGHTNING, USDT, USDC, USDCE, or BRLA. You get a DEPOSIT_ASSET_SUCCESS webhook when the funds land. Full reference: Deposit.

Step 5 — Pay out to PIX (off-ramp)

Turn the wallet's crypto into a BRL PIX payment to any key. Hodle covers gas, swaps stable → BRLA, and settles the recipient.

curl -X POST https://api.hodle.com.br/api/wallet/payout \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subAccountId": "5b9f...e21a",
    "value": 5000,
    "network": "polygon",
    "pixKey": "recipient@example.com",
    "pixKeyType": "EMAIL"
  }'
202 Accepted
{ "success": true, "transactionId": "tx_7c1d...", "status": "PROCESSING", "valueInBrl": "50.00", "fee": "2.75" }

Then poll until settled (or use the webhook):

curl https://api.hodle.com.br/api/wallet/payout/tx_7c1d... -H "Authorization: Bearer $API_KEY"

States: PROCESSING → COMPLETED | FAILED. On COMPLETED the response carries endToEndId (the bank's PIX reference). On FAILED the on-chain transfer is reverted and the balance restored. Fees: R$1.50 fixed + 2.5%. Full reference: Payout.

Lightning shortcut. If you only need Lightning → PIX (no wallet or KYC), skip Steps 3–5 and issue a Lightning invoice directly — it settles to a PIX key when paid.

Step 6 — Reconcile

Pull every operation for a window and close your books. Each row carries the on-chain txHash and the PIX endToEndId — the join keys against your bank report.

curl -X POST https://api.hodle.com.br/api/account/statement \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "subAccountId": "5b9f...e21a", "from": "2026-06-01", "to": "2026-06-30" }'

Reference: Account statement.

Events to handle

Subscribe to webhooks instead of polling. The lifecycle emits:

EventWhen
KYC_APPROVED / KYC_REJECTEDKYC resolves
DEPOSIT_ASSET_SUCCESSon-ramp funds land
PAYOUT_SUCCESSFUL / PAYOUT_FAILEDpayout settles or fails
DISPUTE_CREATED / DISPUTE_ACCEPTED / DISPUTE_REJECTED / DISPUTE_CANCELEDa Pix you received is contested (MED) and resolves

Every webhook is signed with X-Hodle-Signature (HMAC-SHA256) — verify it before trusting the body.