Search the statement by fields the provider cannot filter

Filters the statement by **PIX key, counterparty, amount range, direction and status** — fields the banking provider does not filter server-side. ### Read this before integrating This endpoint is **expensive by construction**. Because the provider cannot filter by these fields, every call walks the statement for the period page by page and applies the filters row by row. A single call may cost dozens of upstream requests and take **considerably longer** than the regular statement. It exists to make one-off investigation and manual reconciliation easy. **Do not abuse it, and never use it for recurring queries or polling.** For continuous tracking of incoming PIX, use [webhooks](/docs/webhooks); for bulk data, use the regular paginated statement or the CSV export. Prefer `GET /v1/accounts/{accountId}/statement` whenever its native filters are enough (period, operation type, order). Reach for this endpoint only when you need a field that only it can filter. ### Pagination is by cursor, not page number There is no page number: an item's position in the filtered result has no fixed relationship to its position in the raw statement, so jumping to an arbitrary page would mean re-walking the period from the start. Each call spends a bounded budget (a maximum number of provider pages and a wall-clock limit). When the budget runs out before the end of the period, the response carries `exhausted: false` and a `nextCursor` — repeat the call passing `cursor=<nextCursor>` to resume exactly where the scan stopped. When `exhausted` is `true`, the period was fully walked and what you received is everything that matches. ### Default order is oldest first; `order=desc` is for "just the end of the day" By default the scan runs in ascending date order and the response echoes `order: "asc"`. This is what makes cursor resumption exact rather than a preference: the cursor is a position in the provider's statement, so in descending order an entry arriving mid-scan would enter at the top and push every later position along — the resumed call would return rows you already received. In ascending order new entries land at the end and nothing already scanned moves. Since the default window is the current day, it almost always includes "now", so this is the common case. `order=desc` exists for accounts with thousands of entries a day that only want the **most recent** ones: the scan starts from the newest and stops as soon as the result page is full. In this mode **`cursor` is refused** (`400 invalid_cursor`) for the reason above. To continue, use time instead of position: when `exhausted` is `false` the response carries `nextOccurredBefore`; pass it as `occurredBefore` on the next call. It is the instant of the last row examined, and the window is inclusive, so rows sharing that same second may come back — deduplicate by `id`. A time boundary does not move when a new entry lands at the top, which is what makes it safe where a cursor is not. Each continuation re-reads from the newest down to the boundary (the provider paginates by position), so `desc` is for the tail of the period; to walk a whole period backwards, use `asc` with a cursor. ### `occurredAfter` / `occurredBefore` narrow by time of day Both are RFC 3339 instants **with an explicit offset** (`-03:00` or `Z`), inclusive on both ends, applied on top of the date window. They only shorten the scan when they are the boundary in the scan direction: `occurredAfter` with `order=desc` and `occurredBefore` with `order=asc` stop the scan the moment the boundary is crossed (`exhausted: true`). In the opposite direction they are just filters — the provider only accepts dates, so the pages before the instant are still read. Typical use: `order=desc&occurredAfter=2026-09-20T17:00:00-03:00` to get everything since 17:00 without walking the morning. A call may legitimately return **zero items with a cursor** (or with `nextOccurredBefore`): it means the budget was spent on rows that did not match, not that there is nothing to find. The cursor is bound to the filter set. Changing any filter invalidates it and the API answers `400 invalid_cursor` — start the search over without a cursor. There is no total count, on purpose: counting would require walking the whole period, which is the very cost this design avoids.

Authentication

AuthorizationBearer

Bearer authentication of the form Bearer <token>, where token is your auth token.

Path parameters

accountIdstringRequired
Account identifier.

Headers

X-Tenant-IdstringRequired
Tenant context used for authorization and routing.
X-Request-TimestampstringRequired

Unix seconds. Required on the signed host; tolerance is 300s either way (403 request_timestamp_skew).

X-Content-SHA256stringRequired

Lowercase hex SHA-256 of the body. An empty body hashes the empty string, so the header is always present. Mismatch returns 400 body_hash_mismatch.

X-Request-SignaturestringRequired

