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

# Listar Contactos

> Obtiene la lista de contactos con filtros y paginación

Obtén todos los contactos de tu negocio con soporte para búsqueda, filtros y paginación cursor-based.

***

## Query Parameters

<ParamField query="limit" type="number" default="50">
  Número de contactos por página (máximo 100)
</ParamField>

<ParamField query="cursor" type="string">
  Cursor para paginación. Usar `next_cursor` de la respuesta anterior.
</ParamField>

<ParamField query="search" type="string">
  Búsqueda por nombre, teléfono o email
</ParamField>

<ParamField query="tags" type="string">
  Filtrar por tags (separados por coma). Ej: `cliente,premium`
</ParamField>

<ParamField query="funnel_stage_id" type="string">
  Filtrar por etapa del funnel (UUID)
</ParamField>

<ParamField query="source" type="string">
  Filtrar por origen: `whaapy`, `api`, `import`, `webhook`, `manual`
</ParamField>

<ParamField query="sort_by" type="string" default="created_at">
  Campo para ordenar: `created_at`, `updated_at`, `name`, `last_contact_at`
</ParamField>

<ParamField query="sort_order" type="string" default="desc">
  Orden: `asc` o `desc`
</ParamField>

***

## Ejemplos

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.whaapy.com/contacts/v1?limit=20&tags=cliente" \
    -H "Authorization: Bearer wha_TU_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    'https://api.whaapy.com/contacts/v1?limit=20&tags=cliente',
    {
      headers: { 'Authorization': 'Bearer wha_TU_API_KEY' }
    }
  );
  const data = await response.json();
  console.log(data.contacts);
  ```

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

  response = requests.get(
      'https://api.whaapy.com/contacts/v1',
      params={'limit': 20, 'tags': 'cliente'},
      headers={'Authorization': 'Bearer wha_TU_API_KEY'}
  )
  print(response.json())
  ```

  ```php PHP theme={null}
  $ch = curl_init('https://api.whaapy.com/contacts/v1?limit=20&tags=cliente');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer wha_TU_API_KEY'
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  echo $response;
  ```
</RequestExample>

***

## Respuesta Exitosa

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "contacts": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "phone_number": "+5215512345678",
        "name": "Juan Pérez",
        "email": "juan@email.com",
        "avatar_url": null,
        "tags": ["cliente", "premium"],
        "custom_fields": { "company": "Acme Inc" },
        "external_ids": {},
        "notes": null,
        "funnel_stage": { "id": "uuid", "name": "Qualified" },
        "source": "whaapy",
        "company": "Acme Inc",
        "address": null,
        "city": "CDMX",
        "state": null,
        "postal_code": null,
        "country": "MX",
        "last_contact_at": "2026-01-28T10:00:00Z",
        "created_at": "2026-01-01T00:00:00Z",
        "updated_at": "2026-01-28T10:00:00Z"
      }
    ],
    "pagination": {
      "total": 150,
      "limit": 20,
      "has_more": true,
      "next_cursor": "eyJpZCI6Inl5eSJ9"
    }
  }
  ```
</ResponseExample>

### Campos de Respuesta

| Campo                    | Descripción                                          |
| ------------------------ | ---------------------------------------------------- |
| `contacts`               | Array de objetos de contacto                         |
| `pagination.total`       | Total de contactos que coinciden con los filtros     |
| `pagination.limit`       | Límite usado en la consulta                          |
| `pagination.has_more`    | Si hay más resultados disponibles                    |
| `pagination.next_cursor` | Cursor para la siguiente página (null si no hay más) |

***

## Paginación

Whaapy usa paginación **cursor-based** para eficiencia con grandes volúmenes de datos.

<Steps>
  <Step title="Primera página">
    Haz una request sin cursor:

    ```bash theme={null}
    GET /contacts/v1?limit=50
    ```
  </Step>

  <Step title="Páginas siguientes">
    Usa el `next_cursor` de la respuesta anterior:

    ```bash theme={null}
    GET /contacts/v1?limit=50&cursor=eyJpZCI6Inl5eSJ9
    ```
  </Step>

  <Step title="Fin de resultados">
    Cuando `has_more` sea `false` y `next_cursor` sea `null`, no hay más resultados.
  </Step>
</Steps>

***

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Obtener Contacto" icon="user" href="/api-reference/contacts/get">
    Detalles completos de un contacto
  </Card>

  <Card title="Búsqueda Avanzada" icon="magnifying-glass" href="/api-reference/contacts/search">
    Filtros complejos y operadores
  </Card>

  <Card title="Crear Contacto" icon="user-plus" href="/api-reference/contacts/create">
    Agregar nuevos contactos
  </Card>

  <Card title="Listar Tags" icon="tags" href="/api-reference/contacts/tags">
    Ver todos los tags disponibles
  </Card>
</CardGroup>
