---
type: reference
title: Referencia del payload del webhook
summary: La petición exacta que recibe un webhook de verificación alojada, cada campo del cuerpo, y los headers que Caputchin envía.
---

Cuando un envío supera la verificación, el reenviador envía un `POST` a tu URL de webhook configurada. Esta página es el contrato exacto de esa petición. Para el recorrido de configuración, mira [configura la verificación alojada](/docs/hosted-verification/set-up); para el concepto, mira [verifica sin backend](/docs/hosted-verification/overview).

## Línea de petición y headers

El reenviador envía un `POST` con un cuerpo JSON y estos headers:

| Header | Valor |
|---|---|
| `content-type` | `application/json` |
| `accept` | `application/json` |
| `user-agent` | `Caputchin-Forwarder/0.1` |
| `x-caputchin-test` | `1`, presente solo en una **Test delivery** del dashboard; ausente en los envíos reales |

La llamada se envía con redirects desactivados y un timeout de unos segundos. La petición no va firmada; el secreto de la URL del webhook es lo que la autentica.

## Cuerpo

El cuerpo es un objeto JSON con dos claves de nivel superior, `caputchin` (metadato de verificación que Caputchin añade) y `form` (tus campos enviados):

```json
{
  "caputchin": {
    "site_key": "cpt_pub_...",
    "session_id": "...",
    "game_id": "caputchin/games/leaf-memory",
    "score": 847,
    "duration_ms": 4200,
    "verified_at": 1748640000000
  },
  "form": {
    "email": "visitor@example.com",
    "message": "Hello!"
  }
}
```

### El objeto `caputchin`

| Campo | Tipo | Significado |
|---|---|---|
| `site_key` | string | La clave pública `cpt_pub_...` de la que vino el envío. |
| `session_id` | string | Un id de sesión de verificación opaco, útil para correlación o deduplicación. En una entrega de prueba lleva el prefijo `test_`. |
| `game_id` | string o null | El juego que jugó el visitante. Null cuando la verificación corrió sin juego. |
| `score` | number o null | La puntuación del juego. Metadato declarado por el cliente para analítica, nunca una señal de confianza. Null cuando no aplica. |
| `duration_ms` | number o null | Cuánto pasó el visitante jugando el juego, en milisegundos. Declarado por el cliente, no una señal de confianza. Null cuando no aplica (por ejemplo una verificación sin juego). |
| `verified_at` | number | Cuándo Caputchin verificó el token, como un epoch Unix en milisegundos. |
| `test` | boolean (opcional) | Presente y `true` solo en una entrega de prueba del dashboard. Ausente en los envíos reales. |

`game_id`, `score` y `duration_ms` son cada uno nullable en un envío real, así que protege contra null antes de leerlos. Ninguno de los campos de `caputchin` es una decisión de confianza: la confianza es que la petición llegara siquiera, porque un envío que falla la verificación nunca se reenvía.

### El objeto `form`

`form` es un objeto plano de tus campos enviados como claves string y valores string, exactamente como se postearon, con un cambio: el campo `caputchin-token` se elimina antes de la entrega, así que nunca aparece aquí. El reenviador acepta solo campos de texto; un envío que lleve una subida de archivo se rechaza antes de cualquier entrega.

## Qué debería devolver tu handler

Devuelve cualquier estado `2xx` para acusar recibo. El reenviador trata una respuesta de no-`2xx`, un timeout, o un fallo de conexión como una entrega fallida, y una entrega fallida no se reintenta. Rastrea la salud de entrega en la página de [estadísticas](/docs/hosted-verification/statistics).

## Véase también

- [Configura la verificación alojada](/docs/hosted-verification/set-up): cablea un webhook y dispara una entrega de prueba.
- [Verifica sin backend](/docs/hosted-verification/overview): el concepto, la postura de privacidad, y las reglas de seguridad de URL.
- [Estadísticas de verificación alojada](/docs/hosted-verification/statistics): leer el éxito y el fallo de entrega.