Detached JWS (<protected>..<signature>, ES256 or PS256) over METHOD\nPATH?QUERY\nTIMESTAMP\nIDEMPOTENCY_KEY_OR_EMPTY\nX_CONTENT_SHA256.

Query parameters

startDatedateOptional

Inclusive start date (YYYY-MM-DD). Default: today.

endDatedateOptional

Inclusive end date (YYYY-MM-DD). Maximum window is 31 days.

cursorstringOptional

Opaque resume token from a previous nextCursor. Only valid for the same filter set and only with order=asc; with order=desc it is refused (400 invalid_cursor) — continue with occurredBefore instead.

orderenumOptionalDefaults to asc

Scan direction. asc (default) walks oldest → newest and supports cursor. desc walks newest → oldest, for “only the most recent” queries on busy accounts; no cursor, continue with occurredBefore=<nextOccurredBefore>.

Allowed values:
occurredAfterdatetimeOptional

Inclusive lower bound on the row instant (RFC 3339 with offset). With order=desc it stops the scan once crossed, which is what makes “everything since 17:00” cheap; with order=asc it is only a filter.

occurredBeforedatetimeOptional

Inclusive upper bound on the row instant (RFC 3339 with offset). With order=asc it stops the scan once crossed; with order=desc it is the continuation boundary (pass the previous nextOccurredBefore).

sizeintegerOptional1-100Defaults to 50

Maximum number of matching items per call (max 100).

directionenumOptional

Credits (IN) or debits (OUT).

Allowed values:
operationenumOptional
Operation type. Pushed down to the provider when possible, narrowing the scan.
Allowed values:
statusstringOptional

Canonical status (COMPLETED, PROCESSING, FAILED, REFUNDED, REVERSED).

pixKeystringOptional

Exact PIX key used in the transaction, case-insensitive. On a credit this is the key of this account that received; on a debit, the destination key. Rows without a key (payer used branch/account, or non-PIX operations) never match this filter.

counterpartyNamestringOptional

Partial counterparty name. Accent- and case-insensitive, and order-independent: every whitespace-separated term must appear somewhere in the name, in any order.

counterpartyDocumentstringOptional

Counterparty CPF/CNPJ. Punctuation is ignored.

minAmountdoubleOptional
Minimum absolute amount, inclusive.
maxAmountdoubleOptional
Maximum absolute amount, inclusive.

Response

Matching statement rows for the scanned portion of the period, in the requested order (oldest first by default).

accountIdstring
itemslist of objects
exhaustedboolean

true = o recorte foi varrido até o fim (ou a fronteira de horário foi cruzada) e estes são TODOS os lançamentos que casam com o filtro. false = ainda há o que varrer; continue com nextCursor (asc) ou occurredBefore=nextOccurredBefore (desc).

tenantIdstringOptional
sourcestringOptional
startDatedateOptional
endDatedateOptional
sizeintegerOptional
Quantidade de itens nesta resposta.
orderenumOptional

Direção da varredura, ecoada do pedido. asc (padrão) é a única com cursor: a varredura tem de ser crescente para o cursor retomar na posição certa — em ordem decrescente, um lançamento que chega durante a varredura desloca as posições já lidas. desc continua por tempo (nextOccurredBefore).

nextCursorstringOptional

Token opaco de retomada. Presente apenas quando exhausted é false e order é asc. Só vale para a mesma combinação de filtros.

nextOccurredBeforedatetimeOptional

Fronteira de continuação em order=desc, presente quando exhausted é false: instante do último lançamento examinado. Repita a chamada com occurredBefore igual a este valor. Como o limite é inclusivo, lançamentos no mesmo segundo podem voltar — dedupe pelo id. Ausente se o último lançamento examinado não tinha instante conhecido.

partialReasonenumOptional

Por que a varredura parou antes do fim do período. page_full = a resposta encheu; scan_budget / time_budget = o orçamento de páginas ou de tempo da chamada acabou; partner_error = o liquidante recusou uma chamada no meio da varredura e devolvemos o que já havia sido coletado.

scanobjectOptional
Custo desta chamada, para o cliente dimensionar o uso.
fetchedAtdatetimeOptional

Errors

400
Bad Request Error
404
Not Found Error
500
Internal Server Error