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

# Buscar contacto

> Buscar información de un contacto por número de teléfono

## Descripción

Este endpoint permite buscar información de un contacto por su número de teléfono. Retorna datos del contacto, si ha respondido mensajes y el estado de la ventana de sesión de WhatsApp.

Es útil para flujos de **envío condicional y follow-up automatizado**: antes de enviar un follow-up, podés consultar si el contacto ya respondió y si la ventana de sesión está activa.

<Note>
  El endpoint retorna `200` incluso si el contacto no existe. Usá el campo `found` para verificar existencia.
</Note>

## Header de autenticación

<ParamField header="X-API-Key" type="string" required>
  Tu API Key de Mindo. Formato: `mindo_xxxxxxxxxxxxxxxxxxxxxxxx`
</ParamField>

## Query parameters

<ParamField query="phone" type="string" required>
  Número de teléfono a buscar. El sistema normaliza automáticamente el número, por lo que acepta múltiples formatos (E.164 con o sin `+`, con `15` para Argentina, con espacios o guiones).
</ParamField>

## Respuesta (200 OK)

<ResponseField name="found" type="boolean">
  `true` si el contacto existe en alguna lista de la compañía.
</ResponseField>

<ResponseField name="contact" type="object">
  Información del contacto. `null` si no fue encontrado.

  <Expandable title="Propiedades de contact">
    <ResponseField name="id" type="integer">
      ID interno del contacto.
    </ResponseField>

    <ResponseField name="fullName" type="string">
      Nombre completo del contacto. Puede ser `null`.
    </ResponseField>

    <ResponseField name="phone" type="string">
      Número de teléfono en formato E.164.
    </ResponseField>

    <ResponseField name="email" type="string">
      Email del contacto. Puede ser `null`.
    </ResponseField>

    <ResponseField name="contactListId" type="integer">
      ID de la lista de contactos a la que pertenece.
    </ResponseField>

    <ResponseField name="contactListName" type="string">
      Nombre de la lista de contactos.
    </ResponseField>

    <ResponseField name="source" type="string">
      Origen del contacto: `manual`, `csv_import`, `organic`, `whatsapp_sync`, `instagram_sync`, `group`, `api`, `other`. Puede ser `null`.
    </ResponseField>

    <ResponseField name="createdAt" type="string (ISO 8601)">
      Fecha de creación del contacto.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="hasReplied" type="boolean">
  `true` si el contacto envió al menos un mensaje en algún chat. Útil para lógica de follow-up: si es `false`, el contacto es candidato para re-envío.
</ResponseField>

<ResponseField name="lastReplyAt" type="string (ISO 8601)">
  Fecha/hora del último mensaje enviado por el contacto. `null` si nunca respondió.
</ResponseField>

<ResponseField name="sessionWindowActive" type="boolean">
  `true` si hay una ventana de sesión de WhatsApp activa (24h desde el último mensaje del usuario). Si está activa, se pueden enviar mensajes de texto libre; si no, solo templates aprobados.
</ResponseField>

<ResponseField name="sessionExpiresAt" type="string (ISO 8601)">
  Fecha/hora de expiración de la ventana de sesión activa. `null` si no hay ventana activa.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.mindosoftware.com/api/v1/contact-lookup/?phone=5492235961983" \
    -H "X-API-Key: mindo_xxxxxxxxxxxxxxxxxxxxxxxx"
  ```

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

  response = requests.get(
      "https://api.mindosoftware.com/api/v1/contact-lookup/",
      params={"phone": "5492235961983"},
      headers={"X-API-Key": "mindo_xxxxxxxxxxxxxxxxxxxxxxxx"}
  )

  data = response.json()

  if data["found"]:
      print(f"Contacto: {data['contact']['fullName']}")
      print(f"Respondió: {data['hasReplied']}")
      print(f"Ventana activa: {data['sessionWindowActive']}")
  else:
      print("Contacto no encontrado")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.mindosoftware.com/api/v1/contact-lookup/?phone=5492235961983",
    {
      headers: {
        "X-API-Key": "mindo_xxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  );

  const data = await response.json();

  if (data.found) {
    console.log("Contacto:", data.contact.fullName);
    console.log("Respondió:", data.hasReplied);
    console.log("Ventana activa:", data.sessionWindowActive);
  } else {
    console.log("Contacto no encontrado");
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Contacto encontrado theme={null}
  {
    "found": true,
    "contact": {
      "id": 123,
      "fullName": "Juan Perez",
      "phone": "+5492235961983",
      "email": "juan@ejemplo.com",
      "contactListId": 5,
      "contactListName": "Lista Principal",
      "source": "organic",
      "createdAt": "2025-01-15T10:30:00Z"
    },
    "hasReplied": true,
    "lastReplyAt": "2025-03-28T14:22:00Z",
    "sessionWindowActive": true,
    "sessionExpiresAt": "2025-03-29T14:22:00Z"
  }
  ```

  ```json 200 - Contacto no encontrado theme={null}
  {
    "found": false,
    "contact": null,
    "hasReplied": false,
    "lastReplyAt": null,
    "sessionWindowActive": false,
    "sessionExpiresAt": null
  }
  ```

  ```json 400 - Parámetro faltante theme={null}
  {
    "error": "El parametro 'phone' es requerido"
  }
  ```

  ```json 401 - No autenticado theme={null}
  {
    "error": "Este endpoint requiere autenticacion con API Key (header X-API-Key)"
  }
  ```
