# API de contactos de NoRestChat

Da de alta contactos en NoRestChat (Email Marketing) desde tu web, tu landing, tu plataforma de cursos o una herramienta como Zapier o Make. Cada contacto puede llevar una etiqueta, y esa etiqueta puede poner en marcha una automatización de correos (por ejemplo, la de bienvenida o la de un lanzamiento).

- Versión: v1
- Página web de esta documentación: https://www.norestchat.com/docs/api
- Contacto: norestchat@gmail.com

## Resumen rápido

```
POST https://www.norestchat.com/api/v1/contacts
X-Api-Key: TU_CLAVE
Content-Type: application/json

{"email": "persona@ejemplo.com", "name": "Ana", "tag": "Lanzamiento"}
```

## Endpoint

`POST https://www.norestchat.com/api/v1/contacts`

Usa siempre la dirección con **www**. Sin www hay una redirección y muchos clientes HTTP pierden el cuerpo del POST por el camino: el contacto no llega.

## Autenticación

Cada cuenta tiene una clave de API. Se encuentra en NoRestChat → Email Marketing → **Integración con tu web**. Se puede enviar de tres formas (elige una):

1. Cabecera `X-Api-Key: TU_CLAVE` (recomendada).
2. Cabecera `Authorization: Bearer TU_CLAVE`.
3. Parámetro `api_key` en la URL o en el cuerpo. Solo para herramientas que no permiten cabeceras, como algunos plugins de formularios.

La clave da acceso a tu lista de contactos: guárdala como variable de entorno en tu servidor (por ejemplo `NOREST_API_KEY`) y **haz la llamada siempre desde el servidor**, nunca desde el navegador. Si la clave se filtra, genera una nueva en la misma página.

## Datos que acepta

Formato: JSON (`Content-Type: application/json`) o formulario (`application/x-www-form-urlencoded` / `multipart/form-data`).

| Campo | Obligatorio | Descripción |
|---|---|---|
| `email` | Sí | Email del contacto. También acepta `correo`, `your-email`, `email_address`. |
| `name` | No | Nombre. También acepta `nombre`, `your-name`, `full_name`, `first_name`. |
| `phone` | No | Teléfono. También acepta `telefono`, `tel`, `movil`, `whatsapp`. |
| `tag` | No | Etiqueta que se añade al contacto. También acepta `etiqueta`. Si no existe, se crea. |
| `sequence_id` | No | ID de una automatización activa en la que inscribir al contacto directamente. |

Los formularios de Elementor funcionan directamente con la acción **Webhook**: NoRestChat reconoce los campos aunque lleguen con la etiqueta del campo como nombre.

## Qué pasa al recibir un contacto

- **Contacto nuevo:** se crea con consentimiento de email marcado (el formulario de origen es responsable de recogerlo con su casilla).
- **El email ya existe:** no se duplica. Se actualizan nombre y teléfono si llegan, se añade la etiqueta y se inscribe en las automatizaciones que correspondan. Cuenta como éxito.
- **Se había dado de baja y se vuelve a apuntar:** se reactiva, porque volver a apuntarse es un consentimiento nuevo. Quien rebotó o marcó un correo como spam no se reactiva nunca.
- **Etiqueta:** si en tu cuenta hay una automatización con el disparador "Se añade la etiqueta X", el contacto entra en ella al recibir esa etiqueta y le llegan sus correos. **No hace falta llamar a ningún otro endpoint para el correo de bienvenida.**
- **Automatizaciones de "contacto creado":** se disparan solo cuando el contacto es nuevo.

## Respuestas

Éxito (contacto nuevo):

```json
{"ok": true, "contact_id": "6f1c…", "created": true}
```

Éxito (el email ya existía):

```json
{"ok": true, "contact_id": "6f1c…", "created": false}
```

Errores:

