# API de puntos de captura

> El endpoint público que convierte un envío de otra plataforma en contacto + consentimiento. Contrato exacto, campos, respuestas, el cambio de agosto de 2026 y qué nivel de contacto crea cada envío.

Fuente / source: https://soporte.konverda.com/es/docs/desarrolladores/puntos-de-captura
Idioma / language: es
Actualizado / updated: 2026-08-26

---
Un **punto de captura** expone un endpoint público de **plataforma a plataforma** (Zapier, Make, tu backend) que convierte un envío en contacto + consentimiento, con su origen registrado y, si la conectas, una automatización de bienvenida.

Los puntos se crean y gestionan en la app, en **Captación → API**. La URL exacta de cada punto está en su propia fila.

:::nota
Para captar **personas** con una página, este endpoint no es el camino: usa **Captación → Formularios**, que aloja la página, su casilla de consentimiento y su analítica. Este endpoint es para máquinas.
:::

## El endpoint {#endpoint}

```http
POST https://app.konverda.com/webhooks/capture/<token-del-punto>
Content-Type: application/json
```

Se recomienda `application/json`; también se acepta `application/x-www-form-urlencoded`. **La respuesta es SIEMPRE JSON.**

:::aviso
La URL contiene el token del punto: es la credencial. Trátala como una contraseña. Si se filtra, desactiva el punto desde **Captación → API** y crea uno nuevo.
:::

:::importante
**25 de agosto de 2026.** Hasta esa fecha este endpoint aceptaba envíos sin el campo `consent`, y también servía formularios de navegador (posts *urlencoded* contestados con páginas HTML). Las dos cosas cambiaron el mismo día y no se anunciaron.

Un envío sin `consent` afirmativo responde `422 consent_required` y **no da de alta a nadie**.


## Payload mínimo {#payload}

```json
{
  "phone": "+34 612 345 678",
  "name": "Ana Pérez",
  "consent": true
}
```

## Referencia de campos {#campos}

