The Pix2Depix REST API converts BRL (Brazil Pix) to and from DePix, a BRL-pegged asset on the Liquid Network — so you can accept Pix payments that settle on-chain and pay out on-chain balances back to a Pix key.This guide walks you through a deposit (BRL → DePix) from first request to confirmation, then shows an optional payout (DePix → BRL). More about DePix at depix.info.
Every request is authenticated with a Bearer JWT (RS256), and you issue it yourself from the #Bot section of your private Telegram channel with Eulen. There are two ways to get one:
Client credentials (recommended)./addclientcredentials <label> gives you a client_id and client_secret. Exchange them at POST /api/v2/auth/login for a short-lived access token plus a refresh token, and renew with POST /api/v2/auth/refresh.
Legacy API token./apitoken <label> <days> [all|deposit|withdraw|user] returns a long-lived token directly, valid for up to 365 days.
Either way the header is the same. Send it on every call:
GET /ping validates your token and echoes back its decoded claims, so it's the fastest way to confirm your credentials and scopes are correct:
Your token carries a scope claim, an array holding any of deposit, withdraw and user. Calling an endpoint outside your granted scopes returns 403 Forbidden. Client credentials spell the payout scope withdrawal; both spellings are accepted on the API. See the Authentication page for the full claim reference.
Hold on to id — you'll use it to track the deposit in step 4.
There is no idempotency — do not retry blindly
This API has no idempotency key. X-Nonce is generated by the server and returned in the response header for tracing; a nonce you send is not read. If a deposit or withdrawal times out, check its status before resending, or you may create it twice. See Synchronous requests & safe retries.
The response gives you everything you need to present the payment:
qrImageUrl — a ready-to-render PNG of the QR code. Display it as an image for the user to scan.
qrCopyPaste — the Pix "copia e cola" payload. Offer it as a copy-paste code for users paying from a banking app on the same device.
One QR, one payment, one window
Instruct the end user to pay only with the qrImageUrl or qrCopyPaste returned for this deposit. A payment made any other way does not reach it — not the bank app's "repeat transfer" option, not a direct transfer to the destination account, not standalone banking details, and not an in-app AI assistant asked to create or edit the payment.Each QR is single-use and tied to one deposit id. Paying it twice, or reusing it for a different purchase, will not credit a second time. Pix QRs also expire: once the window closes, create a new deposit for a fresh QR rather than retrying the old one.
Once the user pays, the deposit moves through a series of statuses. Prefer webhooks — Eulen sends an HTTP POST callback to your registered endpoint as the status changes, so you don't have to poll.Treat approved as your confirmation signal: it means the payment was received and cleared, and the DePix will be sent shortly. It fires faster than depix_sent, so it's the recommended trigger for fulfilling the user's order.As a fallback — for example, if a webhook delivery is missed — poll GET /deposit-status:
Common deposit statuses you'll observe:
Status
Meaning
pending
QR generated, awaiting payment
under_review
Paid, under review by us
approved
Received & cleared — DePix will be sent soon (confirm on this)
depix_sent
DePix sent
delayed
Held until delayUntil
expired
QR expired before payment
refunded
Refunded to payer (e.g. via MED)
canceled
Canceled
error
Contact support
Held states
A deposit may pause in under_review or delayed before reaching approved. These are expected intermediate states — wait for approved rather than treating a held deposit as failed. A new end user's first deposit is the most common reason for the extra check, and it usually proceeds once cleared.
To reconcile a batch of deposits (e.g. after downtime), use GET /deposits?start=&end=&status= as the documented webhook fallback. start is inclusive and end is exclusive (start <= x < end); dates are YYYY-MM-DD or RFC3339.
If your token has the withdraw scope, you can send DePix back out as a Pix payout with POST /withdraw. Provide the destination pixKey, exactly one of depositAmountInCents (DePix to send) or payoutAmountInCents (BRL to receive), and a beneficiary identification — at least one of taxNumber or euid.
The pixKey must belong to the beneficiary you identify with taxNumber / euid. If you send both, they must match — the request is rejected outright when they disagree, and a mismatch the API lets through can still be rejected by the receiving bank.
Track the payout with GET /withdraw-status?id=<withdrawalId>, or via the withdraw webhook.
Authentication — full JWT claim reference, scopes, and how to validate tokens.
Webhooks — register an endpoint and handle the deposit, withdraw, and med event types.
Errors — HTTP status codes and the response.errorMessage envelope.
Changelog — track API changes, including the beneficiary-identification requirement (effective 2026-05-01).
MED webhooks
The med event type notifies you when a MED (Pix special refund) is filed against a past deposit. Register it the same way as the other two, with /registerwebhook med <url> <secret>.