# Paginación

> Formato del sobre de respuesta y cómo paginar los resultados

Source: https://docs.graph8.com/es/developers/pagination/

Todas las respuestas de la API usan un sobre JSON estándar. Los endpoints de listado incluyen metadatos de paginación para facilitar la iteración sobre conjuntos de datos grandes.

---

## Sobre de respuesta

Cada respuesta envuelve su contenido en un campo `data`:

```json
{
  "data": { ... }
}
```

Los endpoints de listado también incluyen un objeto `pagination`:

```json
{
  "data": [ ... ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 342,
    "has_next": true
  }
}
```

### Campos de paginación

| Campo | Tipo | Descripción |
|-------|------|-------------|
| `page` | integer | Número de página actual (indexado desde 1) |
| `limit` | integer | Número de elementos por página |
| `total` | integer | Total de elementos en todas las páginas |
| `has_next` | boolean | `true` si hay más páginas disponibles |

---

## Parámetros de consulta

Todos los endpoints de listado aceptan estos parámetros de paginación:

| Parámetro | Tipo | Valor predeterminado | Rango | Descripción |
|-----------|------|----------------------|-------|-------------|
| `page` | integer | `1` | 1+ | Número de página a recuperar |
| `limit` | integer | `50` | 1-200 | Número de elementos por página |

---

## Iteración entre páginas

Use `has_next` para determinar cuándo detener la paginación.

**cURL**

```bash
# Fetch page 1
curl "https://be.graph8.com/api/v1/contacts?page=1&limit=100" \
  -H "Authorization: Bearer $API_KEY"

# If has_next is true, fetch page 2
curl "https://be.graph8.com/api/v1/contacts?page=2&limit=100" \
  -H "Authorization: Bearer $API_KEY"
```

**Python**

```python
import requests

API_KEY = "your_api_key_here"
BASE_URL = "https://be.graph8.com/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

all_contacts = []
page = 1

while True:
    response = requests.get(
        f"{BASE_URL}/contacts",
        headers=HEADERS,
        params={"page": page, "limit": 200}
    )
    data = response.json()

    all_contacts.extend(data["data"])

    if not data["pagination"]["has_next"]:
        break
    page += 1

print(f"Fetched {len(all_contacts)} contacts")
```

**TypeScript**

```typescript
const API_KEY = "your_api_key_here";
const BASE_URL = "https://be.graph8.com/api/v1";

async function fetchAllContacts() {
  const allContacts = [];
  let page = 1;

  while (true) {
    const response = await fetch(
      `${BASE_URL}/contacts?page=${page}&limit=200`,
      { headers: { Authorization: `Bearer ${API_KEY}` } }
    );
    const { data, pagination } = await response.json();

    allContacts.push(...data);

    if (!pagination.has_next) break;
    page++;
  }

  return allContacts;
}
```

---

## Buenas prácticas

- **Use el valor máximo de `limit` (200)** al exportar conjuntos de datos grandes para reducir el número de solicitudes.
- **Verifique `has_next`** en lugar de calcularlo a partir de `page * limit < total`: así evita errores de desfase en los índices.
- **Respete los límites de frecuencia**: agregue una pausa breve entre páginas cuando consulte muchas páginas. Consulte [Límites de frecuencia](https://docs.graph8.com/developers/rate-limits/).
- **No asuma un orden determinado**: los resultados se devuelven en el orden predeterminado de cada recurso. Si necesita un orden específico, ordene del lado del cliente.
