Pix in
2 operations under /v1/consumers/{consumerId}/pix (GET): parameters, status codes, refusal bodies, and the same request in curl, HTTP, Python and TypeScript.
Base URL: https://api.codespar.dev
Every operation below requires a Bearer token. See Authentication.
GET /v1/consumers/{consumerId}/pix/charges/{reference}
https://api.codespar.dev/v1/consumers/{consumerId}/pix/charges/{reference}A minted Pix charge's state
Our books for the charge, plus the provider's live state for a PENDING dynamic cob. READ ONLY: this never credits. Crediting stays with the webhook and the reconciler.
reference resolves against three columns: the charge id, the provider transaction id recorded at mint, and the client request id. A value that matches two different charges is 409 rather than an answer for whichever came first.
provider is null in two honest cases, and the difference matters. A charge already settled or expired on our books is terminal here, and a provider consult would add nothing. A static cob carries no identifier the homologated consult accepts, so whether it is still payable cannot be verified at all, and settlement for it can only arrive by webhook.
provider.result: "not_found" is an answer about the COB, not proof the payment never happened. Confirm the payment itself with the receivement query, using the end-to-end id from the payer's receipt, before minting a replacement charge. Minting one on a not-found can bill the payer twice.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
consumerId | string | yes | — |
reference | string | yes | The charge id, the mint's transaction id, or its client request id. Up to 128 characters of letters, digits, _ and -. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | reference does not look like any of the three identifiers this route resolves. |
404 | object | No Pix charge with this reference. Deliberately the same answer for a charge another organization holds. |
409 | object | The reference matches more than one charge, because one value can sit in one row's transaction id and another row's client request id. Query by the charge id instead. |
500 | object | The charge status could not be read. |
502 | object | The provider consult did not answer, or it answered for a DIFFERENT cob than this charge and was refused rather than reported as this charge's state. Nothing about the charge was changed; retry later. details.reason names which of the two it was. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
amount_minor | integer | yes | — |
charge_id | string | yes | — |
client_request_id | string,null | yes | Null for a static cob. |
created_at | string (date-time) | yes | — |
currency | string | yes | — |
provider | object,null | yes | Null when the provider was not consulted: the charge is already terminal on our books, or it is a static cob carrying no identifier the consult accepts. |
settled_at | string,null (date-time) | yes | — |
status | string | yes | Our books: pending, settled or expired. Left open rather than enumerated because the value is carried as a plain string end to end. |
status_message | string | yes | Prose written for the caller, explaining what the combination above does and does not prove. |
transaction_id | string,null | yes | The provider transaction id recorded at mint. |
wallet_id | string | yes | — |
curl -X GET https://api.codespar.dev/v1/consumers/{consumerId}/pix/charges/{reference} \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/consumers/{consumerId}/pix/charges/{reference} HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/consumers/{consumerId}/pix/charges/{reference}",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/consumers/{consumerId}/pix/charges/{reference}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/consumers/{consumerId}/pix/charges/{reference}", {
path: {
consumerId: "csm_0000000000000000",
reference: "string"
}
});{
"charge_id": "charge_0000000000000000",
"status": "string",
"amount_minor": 1000,
"currency": "BRL",
"transaction_id": "transaction_0000000000000000",
"client_request_id": "clientrequest_0000000000000000",
"wallet_id": "wlt_0000000000000000",
"created_at": "2026-01-15T12:00:00.000Z",
"settled_at": "2026-01-15T12:00:00.000Z",
"provider": {
"result": "ok",
"status": "string",
"transaction_id": "transaction_0000000000000000",
"identity_verified": true,
"last_update": "string",
"create_at": "string",
"expiration_seconds": 0,
"revision": "string"
},
"status_message": "string"
}GET /v1/consumers/{consumerId}/pix/receivements/{endToEndId}
https://api.codespar.dev/v1/consumers/{consumerId}/pix/receivements/{endToEndId}Did this specific Pix land on this consumer's account
Asks the provider about one inbound payment by its end-to-end id and, when it is a receivement on this consumer's OWN account, correlates it to a charge on our books. READ ONLY: this never credits.
The tenant binding is provider truth, not our own record: the answer's credit-party account must equal the account we resolved for this consumer. A mismatch answers exactly the same 404 a genuine miss does, so a bearer end-to-end id cannot become a probe for another tenant's receivements. An answer this backend cannot bind at all, or cannot classify, is 502 rather than a guess in either direction.
A 404 is not proof the payment never arrived. The provider indexes a receivement up to about two minutes after settlement, usually under a minute, so a just-paid Pix can genuinely answer not-found. Retry shortly before concluding anything.
received: false with a provider_transaction_type named is a real answer, not a failure: a movement exists under this id on this account but is not an inbound receivement. A reversal of a Pix the consumer SENT credits the same account and looks like this.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
consumerId | string | yes | — |
endToEndId | string | yes | The payment's end-to-end id, the reference the payer's receipt carries. 16 to 64 alphanumeric characters. |
Responses
| Status | Body | Description |
|---|---|---|
200 | object | OK |
400 | object | endToEndId does not have the shape of an end-to-end id. |
404 | object | No receivement with this end-to-end id on this consumer's account. Also the answer when the movement exists but belongs to another account, which is what keeps a bearer identifier from probing across tenants. |
409 | object | The consumer has no active Pix funding source, so there is no account to bind the answer to. Checked BEFORE the provider is queried, so an unbindable consumer never causes a lookup on a bearer identifier. |
500 | object | The receivement status could not be read. |
502 | object | The provider consult did not answer, or answered in a shape this backend cannot tenant-bind or cannot classify. Fail-closed in all three cases; details.reason names which. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
amount_minor | integer,null | yes | Minor-unit truth from OUR charge row. Null when uncorrelated. |
charge_id | string,null | yes | — |
charge_status | string,null | yes | — |
correlation | "charge_matched" | "no_correlator_returned" | "no_charge_matched" | "charge_ambiguous" | "not_attempted" | yes | How this receivement was tied to a charge on our books. None of the empty outcomes proves a credit is not coming: the reconciler matches the account STATEMENT on a field this consult never returns. |
devolutions | array of object | yes | Our devolution rows keyed on this end-to-end id, whatever the movement type is. |
end_to_end_id | string | yes | — |
initiation_type | string,null | yes | — |
provider_amount | — | no | The provider's own representation of the amount, passed through unconverted. |
provider_transaction_id | string,null | yes | — |
provider_transaction_type | string | yes | The provider's discriminator, verbatim. |
received | boolean | yes | True only when the provider classifies the movement as the homologated inbound type. A movement of another type on the same account (a reversal of a Pix the consumer SENT, for one) answers false with the type named below. |
status_message | string | yes | — |
transaction_id_brcode | string,null | yes | — |
transaction_identification | string,null | yes | — |
wallet_credited | boolean | yes | — |
wallet_id | string,null | yes | — |
curl -X GET https://api.codespar.dev/v1/consumers/{consumerId}/pix/receivements/{endToEndId} \
-H "Authorization: Bearer $CODESPAR_API_KEY"GET /v1/consumers/{consumerId}/pix/receivements/{endToEndId} HTTP/1.1
Host: api.codespar.dev
Authorization: Bearer $CODESPAR_API_KEYimport os
import requests
res = requests.get(
"https://api.codespar.dev/v1/consumers/{consumerId}/pix/receivements/{endToEndId}",
headers={"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"},
)
res.raise_for_status()
data = res.json()const res = await fetch("https://api.codespar.dev/v1/consumers/{consumerId}/pix/receivements/{endToEndId}", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CODESPAR_API_KEY}`,
},
});
const data = await res.json();const result = await cs.api.get("/v1/consumers/{consumerId}/pix/receivements/{endToEndId}", {
path: {
consumerId: "csm_0000000000000000",
endToEndId: "endtoend_0000000000000000"
}
});{
"end_to_end_id": "endtoend_0000000000000000",
"received": true,
"provider_transaction_type": "string",
"initiation_type": "string",
"provider_transaction_id": "providertransaction_0000000000000000",
"transaction_id_brcode": "string",
"transaction_identification": "string",
"correlation": "charge_matched",
"charge_id": "charge_0000000000000000",
"charge_status": "string",
"wallet_id": "wlt_0000000000000000",
"amount_minor": 1000,
"wallet_credited": true,
"devolutions": [
{
"devolution_id": "devolution_0000000000000000",
"status": "string",
"amount_minor": 1000
}
],
"status_message": "string"
}