Skip to navigation

Changelog

v2.88.0 — Batch PIX via API (M2M)

  • New: batch PIX at /v1/accounts/{accountId}/pix/batches (guide). Five steps: GET .../template downloads the CSV template; POST .../batches creates the DRAFT batch (Idempotency-Key required); POST .../items/csv (raw file, up to 5 MiB) or PUT .../items (1–50 JSON items) add rows atomically; POST .../review runs the asynchronous pre-flight; POST .../dispatch with {"acknowledged": true} fires. Each row pays a PIX key or a bank account and becomes a regular PIX out (same limits, policies, statement and pix.out.*).
  • Review before any debit. review resolves keys in DICT (24-hour cache; counts toward the lookup window), detects identifier already used on the account and amounts above the per-operation limit, and returns a summary with totalAmount/validAmount, available balance and daily/nightly/monthly limits with sufficient flags. INVALID items block dispatch until fixed or removed.
  • Correction and receipts. GET .../items/export?status=failed returns only failed/invalid rows in the template format plus errorCode/errorMessage — the file uploads as is to a new batch. GET .../items/{itemId}/receipt renders one PDF; POST .../receipts creates an export job (pix_batch_receipts, ZIP with one PDF per item and resumo.csv). File names: {YYYY-MM-DD}_{HHMM}_PIX_{amount}_{receiver}_{identifier}_{endToEnd}.pdf.
  • New webhook pix.batch.completed with status (COMPLETED, PARTIAL_FAILED, FAILED) and statistics (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 feature pix_batch and pixBatch.enabled=true in the account policy are set by CorpX (403 feature_disabled / 403 pix_batch_account_disabled). pixBatch.maxItems caps rows per batch (default 50, hard cap 5,000), returned as limits.maxItems. Dispatch honours cashout locks and the transaction PIN like POST /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}/close removes 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 need tenant_manager or admin; credentials need accounts.close (legacy api2/write still passes). A viewer cannot close.
  • An exclusive account with a non-zero raw settlement-bank balance returns 422 account_has_balance and leaves the row active. A zero balance emails MT support and then writes status=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 suspended row is always 404 account_not_found on this route. closed cuts the API, webhook fanout, and the tenant catalog.
  • GET /v1/accounts/{accountId}/bank-account no 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/pin returns 403 pin_change_disabled, and DELETE .../security/pin/{document} returns 403 pin_invalidate_disabled. The first enrollment still uses PUT. Verify and status are unchanged.
  • POST /v1/accounts/{accountId}/security/pin/reset-request returns 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 409 pin_reset_not_enrolled. The optional displayMessage is shown on the page. The link lasts 30 minutes; the fifth request in the same hour returns 429 pin_reset_rate_limited.

v2.86.0 — GET /pix/limits deprecated

  • GET /v1/accounts/{accountId}/pix/limits is deprecated. The route still returns the partner PIX ceilings and now sends Deprecation: true and Link with rel="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/available fills PIX, TED, boleto, and internal transfers from the previous store when the account has no ceiling of its own. The response uses source: legacy.
  • On legacy, singleTransfer is the per-transaction ceiling (PIX). daytime is 07:00–22:00 and nighttime is 22:00–07:00. monthly stays empty. For TED, boleto, and internal transfers, daytime used 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}/statement treats page as a zero-based index, matching the docs and the page field in the response. page=0 is the first page and page=1 is the second. Previously both returned the same page.
  • A PIX refund line is now marked. It carries reversal: true, partnerType: PIX_REFUND and originalEndToEnd (the PIX being refunded). operation stays PIX. The original PIX, once refunded, carries refundEndToEnd, including a partial refund.
  • size above 100 is capped at 100 (the contract said 500). Order is by instant, with one-second resolution and no guaranteed tie-break. Prefer order=asc, dedupe by endToEndId or partnerId, and use webhooks for real-time credits.

v2.84.0 — Standalone identity verification

  • New POST/GET /v1/identity-verifications surface to prove control of a CPF before password_reset, second_factor_reset, high_value_transaction, or sensitive_action, independently of onboarding or a bank account. Creation returns verificationLink and starts at PENDING; terminal states are APPROVED, FAILED, and EXPIRED.
  • The API requires a master M2M credential, X-Tenant-Id, the identity_verification.manage scope, the tenant feature, and an exactly registered callbackUri. displayMessage is 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: purpose and referenceId must match creation. An exact retry is idempotent; a competing or different binding returns 409. The consumption window defaults to 10 minutes (maximum 60).
  • Fixed quota of 10 201 creations per tenant per BRT calendar month. Every 201 counts and is never refunded, including later failure or expiry. A closed quota returns HTTP 429 with identity_verification_monthly_limit_exceeded; rate_limited remains a separate traffic control.
  • The identity.verification.completed event, signed in X-Signature, reports APPROVED, FAILED, and EXPIRED. Evidence is available from GET /v1/identity-verifications/{id}/artifacts, protected by the dedicated kyc.read scope.