</ResponseExample>

## Formatos de teléfono aceptados

El sistema normaliza automáticamente el número. Todos estos formatos son equivalentes:

| Formato              | Ejemplo               |
| -------------------- | --------------------- |
| E.164 con `+`        | `+5492235961983`      |
| E.164 sin `+`        | `5492235961983`       |
| Con `15` (Argentina) | `+54223155961983`     |
| Con `15` sin `+`     | `54223155961983`      |
| Con espacios/guiones | `+54 223 15-596-1983` |

<Note>
  Para números fuera de Argentina, usar formato E.164 con código de país.
</Note>

## Caso de uso: Follow-up condicional

<AccordionGroup>
  <Accordion title="Flujo de follow-up automatizado">
    Flujo típico para campañas de follow-up:

    1. **Enviar template inicial** vía [`/api/v1/meta-templates/send/`](/api-reference/mensajes/enviar-mensaje)
    2. **Esperar un período** (ej: 24-48 horas)
    3. **Consultar estado** vía `/api/v1/contact-lookup/?phone=...`
    4. **Decidir acción** según la respuesta:
       * `found: false` — Contacto no existe, revisar número
       * `hasReplied: true` — Ya respondió, no enviar follow-up
       * `hasReplied: false` + `sessionWindowActive: true` — Enviar mensaje libre de follow-up
       * `hasReplied: false` + `sessionWindowActive: false` — Enviar template de follow-up

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

    API_KEY = "mindo_xxxxxxxxxxxxxxxxxxxxxxxx"
    BASE_URL = "https://api.mindosoftware.com"

    # Paso 1: consultar estado del contacto
    lookup = requests.get(
        f"{BASE_URL}/api/v1/contact-lookup/",
        params={"phone": "5492235961983"},
        headers={"X-API-Key": API_KEY}
    ).json()

    # Paso 2: decidir acción
    if not lookup["found"]:
        print("Contacto no existe en la plataforma")
    elif lookup["hasReplied"]:
        print(f"Ya respondió el {lookup['lastReplyAt']}, omitir follow-up")
    else:
        print("No respondió, enviar follow-up")
        if lookup["sessionWindowActive"]:
            print("Ventana activa: se puede enviar mensaje libre")
        else:
            print("Ventana expirada: usar template")
    ```

    ```javascript JavaScript theme={null}
    const API_KEY = "mindo_xxxxxxxxxxxxxxxxxxxxxxxx";
    const BASE_URL = "https://api.mindosoftware.com";

    // Paso 1: consultar estado del contacto
    const response = await fetch(
      `${BASE_URL}/api/v1/contact-lookup/?phone=5492235961983`,
      { headers: { "X-API-Key": API_KEY } }
    );
    const lookup = await response.json();

    // Paso 2: decidir acción
    if (!lookup.found) {
      console.log("Contacto no existe en la plataforma");
    } else if (lookup.hasReplied) {
      console.log(`Ya respondió el ${lookup.lastReplyAt}, omitir follow-up`);
    } else {
      console.log("No respondió, enviar follow-up");
      if (lookup.sessionWindowActive) {
        console.log("Ventana activa: se puede enviar mensaje libre");
      } else {
        console.log("Ventana expirada: usar template");
      }
    }
    ```
  </Accordion>
</AccordionGroup>
