Boleto Issuance Guide
Boleto issuance is temporarily disabled. Expected return on 30 October 2026.
Issue a boleto on behalf of the account. The account is the beneficiary and a third party pays. The other direction, paying someone else’s boleto, is Boleto Pay.
The boleto_charge feature starts disabled for every tenant, including tenants created after this release. While it is off, every route under /v1/accounts/{accountId}/boleto/charge returns 403 feature_disabled. CorpX turns it on from the admin panel. Turning it off later does not cancel a boleto already issued.
Credential scope: boleto_charge.manage. This is money in, not cashout. Reads also accept read. Single issuance and batches are BaaS operations; Internet Banking credentials remain read-only for boleto charges.
Register the beneficiary
The holder must be a beneficiary at the settlement bank before the first issuance. Registration uses the account’s own data (name, tax id and, when the holder has more than one active account, branch and account). Do not send a body. Any JSON other than empty or {} returns 400 invalid_payload.
Live read. 404 boleto_charge_beneficiary_not_found when the account was never registered. 422 boleto_charge_account_holder_not_found when the settlement bank does not recognize the holder in the boleto module: that is not a missing beneficiary.
Updates registration data. The facade resolves the beneficiary from the account; do not send the id. A person account accepts name and socialName. A company account accepts legalName and tradeName. Email, phone and representative apply to both. At least one field. 202 returns operationId.
targetStatus is ELIGIBLE, UNDER_REVIEW or INELIGIBLE. Transitions: eligible goes to under review or ineligible; under review goes to eligible or ineligible; ineligible only returns to under review. Anything else is 409 boleto_charge_beneficiary_transition_invalid and is not sent to the bank. reason is required. documentId is required when the target is INELIGIBLE.
Closes the relationship. After confirmation, the account cannot issue new boletos. Register again to come back. reason is required. terminationDate is optional, YYYY-MM-DD, today or later in Brasília time. 202 carries operationId.
Lists beneficiaries from the settlement bank and keeps only tax numbers of the tenant’s accounts. The page is the bank’s page, so it can come back shorter. hasNext means the bank has another page.
The first POST /boleto/charge also registers on its own, with the same 202, if you have not called registration first.
Monthly quotas
Two quotas are enforced together in the Brasília calendar month (America/Sao_Paulo):
There is no unlimited mode. The effective balance is always the lower of tenant and account. Read both with:
The response carries periodStart, resetsAt, effectiveRemaining, and tenant / account blocks (limit, used, remaining, source). account.personType is PF or PJ; source says whether the limit came from default, tenant, or account.
An issuance consumes quota only after the beneficiary has been validated and the operation admitted. An idempotent repeat of the same boleto, a pending/ineligible beneficiary, and a quota denial do not count. Once admitted, the slot is permanent: a later settlement-bank failure is not refunded.
Issue
identifier is required in the JSON body and is this operation’s only idempotency key. The Idempotency-Key header does not replace it. Repeating the same boleto returns 200 without issuing another or consuming quota again.
The 202 carries chargeId (the settlement bank’s id), barcode, digitableLine, ourNumber and registrationCondition: PENDING. Registration at the central base arrives later as boleto.charge.registered or boleto.charge.registration_failed.
Request fields
Money is a number in BRL with two decimal places. Never cents, never a string.
interest and fine share the charge shape: calculationModel, typeId, typeKey, value and startDate. discount.groups[] carries sequence, typeId, typeKey, value and limitDate. A typeKey containing percentage treats value as a percent of face value; otherwise value is BRL.
A charge that disagrees with its model returns 422 boleto_charge_rules_inconsistent. A bad discount date returns 422 boleto_charge_discount_invalid. Abatement plus discounts that zero the boleto return 422 boleto_charge_reductions_exceed_amount. An identifier already active returns 409 boleto_charge_identifier_in_use. A barcode already active returns 409 boleto_charge_barcode_active.
Response fields
Consult
The two reads have different guarantees:
- Local list. The first GET pages through the Postgres mirror and does not call MT. Every item has
updatedAt, the instant of the last successful synchronization. Filters:barcode(44 digits),payer(name or tax id),dueDate,status,page(minimum 1), andpageSize(1 to 200, default 50). The response carriesitems,page,pageSize,totalItems,totalPages, andhasNext. - Always-live detail. The GET with
{chargeId}calls MT every time, updates the mirror, and returns the current result with the newupdatedAt. If MT fails, the API returns an error; it never serves an old cached result.
There is no historical backfill. The list starts with new v2.85.0 issuances. An older boleto enters the mirror after a successful detail lookup.
Issue in batches
Batch routes are BaaS-only and require boleto_charge.manage.
POST /v1/accounts/{accountId}/boleto/charge/batchescreates an emptyDRAFT. It requiresIdempotency-Key; the optional JSON body acceptsname(up to 120 characters).PUT .../batches/{batchId}/itemsadds 1–50 JSON requests per call.DELETE .../batches/{batchId}/items/{itemId}removes an item while the batch is stillDRAFT.POST .../batches/{batchId}/dispatchreserves quota and starts asynchronous processing.GET .../batches/{batchId}?page=1&pageSize=50follows statistics and per-item results.GET .../batcheslists the account’s batches.
Every item uses exactly the single-issuance body, including the required identifier. A chunk upload is atomic: if one item is invalid or conflicts, none of the 1–50 is stored. A batch accepts at most 5,000 items. boleto_charge_batch_chunk_invalid means the chunk is outside the 1–50 range; boleto_charge_batch_too_large means the batch would exceed 5,000; and boleto_charge_batch_item_conflict means the same identifier has another payload in the batch.
Only DRAFT is editable. States are:
Dispatch is atomic too: every item must fit both the tenant and account remaining balances at once. If either balance is too small, the API returns 429 boleto_charge_monthly_limit_exceeded, reserves nothing, starts no issuance, and leaves the batch in DRAFT. Once the batch is admitted, the full reservation is consumed without refund, including items that later fail at the settlement bank.
Each boleto sent for issuance may incur charges under the commercial terms agreed with CorpX. Review the items and quota before dispatch. The Portal asks for explicit confirmation on screen; that is a UI safeguard, not an API field.
Batch statistics
statistics.generation tracks total, pending, processing, issued, failed, and progressPercentage. A batch finishes when all issuance attempts finish; registration, payment, and expiration continue on each individual boleto.
statistics.payment tracks issued, paid, unpaid, overdue, paidAmount, and conversionRate. Conversion is:
Failed issuance items are excluded from the denominator. Payment statistics therefore keep changing after the batch reaches a terminal state.
When all attempts finish, the API sends boleto.charge.batch.completed with the final state and a generation summary (total, issued, failed). Read the batch for current payment conversion. With an HMAC subscription, validate X-Signature over the raw bytes and deduplicate on the envelope id.
Lifecycle
- Beneficiary registration, if there is none yet (202, a few minutes).
- Issuance (202). The boleto starts
OPENwith registrationPENDING. boleto.charge.registeredorboleto.charge.registration_failed.- Then
boleto.charge.settled(also aBOLETOline on the statement),overdue,written_off,cancelledorexpired.
boleto.charge.failed is in the catalog and is not sent in this version.
There is no way to write off an open boleto. The settlement bank does not offer that yet; DELETE exists in the code, returns 501, and is outside this contract. When validity must be predictable, send expirationPolicy.paymentLimitDate at issuance.