> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Documentação das APIs da DeliveryVip, em português. Regras que mais quebram integrações: (1) Merchant API: faça polling em GET /merchant/v3/events:polling no máximo a cada 30 s por token; confirme todo evento recebido com POST /merchant/v3/events/acknowledgment e corpo [{"id": "<eventId>"}] (o campo lido é id, não eventId), inclusive eventos repetidos ou que o sistema não trata; deduplique por eventId; o evento é só um aviso, busque o pedido na orderURL. (2) Tokens client_credentials valem 24 h e não têm refresh_token: peça outro ao receber 401. (3) Webhooks: valide a assinatura HMAC sobre o corpo bruto e responda 2xx rápido; o polling é a reconciliação. (4) Open Delivery: host od.deliveryvip.com.br, um client_secret por loja, datas em UTC. (5) Fidelidade: o operador implementa 5 rotas assinadas com HMAC e chama o config push; o estorno precisa ser idempotente. (6) Partner API: scope dv.partner. Não invente endpoints: use a referência gerada das specs OpenAPI.

# Paginação

> Navegue pelas listagens paginadas com os cursores next e previous, o header Link e o parâmetro per_page.

As listagens que podem crescer muito devolvem os resultados em páginas. A paginação é por **cursor**: cada resposta diz, nos headers, qual valor usar para buscar a próxima página ou a anterior.

> [!NOTE]
>
> **Onde vale:** `GET /merchant/v3/{merchantId}/orders` e `GET /merchant/v3/{merchantId}/discounts`. As listagens da Partner API V2 não são paginadas, e o polling de eventos tem a própria regra de lote (até 100 eventos, veja [Consultar novos pedidos](/docs/guides/merchant/order/fluxo-de-integracao/consultar-novos-pedidos.md)).

## Como funciona

**1. Busque a primeira página**

Chame a listagem sem cursor. Os resultados vêm do **mais recente para o mais antigo**, 30 por página.

**2. Leia os headers**

Se houver mais páginas, a resposta traz `X-Next-Cursor` (e `X-Previous-Cursor` a partir da segunda página), além do header `Link` com as URLs prontas.

**3. Peça a próxima página**

Repita a chamada com `?next={X-Next-Cursor}`, ou siga a URL `rel="next"` do `Link`. Quando a resposta não trouxer `X-Next-Cursor`, você chegou ao fim.

## Parâmetros

**next** `string`

Valor de `X-Next-Cursor` da resposta anterior. Traz a página seguinte.

**previous** `string`

Valor de `X-Previous-Cursor`. Traz a página anterior. Não envie junto com `next`: a combinação retorna `400 Bad Request`.

**per\_page** `integer` (default: 30)

Itens por página, entre **30 e 250**. Valores fora da faixa são ajustados para o limite mais próximo (`per_page=10` devolve 30 itens).

Mantenha os mesmos filtros e o mesmo `per_page` em todas as páginas da mesma consulta. As URLs do header `Link` já fazem isso por você.

## Headers da resposta

**X-Next-Cursor** `string`

Cursor da próxima página. Ausente na última página.

**X-Previous-Cursor** `string`

Cursor da página anterior. Ausente na primeira página.

**Link** `string`

As mesmas páginas como URLs completas, com `rel="next"` e `rel="prev"`. Ausente quando tudo cabe em uma página.

Use `--include` no cURL para ver os headers:

```bash theme={null}
curl --include 'https://api.deliveryvip.com.br/merchant/v3/{merchantId}/orders?per_page=50' \
  --header 'Authorization: Bearer {token}'
```

```http Headers da resposta theme={null}
HTTP/1.1 200 OK
X-Next-Cursor: WyIyMDI2LTEwLTI4VDE4OjQwOjEyLjAwMC0wMzowMCIsIjY0OTM5ODQyIl0=
X-Previous-Cursor: WyIyMDI2LTEwLTI5VDA5OjEyOjMwLjAwMC0wMzowMCIsIjFjMmY2YTRlIl0=
Link: <https://api.deliveryvip.com.br/merchant/v3/{merchantId}/orders?per_page=50&next=WyIy...>; rel="next", <https://api.deliveryvip.com.br/merchant/v3/{merchantId}/orders?per_page=50&previous=WyIy...>; rel="prev"
```

> [!WARNING]
>
> Trate o cursor como **opaco**: use o valor exatamente como veio, sem decodificar nem montar o seu. Na query, ele precisa estar codificado para URL (o `=` do final vira `%3D`). As bibliotecas de HTTP fazem isso quando você passa o valor como parâmetro.

## Percorrendo todas as páginas

```bash cURL theme={null}
# primeira página
curl --include 'https://api.deliveryvip.com.br/merchant/v3/{merchantId}/orders?starts_at=2026-10-01' \
  --header 'Authorization: Bearer {token}'

# próxima página, com o X-Next-Cursor recebido
curl --include --get 'https://api.deliveryvip.com.br/merchant/v3/{merchantId}/orders' \
  --data-urlencode 'starts_at=2026-10-01' \
  --data-urlencode 'next={cursor}' \
  --header 'Authorization: Bearer {token}'
```

```js Node.js theme={null}
async function listAllOrders(merchantId, token) {
  const orders = []
  let cursor = null

  do {
    const url = new URL(`https://api.deliveryvip.com.br/merchant/v3/${merchantId}/orders`)
    url.searchParams.set('per_page', '100')
    if (cursor) url.searchParams.set('next', cursor)

    const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
    if (response.status === 204) break
    orders.push(...(await response.json()))
    cursor = response.headers.get('x-next-cursor')
  } while (cursor)

  return orders
}
```

```python Python theme={null}
def list_all_orders(merchant_id, token):
    orders, cursor = [], None
    while True:
        params = {"per_page": 100}
        if cursor:
            params["next"] = cursor
        response = requests.get(
            f"https://api.deliveryvip.com.br/merchant/v3/{merchant_id}/orders",
            headers={"Authorization": f"Bearer {token}"},
            params=params,
        )
        if response.status_code == 204:
            break
        orders.extend(response.json())
        cursor = response.headers.get("X-Next-Cursor")
        if not cursor:
            break
    return orders
```

> [!NOTE]
>
> Uma listagem **sem resultados** responde `204 No Content`, sem corpo e sem headers de paginação.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.