# Paginação (/docs/pix-processamento/best-practices/pagination)



<QuickLinks>
  <QuickLink href="/docs/pix-processamento/endpoints/reports/get_user_transactions" title="GET /user/transactions" />

  <QuickLink href="/docs/pix-processamento/endpoints/reports/post_user_report" title="POST /user/report" />

  <QuickLink href="/docs/pix-processamento/endpoints/callbacks/get_user_callbacks" title="GET /user/callbacks" />
</QuickLinks>

Endpoints que listam recursos (`/user/transactions`, `/user/callbacks`, `/user/infractions&#x60;) usam paginação clássica por &#x2A;*`page` + `limit`** com flag `hasNextPage`.

## Padrão de loop [#padrão-de-loop]

<Tabs items="['curl', 'Node.js']">
  <Tab value="curl">
    ```bash
    PAGE=1
    LIMIT=100

    while : ; do
      RESP=$(curl -s "https://api.payzu.processamento.com/v1/user/transactions?dateFrom=2025-11-01&page=$PAGE&limit=$LIMIT" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json")

      echo "$RESP" | jq -c '.data[]'

      HAS_NEXT=$(echo "$RESP" | jq -r '.hasNextPage')
      [ "$HAS_NEXT" != "true" ] && break
      PAGE=$((PAGE+1))
    done
    ```
  </Tab>

  <Tab value="Node.js">
    ```ts
    async function* iterateTransactions(filters: Record<string, string>) {
      let page = 1;
      const limit = 100;
      while (true) {
        const params = new URLSearchParams({ ...filters, page: String(page), limit: String(limit) });
        const res = await fetch(`https://api.payzu.processamento.com/v1/user/transactions?${params}`, {
          headers: {
            Authorization: `Bearer ${process.env.PAYZU_TOKEN}`,
            'Content-Type': 'application/json',
          },
        });
        const { data, hasNextPage } = await res.json();
        for (const tx of data) yield tx;
        if (!hasNextPage) return;
        page++;
      }
    }

    for await (const tx of iterateTransactions({ dateFrom: '2025-11-01' })) {
      await process(tx);
    }
    ```
  </Tab>
</Tabs>

## Filtros disponíveis [#filtros-disponíveis]

| Filtro                | Quando usar                                                |
| --------------------- | ---------------------------------------------------------- |
| `dateFrom` / `dateTo` | Janela temporal (ISO 8601).                                |
| `clientReference`     | Encontra a transação correspondente ao seu pedido.         |
| `virtualAccount`      | Filtro por tenant (multi-loja).                            |
| `status`              | CSV: `COMPLETED,PENDING`. Aceita múltiplos.                |
| `type`                | CSV: `DEPOSIT,WITHDRAW,COMMISSION`.                        |
| `endToEndId`          | Identificador único Bacen.                                 |
| `document`, `name`    | Filtros por pagador. `document` apenas dígitos (11 ou 14). |
| `amount`              | Filtro por valor exato.                                    |

## Limite e tamanho da página [#limite-e-tamanho-da-página]

| Item        | Valor              |
| ----------- | ------------------ |
| `limit` max | **100** por página |
| Default     | 20                 |

Páginas grandes demais degradam latência. Se precisa de período longo (mês, ano) ou exportar tudo, **prefira o relatório assíncrono**.

## Quando usar relatório assíncrono em vez de paginar [#quando-usar-relatório-assíncrono-em-vez-de-paginar]

| Cenário                                | Recomendação                                                                                        |
| -------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Listagem em tela (dashboard)           | `GET /user/transactions` com paginação.                                                             |
| Verificação pontual                    | `GET /user/transactions?clientReference=order-1234`.                                                |
| Conciliação diária (\< 10k transações) | `GET /user/transactions` paginado.                                                                  |
| Conciliação mensal/anual               | [`POST /user/report`](/docs/pix-processamento/endpoints/reports/post_user_report) (CSV assíncrono). |
| BI/Data Warehouse                      | `POST /user/report` rodado diariamente, ingestão por ETL.                                           |

<Callout type="info">
  O relatório assíncrono gera arquivo CSV com URL assinada de download. Não tem limite de linhas e roda em background. Veja o [tutorial de Conciliação](/docs/pix-processamento/tutoriais/reconciliation).
</Callout>

## Armadilhas comuns [#armadilhas-comuns]

| Armadilha                                              | Sintoma                                          |
| ------------------------------------------------------ | ------------------------------------------------ |
| Pegar tudo sem `dateFrom` em conta com volume          | Resposta lenta, possível timeout                 |
| `limit=1000` (acima do permitido)                      | API rejeita ou trunca                            |
| Iterar até `data.length === 0` em vez de `hasNextPage` | Loop infinito em página vazia da última iteração |
| Página fixa (`page=1` sempre)                          | Só lê o primeiro 100, perde o resto              |
| Passar `document` com pontuação (`123.456.789-00`)     | Erro 400, regex aceita só dígitos                |