| Campo | Tipo | Descripción |
|---|---|---|
| `phone` | texto · recomendado | Teléfono WhatsApp del contacto. Formato local permitido si el servidor tiene prefijo por defecto. Si tu formulario lo tiene como opcional y la persona lo deja vacío, envía el registro igualmente: se acepta con `200`, no crea contacto y cuenta como «sin teléfono» en las analíticas del punto (la tasa de WhatsApp necesita ese dato). Un valor presente pero irreconocible se rechaza. |
| `name` | texto · opcional | Nombre del contacto. |
| `email` | texto · opcional | Se guarda en la ficha del contacto (el más reciente gana). No se usa para mensajería; un valor con formato no reconocible se ignora sin rechazar el envío. |
| `consent` | obligatorio si hay `phone` · `true`, `1`, `"1"`, `"true"`, `"yes"`, `"on"`, `"sí"` o `"si"` | Afirma que la persona aceptó recibir mensajes de WhatsApp EN TU PLATAFORMA. Con un teléfono y sin esta señal el envío se rechaza con `422 consent_required` y no se crea ningún contacto; sin teléfono no hay nada que consentir todavía y no se exige. Qué NIVEL concede lo decide la configuración del punto — ver [Consentimiento](#consentimiento). |
| `_hp` | texto · dejar VACÍO | Trampa antibots invisible: cualquier valor marca el envío como bot (y responde `200` a propósito, sin crear nada). |
| `cf-turnstile-response` | texto | Token de Cloudflare Turnstile — solo si el punto lo exige. |

:::nota
Este endpoint acepta las formas de texto a propósito: le llegan formularios y automatizadores que solo saben mandar cadenas. La [API de pedidos](/es/docs/desarrolladores/api-de-pedidos#campos) es más estricta — allí `consent` tiene que ser un booleano real. No es una incoherencia: son dos emisores distintos.
:::

## Probarlo con curl {#curl}

```bash
curl -X POST 'https://app.konverda.com/webhooks/capture/<token-del-punto>' \
  -H 'Content-Type: application/json' \
  -d '{ "phone": "+34612345678", "name": "Ana Pérez", "consent": true }'
```

## Respuestas {#respuestas}

| Código | Cuerpo | Significado |
|---|---|---|
| `200` | `{"ok":true}` | Registrado — o recibido sin teléfono (cuenta, no crea contacto) — o bot silenciosamente filtrado (`_hp` relleno). Un bot recibe el mismo `200` a propósito: un rechazo le enseñaría qué campo lo delató. |
| `400` | `{"error":"bad_payload","message":"…"}` | El cuerpo no se pudo leer o no es un objeto con campos (JSON inválido, `text/plain`, `{}` vacío). |
| `403` | `{"error":"verification_failed"}` | Turnstile no verificado (el punto lo exige y el token no valida). |
| `404` | `{"error":"not_found"}` | Token desconocido o punto desactivado. |
| `422` | `{"error":"consent_required","message":"…"}` | El payload no afirma el consentimiento (`consent` ausente o no afirmativo). El `message` explica en una frase qué falta. |
| `422` | `{"error":"invalid_phone"}` | `phone` presente pero irreconocible. (Ausente NO es un error: ver [campos](#campos).) |
| `429` | `{"error":"rate_limited"}` | Más de 10 envíos por minuto por IP y punto. |

Cada rechazo (`400`, `403`, `422`) queda contado en las analíticas del punto con su motivo — «Rechazados en la puerta» — para que una integración mal configurada se vea en el embudo y no solo en este código de error.

## Consentimiento: qué nivel de contacto crea cada envío {#consentimiento}

Un contacto tiene DOS niveles posibles. **«Marketing»** = puede recibir campañas, oleadas, automatizaciones proactivas y plantillas 1:1. **«No»** = solo podemos responderle cuando escribe él, y ningún mensaje que iniciemos nosotros le llega (el intento queda registrado como `not_marketing`).

Aquí el nivel no lo decide solo tu payload: lo decide **la configuración del punto** («Consentimiento explícito», en la fila del punto) combinada con el `consent` que envías.

| Configuración del punto | Base registrada | Opt-in resultante | Qué puede recibir |
|---|---|---|---|
| «Consentimiento explícito» ACTIVADO + `consent` afirmativo | `checkbox` | Marketing | Todo: campañas, oleadas, la automatización de bienvenida y plantillas 1:1. Al ser un acto explícito de la propia persona, levanta una baja anterior. |
| «Consentimiento explícito» DESACTIVADO + `consent` afirmativo | `form` | No | Solo respuestas cuando la persona escribe. La automatización de bienvenida de este punto NO se envía (queda registrada como `not_marketing`). Una baja anterior se respeta siempre. |
| `consent` ausente o falso, con `phone` | — (no se procesa) | No se crea contacto | `422 consent_required`. |
| Sin `phone` | — | No se crea contacto | `200`: el envío se cuenta como «sin teléfono» en las analíticas del punto. |

:::aviso
`consent` es obligatorio y no es una formalidad: envíalo afirmativo solo cuando la persona haya aceptado de verdad (una casilla en tu plataforma, no un valor fijo). Y revisa la configuración del punto: si su «Consentimiento explícito» está desactivado, TODOS los contactos que entren por aquí quedarán en nivel «No» — entran en Contactos, pero no recibirán la bienvenida ni ninguna campaña hasta que den su consentimiento explícito por otra vía.
:::

## Un contacto en nivel «No» no es un contacto perdido {#nivel-no}

En cuanto **te escribe**, la conversación se abre y puedes responderle. Ahí es donde entran las **palabras clave**: una palabra que la persona escribe es una puerta que abre ella, así que funciona con cualquier nivel de consentimiento. Si captas leads por este endpoint, dales una palabra que escribir.

## Seguir leyendo {#seguir-leyendo}

- [El opt-in de marketing y «Añadir a marketing»](/es/docs/contactos-y-consentimiento/el-opt-in-de-marketing)
- [La baja y qué recuerda la plataforma](/es/docs/contactos-y-consentimiento/la-baja-y-que-recuerda-la-plataforma)
- [API de pedidos (conexión genérica)](/es/docs/desarrolladores/api-de-pedidos) — el otro endpoint público, para ventas.
