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

# Paginación y filtros

> Todas las listas se paginan con un cursor opaco: devuelve next_cursor como cursor mientras has_more sea true.

Todas las listas responden con la misma forma:

```json theme={null}
{
  "data": [ … ],
  "next_cursor": "eyJvIjoyfQ",
  "has_more": true
}
```

| Parámetro | Significado |
| - | - |
| `limit` | Tamaño de página, de 1 a 100. Por defecto 25. |
| `cursor` | El `next_cursor` de la página anterior. Omítelo en la primera página. |

`next_cursor` es `null` en la última página. El cursor es opaco: no lo construyas ni lo decodifiques. Un cursor que Brelio no emitió responde `422 OPERATION_INPUT_INVALID` con `params.issues[0].path` = `"cursor"`.

## Lee todas las páginas

```bash theme={null}
curl "https://api.brelio.app/v1/patients?limit=2" \
  -H "Authorization: Bearer $BRELIO_API_KEY"
# → { "data": [ …2 pacientes… ], "next_cursor": "eyJvIjoyfQ", "has_more": true }

curl "https://api.brelio.app/v1/patients?limit=2&cursor=eyJvIjoyfQ" \
  -H "Authorization: Bearer $BRELIO_API_KEY"
# → { "data": [ …1 paciente… ], "next_cursor": null, "has_more": false }
```

```javascript Node.js theme={null}
async function* listAll(path, params = {}) {
  let cursor
  do {
    const query = new URLSearchParams({ ...params, limit: '100', ...(cursor ? { cursor } : {}) })
    const response = await fetch(`https://api.brelio.app/v1${path}?${query}`, {
      headers: { Authorization: `Bearer ${process.env.BRELIO_API_KEY}` },
    })
    if (!response.ok) throw new Error(JSON.stringify(await response.json()))
    const page = await response.json()
    yield* page.data
    cursor = page.has_more ? page.next_cursor : undefined
  } while (cursor)
}

for await (const professional of listAll('/professionals', { status: 'active' })) {
  console.log(professional.firstName, professional.lastName)
}
```

```python Python theme={null}
import os
import requests

def list_all(path, **params):
    cursor = None
    while True:
        query = {**params, "limit": 100, **({"cursor": cursor} if cursor else {})}
        response = requests.get(
            f"https://api.brelio.app/v1{path}",
            params=query,
            headers={"Authorization": f"Bearer {os.environ['BRELIO_API_KEY']}"},
            timeout=10,
        )
        response.raise_for_status()
        page = response.json()
        yield from page["data"]
        if not page["has_more"]:
            return
        cursor = page["next_cursor"]

for professional in list_all("/professionals", status="active"):
    print(professional["firstName"], professional["lastName"])
```

## Filtros

Los filtros son parámetros de consulta. Aceptan los mismos nombres de campo y valores que las tablas de la web de Brelio. Cada lista tiene los suyos en la [referencia de la API](https://docs.brelio.com/es/reference/operations.md):

| Lista | Filtros |
| - | - |
| `GET /v1/patients` | `search` (nombre, email, teléfono, código de paciente, código interno o número de identificación, como el buscador de la web), `status` (`active`, `inactive`, `discharged`) |
| `GET /v1/professionals` | `status` (`pending`, `active`, `inactive`) |
| `GET /v1/services` | `search`, `status` (`active`, `inactive`) |
| `GET /v1/agenda` | `from`, `to` (obligatorios, como mucho 31 días de diferencia), `professionalId`, `centerId` |

Los pacientes se ordenan por apellido. Los pacientes archivados no aparecen en las listas.

Las páginas de fichas de pacientes cuentan para el [techo de fichas por hora](https://docs.brelio.com/es/concepts/rate-limits.md) según las fichas que devuelven.


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