Create a PIX transaction
Creates an outbound PIX payment. What happens next depends on where the payee is, and the two branches answer with different statuses and different bodies — a client has to handle both.
An on-us payee (payee.ispb equal to this participant’s own ISPB, on a direct order) settles SYNCHRONOUSLY as an INTRA_PSP ledger transfer and answers 201 with the transaction already EXECUTED. The account credited is the one payee.branch, payee.accountNumber and payee.accountDigit name, and it must belong to payee.document (422 PIX-0134). On a payment by key (payee.key) those coordinates are first checked against DICT (§8.2.14, asked as the payer; JDPI answers a key of this institution from its own base): a field the order states differently from the account DICT binds the key to is refused 422 PIX-0033 naming that field (the branch is compared by value, so “1” and “0001” name the same branch, here and in the paying participant’s records), a key DICT does not hold is 404 PIX-1011, and JDPI unavailable is 503 PIX-1050 — all before anything is held. Send the payee object GET /v1/entries//lookup answered and it matches. Any other payee settles over SPI in TWO PHASES: the amount is first HELD on the paying position as a pending ledger debit, and only then is the order submitted to JDPI (§8.4.1), which is asynchronous by design — nothing has settled when the call returns. A direct order answers 201 with the transaction PENDING; an order routed through a registered indirect (indirectId in the body) answers 202 carrying JD’s own §8.4.1 acknowledgement byte-for-byte when JDPI returns one, whose idReqJdPi is the handle the outcome is read with, and 201 PENDING with this plugin’s body when JDPI’s answer proves nothing. Either way, poll GET /v1/transactions/: a background reconciler consults JDPI §8.4.2 and then commits or cancels the hold, and the money is not settled until the status says so.
WHAT indirectId ACTUALLY MOVES, because it is more than a label. This participant may serve INDIRECT participants — other institutions registered here with POST /v1/indirects that reach SPI through this participant’s ISPB. Naming one on an order changes THREE things at once: the amount is held on that institution’s @pi_{ispb} settlement position instead of on the payer’s own, the persisted order is stamped with that institution so it appears in GET /v1/indirects//transactions, and the response shape changes from 201-plus-plugin-body to 202-plus-JD-body whenever JDPI acknowledges the order. The identifier is ROUTING DATA, not a credential: this participant authenticates you, and guaranteeing that the order really belongs to that institution is your responsibility, not this API’s.
⚠️ indirectId IS REFUSED 422 PIX-0111 WHILE THIS TENANT’S INDIRECT-PARTICIPANTS FEATURE IS SWITCHED OFF, and the refusal names the setting an operator has to turn on. The order is never quietly executed as a DIRECT one: that would hold the amount on the payer’s own position instead of the institution’s @pi_{ispb}, so the money would leave an account you never named, behind a 201. The refusal is decided before the payer is read, so nothing is held and no order is persisted. An order carrying NO indirectId is unaffected.
When the order reaches its outcome, an indirect order may ALSO push a NOTICE to the endpoint that registration carries (delivery.endpointUrl), queued by the background reconciler once JD’s terminal outcome is known — an HTTPS POST forwarding JD’s own result body verbatim, carrying X-Lerian-Signature (‘sha256=’ followed by the hex HMAC-SHA256 of the exact body bytes under the registration’s shared secret) and X-Lerian-Timestamp. Do not build on the notice arriving. No notice is queued at all when this deployment has no outbound queue configured, and none is queued when the outcome carries no JD result body to forward — an order cancelled locally, without a JD answer, is exactly that case. Delivery of a notice that WAS queued is AT-LEAST-ONCE and can still fail permanently while the payment stands. So the institution must dedup on the end-to-end id and treat GET /v1/indirects//transactions, not the notice, as the record of truth: it is the only place an outcome whose notice was never queued becomes visible. A direct order pushes no notice at all.
End-to-end ids: send endToEndId only when you already hold one (from a key lookup or a QR decode), and then payee.key is mandatory with it. Omit it on a manually typed order and SPI mints one — the response carries the minted value. Idempotency: the X-Idempotency header is REQUIRED, and it is what makes a retry safe on every branch, on-us included: once an order is recorded under a key, a resend under that key is refused 409 PIX-0029 and moves no money. Keys are scoped to the payer (the organization, plus the indirect participant on an indirect order); a new order needs a new key. Amounts are integer centavos.
Every refusal below is decided before the hold is taken, so it moves ZERO money; when JDPI refuses the order after the hold exists, the call answers the refusal, the hold is released and the order stays in GET /v1/transactions with status ERROR — or PENDING, when the ledger does not confirm the release, until the background reconciler resolves it; when JDPI’s answer does not prove a refusal (a timeout, a 5xx, a 408, 409 or 422 — except JD’s payment-signature refusals JDPISPI017 and JDPISPI018, which prove one whatever status carries them and are never re-sent), the hold is kept and the order answers 201 PENDING with this plugin’s body, an indirect order included, its final status coming later. The same release follows 409 PIX-0136, refused before JDPI is called when the paying participant’s payment-order signing settings are written but cannot sign (a setting missing, an algorithm this plugin does not sign with, a key that does not fit it, or a certificate that is not the key’s own); the message names the setting, and nothing reaches JDPI unsigned. Refusals: 409 PIX-0029 when this endToEndId or X-Idempotency key was already used by an order that may have moved money, and 409 PIX-0133 when that order was refused and moved none (send a new order under a new key); 409 PIX-0076 when the paying position lacks the amount; 409 PIX-0078 on a transfer to the same account; 409 PIX-0075 when the account’s period limit is exceeded; 422 PIX-0030 on a non-positive amount; 422 PIX-0037 when endToEndId arrives without payee.key; 422 PIX-0108 when the payer — or, on an indirect order, the indirect’s @pi — resolves in the CRM but is not bound to a ledger account; 422 PIX-0111 when an indirectId is supplied while this deployment’s indirect-participants feature is off (naming the setting to enable — the order is refused, never quietly paid from the payer’s own account), 404 PIX-0095 for an unknown or malformed indirectId and 422 PIX-0100 when the indirect it names is not ACTIVE; 422 PIX-0127 when this deployment acts as SEVERAL direct participants and the order names none of them in payerIspb, and 422 PIX-0128 when the one it names is not among them; when the payee banks at the PAYING participant — the order would normally settle internally, never touching SPI — and that participant has declared its ISPB shared with another core, the ownership map says which books hold the payee’s account (asked about the account the credit would land on, as the paying participant’s CRM holds it — see the next sentence for which one that is): 422 PIX-0129 when it holds that account elsewhere or nowhere, 422 PIX-0132 when the payee’s account record cannot be used to ask (a blank account, or a blank branch on anything but a payment account, on record, or one the map refuses as malformed — the record has to be fixed, a retry changes nothing), 503 PIX-0130 when it could not answer (safe to retry: nothing was created) and 502 PIX-0131 when it answered in a form that cannot be acted on; each of the four is refused before anything is held and is NOT rerouted over SPI, so a payee you believe is reachable must be paid through the institution that actually holds the account; an on-us payment WITHOUT payee.key is a payment by bank details, and it is credited on the account payee.branch, payee.accountNumber and payee.accountDigit name — number and digit together, exactly the account an interbank Pix carries — which must belong to payee.document, as the receiving institution checks on an interbank Pix: 404 PIX-2016 when the paying participant holds no such account, 422 PIX-0134 when it belongs to someone else, 422 PIX-0033 when no account is typed, 422 PIX-0108 when it is not bound to a ledger account (a payment account, accountType 3, is looked up by its account alone); an on-us payment WITH payee.key is credited on the account payee.branch, payee.accountNumber and payee.accountDigit name once DICT has confirmed them, checked exactly as a payment by bank details (404 PIX-2016, 422 PIX-0134), while an order naming no account is 422 PIX-0033; 422 PIX-0108 when that payee is not bound to a ledger account; 422 PIX-0102 when payerIspb is supplied on an indirect order and is not the participant recorded at that indirect’s registration; 409 PIX-0105 when the ledger the money leaves from declares no accounting route for the direction; 500 PIX-0120 when a CRM record names no usable ledger of the paying participant, or one this deployment does not declare (its body is scrubbed, but the code names the cause: the record needs fixing, not the order); 400 PIX-0061 when the X-Idempotency header is missing, blank or over 255 bytes, when accountId is empty or when an accountType is outside the PIX domain 0..4. On an indirect order a JD refusal is passed back with JD’s own status and body instead of a problem+json. An on-us payee who banks at the paying participant but in a DIFFERENT ledger of it is served rather than refused: the amount is reserved on the payer’s ledger, credited on the payee’s ledger, and the reserve is then committed — so the order answers EXECUTED only once both legs landed. Both on-us shapes persist their transaction before the first posting, so their failures are not invisible: an order the ledger refuses answers an error AND leaves a transaction you will find in GET /v1/transactions with status ERROR (it does not count against the account’s period limit: only a hold that reached the ledger does); a same-ledger order whose posting the ledger leaves unknown answers 5xx and stays PENDING until the reconcile worker finds the posting and settles it EXECUTED — a posting the ledger does not show yet never fails the order, because the ledger may record a posting after answering for it; and a cross-ledger order whose credit the payee’s ledger has not yet confirmed delivered is ACCEPTED and still settling: it answers 201 with status PENDING, the money stays held, and the reconcile worker completes it — poll GET /v1/transactions rather than retrying it as a fresh payment. NOT every failure on that branch became a 201, and the exception matters because the money has already moved: when the credit HAS landed and the ledger then leaves the outcome of CLOSING the hold unknown — the settle failed, or a release could not be proved — the order still answers 5xx AND still leaves the transaction PENDING. So a 5xx here never means nothing happened. Poll GET /v1/transactions; if you retry, retry with the SAME X-Idempotency key, because a fresh key is a second payment.
Authorizations
JWT bearer token issued by the identity provider.
Headers
Idempotency key for this payment order: any stable string you choose, up to 255 bytes, sent as the X-Idempotency request header (the same header, by the same name, that MED writes and the Midaz ledger take). REQUIRED: omitting it, sending only whitespace, or sending more than 255 bytes is refused 400 PIX-0061 before anything is read, held or sent. Send the SAME value again to retry the SAME order: once an order is recorded under the key, a resend is answered 409 PIX-0029 and moves no money, whether that order went to SPI or settled on-us, so read its outcome with GET /v1/transactions. Keys are scoped to the payer: the organization, plus the indirect participant on an indirect order. A new order needs a new key. BREAKING CHANGE: this replaces the optional body field clientRequestId, which no longer exists.
"order-2026-09-25-0001"
Body
The CRM account id of the payer.
"acc-123"
Transaction amount in centavos (an integer, e.g. 10050 = R$ 100,50).
10050
The recipient bank data.
Free-text payment description.
"Invoice 42"
SPI end-to-end id. Omit ONLY for a manually-typed payment order: per JDPI §8.4.1 the id does not exist yet and is generated by SPI on this call. If you obtained one from decode-QRCode (§8.3.3) or from GET /v1/entries/{entryId}/lookup (consultar-chave, §8.2.14) you MUST send it — omitting it makes SPI mint a DIFFERENT id, which will not match the payee's QR/txId conciliation, and on a payment by key it makes the order go out as manually typed.
"E1234567890"
Optional registered-indirect identifier (UUID) routing this outbound order through an indirect participant's PIX position. Omit for a direct order. Validated server-side before any money moves; unknown or inactive is rejected. Refused 422 PIX-0111, naming the setting to enable, while this deployment's indirect-participants feature is off — the order is never executed as a direct one, which would hold the funds on the payer's own account instead of the indirect's PIX position.
"3f2504e0-4f89-41d3-9a0c-0305e82c3301"
The ISPB of the institution the money leaves from. This deployment may act as SEVERAL direct SPI participants — one ISPB each, each with its own books — and this field is the only thing on the order that says which of them pays. OPTIONAL while it acts as a single participant: omit it and that one pays. REQUIRED once it acts as several — omitted is 422 PIX-0127, and an ISPB this deployment does not act as is 422 PIX-0128. It is ROUTING DATA you supply and guarantee, exactly like indirectId: never a credential, never read from a header or a path, and it never widens what your token can reach. It also decides what counts as on-us — a payee on the PAYING institution ISPB settles as an internal transfer, a payee on a sibling institution of this same deployment is an ordinary Pix over SPI. On an order carrying indirectId it must be blank or the participant recorded at that indirect's registration, which is not necessarily the deployment default one (422 PIX-0102). Send it as an absent key, not an empty string; an empty value is refused 400 PIX-0061.
^[0-9]{8}$"12345678"
Numeric eTransactionPriority (1=PRIMARY,2=SECONDARY).
1
Response
Created
Transaction amount in centavos.
10050
The created transaction id.
"d1f9c0a2-..."
eTransactionStatus name.
"PENDING"
Payment description.
"Invoice 42"
The SPI end-to-end id.
"E1234567890"
Numeric eTransactionFlow (2=CASH_OUT,3=INTRA_PSP).
2
The JDPI request id (external CASH_OUT).
"REQ-123"
Numeric eTransactionPriority.
1