| Código | Cuerpo | Qué significa | Qué hacer |
|---|---|---|---|
| 400 | `{"ok": false, "error": "invalid_email"}` | Falta el email o no es válido. | Revisa el nombre del campo y el valor. |
| 401 | `{"ok": false, "error": "invalid_api_key"}` | La clave no existe o es incorrecta. | Copia de nuevo la clave desde Integración con tu web. |
| 403 | `{"ok": false, "error": "contact_limit_reached"}` | La cuenta ha llegado al límite de contactos de su plan. | Amplía el plan; no reintentes. |
| 423 | `{"ok": false, "error": "workspace_inactive"}` | La cuenta está dada de baja o bloqueada. En pausa sí se aceptan contactos. | Contacta con NoRestChat. |
| 503 | `{"ok": false, "error": "service_unavailable"}` | Fallo temporal. | Reintenta más tarde (ver abajo). |

## Doble confirmación (doble opt-in)

Por la API no se envía correo de confirmación: el contacto queda dado de alta directamente. Recoge el consentimiento en tu formulario (casilla sin marcar por defecto y enlace a tu política de privacidad) y guarda la prueba en tu sistema. Si necesitas doble confirmación, usa un formulario de NoRestChat (Email Marketing → Formularios) con esa opción activada.

## Buenas prácticas

- **Guarda primero en tu sistema y envía a NoRestChat después, en segundo plano.** Así la persona no espera y, si NoRestChat no responde, la inscripción no se pierde.
- **Reintenta solo errores temporales:** respuestas 503, tiempos de espera y fallos de red. Por ejemplo, 3 intentos con esperas de 1, 5 y 15 minutos. No reintentes 400, 401, 403 ni 423: registra el error para revisarlo.
- **Tiempo de espera de la petición:** 15 segundos es suficiente.
- **Normaliza el email** (sin espacios). NoRestChat lo pasa a minúsculas.

## Pruebas

No hay modo de pruebas separado. Para probar sin poner en marcha una automatización real, usa una etiqueta que no tenga automatización asociada, por ejemplo `"tag": "Prueba"`. El contacto se crea pero no recibe correos. Después bórralo desde Contactos. Para la prueba final, usa un email tuyo con la etiqueta real y comprueba que llega el primer correo.

## Ejemplos

cURL:

```bash
curl -X POST "https://www.norestchat.com/api/v1/contacts" \
  -H "X-Api-Key: $NOREST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "persona@ejemplo.com", "name": "Ana", "tag": "Lanzamiento"}'
```

PHP:

```php
$ch = curl_init("https://www.norestchat.com/api/v1/contacts");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => [
        "X-Api-Key: " . getenv("NOREST_API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "email" => $email,
        "name" => $name,
        "tag" => "Lanzamiento",
    ]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
```

JavaScript (Node.js 18 o superior, en el servidor):

```javascript
const response = await fetch("https://www.norestchat.com/api/v1/contacts", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.NOREST_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email, name, tag: "Lanzamiento" }),
  signal: AbortSignal.timeout(15000),
});
const result = await response.json();
if (!result.ok) console.error("NoRestChat:", response.status, result.error);
```

Python:

```python
import os, requests

response = requests.post(
    "https://www.norestchat.com/api/v1/contacts",
    headers={"X-Api-Key": os.environ["NOREST_API_KEY"]},
    json={"email": email, "name": name, "tag": "Lanzamiento"},
    timeout=15,
)
result = response.json()
```

## Elementor, Zapier y Make

- **Elementor:** en el formulario, Acciones después de enviar → **Webhook**. URL: `https://www.norestchat.com/api/v1/contacts?api_key=TU_CLAVE&tag=TU_ETIQUETA`. No hace falta cambiar los nombres de los campos.
- **Zapier / Make:** usa un paso de petición HTTP (Webhooks by Zapier → POST, o HTTP → Make a request) con la URL, la cabecera `X-Api-Key` y el cuerpo JSON de arriba.
- **Otros plugins (WPForms, Fluent Forms, Contact Form 7…):** cualquier opción de "webhook" o "enviar a URL" sirve. Si no permite cabeceras, pon la clave y la etiqueta en la URL como en el ejemplo de Elementor.

## Preguntas frecuentes

**¿Se duplica un contacto si se apunta dos veces?** No. Se actualiza el que existe.

**¿Puedo añadir varias etiquetas?** En cada llamada se añade una. Para varias, haz una llamada por etiqueta.

**¿Cómo sé si ha llegado?** Busca el email en NoRestChat → Contactos. En su ficha verás "Contacto creado por API externa" o la etiqueta añadida.