Skip to main content

Changelog

This document records all notable changes to the CorpX API.

v2.20.1 (2026-06-15) - fee.charged and fee.refunded for external fees

Fee webhooks are now emitted when the fee is issued outside the API (by the billing service or the settlement provider). Previously these cases were delivered as transfer.internal.out (charge) or transfer.internal.in (refund), which contradicted the contract — they now follow the official typing:

  • fee.charged — emitted when a fee is debited from the client account to the fee counterparty (e.g. Corp X Brasil LTDA or MT Instituição de Pagamento SA). Includes feeServiceType (PIX / TED / BOLETO / INTERNAL_TRANSFER / MONTHLY / OTHER) and originalRef / transactionRef referencing the operation that triggered the charge.
  • fee.refunded — emitted when the settlement provider refunds a previously charged fee.

Fees triggered via API (rare today) still don't generate these events; they are exclusive to externally originated movements.

The shape follows the contract documented in Webhooks → 9. fee.charged / 9.1. fee.refunded.

v2.20.0 (2026-06-12) - DICT lookup rate limits and 24h cache

DICT lookups (GET /v1/accounts/{accountId}/pix/key/{pixKey}) now honor the limits configured in the tenant or account policy:

  • maxLookupsPerDay — absolute cap per calendar day (BRT). 0 or unset = unlimited.
  • maxLookupRatio — relative cap: ratio × pix_outs_24h. Example: ratio 3.0 with 100 PIX outs in the last 24h allows 300 lookups in the same window.

When both are configured, the most restrictive applies. Exceeding either returns 429 dict_lookup_limit_exceeded with the current counter in message.

The 24h cache is now effectively active: repeated lookups of the same key within 24h return immediately with cached: true and do not count toward the limit — the policy is meant to protect DICT against abuse, not penalize repeat queries. Send noCache=true to force a fresh lookup.

Limits are configured in the Backoffice (Policies → DICT Lookup). Tenants without a policy remain unrestricted (unchanged behavior).

v2.19.1 (2026-06-11) - Fix: spurious pix.refund.received webhook on issued refunds

Fixed: when issuing a refund (POST /v1/accounts/{accountId}/pix/out/refund), your webhook endpoint could receive a spurious pix.refund.received event — as if you had received a refund from a third party, when in fact you were the one who issued it.

Corrected behavior:

  • Refund issued by you via the API: you receive only the normal refund flow confirmation (pix.refund.completed / pix.refund.failed). No pix.refund.received is generated.
  • Refund issued outside the API (e.g. settlement provider channels): you receive pix.refund.completed / pix.refund.failed with external: true.
  • Refund received from a third party (counterparty returned a PIX you sent): pix.refund.received continues to be sent normally.

v2.19.0 (2026-06-10) - R$ 15,000 per-transaction PIX limit removed; BigPix deprecated

The R$ 15,000 per-transaction PIX limit has been removed by the settlement provider. POST /v1/accounts/{accountId}/pix/out (and the /async, /bank-account, /qr-code variants) now accept any amount in a single transaction — no need to split into multiple PIX transfers.

As a result, BigPix is deprecated:

  • POST /v1/accounts/{accountId}/pix/out/bigpix
  • POST /v1/accounts/{accountId}/pix/out/bank-account/bigpix
  • GET /v1/accounts/{accountId}/pix/out/bigpix/{batchId}

These endpoints remain functional for backward compatibility, but responses now include the Deprecation: true header. We recommend migrating to POST /pix/out (or /pix/out/bank-account), which has the same request shape — just send the total value in the amount field. The final removal date will be announced in this changelog in advance.

Your account's operational limits (daily, nighttime, per counterparty) still apply — see GET /v1/accounts/{accountId}/limits.

v2.18.3 (2026-06-09) - Webhooks for external internal transfers

Internal transfers between accounts at the same bank (MT Bank) originated outside the API — such as through the mobile app or partner console — now trigger transfer.internal.in (for the receiving account) or transfer.internal.out (for the sending account) webhooks.

This complements existing behavior: internal transfers initiated via POST /v1/accounts/{accountId}/transfers/internal already fired webhooks for both ends. Now, movements you didn't initiate through the API will also notify your webhook endpoint, with the external: true field in the payload indicating the origin was external.

v2.18.2 (2026-06-07) - More precise refund error

PIX refund (POST /v1/accounts/{accountId}/pix/out/refund): when the original transaction cannot be refunded (it is not Confirmed — already refunded/reversed, rejected, or still processing), the rejection now returns errorCode: conflict with the settlement bank's reason in errorReason/message (e.g. Transação com status diferente de 'Confirmado'.).

Previously this case returned errorCode: invalid_payload with the errorReason containing the partner's raw JSON. The code now correctly reflects a state conflict (not an invalid payload) and the reason comes through clean.

Additionally, the statement exact lookup (by endToEndId/identifier on GET /v1/accounts/{accountId}/statement) now queries the settlement bank directly and may include the optional initiation, errorMessage, and fee fields on the item, plus full payer/payee/counterParty.

v2.18.1 (2026-06-07) - Balance is read-only (no balance locking on our side)

