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

# API de eventos del navegador — POST /ct

> Referencia del endpoint de recogida de eventos del navegador, el que usa el SDK de Scanova para enviar páginas vistas, clics y eventos propios del visitante.

El endpoint `/ct` recibe los eventos del navegador que envía el SDK de Scanova. En la mayoría de los casos no lo llamarás directamente: de eso se encarga el SDK. Esta página documenta el formato de la petición para integraciones propias o para depurar.

**URL base:** `https://t.scanova.io`

## Endpoint

```
POST https://t.scanova.io/ct
```

No hace falta ninguna cabecera de autenticación. Las peticiones se validan comparando la cabecera `Origin` o `Referer` con la lista **Allowed Domains** del sitio.

## Petición

**Cabeceras:**

```http theme={null}
Content-Type: application/json
Origin: https://yoursite.com
```

**Cuerpo:**

```json theme={null}
{
  "event_id": "f9ac7db6-f900-4d8e-8918-c846834195a8",
  "site_id": "YOUR_SITE_ID",
  "event_type": "cta_click",
  "scan_session_id": "7ad26d4f-3181-4ef8-b6ca-b8f59499dd43",
  "web_session_id": "2d0c328a-01d0-4010-85f4-f327130d1bd4",
  "visitor_id": "363fe851-7d8f-4090-902f-0f5a462829f5",
  "page_url": "https://yoursite.com/pricing",
  "referrer": "https://yoursite.com/",
  "timestamp": "2026-05-13T10:00:00.000Z",
  "device": {
    "user_agent": "Mozilla/5.0 ...",
    "screen_width": 1440,
    "screen_height": 900,
    "language": "en-US"
  },
  "metadata": {
    "button_text": "Start Free Trial",
    "section": "pricing"
  }
}
```

## Campos

| Campo             | Tipo        | Obligatorio | Descripción                                       |
| ----------------- | ----------- | ----------- | ------------------------------------------------- |
| `site_id`         | cadena      | Sí          | ID del sitio de seguimiento                       |
| `event_type`      | cadena      | Sí          | Nombre del evento en snake\_case                  |
| `event_id`        | cadena UUID | No          | ID de deduplicación. Se genera solo si lo omites. |
| `scan_session_id` | cadena UUID | No          | ID de atribución del escaneo                      |
| `web_session_id`  | cadena UUID | No          | ID de sesión del navegador (30 minutos)           |
| `visitor_id`      | cadena UUID | No          | ID de visitante persistente (cookie de 1 año)     |
| `page_url`        | cadena      | No          | URL de la página actual                           |
| `referrer`        | cadena      | No          | URL de procedencia                                |
| `timestamp`       | ISO 8601    | No          | Hora del evento. Por defecto, la de recepción.    |
| `device`          | objeto      | No          | User-agent, dimensiones de pantalla, idioma       |
| `metadata`        | objeto      | No          | Datos propios. Máximo 10 KB y 5 niveles.          |
| `consent`         | cadena      | No          | `granted`, `denied` o `pending`                   |

## Respuesta

**Correcta (`200`):**

```json theme={null}
{
  "event_id": "f9ac7db6-f900-4d8e-8918-c846834195a8"
}
```

**Respuestas de error:**

| Estado | Causa                                                                           |
| ------ | ------------------------------------------------------------------------------- |
| `400`  | Falta un campo obligatorio o el `site_id` no es válido                          |
| `403`  | El `Origin` o `Referer` de la petición no está en los Allowed Domains del sitio |
| `413`  | El contenido supera el límite de tamaño                                         |
| `422`  | Error de validación de un campo                                                 |
| `429`  | Límite de frecuencia superado (100 peticiones por minuto y IP)                  |

## CORS

El endpoint `/ct` admite CORS. Las peticiones del navegador desde dominios permitidos se aceptan con:

```
Access-Control-Allow-Origin: <origin>
Access-Control-Allow-Methods: POST, OPTIONS
```

Las peticiones preflight (`OPTIONS`) devuelven `204` con las cabeceras CORS correspondientes.

## Endpoint de lotes

Para enviar varios eventos del navegador en una sola petición:

```
POST https://t.scanova.io/collect/batch
```

El cuerpo de la petición envuelve un array:

```json theme={null}
{
  "events": [
    { "site_id": "...", "event_type": "pageview", ... },
    { "site_id": "...", "event_type": "scroll", "metadata": { "scroll_depth": 25 } }
  ]
}
```

Hasta 100 eventos por petición por lotes.