v2.85.0 — Boleto Charge batches, quotas, and local mirror

  • identifier is now required in the JSON body of POST /v1/accounts/{accountId}/boleto/charge; Idempotency-Key is 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 in DRAFT, dispatch, and read paginated results. States are DRAFT, QUEUED, PROCESSING, COMPLETED, PARTIAL_FAILED, and FAILED.
  • Dispatch starts only if every item fits the tenant and account remaining quotas. 429 boleto_charge_monthly_limit_exceeded reserves nothing and leaves the batch in DRAFT; 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 new boleto.charge.batch.completed, signed in X-Signature for HMAC subscriptions, delivers the terminal state and a statistics snapshot.

v2.81.0 — PIX out amount leaves policy

  • pixOut.maxAmount and pixOut.nightMaxAmount no longer apply. Stored JSON is kept and ignored. Those rules no longer appear on policy.violation.
  • An amount refusal for PIX out, TED, boleto, or an internal transfer is 422 limit_exceeded_transaction. Remaining amount comes from GET /v1/accounts/{accountId}/limits/available.
  • Each window on that read gains source: account, tenant_default, or global_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_out ceiling.
  • pixIn.maxAmount, qrCode.minAmount/maxAmount, and refund.maxAmount are unchanged.

v2.82.0 — Bank slip issuance

  • Issue a boleto for your own account at POST /v1/accounts/{accountId}/bank-slips. Scope bank_slip.manage. The bank_slip_issuance feature starts disabled for every tenant, including tenants created after this release. While it is off, every bank-slip route returns 403 feature_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. bankSlipId is the id returned at issuance. There is no write-off of an open slip: DELETE returns 501 bank_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.failed is 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, scope bank_slip.manage, feature bank_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: 202 boleto_charge_beneficiary_pending (Retry-After: 300) while the settlement bank reviews it; 200 when already eligible; 422 boleto_charge_beneficiary_ineligible and 502 boleto_charge_beneficiary_registration_failed, with the partner reason in message.
  • 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.failed stays reserved and is not sent.
  • The feature is now boleto_charge and remains disabled for everyone. There is no write-off of an open boleto; use expirationPolicy.paymentLimitDate.
  • Boleto Pay (paying someone else’s boleto) changes name in the docs only. Paths /boleto/preview, /boleto/pay and /boleto/payments/{id}, and events boleto.paid and boleto.failed, stay the same.

v2.79.1 — Webhook for refunds you start

  • pix.refund.completed and pix.refund.failed are delivered again when the refund starts from POST /pix/out/refund.
  • Payload and event IDs are unchanged. Partner redeliveries stay idempotent.

v2.79.2 — Internal transfer webhooks name both sides

  • transfer.internal.in and transfer.internal.out now include source and destination with 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 email or phone key 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, then POST .../pix/keys/verify.
  • When it is off, POST /v1/accounts/{accountId}/pix/keys (and verify/resend) returns 422 pix_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/banks lists participants (name, COMPE, ISPB, ted / pix) at tenant level — not under /v1/accounts/{accountId}/....
  • GET /v1/banks/{code} resolves 341 or 60701190 to the same row; 404 bank_not_found if 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|pj and GET /v1/accreditations/{id} accept read or accreditation.manage. kyc.read remains the only scope that downloads evidence.

v2.75.2 — Account number on the tenant account list

  • GET /v1/backoffice/tenants/{tenantId}/accounts now returns accountNumber on each item. It is the local override (accounts.account_number); when none is stored the field is null. IB and the backoffice no longer need a GET /bank-account per row.

v2.76.0 — Ownership OTP for email and phone PIX keys

  • POST /v1/accounts/{accountId}/pix/keys with email or phone no longer returns 422. The facade sends an OTP (email or SMS) and responds 202 pending_verification with challengeId and a masked destination. The partner is called only after the code is confirmed.
  • POST /v1/accounts/{accountId}/pix/keys/verify confirms the code and registers the key (201). Errors: code_invalid, code_expired, challenge_locked, challenge_not_found.
  • POST /v1/accounts/{accountId}/pix/keys/verify/resend resends (60s cooldown, 3 sends max). A delivery failure returns 503 otp_send_failed and 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/advanced gains order=desc for accounts with thousands of entries a day that only want the most recent ones: the scan starts from the end and stops once it crosses occurredAfter. No cursor in this mode (400 invalid_cursor); continuation is by time, nextOccurredBefore → occurredBefore, inclusive bound (deduplicate by id).
  • New occurredAfter / occurredBefore filters (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.
  • order in the response now echoes asc or desc. Behaviour without order is unchanged.