Query Cash-In by ID
Queries the status and details of a PIX transaction by its transaction ID.
Endpoint
GET /api/external/transactions/:idHeaders
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | String | Yes | ApiKey {client_id}:{client_secret} |
X-Key-Case | String | No | Set to camelCase to receive response fields in camelCase (default is snake_case) |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | String | Yes | Transaction ID (transaction_id) |
Example
curl -X GET https://api.owem.com.br/api/external/transactions/7popu57v6us7p6pcicgq12345 \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"Success Response (200)
{
"worked": true,
"data": {
"id": "a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d",
"transaction_id": "7popu57v6us7p6pcicgq12345",
"end_to_end_id": "E37839059202603071530000001",
"external_id": "order-9876",
"type": "pix",
"status": "settled",
"amount": 300000,
"fee_amount": 0,
"net_amount": 300000,
"description": "Pedido #1234",
"direction": "inbound",
"counterparty_name": "Maria Santos",
"payer_document": "12345678901",
"recipient_document": "37839059000188",
"recipient_key": "contato@empresa.com.br",
"payer_ispb": "60701190",
"payer_bank_name": "ITAU UNIBANCO S.A.",
"created_at": "2026-03-07T15:30:00Z",
"completed_at": "2026-03-07T15:30:02Z"
}
}| Field | Type | Description |
|---|---|---|
worked | Boolean | true indicates operation success |
data.id | String | Internal transaction ID. For settled transactions (default shape above), the format is 32-character lowercase hex without hyphens (e.g., a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d). In other shapes (QR not yet linked, failures), the field may not be present or may have another format (UUID with hyphens when derived directly from qrcodes.id) |
data.transaction_id | String | Public transaction identifier. For PIX IN via this pipeline, takes the form PIXIN + E2E (e.g., PIXINE37839059202603071530000001) -- the prefix is always PIXIN followed by the E2E itself (which starts with E). Use it as an opaque identifier; do not try to extract the E2E via careless string-split, as the concatenation has no separator |
data.end_to_end_id | String | BACEN end-to-end ID (E2E, format ^E\d{8}[a-zA-Z0-9]{22,26}$) |
data.external_id | String | null | Your system identifier. null if not provided at creation |
data.type | String | pix for transactions settled via the normal pipeline. pix_qrcode when the id queried resolves only in qrcodes (QR still pending/expired/cancelled, OR QR already paid but not yet linked to the final row in transactions -- short window post-settlement). pix_return on received refunds (see PIX Refunds) |
data.status | String | Current status (see table below) |
data.amount | Integer | Amount in base units (÷ 10,000 for BRL). 300000 = R$ 30.00 |
data.fee_amount | Integer | Fee amount in base units |
data.net_amount | Integer | Net amount in base units (for PIX IN, normally amount - fee_amount) |
data.description | String | null | Transaction description |
data.direction | String | inbound for incoming, outbound for outgoing |
data.counterparty_name | String | null | For inbound, name of the payer; for outbound, name of the recipient |
data.payer_document | String | null | Payer's CPF/CNPJ. Present in received payments when the issuing bank sends it |
data.recipient_document | String | null | Recipient's CPF/CNPJ |
data.recipient_key | String | null | PIX key used in the incoming payment (evp/email/phone/cpf/cnpj) |
data.payer_ispb | String | null | 8-digit ISPB of the payer's bank |
data.payer_bank_name | String | null | Payer's bank name (resolved from the ISPB) |
data.created_at | String | Creation date (ISO 8601 in UTC) |
data.completed_at | String | null | Completion date (ISO 8601 in UTC), null if still pending |
Endpoint also answers for outbound
Despite this document's focus on receivables, GET /api/external/transactions/:id is the same endpoint for PIX IN and PIX OUT. When the id resolves to an outgoing in processing or a failure, the response has the format described in Query Cash-Out by ID (status: processing / status: failed with reason_code/reason_description).
Possible Statuses
Possible values returned in the status field:
| Status | Origin | Description |
|---|---|---|
settled | transactions | Final success state. Payment received and credited to the account. Same value as the pix.charge.paid webhook with status: "paid". |
settled | qrcodes (fallback) | Also emitted when the QR has paid_at but the final row in transactions has not yet been persisted -- short window between BACEN Phase 2 ACCC and local persistence. In this case type: "pix_qrcode" and some fields (end_to_end_id, counterparty_name, payer_*) may be only partially populated |
pending | qrcodes | QR Code generated, awaiting payment |
expired | qrcodes | QR Code expired (TTL configurable per account, default 1h). Also applied automatically on QRs whose expires_at has passed but that have not yet been processed by the worker |
cancelled | qrcodes | QR Code cancelled manually by the merchant (via portal) or in administrative operations (e.g., static→dynamic bulk migration of April 2026) |
failed | failed_transactions | Credit attempt rejected (e.g., limit exceeded, account blocked, duplicate, BACEN rejection). The reason_code field indicates the structured reason. |
When failed is emitted
Although less frequent than in cash-out, receipts may fail in specific scenarios: BACEN rejection post-ACSP (e.g., AC03, AM02, DUPL), operational limit exceeded, destination account blocked or nonexistent. In these cases, the record appears in failed_transactions with direction = "inbound" and the endpoint returns the following additional format (fields exclusive to the failed path):
{
"worked": true,
"data": {
"status": "failed",
"transaction_id": "PIXINE37839059202603071530000001",
"end_to_end_id": "E37839059202603071530000001",
"amount": 300000,
"fee_amount": 0,
"external_id": "order-9876",
"type": "pix",
"direction": "inbound",
"payment_status": "failed",
"failure_reason": "rejected: AC03",
"reason_code": "AC03",
"reason_description": "Invalid creditor account number",
"started_at": "2026-03-07T15:30:00Z",
"failed_at": "2026-03-07T15:30:02Z",
"recipient": {
"name": "Empresa Exemplo LTDA",
"key": "contato@empresa.com.br"
}
}
}When you query by the tx_id of the QR and the QR has not yet been paid, the endpoint returns pending/expired/cancelled (derived from qrcodes, without a row in transactions). In this case the payload is reduced: id, transaction_id (= tx_id), amount, status, description, recipient_key (PIX key of the QR), type: "pix_qrcode", direction: "credit", created_at (when the QR was generated) and completed_at (when paid, or null). The counterparty_name field is null in this shape (it is only filled when there is a real row in transactions).
Note on bulk cancellation: during the April 2026 migration from static to dynamic QRs, a batch of active static QRs with fixed value was administratively cancelled (status cancelled). Queries return this status normally; no special handling is needed.
Error Response (404)
{
"worked": false,
"detail": "Transação não encontrada"
}Error Response (401)
{
"error": {
"status": 401,
"message": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
}
}Polling vs Webhook
To track the status of a charge, prefer using Webhooks over polling. If you need to query, use intervals of at least 5 seconds.