Contract clarification: the API does not handle balance locking. GET /v1/accounts/{accountId}/balance only displays the amount blocked by the settlement bank in the locked field (a mirror of MT's block). There is no balance lock/unlock endpoint and no "local hold".

The balance response no longer includes the locks field (list of local locks) — it was never populated and has been removed from the spec. The total, locked, available, currency, and updatedAt fields are unchanged.

v2.18.0 (2026-06-06) - Daily balances, richer counterparty, and new statement filters

New endpoint GET /v1/accounts/{accountId}/daily-balance: returns the account's daily balance series — opening balances (total / blocked / available at the start of each day) plus the consolidated daily flows (PIX in/out, TED in/out, internal transfers, boleto payments, stablecoin mint/burn, and fees). Dates are calendar days in Brasília time (BRT). Maximum window of 30 days. Only closings from 2026-06-04 onward are returned (earlier partner data was unreliable and is omitted; earlier data is omitted) — the response includes cutoffDate and timezone.

Statement (GET /v1/accounts/{accountId}/statement) — new fields (additive, backward-compatible):

  • transactionType: code C (credit/incoming) or D (debit/outgoing), mirroring direction.
  • counterParty now includes the counterparty's bank details when the partner provides them: bankName, bankIspb, bankCode, branch, account, accountType, pixKey (previously only name and document).

Statement — filtering is now 100% server-side:

  • The operation filter (PIX, TED, BOLETO, INTERNAL_TRANSFER) is applied at the partner, with exact totalElements/totalPages. Combine it with order (asc/desc) and startDate/endDate.
  • The status and operation=FEE filters were removed: they only applied to the current page (post-pagination), producing inconsistent counts. The filteredCount response field was also removed. To filter by status or fee, process the returned items on your side.

v2.17.0 (2026-06-05) - identifier length limit raised to 38 characters

The identifier field sent by integrators in PIX out, QR codes (static/dynamic), and internal transfers now accepts up to 38 characters (previously: 32). The allowed charset ([A-Za-z0-9._-]) and the reserved fee- prefix remain unchanged.

This is a fully backward-compatible change: existing identifiers up to 32 characters keep working without any client code change. Only the cap was relaxed.

Why: aligns the per-payment limit with the BigPix base identifier limit (already 38 chars). Integrators using both flows no longer need separate id-generation schemes.

v2.16.0 (2026-06-02) - Legacy statement (pre-cutover)

New endpoint GET /v1/accounts/{accountId}/statement/legacy to query history imported from the previous core (Finaya/Stark), stored in legacy_transactions.

Contract: same shape as GET /v1/accounts/{accountId}/statement (page, size, startDate, endDate, status, operation). Response has source: legacy and header X-Source: legacy. Each item includes ispb (30306294 Finaya, 20018183 Stark) and source: legacy.

No change to the live statement (GET .../statement) — still MT Bank real-time only.

Unified legacy + live bulk view: async CSV export (POST /v1/accounts/{accountId}/exports).

v2.15.0 (2026-05-30) - Statement CSV export restored

Statement CSV export is back on the live MT Bank model plus legacy history (legacy_transactions).

Endpoints:

  • POST /v1/accounts/{accountId}/exports — queue async job (202)
  • GET /v1/accounts/{accountId}/exports — list jobs
  • GET /v1/accounts/{accountId}/exports/{exportId}/download — presigned URL

CSV: statement-aligned columns with an ispb column to tell Finaya/Stark (legacy) from MT Bank (live). No post-transaction balance column. Live fetches are chunked in 31-day windows.

v2.14.0 (2026-05-30) - Bank account details lookup

New endpoint GET /v1/accounts/{accountId}/bank-account to retrieve the bank code (COMPE), branch, and account number for the credentialed account.

Response (200):

  • bankCode, bankIspb, bankName, branch, accountNumber
  • holderDocument, holderName, accountId, status

Useful for deposit instructions or reconciliation without relying on PIX keys. Accounts still in accreditation return 422 with a clear message.

v2.13.0 (2026-05-25) - Richer QR Code decode

POST /v1/accounts/{accountId}/pix/out/qr-code/decode now exposes all the data the partner already returns from the QR capture step — previously most of it lived only in internal logs. The change is fully backward compatible: every existing field is preserved and keeps its name and shape; new fields are additive.

New optional fields (populated when the partner returns them):

  • originalAmount — face value of the QR before discount/interest/ penalty (may differ from amount for dynamic-due-date).
  • qrCodeType (static | dynamic-immediate | dynamic-due-date) and qrCodeTypeId (numeric) — promoted to top level (they used to live inside Extra).
  • allowChange — now actually populated from the partner (AllowPayerChangeValue) on dynamic-immediate. Previously documented but never set.
  • payeeTradeName — fantasy / trade name of a legal entity (typical for dynamic-due-date invoices).
  • bankIspb / bankBranch / bankAccount / accountType — beneficiary bank account details. accountType is canonicalised to CHECKING | SAVINGS | PAYMENT | SALARY (upper snake-case for unknown variants).
  • discount, deduction, interest, penalty — charge components for dynamic-due-date. Relationship: amount = originalAmount - discount - deduction + interest + penalty. Previously only discount was documented (and was always 0).
  • dueDate and paymentDeadline — promoted to top level (they remain inside Extra for backward compatibility).

Compatibility: key, amount, payeeName, payeeDocument, identifier, decodeId, description keep their names and shapes. Existing integrations continue to work unchanged.

v2.12.1 (2026-05-24) - PIX status PENDING_APPROVAL

New canonical status returned by PIX endpoints (GET /v1/accounts/{accountId}/pix/payments/lookup, GET /v1/accounts/{accountId}/payments/{paymentId}, statement, and webhook envelopes):

  • PENDING_APPROVAL — the partner accepted the PIX OUT request but is holding it for internal approval (multi-step authorisation, 2FA, anti-fraud review). There is no endToEndId yet, and funds have not moved. At some point the partner will release (transition to PENDINGCOMPLETED) or reject (transition to FAILED).

Why the new status: previously, this scenario leaked the partner's raw value (AWAITING-AUTHORIZATION) through the public API. Starting this release, we never propagate raw partner values — every status is canonicalised. Anything outside the known vocabulary maps to UNKNOWN plus a structured warning on our side so we add the mapping in the next release.

No impact for ordinary PIX OUT integrations (typical flow still goes PROCESSINGCOMPLETED/FAILED). Integrations that monitor intermediate states must treat PENDING_APPROVAL as non-terminal (keep polling or wait for the next webhook).

pix.out.completed / pix.out.failed webhooks still only fire on terminal statesPENDING_APPROVAL does not trigger an outbound webhook.

v2.12.0 (2026-05-23) - TED available (send + receive)

Major release: TED (Transferência Eletrônica Disponível BACEN) is now a public API product. Covers interbank send, async status query, and receiving webhooks. Settlement bank: MT Instituição de Pagamentos (Compe 681 / ISPB 50871921). See the TED guide.

New endpoints

  • POST /v1/accounts/{accountId}/ted/out — sends TED (async, 202)
  • GET /v1/accounts/{accountId}/transfers/ted/{tedId} — query status (PROCESSINGCOMPLETED | FAILED)

New webhooks

  • ted.out.requested — TED registered at the settlement bank (initial status)
  • ted.out.confirmed — settlement confirmed (terminal — success)
  • ted.out.failed — rejection/expiration/48h timeout (terminal — failure)
  • ted.in.received — TED received in your account

Window and timing

  • Business days 06:30–17:00 → settlement same business day (~30min after send)
  • Outside the window → scheduled for D+1; status stays PROCESSING until settled
  • Server runs defensive polling every 1 minute for up to 48 hours — guarantees convergence even if settlement bank webhook fails

Deprecation

ted.payment (v1 legacy catalog) becomes a deprecated alias of ted.out.confirmed. Both are dispatched together during v2.x lifecycle; ted.payment will be removed in v3.0 (date TBA).

  • New integrators: subscribe only to ted.out.confirmed
  • Legacy integrators: can keep ted.payment until v3.0; migration is unsubscribe + subscribe to ted.out.confirmed (identical payloads)

v2.11.1 (2026-05-22) - Fix: duplicate webhooks for tenants with multiple subscriptions

Bug fix that directly affects integrators with more than one active subscription for the same eventType within the same tenant.

Previously, each matching subscription generated a separate POST to egress (Hookdeck). Because the Hookdeck filter matches tenantId + type in the body, every one of those POSTs got delivered to ALL destinations, multiplying deliveries: a tenant with N subscriptions to the same event received N² deliveries instead of N.

Starting from this release, every event generates one single POST to egress; Hookdeck fans it out to the N destinations (1 delivery per subscription, no duplication).

No payload or contract change — only the delivery count is fixed. Client-side dedup by envelope id (good practice) is still safe.

v2.11.0 (2026-05-22) - Webhook envelope back to the v1 shape

The egress webhook payload (delivered to the URL registered via POST /v1/webhooks) is back to the same envelope documented in v1. Customers that migrated from v1 → v2 without changing their webhook parser now receive the fields exactly where they used to expect them.

Envelope (all events):

FieldBefore (v2.10)Now (v2.11)
schemaVersionmissing"1.0"
environmentmissing"production" | "sandbox"
accountId (root)only inside data.accountIdadded at root (still in data.accountId)
tenantId (root)already presentkept

data field changes per event (to match v1):

  • pix.in.completed: endToEndId renamed to endToEnd; added receivedAt.
  • pix.out.completed / pix.out.failed: status is now "SUCCESS" / "FAILED" (used to be "COMPLETED"); added key: { type, key } when the PIX was by key; added completedAt; added error alias for errorReason on failures.
  • pix.refund.received: refundEndToEndIdrefundEndToEnd; originalEndToEndIdoriginalEndToEnd; added receivedAt.
  • qrcode.paid: endToEndIdendToEnd; paidAmountamount; payerName/payerDocument grouped into payer: { name, document }; added qrcodeId (= txid), type (static | dynamic), receivedAt, status: "SUCCESS".
  • qrcode.cancelled: added status: "CANCELLED" and type.
  • qrcode.expired: added status: "EXPIRED" and type.
  • pix.med.opened / pix.med.updated: names fixed to pix.med.* (the backend was emitting med.opened / med.decided, which were not in the public catalog — effectively integrators never received these events). originalEndToEndIdoriginalEndToEnd; added status (OPEN | PENDING_DECISION | ACCEPTED | REJECTED | CANCELED).
  • transfer.internal.in / transfer.internal.out: endToEndIdendToEnd.
  • boleto.paid / boleto.failed: status is now "SUCCESS" / "FAILED"; added error alias on failures.

Removed: the currency field is no longer emitted nor documented — all monetary values are in BRL by contract and use the dot decimal separator (150.50). The currency column never reached production in v2 for most events; this closes the last gap.

Compatibility

No aliases are emitted for the old names. If you used data.endToEndId on PIX in or data.paidAmount on QR paid, you must rename to data.endToEnd and data.amount. See the up-to-date examples in Webhooks.

v2.10.0 (2026-05-22) - Refund reason aligned with partner bank

POST /v1/accounts/{accountId}/pix/out/refund (and POST /pix/out with mode=REFUND) now accepts a closed set of kebab-case slugs on the reason field. The legacy values (USER_REQUESTED, FRAUD, BANK_ERROR, CASHIER_ERROR, CUSTOMER_REQUEST) are no longer accepted — payloads using those values receive HTTP 400 with a clear message listing the valid slugs.

Accepted slugs are forwarded verbatim to the partner bank (MT Bank), with no translation:

SlugWhen to use
user-requestedEnd customer requested the refund
transaction-errorGeneric transaction error
unauthorized-transactionTransaction not authorized
fraudConfirmed/suspected fraud
trade-disagreementCommercial dispute
withdrawal-purchasePIX Saque/Troco
contractual-divergenceContractual disagreement
operational-errorOperational/processing error
duplicate-paymentDuplicate payment

Why this change: the v2 refund endpoint was returning HTTP 422 on every request because the legacy vocabulary did not match what the partner bank accepts. This version aligns public API and partner 1:1, avoiding opaque mappings.

v2.9.0 (2026-05-21) - Counterparty document on statement

Statement items (GET /v1/accounts/{accountId}/statement) now include the counterparty document (CPF/CNPJ) in addition to the name:

  • recipientName: counterparty name (already existed).
  • recipientDocument: new field — CPF (11 digits) or CNPJ (14 digits), unmasked (digits-only).
  • counterParty: new object aggregating { name, document }. Omitted when both fields are empty.

For transactions with direction: "IN", the counterparty is the payer; for direction: "OUT", the recipient. All fields are backward-compatible — integrators that don't need the document don't have to change anything.

v2.0 (2026-05-21) - New CorpX platform

v2 is a full rewrite of the platform on faster, more predictable infrastructure, with direct integration to the new settlement bank. Mostly backward compatible with v1.

Migration guide

Everything you need to migrate in one place:

Auth

  • New base URL: https://tenant.api.corpx.com/v1 (was https://api.corpxapi.com/v1)
  • New Token URL: https://auth.api.corpx.com/oauth2/token
  • New client_id + client_secret per integrator (delivered via secure channel)
  • Scopes: api/fullapi2/read api2/write
  • Idempotency-Key is now optional (auto-generated if missing)
  • X-Tenant-Id is required on all /v1/* requests (except GET /v1/me and health); must match the account tenant when accountId is in the path

Statement consolidated into a single endpoint

  • GET /v1/accounts/{accountId}/statement is now always live — queries the settlement bank in real time (no local cache).
  • Derived endpoints that used to read from the same cache (/pix/transactions, /pix/payments, /payments alias) are also live now.
  • The previous v1 API and backoffice remain online in read-only mode for 30 days after cutover for historical lookup.
  • /transactions/real-statement, /transactions/legacy-statement and /payments/{id}/legacy do not exist on v2 — use /statement (current data) or the v1 read-only API (history).

Deprecated endpoints (still work until 2026-11-21)

4 paths that existed on v1 and weren't kept in the canonical v2 shape come back as deprecated aliases. They keep responding normally, but attach 3 warning headers to the response:

Deprecation: true
Sunset: Sat, 21 Nov 2026 00:00:00 GMT
Link: </v1/accounts/.../new-path>; rel="successor-version"

These headers follow RFC 8594 (Deprecation) and RFC 9745 (Sunset). Planned sunset: 2026-11-21 — after that date they start returning 410 Gone. They no longer appear in the OpenAPI or the Postman collection.

  • GET /v1/accounts/{id}/pix/payments/{paymentId} → use /pix/payments/lookup?identifier=
  • GET /v1/accounts/{id}/payments/{paymentId} (alias without /pix/) → use /pix/payments/lookup?identifier=
  • GET /v1/accounts/{id}/pix/qr-code (no /lookup) → use /pix/qr-code/lookup?identifier=
  • POST /v1/accounts/{id}/pix/out/qrcode (no hyphen) → use /pix/out/qr-code

Removed endpoints (return 404 on v2)

  • POST /v1/webhooks/replay → no replacement
  • GET /v1/integrator/webhooks → use GET /v1/webhooks
  • GET /v1/integrator/webhooks/{id}/deliveries → no replacement
  • POST /v1/integrator/events/replay + /batch → no replacement
  • POST .../pix/med/{medId}/send + /response → use /decide + /answer

GET /v1/health still exists on v2 (and now has an additional GET /health alias for external health checks).

New endpoints

  • GET /v1/me (debug for the authenticated client_id)
  • GET /v1/transactions/{id}/timeline (no accountId in the path)
  • GET /v1/accounts/{id}/pix/out/bigpix/{batchId} (aggregated BigPix batch status)
  • GET /health (alias for /v1/health without the prefix)
  • Boleto family (POST .../boleto/preview|pay, GET .../boleto/payments/{id}) — was 503 on v1, now active

Behavior changes (same path, new shape or semantics)

  • Statement and derived endpoints: cache → live; no derived tariff_ref; X-Source: live header; max window per query 31 days.
  • Internal transfer by-bank-account: accepts optional holderDocument + holderName (non-breaking).
  • Locked balance unlock: v2 only validates lockId; extra fields are ignored (non-breaking).
  • fee field on the transaction object removed temporarily — manual reconciliation via identifier=fee-{slug}-{operationReferenceId} in the statement. Returns with no payload change in a future release.

MED and webhooks temporarily suspended

  • /v1/accounts/{id}/pix/med/* endpoints return HTTP 503 during the migration. Open disputes follow BACEN's natural lifecycle — only the API integration is paused.
  • Suspended webhooks: fee.*, pix.med.*, edi.*. Subscriptions to these events can stay active — once they're back they resume automatically. Fees still show up in the statement as separate lines (with identifier=fee-{slug}-{ref}).

Compat (no change to your code)

  • BigPix (POST .../pix/out/bigpix and .../bank-account/bigpix): body stays single ({amount, key, ...}); chunking remains server-side, same as v1.
  • PIX out variants (/pix/out/async, /bank-account/async, /bank-account/bigpix): preserved.
  • /v1/accounts/{accountId}/transfers/internal (all 3 modes): path and body preserved.
  • /v1/accounts/{id}/pix/qr-code/static body: value stays as on v1.
  • /v1/accounts/{id}/pix/out/qr-code/decode: path preserved.
  • /v1/accounts/{id}/pix/keys (GET + POST + DELETE): kept.
  • /v1/accounts/{id}/pix/key/{pixKey} (DICT lookup): kept.

Support

Contact: suporte-api@corpx.com during the tenant cutover — reply within 1h in business hours.


v1.30.3 (2026-04-30) - Duplicate webhooks removed (pix.refund.completed, pix.out.failed, qrcode.paid)

Fixes

  • Duplicate webhooks eliminated: in some scenarios the platform emitted two webhooks for the same event — one following the documented format and a second one with a legacy format that was never described in the documentation. The behavior is now corrected: each event generates exactly one notification, always in the documented format.

    Events affected:

    • pix.refund.completed (sent when a PIX refund completes)
    • pix.out.failed (sent when an outbound PIX fails)
    • qrcode.paid (sent when a QR code is paid)

    The legacy format was never present in docs/webhooks — it was a parallel emission from an internal routine that escaped the documentation. Integrations that relied only on documented fields will not notice any difference besides the absence of the duplicate notification.

  • data.status field in pix.refund.completed now always returns SUCCESS, aligned with the official status vocabulary. Previously, in some cases it leaked REFUNDED (the status of the original PIX transaction).

Fields and formats that disappear (only for integrations coupled to the undocumented legacy format)

Legacy field / formatReplaced by (documented format)
id: refund_completed_{paymentId}_{ts}id as a sha256-hash string
id: pix_out_failed_{paymentId}_{ts}id as a sha256-hash string
id: qr_paid_{txid}_{ts}id as a sha256-hash string
data.status: COMPLETED (on pix.refund.completed)data.status: SUCCESS
data.status: REFUNDED (on pix.refund.completed)data.status: SUCCESS
data.refundId (on pix.refund.completed)use data.transactionId (already documented)
data.failedAt (on pix.out.failed)use occurredAt from the envelope
data.paymentId (on pix.out.failed)use data.transactionId (already documented)
payer.account / payee.accountpayer.accountNumber / payee.accountNumber

If your integration consumed any of these legacy-only fields, update it to use the documented fields before adopting this version.

Always deduplicate webhooks on your side using a strong key from the payload:

  • For pix.refund.completed: data.refundEndToEnd (BACEN D-code, globally unique).
  • For pix.out.failed: data.endToEnd (BACEN E-code) or data.identifier.
  • For qrcode.paid: data.endToEnd or data.qrcodeId.

These fields are unique per transaction and present on every event.


v1.30.2 (2026-04-30) - Webhook timestamps standardized to UTC

Fixes

  • Date fields inside data are now always in UTC with the Z suffix across every webhook. Previously some fields (receivedAt, completedAt, initiatedAt, chargedAt, openedAt) were forwarded without a timezone indicator, which led strict ISO 8601 parsers to interpret them as the consumer's local time — producing up to 3-hour drifts on BRT machines.
  • Standard consolidated and documented at Webhooks → Date and time format.
  • Documentation already showed Z (UTC) in all examples; now every emitted payload matches the standard.

v1.30.1 (2026-04-29) - qrcode.paid webhook kept (not deprecated)

Deprecation reverted

  • qrcode.paid remains officially supported. The deprecation notices that appeared in the Webhooks Guide (in PT, EN and ZH) were removed. The event is still valid and stable; no migration is required.
  • The equivalent event pix.in.completed with method: QR_CODE_DYNAMIC or QR_CODE_STATIC remains available as an alternative (and continues to be dispatched in parallel) — pick whichever best fits your integration.

v1.30.0 (2026-04-23) - Internal transfers: error mapping + identifier in webhook

Fixes

  • Banking partner account_disabled (TX00012) error mapping: when the source account is disabled at the banking partner, the API now returns HTTP 422 with errorCode: partner_account_disabled. Previously this case was mapped to HTTP 502 (Bad Gateway), misleading integrators into treating it as infrastructure failure rather than a business rule. The change applies to all three internal transfer endpoints (/transfers/internal, /transfers/internal/by-document, /transfers/internal/by-bank-account).
  • Unified banking partner error classification: HTTP errors from the core banking service (used for internal transfers and account lookups) now go through the same classifier already used by the other endpoints. Specific codes such as insufficient_balance, daily_limit_exceeded, account_disabled now return 422 instead of 502.

Improvements

  • identifier and description now returned in the transfer.internal.out webhook: the integrator-supplied identifier and description from the original POST /transfers/internal* request are now propagated to the webhook sent to the payer account, allowing reconciliation without consulting the statement.
  • Custom payer description replaces the default Transferência Interna text in the statement (GET /statement) when provided in the request.
  • coreId now included in every ledger-entry webhook: the UUID of the banking partner's core ledger line (same value returned in the statement's coreId field) is now propagated in pix.in.completed, pix.out.completed, pix.out.failed, pix.refund.*, qrcode.paid, transfer.internal.*, fee.charged and fee.refunded. Allows reconciliation across webhook ↔ statement ↔ partner exports through a single stable key.
  • Standardized status across every ledger-entry webhook: data.status is now guaranteed on all PIX, QR, internal transfer, refund and fee events. Standardized vocabulary: SUCCESS (operation completed), FAILED (operation failed, with data.error), REVERSED (previously completed entry was reversed). MED events (pix.med.*) keep their own vocabulary (OPEN, PENDING_DECISION, ACCEPTED, REJECTED, CANCELED). Full table in docs/webhooks.

New errorCode values

CodeHTTPMeaning
partner_account_disabled422The source account is disabled at the banking partner (reactivation required)

v1.29.0 (2026-04-18) - Lookup internal transfer recipient by document

New Features

  • Recipient preview for internal transfers: New endpoint GET /v1/accounts/{accountId}/transfers/internal/lookup/{document} lets you preview the holder name before executing an internal transfer by CPF/CNPJ. Useful for showing a confirmation step to the end user.
  • The name is returned with a privacy mask: the first name is kept in full; remaining surnames are reduced to their first letter followed by ***. Connectors like "de", "da", "dos" are preserved.
    • Example: "JOAO DA SILVA PEREIRA""JOAO da S*** P***"
  • The endpoint also returns the accountStatus at the banking partner.
  1. User enters the recipient's CPF/CNPJ
  2. Integrator calls GET /transfers/internal/lookup/{document} and shows maskedName for confirmation
  3. User confirms
  4. Integrator calls POST /transfers/internal/by-document to execute the transfer

v1.28.0 (2026-04-17) - Deprecated webhooks removed

Breaking Changes

  • payment.sent and payment.refunded webhooks disabled: These events were deprecated in v1.15.0 (2026-02-20) and have now been permanently disabled.
    • payment.sent → use pix.out.completed (includes method field and payment object)
    • payment.refunded → use pix.refund.completed (includes originalEndToEnd, refundEndToEnd and party details)
  • If your integration still subscribes to these events, migrate immediately to the replacements listed above.

v1.27.0 (2026-04-14) - PIX Out by bank account

New Features

  • PIX Out by bank account: New endpoints to send PIX transfers using the recipient's bank details (ISPB, branch, account number) instead of a PIX key:
    • POST /v1/accounts/{accountId}/pix/out/bank-account — Synchronous transfer by bank account.
    • POST /v1/accounts/{accountId}/pix/out/bank-account/async — Asynchronous (queued) transfer.
    • POST /v1/accounts/{accountId}/pix/out/bank-account/bigpix — Large transfer with automatic chunking.
  • Required fields: bankIspb (bank ISPB code), accountNumber, accountBranch, documentNumber (recipient CPF/CNPJ), and name.
  • The accountType field accepts CHECKING_ACCOUNT, SAVINGS_ACCOUNT, or PAYMENT (default: CHECKING_ACCOUNT).

Notes

  • Webhooks, fees, and reconciliation are the same as PIX Out by key — transactions appear as PIX_OUT in the statement.
  • The async endpoint uses the same FIFO queue as PIX Out by key — same ordering and idempotency guarantees.
  • BigPix works the same: splits into R$ 15,000 chunks (configurable via policy), fee charged once per operation.

v1.26.1 (2026-04-13) - Stability fixes

Bug Fixes

  • Static QR Code: Fixed an issue where the amount encoded in the static QR code could differ from the requested value in some scenarios.
  • Webhook pix.in.completed: Fixed a scenario where the identifier field was missing from the webhook payload for QR code payments, even when the identifier was available.

v1.26.0 (2026-04-09) - Boleto payment

New Features

  • Boleto payment: New endpoints to look up and pay bank slips, utility bills, and taxes:
    • POST /v1/accounts/{accountId}/boleto/preview — Look up boleto data by barcode or "linha digitável". Returns beneficiary, bank, original amount, interest, fine, discount, and total updated amount.
    • POST /v1/accounts/{accountId}/boleto/pay — Submit boleto payment. Returns paymentId with status PROCESSING.
    • GET /v1/accounts/{accountId}/boleto/payments/{paymentId} — Check boleto payment status. Status progresses from PROCESSING to COMPLETED or FAILED.
  • New transaction type BOLETO_PAYMENT: Boleto payments appear in the statement as outgoing transactions (direction: OUT, transactionType: BOLETO_PAYMENT).
  • Feature flag boleto_payment: The functionality is controlled by a feature flag in tenant_configs. Must be enabled by admin for each tenant that wants to use it.

Notes

  • Bank slips (47 digits), utility bills (48 digits), and taxes are automatically classified by type (boleto, utility, tax).
  • Payment is asynchronous — after POST /boleto/pay, the integrator should poll GET /boleto/payments/{paymentId} to track status.
  • Boleto cancellation and scheduled payments will be implemented in a future version.

v1.25.1 (2026-04-02) - Origin transaction reference in fee.charged and refund improvements

Improvements

  • Enriched fee.charged webhook: The payload now includes originTransactionType (type of the transaction that triggered the fee, e.g. PIX_IN, PIX_OUT) and originTransactionRef (E2E ID of the original transaction). Also includes the full description with calculation details.
  • pix.in.completed webhook with identifier for dynamic QR codes: Fixed a scenario where the QR code identifier was not included in the webhook when the payment confirmation arrived before the charge notification.
  • More resilient refunds: Fixed a scenario where the refund was successfully processed by the banking partner but the API returned a temporary error. The API now detects the confirmation via webhook and returns the D-code correctly.

v1.25.0 (2026-03-26) - payerDescription field, fee webhooks, and refund fixes

New Features

  • payerDescription field in statement and webhooks: The GET /v1/accounts/{accountId}/statement endpoint and the pix.in.completed, pix.out.completed, qrcode.paid, and transfer.internal.* webhooks now return an optional payerDescription field. It contains the message the payer typed when sending the PIX (when available). The description field continues with the standardized descriptive format ("PIX Received - Payer Name").
  • fee.charged and fee.refunded webhooks: Banking fees now generate fee.charged (when charged) and fee.refunded (when reversed) webhooks. To receive them, add these event types to your webhook subscription.

Improvements

  • Richer PIX IN webhooks: pix.in.completed webhooks now always contain complete data: reconciliationId, payerDescription, payer details, and PIX key info. Previously, in some scenarios the webhook could arrive with partial data.

Bug Fixes

  • Refund webhooks (PIX refund): Fixed a scenario where the pix.refund.completed webhook was not delivered to the integrator when the refund confirmation arrived shortly after creation.
  • PIX webhooks for internal transfers (CORPX-CORPX): Fixed the event type for transfers between CORPX accounts. Previously, the recipient could receive pix.out.completed instead of pix.in.completed.
  • reconciliationId in static QR codes: Fixed a scenario where reconciliationId was not included in the pix.in.completed webhook for static QR code payments.
  • Statement status filter: Fixed the status filter on the statement endpoint that in some scenarios did not return results correctly.

v1.24.1 (2026-03-18) - Error semantics improvements (generic 502 reduction)

Improvements

  • We standardized partner-originated errors to semantic HTTP statuses across pix/keys, pix/key/{pixKey} (DICT), pix/limits, pix/out/qr-code, pix/out/qr-code/decode, pix/med, transfers/internal, accreditations, and accounts/{accountId}/balance.
  • Error payload format remains stable: { "errorCode": "...", "message": "..." }.
  • OpenAPI and Postman were updated to reflect the new error formats/statuses.

Changed error mapping (from -> to)

Error / scenarioBeforeNow
Sync Pix Out timeout (POST /pix/out)504 Gateway Timeout207 Multi-Status (partner_timeout)
pix_key_not_found in sync Pix Out (POST /pix/out)502 Bad Gateway422 Unprocessable Entity
Generic partner_error for business/validation failures (PIX/Transfers/MED/Accreditations)502 Bad Gateway422 Unprocessable Entity
pix_key_lookup_failed (classified DICT/partner failure)502 Bad Gateway422 Unprocessable Entity
partner_auth_failed / partner_signature_rejected502 Bad Gateway503 Service Unavailable
partner_internal_error / partner_recipient_unavailable502 Bad Gateway503 Service Unavailable
partner_timeout (upstream timeout endpoints)502 Bad Gateway504 Gateway Timeout
account_not_found from partner-integrated flows502 Bad Gateway404 Not Found
pix_key_not_found in DICT lookup (GET /pix/key/{pixKey})502 Bad Gateway404 Not Found
Unclassified fallback502 Bad Gateway502 Bad Gateway (kept as fallback)

v1.24.0 (2026-03-18) - Sync Pix Out: per-account rate limit and timeout 207

Breaking Changes

  • Sync Pix Out timeout status changed: POST /v1/accounts/{accountId}/pix/out now returns HTTP 207 (partner_timeout) on partner timeout, instead of HTTP 504.
  • Expected handling remains the same: the transfer may have been executed, so check statement/payment status before retrying.

Improvements

  • Per-account rate limit for sync Pix Out: a per-account limit is now enforced (current default 100 req/min, customizable by policy).
  • Next days: the default for synchronous requests will be adjusted to 10 req/min.
  • When exceeded, API returns 429 rate_limit_exceeded with contextual fields (currentRateLimit, scope) and guidance to use async flow.
  • New async cashout endpoint: POST /v1/accounts/{accountId}/pix/out/async schedules payment processing and returns immediate 202 with a paymentId for tracking.
  • BigPix is now async-only: POST /v1/accounts/{accountId}/pix/out/bigpix now schedules processing through the async flow (same behavior as /async) and no longer executes synchronously.

v1.23.0 (2026-03-17) - PIX QR Code Decode

New features

  • PIX QR Code decode/consult: New endpoint POST /v1/accounts/{accountId}/pix/out/qr-code/decode decodes a PIX QR Code EMV string and returns the beneficiary details without executing payment. Returns: name, document, amount, PIX key, bank and account type of the recipient. Useful for displaying a confirmation screen to the user before paying.

v1.22.0 (2026-03-07) - Internal transfer by document and by bank account

New features

  • Internal transfer by document (CPF/CNPJ): New endpoint POST /v1/accounts/{accountId}/transfers/internal/by-document allows creating internal transfers by identifying the destination account via the holder's CPF or CNPJ. Works for any account in the banking ecosystem, not just accounts registered in the API. Required fields: document, value, description.

  • Internal transfer by bank account: New endpoint POST /v1/accounts/{accountId}/transfers/internal/by-bank-account allows creating internal transfers by identifying the destination account via branch and account number (branch + accountNumber). Only works for accounts registered in the API (same tenant). To transfer to external accounts, use the /by-document endpoint.


v1.20.0 (2026-03-01) - Account ownership validation

Improvements

  • Strengthened account ownership validation: The API now verifies that the accountId in the request belongs to the authenticated tenant. Integrators accessing only their own accounts are not affected. This improvement enhances security against unauthorized cross-account access.

v1.19.1 (2026-02-26) - BigPix improvement

Improvements

  • BigPix (POST /v1/accounts/{accountId}/pix/out/bigpix): improved chunk processing robustness for better consistency under high-volume scenarios.

v1.19.0 (2026-02-26) - Transaction timeline

New features

  • Transaction timeline: New endpoint GET /v1/accounts/{accountId}/transactions/timeline returns the timeline of events for a single transaction (by endToEndId or identifier). Includes: BACEN confirmations (short summary text), webhooks sent to the client (with full payload for "View full payload"), fees, refunds, and QR Code lifecycle when applicable. Exactly one query parameter is required: endToEndId or identifier. No changes to existing endpoints or response formats.

v1.18.0 (2026-02-24) - Performance optimizations and independent fee transactions

Improvements

  • Fees as independent transactions: Fees charged by the API now appear as separate lines in the statement, linked to the original transaction. QR Code and payment lookups now include fee details (fees, totalFees).
  • Performance optimizations: Parallel batch processing for reconciliation, support for higher transaction volumes.
  • Automatic fee retry: The self-healing process now includes retry of fees that failed on initial charge.

Bug Fixes

  • Fixed MED dispute rate calculation that was double-counting transactions and disputes.
  • Fixed fee charging that could silently fail under high concurrency.

v1.17.0 (2026-02-22) - Automatic reconciliation and transaction status fix

Improvements

  • Automatic reconciliation (Self-Healing): Expired QR Codes are now automatically marked as expired. Paid QR Codes and pending payments are periodically reconciled with the statement, ensuring consistency even during transient communication failures.
  • Transaction status fix: PIX transactions that have reached a terminal status (SUCCESS, FAILED, REVERSED) can no longer be overwritten by delayed webhooks, eliminating rare cases where a completed transaction could temporarily appear as pending.

v1.16.2 (2026-02-21) - Enriched QR Code and Payment lookups

Improvements

  • QR Code lookup (GET /v1/accounts/{accountId}/pix/qr-code/lookup) and Payment lookup (GET /v1/accounts/{accountId}/pix/payments/lookup, GET /v1/accounts/{accountId}/pix/payments/{paymentId}) now return an enriched transaction object when the transaction is reconciled.
  • The transaction object includes: detailed status, full payer/payee info, balance after transaction, fee details, dispute (MED) info, policy violations, refund references, and error reason (when applicable).

v1.16.1 (2026-02-21) - Partner response fixes

Bug Fixes

  • Fixed HTTP 502 error when deleting a PIX key (DELETE /v1/accounts/{accountId}/pix/keys/{pixKey}). The operation completed successfully, but the API incorrectly returned an error response.
  • Fixed HTTP 502 error when requesting a refund (POST /v1/accounts/{accountId}/pix/refund). The refund was processed successfully, but the API incorrectly returned an error response.
  • General improvements to partner response handling for all PIX operations.

v1.16.0 (2026-02-20) - Lookup Endpoints and Payment Pagination

New Features

  • New GET /v1/accounts/{accountId}/pix/qr-code/lookup for QR Code search by ?identifier=X, ?qrcodeId=X, or ?endToEndId=X.
  • New GET /v1/accounts/{accountId}/pix/payments/lookup for Payment search by ?paymentId=X, ?identifier=X, or ?endToEndId=X.
  • Only one parameter allowed at a time.

Payment List Pagination

  • GET /v1/accounts/{accountId}/payments now supports ?page=0&size=50.
  • Response includes: totalElements, totalPages, page, size, hasNext, hasPrevious.

QR Code List Pagination

  • GET /v1/accounts/{accountId}/pix/qr-codes now supports ?page=0&size=50&status=PAID.
  • Response includes: totalElements, totalPages, page, size, hasNext, hasPrevious.

Route Standardization

  • New alias POST /v1/accounts/{accountId}/pix/out/qr-code (hyphenated, recommended).

Deprecated

  • GET /v1/accounts/{accountId}/payments → use /v1/accounts/{accountId}/pix/payments
  • GET /v1/accounts/{accountId}/payments/{paymentId} → use /v1/accounts/{accountId}/pix/payments/{paymentId}
  • POST /v1/accounts/{accountId}/pix/out/qrcode (no hyphen) → use /pix/out/qr-code
  • Old routes still work but will be removed in a future version.

v1.15.0 (2026-02-20) - Webhook method field and refund reconciliation

New Features

method field in PIX webhooks

  • pix.in.completed, pix.out.completed and pix.out.failed webhooks now include a method field indicating how the transfer was made.
  • PIX IN: PIX_KEY, QR_CODE_STATIC, QR_CODE_DYNAMIC, REFUND_RECEIVED
  • PIX OUT: PAYMENT, REFUND_PIX_KEY, REFUND_QR_STATIC, REFUND_QR_DYNAMIC

Contextual objects in webhooks

  • PIX IN via QR Code includes qrCode object with txid, identifier, type, value.
  • PIX OUT via API includes payment object with paymentId, identifier, reconciled.

Refund reconciliation with QR Codes

  • Refunds of PIX received via QR Code now update the QR Code record with refund details.
  • QR Code query endpoint returns full refund history in refunds[].

Deprecated

  • qrcode.paid: use pix.in.completed with method: QR_CODE_* instead.
  • payment.sent: use pix.out.completed with method: PAYMENT instead.
  • payment.refunded: use pix.out.completed with method: REFUND_* instead.

v1.14.0 (2026-01-16) - BigPix: High-value transfers

New Features

BigPix Endpoint (POST /v1/accounts/{accountId}/pix/out/bigpix)

  • New endpoint for PIX transfers above the individual limit (R$15,000 by default).
  • Automatically splits the amount into multiple smaller transfers, executed in parallel.
  • Each chunk includes identification in the format PIX X/Y - Total R$... - message [id].
  • If identifier is provided, each chunk receives identifier__X/Y.
  • Consolidated response with status FULL (all ok), PARTIAL (some failed) or FAILED (none executed).
  • Includes retry count per chunk and individual details (E2E ID, status, error).
  • Chunk size configurable per tenant via pixOut.chunkSize policy.

v1.13.2 (2026-01-16) - Webhook delivery improvements

Improvements

  • New webhook subscriptions now have redundant headers removed before delivery to the recipient.

v1.13.1 (2026-02-19) - Remove qrCodeFormat and Payment Approval Flow

Breaking Changes

qrCodeFormat field removed from QR Code endpoints

  • The qrCodeFormat field has been removed from dynamic and static QR Code creation endpoints.
  • The API now always returns QR Codes in EMV format (copy-and-paste). IMAGE format is no longer supported.
  • Requests that still send qrCodeFormat will not receive an error, but the field will be ignored.

New Features

Payment Approval Flow

  • When the requireApprovalAbove policy is configured, PIX Out payments above the threshold now create a payment intent with status PENDING_APPROVAL.
  • Administrators can approve or reject pending payments from the admin panel.
  • On approval, the payment is automatically executed. On rejection, the reason is recorded.

v1.13.0 (2026-02-18) - Disputes (MED), Policy Enforcement and Contestation

New Features

Dispute Management (MED)

  • New MED dispute management system with automatic reconciliation of MEDs with transactions via E2E ID.
  • MED data (status, deadline, claimant, reason) now appears linked to the transaction in the statement.
  • MED rate monitoring: daily statistics of MED/PIX-In ratio per tenant.
  • New endpoints:
    • GET /v1/backoffice/tenants/{tenantId}/med-stats - Daily MED statistics.
    • POST /v1/accounts/{accountId}/pix/med/{medId}/answer - MED contestation with response and evidence.
    • POST /v1/accounts/{accountId}/pix/med/{medId}/evidence/upload-url - Evidence file upload.

PIX In Policy Enforcement

  • PIX In rules are now enforced in real-time (previously only logged violations).
  • AUTO_REFUND action now initiates automatic refund of the violating transaction.
  • Policy violations appear in the statement with rule details, action, and message.

New Policy Rules

  • PIX In: Bank code blacklist, same ownership restriction.
  • PIX Out: Whitelist is now evaluated before blacklist (whitelist overrides all other rules).
  • MED: Auto-block balance for MEDs above a threshold, MED/PIX-In rate limit with configurable actions.

Improvements

  • Documentation: new Policies and Rules guide with all rules and evaluation order.
  • Documentation: new Disputes (MED) guide with lifecycle, contestation, and monitoring.

v1.12.1 (2026-02-18) - Required Refund Reason and Pagination Fix

New Features

  • New endpoint GET /v1/accounts/{accountId}/pix/key/{pixKey} for DICT key lookup with 24h cache and configurable rate limiting.

Breaking Changes

reason field now required on refund endpoint

  • The POST /v1/accounts/{accountId}/pix/out/refund endpoint now requires the reason field with one of: USER_REQUESTED, FRAUD, BANK_ERROR, CASHIER_ERROR, CUSTOMER_REQUEST.
  • Requests without reason or with invalid values will return HTTP 400.

Improvements

  • X-API-Version header included in all API responses for version debugging.

Fixes

  • Fixed: statement pagination returned blank pages after page 10 (more than 1000 transactions).

v1.12.0 (2026-02-18) - Policy Engine

New Features

Policy Engine

  • New configurable policy system per tenant and per account, with hierarchy (default -> tenant -> account).
  • Available rules:
    • PIX Out: per-transaction limits, night limits, allowed person types (PF/PJ), CPF/CNPJ whitelist/blacklist, operating hours.
    • PIX In: amount limits, auto-quarantine, configurable violation actions.
    • QR Code: type-specific permissions (dynamic/static), amount limits.
    • PIX Keys: max keys per account.
    • Refund: enable/disable and amount limits.
    • Operating Hours: time window restrictions with overnight support.

v1.11.1 (2026-02-15) - Statement Fixes

Fixes

  • Fixed: statement pagination (GET /v1/accounts/{accountId}/statement) was not working correctly. page and size parameters now return the requested page.
  • Fixed: standardized statement descriptions (e.g., "Transferência Pix", "Devolução Pix", "Tarifa Bancária", "Pagamento de QR Code").
  • Fixed: statement ordering when fees and transactions occurred at the same time.

v1.11.0 (2026-02-15) - Banking Fees in Statement and fee.charged Webhook

New Features

Fees in Statement

  • Banking fees charged per transaction now appear in the statement (GET /v1/accounts/{accountId}/statement) with type FEE.
  • Each fee entry includes a feeServiceType field indicating which operation triggered the charge (e.g., PIX_OUT, PIX_IN).

fee.charged Webhook Event

  • New event type available for subscription: fee.charged.
  • Sent in real-time when a banking fee is charged to the account.
  • Payload includes: amount, currency, feeServiceType, description, chargedAt.

v1.10.0 (2026-02-13) - Reconciliation ID, PIX Reversal Support

New Features

Reconciliation ID

  • All webhooks sent to integrators (qrcode.paid, pix.in.completed, pix.out.completed, pix.out.failed, pix.refund.completed, pix.refund.failed) now include a reconciliationId field when available.
  • The reconciliationId field is also returned in the statement endpoint (GET /v1/accounts/{accountId}/statement), enabling cross-referencing with bank statements.

PIX Reversal Support

  • The API now processes PIX reversals initiated by the recipient. When a PIX Out recipient returns the funds, the transaction is automatically recorded in the statement and linked to the original payment.
  • The original payment status is updated to REFUNDED when the full amount is returned.

Fixes

  • Fixed: qrcode.paid webhook now includes complete payer and payee data (name, document, bank, branch, account), matching pix.in.completed.
  • Fixed: monetary values in synced statement entries were incorrect (duplicate division).

v1.9.0 (2026-02-13) - Payment Lifecycle, QR Code & Webhook Fixes

New Features

Complete Payment Lifecycle (PIX Out)

  • Payments (PIX Out) now have a complete lifecycle with reconciliation tracking.
  • The GET /v1/accounts/{accountId}/payments response now includes:
    • reconciled: whether the payment was confirmed by the banking partner.
    • reconciledAt: confirmation timestamp.
    • transactionId: links the payment to its confirmed transaction in the statement.
  • Payment status flow: CREATEDPENDINGCOMPLETED (or FAILED).

Full Payer/Payee Data in Webhooks

  • pix.in.completed and qrcode.paid webhooks now include complete payer and payee details (name, document, bank, branch, account, PIX key).

Event Type Validation

  • When creating or updating a webhook subscription, event types are validated against the official list. Invalid or legacy event types are rejected with HTTP 400.

Bug Fixes

  • Fixed: PIX Out response was missing endToEndId and currency fields.
  • Fixed: Static QR Code creation failed due to partner API format change.
  • Fixed: removed unused clientId field from static QR Code request.

v1.8.0 (2026-02-11) - Enriched Statement & Webhook Signature Fix

New Features

Statement with Full Transaction Details

  • The statement endpoint (GET /v1/accounts/{accountId}/statement) now returns complete transaction information:
    • transactionType: Transaction type (PIX_IN, PIX_OUT, QR_CODE_PAYMENT, PIX_REFUND).
    • method: Payment method (KEY, STATIC_QR_CODE, DYNAMIC_QR_CODE, MANUAL).
    • status: Current status (SUCCESS, FAILED, PENDING, REFUNDED).
    • direction: Direction (IN or OUT).
    • identifier: Integrator-provided identifier.
    • payer / payee: Full payer and payee details (name, document, bank, branch, account, PIX key).
    • originalEndToEnd / refundEndToEndIds: Linking between refunds and original transactions.
    • qrcodeId / qrcodeIdentifier: QR Code reconciliation data.

Bug Fixes

  • Fixed: webhook HMAC signature was not applied correctly in some subscription update scenarios.

v1.7.0 (2026-02-11) - Webhook Format, Configurable Authentication & HMAC Signing

Breaking Changes

Webhook Payload Format

  • The webhook body now follows the documented envelope format directly: { id, type, occurredAt, schemaVersion, environment, accountId, data }.
  • Redundant fields have been removed. The payload now contains only the documented data.
  • Added tenantId and eventType at root level for easier routing.

Webhook Signature

  • The signature is now sent in the X-Signature header as base64(HMAC_SHA256(secret, raw_body)).
  • The previous format (hex(HMAC_SHA256(secret, timestamp + "." + body)) with X-Timestamp header) has been deprecated.
  • The X-Timestamp, X-Webhook-Event, and X-Webhook-ID headers are no longer sent.

New Features

Configurable Authentication per Subscription

  • Integrators can now choose the authentication method for each webhook subscription:
    • HMAC (recommended): HMAC-SHA256 signature in the X-Signature header.
    • API_KEY: Static key in a configurable header (default: X-API-Key).
    • BASIC: HTTP Basic authentication (Authorization: Basic ...).
    • BEARER: Bearer token (Authorization: Bearer ...).
    • NONE: No authentication (not recommended for production).
  • Configured via the Integrator Portal under Webhooks > Edit Subscription.

Improvements

  • Webhook documentation fully rewritten with signature verification examples in Node.js, Python, and Go.
  • Portuguese documentation locale fully translated.

Bug Fixes

  • Fixed: webhook authentication configuration was not being applied correctly to deliveries in some cases.

v1.6.0 (2026-02-06) - Currency Standardization, Statement Sync & Amount Validation

New Features

Improvements

Currency Standardization

  • All monetary values in the API are now clearly documented as BRL (REAIS) with at most 2 decimal places (centavos precision).
  • Example: 150.75 represents R$150,75.
  • Values with more than 2 decimal places are now rejected with HTTP 400 and a clear error message.
  • Updated all OpenAPI field descriptions with the BRL standard.
  • Fixed QR Code Static creation to accept values in REAIS (previously required centavos).

Enhanced Transaction Details

  • Added transactionType field to transaction responses (PIX_IN, PIX_OUT, QR_CODE_PAYMENT, PIX_REFUND).
  • Added pixKey field to payer/payee details.
  • Fixed QR Code Static/Dynamic classification in statement.

v1.5.0 (2026-02-05) - URL Standardization, Payments API & QR Code Fix

Breaking Changes

URL Standardization

All endpoints that previously used accountId as a query parameter now use it as a path parameter under /v1/accounts/{accountId}/.... This provides consistent, RESTful URL patterns across the entire API.

Migration guide:

Old URLNew URL
GET /v1/pix/transactions?accountId=XGET /v1/accounts/{accountId}/pix/transactions
GET /v1/payments?accountId=XGET /v1/accounts/{accountId}/payments
GET /v1/payments/{id}?accountId=XGET /v1/accounts/{accountId}/payments/{id}
GET /v1/pix/qr-codes?accountId=XGET /v1/accounts/{accountId}/pix/qr-codes
GET /v1/pix/qr-codes/stats?accountId=XGET /v1/accounts/{accountId}/pix/qr-codes/stats
POST /v1/pix/qr-code/accounts/{id}/dynamicPOST /v1/accounts/{accountId}/pix/qr-code/dynamic
POST /v1/pix/qr-code/accounts/{id}/staticPOST /v1/accounts/{accountId}/pix/qr-code/static
GET /v1/pix/qr-code/accounts/{id}GET /v1/accounts/{accountId}/pix/qr-code
DELETE /v1/pix/qr-code/accounts/{id}DELETE /v1/accounts/{accountId}/pix/qr-code
GET /v1/pix/keys/accounts/{id}GET /v1/accounts/{accountId}/pix/keys
POST /v1/pix/keys/accounts/{id}POST /v1/accounts/{accountId}/pix/keys
DELETE /v1/pix/keys/{key}/accounts/{id}DELETE /v1/accounts/{accountId}/pix/keys/{key}
GET /v1/pix/medGET /v1/accounts/{accountId}/pix/med
POST /v1/pix/med/{id}/responsePOST /v1/accounts/{accountId}/pix/med/{id}/response

Note: Legacy URLs continue to work for backward compatibility but are deprecated and will be removed in a future version.

New Features

Payments API

  • GET /v1/accounts/{accountId}/payments: List all PIX Out payment intents.
  • GET /v1/accounts/{accountId}/payments/{paymentId}: Retrieve payment details.

Bug Fixes

QR Code Reconciliation

  • Fixed a race condition where QR code payments were not linked to their transactions when the charge webhook arrived before the PIX webhook.

v1.4.0 (2026-01-16) - Webhook Event Type Standardization & Documentation

New Features

Webhook Event Type Improvements

  • New event pix.med.updated: Notification when a MED/infraction status is updated.
  • Improved PIX IN/OUT differentiation: Clearer distinction between incoming and outgoing PIX events.

Standardized Event Types

The following event types are now consistent across all systems:

  • pix.in.completed - Incoming PIX completed
  • pix.out.completed - Outgoing PIX completed
  • pix.out.failed - Outgoing PIX failed
  • qrcode.paid - QR Code was paid
  • pix.refund.completed - Refund completed
  • pix.refund.failed - Refund failed
  • pix.med.opened - MED/Infraction opened
  • pix.med.updated - MED/Infraction updated

Documentation

  • Full English translation: OpenAPI specification and Postman collection are now fully in English.
  • Updated event type documentation: All webhook documentation updated with standardized event types.
  • Consistency improvements: Event types are now consistent across frontend, API handlers, and documentation.

Breaking Changes

  • Legacy event types (pix.received, pix.cash_in, pix.cash_out) are deprecated in favor of the new standardized types.
  • Existing webhook subscriptions using old event types will continue to work but should be migrated.

v1.3.0 (2026-01-29) - QR Code Statistics and Charge Webhooks

New Features

QR Code Statistics

  • New endpoint GET /v1/pix/qr-codes/stats: Returns aggregated QR Code statistics for the last 24 hours.
    • Number of QR Codes generated, paid, and refunded
    • Total values (generated, paid, refunded)
    • Conversion rate (paid/generated)
    • Hourly aggregated data for trend analysis

Charge Webhooks (COB)

  • QR Code payment notifications: When a dynamic QR Code is paid, the system automatically updates the QR Code status to PAID and notifies via webhook.
  • qrcode.paid event: Webhook sent when a QR Code is confirmed as paid by BACEN.
  • Automatic webhook registration: When creating a PIX key, the charge webhook is automatically registered to receive payment notifications.

Bug Fixes

  • Fixed balance display values.
  • Fixed transaction values in the statement.

Documentation

  • Added QR Code statistics endpoint to OpenAPI specification.
  • Updated Postman collection with new statistics endpoint.

v1.2.0 (2026-01-27) - Integrator Portal and Webhooks

New Features

  • Integrator Portal: Documentation added with portal link and capabilities.

Changes

  • Webhooks via Portal: Webhook configuration now occurs exclusively through the Integrator Portal.
  • Adjusted documentation: Removed references to public webhook management endpoints; only POST /webhooks/replay and GET /v1/webhooks/events retained.

v1.1.0 (2026-01-27) - Webhook Management via API

New Features

Self-Service Webhooks

  • Webhook CRUD via API: You can now create, list, update, and delete webhook configurations directly via API without contacting support.
  • Multiple Authentication Types: Support for HMAC, API_KEY, BASIC, BEARER, and IP_WHITELIST for webhook authentication.
  • Event Type Filter: Configure which event types each webhook should receive.
  • Available Events Endpoint: New GET /v1/webhooks/events endpoint to list all supported event types.

New Webhook Events

  • pix.pending: New event sent when a Pix is pending confirmation (useful for real-time payment tracking).
  • pix.qrcode.cash_in: Specific event for QR Code payments via charge.

Security

  • IP Restriction for Webhooks: Webhook endpoints now support source IP restriction.

Bug Fixes

  • Improved webhook documentation with more detailed examples.
  • Fixed payload examples in webhook events.

v1.0.0 (2025-12-29) - Initial Release (CorpX API)

This is the first official version of the unified public documentation for the CorpX API, focused on external integrators and banking partners.

Main Features

Pix and Payments

  • Pix Out: Instant transfers using Pix keys in a single step.
  • QR Codes: Dynamic and static QR Code generation, with support for capture, status query, and cancellation.
  • Refunds: Refund flow for received Pix.
  • Pix MED: Full support for the Special Return Mechanism for infraction and dispute management.

Account Management

  • Balance Query: Detailed view of total, available, and locked balance.
  • Statement: Paginated transaction and account movement history.
  • Internal Transfers: P2P resource movement between accounts on the same platform.

Webhooks and Notifications

  • Outbound Notifications: Automatic event reception (Pix received, Pix sent, MED updates).
  • Security: HMAC-SHA256 signature on all notifications for origin guarantee.
  • Retries: Automatic retry system with exponential backoff.
  • Replay Self-Service: Endpoints to request notification resend (Individual or Batch) via API.

Security and Idempotency

  • Authentication: OAuth2 via Identity Provider (client_credentials and authorization_code flows).
  • Idempotency: Single execution guarantee for mutable operations via Idempotency-Key header.
  • Transaction Signing: All Pix transfer operations are protected by RSA-SHA512 signatures.

Multi-language Support

  • Documentation available in Portuguese, English, and Simplified Chinese.

Developer Experience

  • OpenAPI 3.0: Complete specification available for download and interactive Swagger UI.
  • Postman Collection: Ready-to-use collection for testing in Sandbox environment.
  • Integrator Guide: Detailed documentation on headers, errors, and best practices.