Lightning Invoice

Generate a Lightning invoice that triggers a PIX payout when paid.

POST /api/lightning/invoice

Generate a Lightning invoice. When the invoice is paid, a PIX payout is automatically sent to the specified PIX key or QR code.

Request

curl --request POST \
  --url https://api.hodle.com.br/api/lightning/invoice \
  --header "Authorization: Bearer $API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "value": 1000,
    "pixKey": "[email protected]",
    "pixKeyType": "EMAIL"
  }'
const res = await fetch('https://api.hodle.com.br/api/lightning/invoice', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.HODLE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    value: 1000,
    pixKey: '[email protected]',
    pixKeyType: 'EMAIL',
  }),
})
const data = await res.json()
import os, requests

res = requests.post(
    "https://api.hodle.com.br/api/lightning/invoice",
    headers={
        "Authorization": f"Bearer {os.environ['HODLE_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "value": 1000,
        "pixKey": "[email protected]",
        "pixKeyType": "EMAIL",
    },
)
data = res.json()

Body examples

With PIX key
{
  "value": 1000,
  "pixKey": "[email protected]",
  "pixKeyType": "EMAIL"
}
With PIX QR Code
{
  "value": 1000,
  "qrCode": "00020126580014br.gov.bcb.pix..."
}

Parameters

FieldTypeRequiredDescription
valuenumberYesAmount the PIX recipient receives, in BRL cents. Min 500 (R$ 5.00). Max is your outbound per-transaction limit (see Limits). With a dynamic qrCode, the QR code amount wins.
pixKeystringNoPIX key for the payout. Mutually exclusive with qrCode.
pixKeyTypestringNoType of the PIX key: PHONE, CPF, EMAIL, RANDOM, or CNPJ.
qrCodestringNoPIX QR Code in copy-paste format. Mutually exclusive with pixKey.
refundAddressstringNoLightning address for refunds in case of failure.
subAccountIdstringNoAttribute the invoice/pix-out to this subaccount (scoped to your API key). Defaults to the main account.

You must provide either pixKey or qrCode, but not both.

Limits

The invoice is an outbound PIX, so it counts against your outbound limits. Inbound and outbound are separate budgets: deposits never consume the payout allowance.

LimitDefault
Minimum per invoiceR$ 5.00
Maximum per invoiceR$ 3,000.00
Monthly outbound totalR$ 120,000.00

There is no separate daily or night-time outbound limit. The monthly window is the calendar month. Limits can be raised per account on request; the figures that apply to you come back in every limit refusal (see Errors).

Fees

A 2% fee (minimum R$ 1.00) is added on top of value. The invoice charges value + fee, so the recipient receives exactly value.

fee   = max(value * 0.02, 100)
total = value + fee

For example, a PIX of R$ 100.00 (value 10000) has a fee of R$ 2.00, and the invoice is priced at R$ 102.00.

Response

200 OK
{
  "success": true,
  "transactionId": "65f1a8b2c3d4e5f6a7b8c9d1",
  "trackId": "3dbbb785-8a1d-41c4-9d15-171e0ddc7c3d",
  "invoice": "lnbc1020n1p5u2g2qsp5...",
  "expiresAt": "2026-09-26T13:18:29.000Z",
  "valueInSatoshis": 28172,
  "pixKey": "12345678000190",
  "qrCode": null,
  "valueInBrl": 102,
  "fee": 2,
  "quote": {
    "brlAmount": 102,
    "btcAmount": 0.00028172,
    "satoshis": 28172,
    "btcToBrlRate": 362069.04
  }
}

Fields

FieldTypeDescription
successbooleanWhether the invoice was created.
transactionIdstringId of the payout. The PAYOUT_* webhooks carry the same value.
trackIdstringTracking id of the payout, also echoed by the webhooks.
invoicestringBOLT11 invoice to be paid. Echoed as invoice in the webhooks.
expiresAtstringISO 8601 instant after which the invoice can no longer be paid.
valueInSatoshisnumberInvoice amount in satoshis.
pixKeystring | nullThe PIX key used.
qrCodestring | nullThe PIX QR code used.
valueInBrlnumberInvoice amount in BRL (value + fee).
feenumberFee in BRL.
quote.brlAmountnumberBRL amount quoted.
quote.btcAmountnumberAmount in BTC.
quote.satoshisnumberAmount in satoshis.
quote.btcToBrlRatenumberBTC to BRL exchange rate.

Expiry

An invoice is payable for 1 hour after creation (expiresAt). An expired invoice cannot be paid and fires no webhook; create a new one.

Webhooks

When the invoice is paid and the PIX settles, Hodle sends PAYOUT_SUCCESSFUL (shown as "Payout confirmado" in the dashboard). A failure sends PAYOUT_FAILED, and a reversal sends PAYOUT_REFUNDED. There is no separate "invoice paid" event.

Match the event to the invoice by data.transactionId (or data.invoice, the same BOLT11 returned here). See the Lightning-funded payload.

Errors

400 Bad Request
{
  "success": false,
  "error": "Validation failed",
  "details": [{ "field": "pixKey", "message": "Não use chave pix e qrCode ao mesmo tempo" }]
}

A value above a limit returns 403 with a stable errorCode (PER_TX_LIMIT_EXCEEDED or MONTHLY_LIMIT_EXCEEDED) and the outbound figures that apply to your account:

403 Forbidden
{
  "success": false,
  "error": "Valor excede o limite por transação de saída de R$ 3000.00",
  "errorCode": "PER_TX_LIMIT_EXCEEDED",
  "limit": {
    "direction": "OUT",
    "monthlyLimitBrlCents": 12000000,
    "monthlyUsedBrlCents": 0,
    "monthlyAvailableBrlCents": 12000000,
    "perTxLimitBrlCents": 300000,
    "resetsAt": "2026-10-01T03:00:00.000Z"
  }
}

A limit refusal is a definitive answer about the account, not a service fault: do not retry it.