Changelog
v2.88.0 — Batch PIX via API (M2M)
- New: batch PIX at
/v1/accounts/{accountId}/pix/batches(guide). Five steps:GET .../templatedownloads the CSV template;POST .../batchescreates theDRAFTbatch (Idempotency-Keyrequired);POST .../items/csv(raw file, up to 5 MiB) orPUT .../items(1–50 JSON items) add rows atomically;POST .../reviewruns the asynchronous pre-flight;POST .../dispatchwith{"acknowledged": true}fires. Each row pays a PIX key or a bank account and becomes a regular PIX out (same limits, policies, statement andpix.out.*). - Review before any debit.
reviewresolves keys in DICT (24-hour cache; counts toward the lookup window), detectsidentifieralready used on the account and amounts above the per-operation limit, and returns a summary withtotalAmount/validAmount, available balance and daily/nightly/monthly limits withsufficientflags.INVALIDitems block dispatch until fixed or removed. - Correction and receipts.
GET .../items/export?status=failedreturns only failed/invalid rows in the template format pluserrorCode/errorMessage— the file uploads as is to a new batch.GET .../items/{itemId}/receiptrenders one PDF;POST .../receiptscreates an export job (pix_batch_receipts, ZIP with one PDF per item andresumo.csv). File names:{YYYY-MM-DD}_{HHMM}_PIX_{amount}_{receiver}_{identifier}_{endToEnd}.pdf. - New webhook
pix.batch.completedwithstatus(COMPLETED,PARTIAL_FAILED,FAILED) andstatistics(total,completed,failed,totalAmount,completedAmount,failedAmount). Per-item events keep being emitted. - Enablement and limits. M2M-only surface with scope
pix_out.create; user tokens get 403. The tenant featurepix_batchandpixBatch.enabled=truein the account policy are set by CorpX (403 feature_disabled/403 pix_batch_account_disabled).pixBatch.maxItemscaps rows per batch (default 50, hard cap 5,000), returned aslimits.maxItems. Dispatch honours cashout locks and the transaction PIN likePOST /pix/out. - New codes in the error catalog:
pix_batch_not_found,pix_batch_item_not_found,pix_batch_account_disabled,pix_batch_chunk_invalid,pix_batch_csv_invalid,pix_batch_too_large,pix_batch_item_conflict,pix_batch_not_editable,pix_batch_empty,pix_batch_not_reviewed,pix_batch_has_invalid_items,pix_batch_acknowledgement_required,pix_batch_insufficient_balance,pix_batch_no_receipts,pix_batch_receipt_unavailable,receipt_render_failed,invalid_pix_batch_policy.
v2.87.0 — Close an account in the tenant
POST /v1/accounts/{accountId}/closeremoves this tenant’s access to the account. The 200 body is the same on both internal paths — the caller cannot tell whether another tenant still operates it. Humans needtenant_manageroradmin; credentials needaccounts.close(legacyapi2/writestill passes). A viewer cannot close.- An exclusive account with a non-zero raw settlement-bank balance returns 422
account_has_balanceand leaves the rowactive. A zero balance emails MT support and then writesstatus=closed/status_source=tenant_close. Already closed in this tenant returns the same 200, without a second email. - Binding to another account, a missing account, or a
suspendedrow is always 404account_not_foundon this route.closedcuts the API, webhook fanout, and the tenant catalog. GET /v1/accounts/{accountId}/bank-accountno longer returns 422 when the live lookup fails and the account number is already stored on the tenant — the overview uses that number (branch 0001).
v2.86.4 — PIN reset on the CorpX page
- When PIN reset on the CorpX page is enabled for the tenant, replacing an existing PIN with
PUT /v1/accounts/{accountId}/security/pinreturns 403pin_change_disabled, andDELETE .../security/pin/{document}returns 403pin_invalidate_disabled. The first enrollment still uses PUT. Verify and status are unchanged. POST /v1/accounts/{accountId}/security/pin/reset-requestreturns the page link (resetUrl). The operator opens it, completes the facial check and, if it is approved, chooses the new PIN on that same page. The body does not accept the PIN. With no PIN on file, the response is 409pin_reset_not_enrolled. The optionaldisplayMessageis shown on the page. The link lasts 30 minutes; the fifth request in the same hour returns 429pin_reset_rate_limited.
v2.86.0 — GET /pix/limits deprecated
GET /v1/accounts/{accountId}/pix/limitsis deprecated. The route still returns the partner PIX ceilings and now sendsDeprecation: trueandLinkwithrel="successor-version".- The canonical read is
GET /v1/accounts/{accountId}/limits/available(Get limits). The four windows, with used and remaining, for PIX, TED, boleto, and internal transfers.
v2.86.2 — Get limits reads the previous store
GET /v1/accounts/{accountId}/limits/availablefills PIX, TED, boleto, and internal transfers from the previous store when the account has no ceiling of its own. The response usessource: legacy.- On
legacy,singleTransferis the per-transaction ceiling (PIX).daytimeis 07:00–22:00 andnighttimeis 22:00–07:00.monthlystays empty. For TED, boleto, and internal transfers,daytimeused is the calendar-day total. - An account that already has its own ceiling stays on the current store (06:00–20:00 and 20:00–06:00).
v2.86.3 — Statement marks refunds and fixes paging
GET /v1/accounts/{accountId}/statementtreatspageas a zero-based index, matching the docs and thepagefield in the response.page=0is the first page andpage=1is the second. Previously both returned the same page.- A PIX refund line is now marked. It carries
reversal: true,partnerType: PIX_REFUNDandoriginalEndToEnd(the PIX being refunded).operationstaysPIX. The original PIX, once refunded, carriesrefundEndToEnd, including a partial refund. sizeabove 100 is capped at 100 (the contract said 500). Order is by instant, with one-second resolution and no guaranteed tie-break. Preferorder=asc, dedupe byendToEndIdorpartnerId, and use webhooks for real-time credits.
v2.84.0 — Standalone identity verification
- New
POST/GET /v1/identity-verificationssurface to prove control of a CPF beforepassword_reset,second_factor_reset,high_value_transaction, orsensitive_action, independently of onboarding or a bank account. Creation returnsverificationLinkand starts atPENDING; terminal states areAPPROVED,FAILED, andEXPIRED. - The API requires a master M2M credential,
X-Tenant-Id, theidentity_verification.managescope, the tenant feature, and an exactly registeredcallbackUri.displayMessageis optional plain text up to 240 characters; link lifetime defaults to 30 minutes (maximum 60). - Approvals are single-use through
POST /v1/identity-verifications/{id}/consume:purposeandreferenceIdmust match creation. An exact retry is idempotent; a competing or different binding returns409. The consumption window defaults to 10 minutes (maximum 60). - Fixed quota of 10
201creations per tenant per BRT calendar month. Every201counts and is never refunded, including later failure or expiry. A closed quota returns HTTP429withidentity_verification_monthly_limit_exceeded;rate_limitedremains a separate traffic control. - The
identity.verification.completedevent, signed inX-Signature, reportsAPPROVED,FAILED, andEXPIRED. Evidence is available fromGET /v1/identity-verifications/{id}/artifacts, protected by the dedicatedkyc.readscope.
v2.85.0 — Boleto Charge batches, quotas, and local mirror
identifieris now required in the JSON body ofPOST /v1/accounts/{accountId}/boleto/charge;Idempotency-Keyis not a fallback. Repeating the same boleto remains idempotent and does not consume quota twice.- New
GET /v1/accounts/{accountId}/boleto/charge/quota. Tenant and account are enforced together in the BRT calendar month: defaults are 100 per tenant, 5 per PF account, and 10 per PJ account. Once admitted, an issuance consumes quota without refund; a pending/ineligible beneficiary and a quota denial do not count. - New BaaS batches: create/list at
.../boleto/charge/batches, add atomic chunks of 1–50 items (5,000 maximum), delete an item inDRAFT, dispatch, and read paginated results. States areDRAFT,QUEUED,PROCESSING,COMPLETED,PARTIAL_FAILED, andFAILED. - Dispatch starts only if every item fits the tenant and account remaining quotas.
429 boleto_charge_monthly_limit_exceededreserves nothing and leaves the batch inDRAFT; an admitted reservation is never refunded after a later failure. - The boleto list now reads the local mirror and includes
updatedAt. Detail always calls the settlement bank, updates the mirror, and returns the current result; a settlement-bank failure never serves stale cache. There is no historical backfill. - Statistics separate generation from payment; conversion is
paid / issued × 100, excluding issuance failures. The newboleto.charge.batch.completed, signed inX-Signaturefor HMAC subscriptions, delivers the terminal state and a statistics snapshot.
v2.81.0 — PIX out amount leaves policy
pixOut.maxAmountandpixOut.nightMaxAmountno longer apply. Stored JSON is kept and ignored. Those rules no longer appear onpolicy.violation.- An amount refusal for PIX out, TED, boleto, or an internal transfer is 422
limit_exceeded_transaction. Remaining amount comes fromGET /v1/accounts/{accountId}/limits/available. - Each window on that read gains
source:account,tenant_default, orglobal_default. An account cell without its own ceiling inherits the tenant default, then the global default. With neither, the cell stays open. - Internal transfers use the local ledger when an effective ceiling exists. The legacy read is only used when the account has no
internal_outceiling. pixIn.maxAmount,qrCode.minAmount/maxAmount, andrefund.maxAmountare unchanged.
v2.82.0 — Bank slip issuance
- Issue a boleto for your own account at
POST /v1/accounts/{accountId}/bank-slips. Scopebank_slip.manage. Thebank_slip_issuancefeature starts disabled for every tenant, including tenants created after this release. While it is off, every bank-slip route returns 403feature_disabled. - On the first issuance of each account the API registers the holder as beneficiary and returns 202
bank_slip_beneficiary_pending(Retry-After: 300). Nothing was issued. Repeat the same body in a few minutes. This happens only that first time. - Reads are live at the settlement bank: list, detail, and beneficiary.
bankSlipIdis the id returned at issuance. There is no write-off of an open slip:DELETEreturns 501bank_slip_write_off_unavailable. - New events:
bank_slip.registered,bank_slip.registration_failed,bank_slip.settled,bank_slip.overdue,bank_slip.written_off,bank_slip.cancelled,bank_slip.expired.bank_slip.failedis reserved and is not sent in this version. - Paying someone else’s slip (
/boleto/pay) is unchanged.
v2.83.0 — Boleto Charge
- Issuing a boleto for your own account is now Boleto Charge, at
/v1/accounts/{accountId}/boleto/charge. The previous name (/bank-slips,bank_slip.*events, scopebank_slip.manage, featurebank_slip_issuance) has no alias: the feature shipped disabled for every tenant, so no integrator could call the old surface. - Explicit accreditation at
POST /v1/accounts/{accountId}/boleto/charge/beneficiary, with no body. The API builds the registration from the account. Responses: 202boleto_charge_beneficiary_pending(Retry-After: 300) while the settlement bank reviews it; 200 when already eligible; 422boleto_charge_beneficiary_ineligibleand 502boleto_charge_beneficiary_registration_failed, with the partner reason inmessage. - The public id is
chargeId. Events:boleto.charge.registered,boleto.charge.registration_failed,boleto.charge.settled,boleto.charge.overdue,boleto.charge.written_off,boleto.charge.cancelled,boleto.charge.expired.boleto.charge.failedstays reserved and is not sent. - The feature is now
boleto_chargeand remains disabled for everyone. There is no write-off of an open boleto; useexpirationPolicy.paymentLimitDate. - Boleto Pay (paying someone else’s boleto) changes name in the docs only. Paths
/boleto/preview,/boleto/payand/boleto/payments/{id}, and eventsboleto.paidandboleto.failed, stay the same.
v2.79.1 — Webhook for refunds you start
pix.refund.completedandpix.refund.failedare delivered again when the refund starts fromPOST /pix/out/refund.- Payload and event IDs are unchanged. Partner redeliveries stay idempotent.
v2.79.2 — Internal transfer webhooks name both sides
transfer.internal.inandtransfer.internal.outnow includesourceanddestinationwith name and tax ID on both sides, including transfers that did not start from the API.- When both accounts are CorpX, both legs are delivered. A webhook without an identifiable counterparty is no longer sent empty.
v2.80.0 — Email and phone PIX keys per tenant
- Registering an
emailorphonekey now requires the tenant capability. New tenants start with it on. Existing tenants stay off until CorpX turns it on. - When the mode is on, the flow is unchanged: 202
pending_verification, OTP, thenPOST .../pix/keys/verify. - When it is off,
POST /v1/accounts/{accountId}/pix/keys(and verify/resend) returns 422pix_key_email_phone_disabled— ask CorpX to enable it. CPF, CNPJ, random keys, listing, deletion, and PIX out are unchanged.
Docs — webhook X-Signature is hex
Deliveries with authType: HMAC sign the raw body as lowercase hex
(hex(HMAC_SHA256(secret, raw_body)), 64 characters). Public docs used
to say Base64; production encoding is unchanged — only the text is.
v2.78.0 — Bank catalog
GET /v1/bankslists participants (name, COMPE, ISPB,ted/pix) at tenant level — not under/v1/accounts/{accountId}/....GET /v1/banks/{code}resolves341or60701190to the same row;404 bank_not_foundif missing.- TED still requires COMPE; PIX by bank details still prefers ISPB. The UI uses both codes from one row.
v2.79.0 — accreditation.manage scope
- An integration credential can carry only
accreditation.manage: it creates and follows PF/PJ accreditations without seeing balance, statement or cashout. GET /v1/accreditations/pf|pjandGET /v1/accreditations/{id}acceptreadoraccreditation.manage.kyc.readremains the only scope that downloads evidence.
v2.75.2 — Account number on the tenant account list
GET /v1/backoffice/tenants/{tenantId}/accountsnow returnsaccountNumberon each item. It is the local override (accounts.account_number); when none is stored the field isnull. IB and the backoffice no longer need aGET /bank-accountper row.
v2.76.0 — Ownership OTP for email and phone PIX keys
POST /v1/accounts/{accountId}/pix/keyswithemailorphoneno longer returns 422. The facade sends an OTP (email or SMS) and responds 202pending_verificationwithchallengeIdand a masked destination. The partner is called only after the code is confirmed.POST /v1/accounts/{accountId}/pix/keys/verifyconfirms the code and registers the key (201). Errors:code_invalid,code_expired,challenge_locked,challenge_not_found.POST /v1/accounts/{accountId}/pix/keys/verify/resendresends (60s cooldown, 3 sends max). A delivery failure returns 503otp_send_failedand the challenge is not usable.- CPF, CNPJ and random keys still return 201 immediately.
v2.77.0 — Advanced search with `order=desc` and time-of-day bounds
GET /v1/accounts/{accountId}/statement/advancedgainsorder=descfor accounts with thousands of entries a day that only want the most recent ones: the scan starts from the end and stops once it crossesoccurredAfter. No cursor in this mode (400 invalid_cursor); continuation is by time,nextOccurredBefore→occurredBefore, inclusive bound (deduplicate byid).- New
occurredAfter/occurredBeforefilters (RFC 3339 with offset, inclusive) in either order. They only shorten the scan when they are the boundary in the scan direction; otherwise they are just filters. orderin the response now echoesascordesc. Behaviour withoutorderis unchanged.