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

Give the subaccount a non-custodial wallet. The same address works across EVM networks (Polygon, Base) — it's an ERC-4337 smart account — plus Tron and Liquid.

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" }'
201 Created
{ "success": true, "data": { "address": "0x4b1f...c9a2", "network": "polygon", "balance": "0" } }

Read balances any time with /api/wallet/get.

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

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