Getting Started
Five minutes to your first Cobrança (charge).
#1. Get your API key
Log in to the Neozentry QA Dashboard → Settings → API Keys → Create key, or via HTTP / CLI as documented in API Keys.
You will receive a key that looks like this:
qa_test_8f3a9b2c1d4e5f6a7b8c9d0e1f2a3b4cqa_test_* keys hit the same production infrastructure with test-safe behavior for integration work; qa_live_* keys move real money. Treat both like a password. Anyone with a key can create charges billed to your account. Store it server-side only — never ship it to a browser or mobile app. The cleartext is shown exactly once at issuance — see API Keys for rotation if you lose it.
#2. Pick your environment
| Environment | Base URL | Notes |
|---|---|---|
| Production | https://qa.liqfy.com.br/v1 | Real money. Real settlements. |
| Sandbox | not yet available | A dedicated test environment is planned but not live — there is no separate sandbox host yet. Test against production with small amounts and a qa_test_* key. |
All examples in this guide use the production base URL.
#3. Make your first call
curl -X POST https://qa.liqfy.com.br/v1/charges \
-H "apikey: $QA_API_KEY" \
-H "Idempotency-Key: order-12345" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "BRL",
"payment_method": "pix",
"description": "Pedido #12345",
"customer": { "name": "Maria Silva", "document": "12345678901" },
"metadata": { "order_id": "12345" }
}'Successful response (201 Created):
{
"id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
"object": "charge",
"amount": 1000,
"currency": "BRL",
"status": "pending",
"payment_method": "pix",
"customer": { "name": "Maria Silva", "document": "12345678901" },
"pix": {
"br_code": "000201BRCODEPIX",
"qr_code_url": "https://qr.example/img.png",
"expires_at": "2026-07-23T15:00:00.000Z"
},
"settlement": {},
"metadata": { "order_id": "12345" },
"created_at": "2026-07-23T14:30:00.000Z"
}The id (ch_…) is your charge handle — use it to fetch status and reconcile webhooks. For Pix the BR Code and QR Code are already in the creation response: no follow-up poll is needed to render the checkout.
pix.txid and settlement.end_to_end_id are BACEN-contextual Pix data, not identifiers — see PIX. settlement stays {} until the charge is paid.
#4. Conventions
These rules apply to every Neozentry QA /v1/charges-family endpoint.
#Authentication
Every request to a merchant-scoped endpoint carries your API key in the apikey header:
apikey: qa_live_...Missing or invalid keys return 401 Unauthorized.
#Amounts are integers in the smallest currency unit
| Currency | What 1000 means |
|---|---|
BRL | R$ 10,00 |
Pix charges settle in BRL only today. Never send decimals — 10.00 is rejected.
#Idempotency is mandatory on writes
Every POST /v1/charges must include the Idempotency-Key header (8–128 characters, scoped by merchant + operation + key — the same key from a different merchant never conflicts).
Replaying the same key with the same request body returns the stored response, guaranteeing a network retry, mobile-app double-tap, or background-job restart never charges twice. Reusing the key with a different body returns 409 and error.code: "idempotency_key_reused" (see Errors). The server retains the record for at least 24 hours.
Recommended: use your internal order id (e.g. order-12345) or a UUID v4.
#Timestamps are ISO 8601 UTC
2026-07-23T14:30:00.000Z#Identifiers
A charge id is always prefixed ch_ followed by an opaque UUID-shaped string — for example ch_a1b2c3d4-e5f6-4789-9abc-def012345678. Treat it as an opaque string: don't parse, don't sort lexicographically, don't infer ordering from the value. ch_… is always the Neozentry QA id; the BACEN pix.txid and settlement.end_to_end_id are contextual Pix data and never substitute it.
#Errors
All errors return the canonical envelope:
{
"error": {
"type": "invalid_request_error",
"code": "invalid_amount",
"message": "amount deve ser um inteiro positivo em centavos.",
"param": "amount"
},
"request_id": "req_01J..."
}Every response — success or error — also carries X-Request-Id. See Errors for the full envelope and status code map.
#Rate limits
200 req/sec, 5000 req/min, 50000 req/hour per authenticated API key by default (Kong's rate-limiting plugin, scoped by consumer). Need more? Email qa@liqfy.com.br.
#5. Charge lifecycle
┌──────────────────────┐
│ pending │ ← created, awaiting payer
└──────────┬───────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌─────────┐
│ paid │ │ expired │ │ failed │
└────┬────┘ └──────────┘ └─────────┘
│
▼
┌──────────┐
│ refunded │
└──────────┘Public status vocabulary: pending, processing, paid, failed, expired, cancelled, refunded, disputed. These are stable states you can branch on; the internal states they map from never appear in a /v1/charges response.
Your fulfillment hook should fire on paid. Everything else is informational — prefer webhooks over polling for that transition.
#6. Check your balance
Once charges start settling, your available balance is one call away — same apikey, no body. The currency query param is optional; without it you get every currency on the account:
curl "https://qa.liqfy.com.br/v1/wallets/balance" \
-H "apikey: $QA_API_KEY"{
"available": 880,
"pending": 0,
"total": 880,
"retained": 0,
"currency": "BRL",
"next_release_at": null,
"next_release_amount": null,
"balances": [
{ "currency": "BRL", "available": 880, "pending": 0, "total": 880 }
]
}Amounts are in centavos (880 = R$ 8,80). available is what you can spend or pay out right now; pending is settled-but-not-yet-released. When a release is scheduled, next_release_at / next_release_amount tell you when and how much. Each currency on the account shows up in balances[].
Just one currency? Add
?currency=BRLfor the flat shape. Need every wallet (by type)?GET /v1/walletsreturns the full list. See the API Reference.