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

# Guía de Integración API

> Documentación completa de la API v1 de woku: wokus, NPS, CSAT, CES, formularios, flows, invitaciones, capturas del SDK móvil y trackers externos

<Info>
  **Disponible en el plan Corporate.** Esta funcionalidad forma parte de las capacidades empresariales de woku. [Conversa con nuestro equipo comercial](https://woku.app/pricing).
</Info>

Esta guía te muestra cómo integrar la API de **woku** en tus propias aplicaciones para automatizar la creación de **wokus**, capturar respuestas de todas las herramientas de feedback, enviar encuestas por correo o WhatsApp y enriquecer tus datos con identificadores de tus sistemas internos.

<Note>
  Esta guía aplica **solo a la versión v1** de la API. Corresponde exactamente a la pestaña **API Reference** que ves en la parte superior de la documentación. Para el comportamiento histórico (rutas sin el prefijo `/v1/`), cambia el selector de versión a **v0**.
</Note>

## Referencia interactiva

Toda la API está documentada de forma interactiva en la pestaña **API Reference** de esta misma documentación. Allí puedes ver cada endpoint con su esquema completo, ejecutarlo en vivo desde el navegador y copiar ejemplos en tu lenguaje preferido.

Esta guía es complementaria: te explica el flujo y el "por qué" de cada llamada para que la integración te tome el menor tiempo posible.

## Introducción

La API de woku te permite operar de forma programática todas las herramientas de feedback: **wokus**, **NPS**, **CSAT**, **CES**, **formularios** y **flows**, además de **invitaciones**, **cuarentenas** y **trackers externos**. Los casos de uso típicos:

1. **Crear wokus automáticamente** cuando ocurre un evento en tu aplicación (por ejemplo, cierre de una venta, fin de una sesión de capacitación, entrega de un producto).
2. **Capturar respuestas** directamente desde tu interfaz o backend, sin redirigir al cliente al sitio de woku: calificaciones y reseñas de wokus, puntajes NPS, CSAT y CES, y respuestas de formularios.
3. **Enviar encuestas por correo o WhatsApp** a listas de destinatarios desde tu backend.
4. **Capturar feedback desde tu app móvil** con un único endpoint idempotente, pensado para el SDK de React Native.
5. **Etiquetar herramientas** con identificadores de tus sistemas (CRM, ERP, ticketing) para luego buscarlas cruzadas.
6. **Extraer respuestas y reportes** hacia tus dashboards y sistemas internos.

Todas las llamadas son HTTP con JSON o `multipart/form-data` y responden con estructuras consistentes.

### URL Base

```
https://clientapi.woku.app
```

Todos los endpoints v1 viven bajo el prefijo `/v1/`.

### Autenticación

Cada empresa registrada en woku tiene una **Clave de Compañía** que se incluye en el header `Authorization` de cada solicitud:

```
Authorization: Bearer <Company-Key>
```

La clave la obtiene el propietario de la empresa desde la sección **Información** de la empresa, en la aplicación administrativa: [https://admin.woku.app](https://admin.woku.app/)

<img src="https://mintcdn.com/woku/4zVAR1XAPSMsEpMD/images/api-clave-empresa.png?fit=max&auto=format&n=4zVAR1XAPSMsEpMD&q=85&s=9577faa826819f297e9559f4bd97837a" alt="Interfaz de la aplicación woku en la sección de 'Información' de la empresa. Se muestran los datos de la compañía, incluyendo el logo, nombre, página web y enlaces a redes sociales como Instagram, Facebook, LinkedIn, X (ex Twitter), TikTok y GitHub. En la parte inferior, se destaca la opción 'Obtener Clave', que permite copiar la clave de la compañía para clientapi.woku.app." className="mx-auto" width="3840" height="2160" data-path="images/api-clave-empresa.png" />

<div style={{ textAlign: 'center', fontSize: '0.875rem', color: '#6b7280' }}><strong>Vista de la ventana de información de la empresa.</strong></div>

<Tip>
  La misma clave que usabas en v0 funciona para v1. No necesitas regenerarla para migrar.
</Tip>

## Compañía

### Obtener la compañía actual

Recupera los datos de la empresa asociada a la Clave de Compañía. Útil para validar que tu integración esté autenticando con la cuenta correcta.

**Endpoint**

```
GET /v1/companies/me
```

**Headers**

* `Authorization: Bearer <Company-Key>`

**Respuestas**

* `200 OK`: Devuelve el objeto de la compañía.
* `403 Forbidden`: La clave no es válida o no tiene permiso.

## Wokus

Las funciones de **wokus** te permiten crear, consultar, calificar y compartir wokus de forma programática.

### Crear un woku con URL de archivo

Crea un woku usando una imagen o video alojado en una URL pública (CDN, S3, ImageKit, etc.).

**Endpoint**

```
POST /v1/wokus
```

**Headers**

* `Content-Type: application/json`
* `Authorization: Bearer <Company-Key>`

**Body**

```json theme={null}
{
  "description": "Customer Service Experience - Store #123",
  "fileUrl": "https://cdn.example.com/images/product-image.jpg",
  "folderSecondaryKey": "store-123",
  "parentFolderSecondaryKey": "region-north",
  "clientEmail": "customer@example.com",
  "clientPhone": 56912345678
}
```

**Campos**

* `description` *(string, obligatorio)*: Entre 3 y 140 caracteres.
* `fileUrl` *(string, obligatorio)*: URL pública de una imagen o video (preferentemente `.mp4`).
* `folderSecondaryKey` *(string, opcional)*: Clave de la carpeta donde se almacena el woku.
* `parentFolderSecondaryKey` *(string, opcional)*: Clave de la carpeta padre. No puede ser la misma que `folderSecondaryKey`.
* `clientEmail` *(string, opcional)*: Email del cliente asociado.
* `clientPhone` *(number, opcional)*: Número de WhatsApp.

**Respuestas**

* `201 Created`: Devuelve el objeto del woku creado.
* `400 Bad Request`: El body no pasó la validación.
* `403 Forbidden`: Clave inválida.

### Crear un woku con archivo (multipart)

Cuando el archivo está en tu propio storage o tu cliente sube la imagen directamente desde un formulario, usa el endpoint con `multipart/form-data`.

**Endpoint**

```
POST /v1/wokus/form-data
```

**Headers**

* `Content-Type: multipart/form-data`
* `Authorization: Bearer <Company-Key>`

**Form fields**

* `file` *(binary, obligatorio)*: Archivo de imagen o video.
* `description` *(string, obligatorio)*: Entre 3 y 140 caracteres.
* `folderSecondaryKey` *(string, opcional)*.
* `parentFolderSecondaryKey` *(string, opcional)*.
* `clientEmail` *(string, opcional)*.
* `clientPhone` *(string, opcional)*.

**Respuestas**

* `201 Created`: Woku creado.
* `400 Bad Request`: Validación fallida (formato de archivo, tamaño, campos requeridos).
* `403 Forbidden`: Clave inválida.

### Obtener los datos de un woku

Recupera el woku junto con sus calificaciones y reseñas.

**Endpoint**

```
GET /v1/wokus/:id/review
```

**Headers**

* `Authorization: Bearer <Company-Key>`

**Path params**

* `id` *(string, obligatorio)*: Identificador del woku.

**Respuestas**

* `200 OK`: Objeto del woku con sus reseñas.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: No existe un woku con ese ID en tu empresa.

### Listar los wokus de la empresa

Lista paginada de los wokus de tu empresa.

**Endpoint**

```
GET /v1/wokus
```

**Query params**

* `page` *(number, opcional)*: Por defecto 1.
* `limit` *(number, opcional)*: Por defecto 20.

**Respuestas**

* `200 OK`: Lista paginada de wokus.
* `403 Forbidden`: Clave inválida.

### Obtener un woku con estadísticas

Devuelve un woku con sus estadísticas agregadas de reseñas.

**Endpoint**

```
GET /v1/wokus/:id
```

**Respuestas**

* `200 OK`: Woku con estadísticas.
* `403 Forbidden`: El woku pertenece a otra empresa.
* `404 Not Found`: No existe el woku.

### Listar las reseñas de un woku

Reseñas en texto y audio, paginadas, de la más reciente a la más antigua. Las reseñas de audio exponen su transcripción. Nunca se incluyen datos de contacto del cliente, solo `clientId`.

**Endpoint**

```
GET /v1/wokus/:id/reviews
```

**Query params**

* `page` *(number, opcional)*.
* `limit` *(number, opcional)*.

**Respuestas**

* `200 OK`: Lista paginada de reseñas.
* `403 Forbidden`: El woku pertenece a otra empresa.
* `404 Not Found`: No existe el woku.

### Calificar con una reseña en texto

Agrega una calificación de 1 a 5 estrellas con un comentario escrito.

**Endpoint**

```
POST /v1/wokus/:id/textnotes
```

**Headers**

* `Content-Type: application/json`
* `Authorization: Bearer <Company-Key>`

**Body**

```json theme={null}
{
  "qualification": 5,
  "description": "Excellent service! The staff was very helpful.",
  "clientEmail": "customer@example.com",
  "clientPhone": 56912345678,
  "anonymous": false
}
```

**Campos**

* `qualification` *(integer, obligatorio)*: Valor entre 1 y 5.
* `description` *(string, obligatorio)*: Reseña en texto, máximo 3000 caracteres.
* `clientEmail` *(string, opcional)*: Si no se entrega, `anonymous` debe ser `true`.
* `clientPhone` *(number, opcional)*.
* `anonymous` *(boolean, opcional)*: Por defecto `false`.

**Respuestas**

* `201 Created`: Reseña registrada.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: No existe el woku.

### Calificar con una reseña en audio

Sube un archivo de audio junto con la calificación.

**Endpoint**

```
POST /v1/wokus/:id/voicemails
```

**Headers**

* `Content-Type: multipart/form-data`
* `Authorization: Bearer <Company-Key>`

**Form fields**

* `file` *(binary, obligatorio)*: Audio. Recomendado `.mp4` o `.wav`.
* `qualification` *(string `"1"`, `"5"`, obligatorio)*.
* `clientEmail` *(string, opcional)*.
* `clientPhone` *(string, opcional)*.
* `anonymous` *(string `"true"` o `"false"`, opcional)*.

**Respuestas**

* `201 Created`: Reseña registrada.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: No existe el woku.

### Compartir un woku por correo

Envía el woku a uno o varios destinatarios. Es el mismo flujo que se inicia desde la interfaz de compartir.

**Endpoint**

```
POST /v1/wokus/:id/share
```

**Headers**

* `Content-Type: application/json`
* `Authorization: Bearer <Company-Key>`

**Body (destinatario único)**

```json theme={null}
{
  "clientEmail": "customer@example.com"
}
```

**Body (múltiples destinatarios)**

```json theme={null}
{
  "clientEmails": ["customer1@example.com", "customer2@example.com"]
}
```

<Tip>
  Debes enviar **uno u otro** de los dos campos, no ambos.
</Tip>

**Respuestas**

* `200 OK`: Envío encolado.
* `400 Bad Request`: Validación fallida (correo mal formado, ambos campos vacíos, etc.).
* `403 Forbidden`: Clave inválida.

## Capturas del SDK móvil

Endpoint único de ingesta pensado para el [SDK de React Native](/docs/desarrollo/sdk-react-native). Recibe una captura normalizada y la enruta según su `kind`: `woku` (reseña de un woku), `nps`, `csat` o `ces`. El canal de la respuesta queda sellado como `mobile-sdk` del lado del servidor.

**Endpoint**

```
POST /v1/captures
```

Acepta dos tipos de contenido:

* `application/json`: capturas de texto o calificación. El body es la captura.
* `multipart/form-data`: capturas con audio. El archivo va en el campo `file` y la captura como JSON en el campo `payload`. El audio está disponible para `woku` y `nps`; los comentarios de audio aún no están soportados para `csat` ni `ces`.

**Body (JSON)**

```json theme={null}
{
  "id": "3f2c9a2e-8b1d-4f6a-9c3e-1a2b3c4d5e6f",
  "kind": "woku",
  "targetId": "671000000000000000000001",
  "rating": 5,
  "comment": "Excelente atención en la tienda.",
  "respondent": { "email": "customer@example.com" }
}
```

**Campos**

* `id` *(string, opcional)*: Identificador generado por el cliente. Se usa como clave de idempotencia.
* `kind` *(string, obligatorio)*: `woku`, `nps`, `csat` o `ces`.
* `targetId` *(string)*: Id del woku (obligatorio para `woku`), del NPS Tool (opcional para `nps`) o del CSAT/CES Tool (obligatorio para `csat` y `ces`).
* `rating` *(integer, opcional)*: Calificación del woku, de 1 a 5.
* `score` *(integer, opcional)*: Puntaje NPS de 0 a 10, o CSAT/CES de 1 a 5.
* `comment` *(string, opcional, máx 3000)*: Comentario en texto. Obligatorio en las capturas de texto de un woku.
* `respondent` *(object, opcional)*: `email`, `phone`, `externalId`. Sin identificador, la captura queda anónima.

**Idempotencia**

La clave de idempotencia se toma del header `X-Woku-Idempotency-Key` o, en su ausencia, del campo `id` del body. Si el mismo envío se reintenta (por ejemplo, por la cola offline del SDK), la API devuelve el resultado ya registrado en lugar de crear un duplicado.

**Respuestas**

* `201 Created`: Captura aceptada. Devuelve `id`, `kind`, `remoteId` y `status: "accepted"`.
* `400 Bad Request`: Validación fallida (falta `targetId`, audio en `csat` o `ces`, `payload` malformado).
* `403 Forbidden`: Clave inválida.

## Respuestas NPS

Puedes capturar puntajes NPS y extraer las respuestas individuales hacia tus sistemas. Los reportes agregados están en la sección [Reportes NPS](#reportes-nps).

### Capturar un puntaje NPS

**Endpoint**

```
POST /v1/nps
```

**Body**

```json theme={null}
{
  "score": 9,
  "npsToolId": "671000000000000000000001",
  "clientEmail": "customer@example.com"
}
```

**Campos**

* `score` *(integer, obligatorio)*: De 0 a 10.
* `npsToolId` *(string, opcional)*: NPS Tool específico. Si se omite, el puntaje se registra a nivel de compañía.
* `clientEmail` *(string, opcional)*: Si no se entrega, la respuesta queda anónima.
* `anonymous` *(boolean, opcional)*.
* `responseChannel` *(string, opcional, máx 48)*: Canal de la respuesta. Por defecto `api`.

**Respuestas**

* `201 Created`: Devuelve `npsId` y el objeto de la respuesta.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: El NPS Tool no pertenece a tu empresa.

### Agregar una reseña a un puntaje NPS

Una vez creado el puntaje, puedes adjuntarle una reseña opcional en texto o audio.

**Endpoints**

```
POST /v1/nps/:id/textnotes
POST /v1/nps/:id/voicemails
```

* **Texto**: body JSON `{ "description": "..." }`, máximo 3000 caracteres.
* **Audio**: `multipart/form-data` con el archivo en el campo `file` (m4a, aac o mp4). La transcripción se genera en el servidor.

**Respuestas**

* `201 Created`: Reseña adjuntada.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: El NPS pertenece a otra empresa.
* `404 Not Found`: No existe el NPS.

### Consultar NPS Tools y respuestas

Endpoints de lectura para traer los datos NPS a tus sistemas:

* `GET /v1/nps-tools`: Lista paginada de los NPS Tools de tu empresa.
* `GET /v1/nps-tool/:id`: Definición de un NPS Tool (para construir la pregunta).
* `GET /v1/nps`: Respuestas paginadas, de la más reciente a la más antigua.
* `GET /v1/nps/:id`: Una respuesta individual.

`GET /v1/nps` acepta los filtros `npsToolId`, `from` y `to` (fechas ISO sobre la fecha de creación) y `withFeedback=true` (solo respuestas con reseña en texto o audio), además de `page` y `limit`. Las respuestas nunca incluyen datos de contacto del cliente, solo `clientId`.

## CSAT y CES

Las familias **CSAT** (satisfacción, escala 1 a 5) y **CES** (esfuerzo, escala 1 a 5) son espejos exactos. Los ejemplos usan `csat`; reemplaza `csat` por `ces` y `csatToolId` por `cesToolId` para obtener la familia CES. A diferencia de NPS, el id de la herramienta es siempre obligatorio: los CSAT y CES son siempre encuestas personalizadas.

### Capturar un puntaje CSAT

**Endpoint**

```
POST /v1/csat
```

**Body**

```json theme={null}
{
  "score": 4,
  "csatToolId": "671000000000000000000002",
  "clientEmail": "customer@example.com"
}
```

**Campos**

* `score` *(integer, obligatorio)*: De 1 a 5.
* `csatToolId` *(string, obligatorio)*: CSAT Tool que responde la encuesta.
* `clientEmail` *(string, opcional)*: Si no se entrega, la respuesta queda anónima.
* `anonymous` *(boolean, opcional)*.
* `responseChannel` *(string, opcional, máx 48)*: Canal de la respuesta. Por defecto `api`.

**Respuestas**

* `201 Created`: Devuelve `csatId` y el objeto de la respuesta.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: El CSAT Tool no pertenece a tu empresa.

### Agregar un comentario a una respuesta CSAT

**Endpoints**

```
POST /v1/csat/:id/textnotes
POST /v1/csat/:id/voicemails
```

* **Texto**: body JSON `{ "description": "..." }`, máximo 3000 caracteres.
* **Audio**: `multipart/form-data` con el archivo en el campo `file` (m4a, aac o mp4). La transcripción se genera en el servidor.

**Respuestas**

* `201 Created`: Comentario aceptado.
* `403 Forbidden`: La respuesta pertenece a otra empresa.
* `404 Not Found`: No existe la respuesta CSAT.

### Consultar tools y respuestas CSAT

* `GET /v1/csat-tools`: Lista paginada de los CSAT Tools de tu empresa.
* `GET /v1/csat-tool/:id`: Definición de un CSAT Tool (para construir la encuesta).
* `GET /v1/csat`: Respuestas paginadas, con los filtros `csatToolId`, `from`, `to` y `withFeedback`.
* `GET /v1/csat/:id`: Una respuesta individual.

La familia CES expone exactamente los mismos endpoints: `POST /v1/ces`, `POST /v1/ces/:id/textnotes`, `POST /v1/ces/:id/voicemails`, `GET /v1/ces-tools`, `GET /v1/ces-tool/:id`, `GET /v1/ces` y `GET /v1/ces/:id`.

## Formularios

Consulta y captura de **formularios** desde tus propios sistemas: renderiza el formulario con su definición, envía respuestas y extrae los resultados.

### Listar los formularios de la empresa

**Endpoint**

```
GET /v1/forms
```

**Query params**

* `page` *(number, opcional)*.
* `limit` *(number, opcional)*.

**Respuestas**

* `200 OK`: Lista paginada de formularios.
* `403 Forbidden`: Clave inválida.

### Obtener la definición de un formulario

Devuelve el formulario activo (campos, configuración, contenido localizado) junto con el branding de la empresa, para renderizarlo en tu propia interfaz.

**Endpoint**

```
GET /v1/forms/:id
```

**Respuestas**

* `200 OK`: Definición del formulario.
* `403 Forbidden`: El formulario pertenece a otra empresa.
* `404 Not Found`: No existe o está inactivo.

### Enviar una respuesta de formulario

**Endpoint**

```
POST /v1/forms/:id/responses
```

**Body**

```json theme={null}
{
  "anonymous": false,
  "email": "respondent@example.com",
  "answers": { "field-uuid-1": "John Doe", "field-uuid-2": 5 }
}
```

**Campos**

* `anonymous` *(boolean, obligatorio)*.
* `email` / `phone` *(string, opcional)*: Requerido según cómo identifica clientes el formulario, cuando la respuesta no es anónima.
* `answers` *(object, obligatorio)*: Respuestas por id de campo. Se validan contra la definición del formulario.
* `responseChannel` *(string, opcional, máx 48)*: Por defecto `api`.

**Respuestas**

* `201 Created`: Respuesta registrada.
* `400 Bad Request`: Validación fallida o el formulario está cerrado.
* `403 Forbidden`: El formulario pertenece a otra empresa.
* `404 Not Found`: No existe o está inactivo.
* `429 Too Many Requests`: El respondente está en cuarentena.

### Listar las respuestas de un formulario

Paginadas, de la más reciente a la más antigua. Las respuestas exponen los valores por id de campo y nunca incluyen datos de contacto del cliente, solo `clientId`.

**Endpoint**

```
GET /v1/forms/:id/responses
```

**Respuestas**

* `200 OK`: Lista paginada de respuestas.
* `403 Forbidden`: El formulario pertenece a otra empresa.
* `404 Not Found`: No existe el formulario.

## Flows

Endpoints de solo lectura. Un flow encadena varios wokus (y opcionalmente un NPS) en un solo recorrido; con estos datos puedes renderizar el recorrido en tu aplicación y capturar con los endpoints existentes (`POST /v1/wokus/:id/textnotes`, `POST /v1/nps`, etc.).

* `GET /v1/flows`: Lista paginada de los flows de tu empresa.
* `GET /v1/flows/:id`: Datos del flow: wokus en orden, branding y NPS vinculado.

**Respuestas**

* `200 OK`: Datos del flow o lista paginada.
* `403 Forbidden`: El flow pertenece a otra empresa.
* `404 Not Found`: No existe el flow.

## Invitaciones

Familia homogénea de endpoints para enviar encuestas por **correo** o **WhatsApp** a una lista de hasta 100 destinatarios. Los envíos son asíncronos: la API responde de inmediato con el detalle por destinatario.

**Endpoints**

```
POST /v1/nps/invitations
POST /v1/csat/invitations
POST /v1/ces/invitations
POST /v1/forms/:id/invitations
POST /v1/wokus/:id/invitations
```

**Body**

```json theme={null}
{
  "channel": "whatsapp",
  "recipients": ["56912345678"],
  "language": "es"
}
```

**Campos**

* `channel` *(string, obligatorio)*: `email` o `whatsapp`.
* `recipients` *(string\[], obligatorio, máx 100)*: Correos para el canal `email`; números con código de país (por ejemplo `56912345678`) para `whatsapp`.
* `language` *(string, opcional)*: `es` o `en`.
* `npsToolId` *(string, opcional, solo NPS)*: Si se omite, se envía la encuesta NPS a nivel de compañía.
* `csatToolId` / `cesToolId` *(string, obligatorio en CSAT y CES)*.

**Respuestas**

* `202 Accepted`: Resumen por destinatario: `accepted` (despachados o encolados) y `rejected` con el motivo (`invalid_recipient`, `quarantined`, `insufficient_credits_or_blocked`, `send_failed`).
* `400 Bad Request`: Validación fallida, o el formulario o woku está cerrado.
* `403 Forbidden`: La herramienta no pertenece a tu empresa.
* `404 Not Found`: No existe el formulario o el woku.

<Tip>
  Los destinatarios mal formados no hacen fallar la solicitud completa: se reportan individualmente en `rejected` con el motivo `invalid_recipient`.
</Tip>

## Cuarentenas

Consulta de solo lectura para saber si un respondente está actualmente en cuarentena, antes de pedirle feedback. No registra nada. Las reglas anti-duplicado se configuran en el panel administrativo; ver [Cuarentenas](/docs/configuracion/cuarentenas).

**Endpoint**

```
GET /v1/quarantines/check?email=<email>
```

**Query params**

* `email` *(string, opcional)*.
* `phone` *(string, opcional)*.

Se requiere al menos uno de los dos.

**Respuestas**

* `200 OK`: Estado de cuarentena del respondente.
* `400 Bad Request`: No se entregó ni `email` ni `phone`.
* `403 Forbidden`: Clave inválida.

## Reportes NPS

Si tu empresa usa la herramienta **NPS**, puedes consultar los reportes agregados directamente desde la API para integrarlos en tus propios dashboards.

### Reporte NPS de la compañía

Devuelve el reporte agregado de **todos los NPS** registrados para tu empresa.

**Endpoint**

```
GET /v1/reports/company-nps
```

**Headers**

* `Authorization: Bearer <Company-Key>`

**Respuestas**

* `200 OK`: Reporte con distribución de promotores, pasivos y detractores, y el puntaje NPS resultante.
* `403 Forbidden`: Clave inválida.

### Reporte NPS de una herramienta

Devuelve el reporte de un **NPS Tool** específico (por ejemplo, "NPS post-evento" o "NPS post-compra").

**Endpoint**

```
GET /v1/reports/nps-tool/:id
```

**Headers**

* `Authorization: Bearer <Company-Key>`

**Path params**

* `id` *(string, obligatorio)*: Identificador del NPS Tool.

**Respuestas**

* `200 OK`: Reporte del NPS Tool.
* `400 Bad Request`: `id` mal formado.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: El NPS Tool no existe o no pertenece a tu empresa.

## Trackers Externos

Los **trackers externos** te permiten asociar identificadores de tus sistemas (CRM, ERP, ticketing, OMS) a tus herramientas de feedback (wokus, NPS, CSAT, CES, formularios y flows) para luego buscarlas cruzadas. Por ejemplo: vincular un woku al `transaction_id` de tu CRM o al `order_id` de tu ERP.

### Modelo

* **Tracker definition**: Una entrada de catálogo a nivel de empresa, como `{ name: "trr", system: "crm interno", description: "..." }`. Se define en el panel administrativo de woku, en la sección Empresa.
* **Tracker value**: Un valor string ligado a un par `(herramienta, Tracker)`. Varias herramientas pueden compartir el mismo valor.

### Listar trackers activos de la empresa

**Endpoint**

```
GET /v1/external-trackers
```

**Query params**

* `page` *(number, opcional)*.
* `limit` *(number, opcional)*.

**Respuestas**

* `200 OK`: Lista paginada de definiciones de trackers.
* `403 Forbidden`: Clave inválida.

### Listar trackers asignados a un woku

**Endpoint**

```
GET /v1/external-trackers/wokus/:id
```

**Respuestas**

* `200 OK`: Trackers asignados al woku.
* `403 Forbidden`: Clave inválida.

### Asignar un valor de tracker a un woku

Crea o actualiza (upsert) el valor de un tracker en un woku.

**Endpoint**

```
POST /v1/external-trackers/wokus/:id
```

**Body**

```json theme={null}
{
  "name": "trr",
  "value": "TX-2026-00043"
}
```

**Campos**

* `name` *(string, obligatorio, máx 60)*: Nombre del tracker definido en tu empresa.
* `value` *(string, obligatorio, máx 500)*: Valor del identificador externo (siempre se almacena como string).

**Respuestas**

* `201 Created`: Valor asignado o actualizado.
* `400 Bad Request`: Validación fallida.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: El woku o el tracker no existen.

### Eliminar un valor de tracker de un woku

**Endpoint**

```
DELETE /v1/external-trackers/wokus/:id/:trackerName
```

**Respuestas**

* `200 OK`: Eliminado.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: El woku o el tracker no existen.

### Buscar wokus por tracker

Encuentra todos los wokus que tienen un determinado `(name, value)`. Útil para volver desde tu CRM al woku correspondiente.

**Endpoint**

```
GET /v1/external-trackers/search?name=<tracker>&value=<value>
```

**Query params**

* `name` *(string, obligatorio)*: Nombre del tracker.
* `value` *(string, obligatorio)*: Valor a buscar.
* `page` *(number, opcional)*.
* `limit` *(number, opcional)*.

**Respuestas**

* `200 OK`: Lista paginada de wokus con sus tracker values.
* `403 Forbidden`: Clave inválida.
* `404 Not Found`: No existen coincidencias.

### Trackers en herramientas VoC (NPS, CSAT, CES, formularios, flows)

Además de los wokus, puedes asignar trackers a las demás herramientas de feedback. El tipo de herramienta va en la ruta como `:entityType`, con uno de estos valores: `nps`, `csat`, `ces`, `form`, `flow`. El `:id` es el id de la herramienta (por ejemplo `npsToolId`, `csatToolId`, `cesToolId`, `formId` o `flowId`).

En la versión 2 de la API estos endpoints y los de wokus se unificarán en un único recurso polimórfico.

#### Listar trackers asignados a una herramienta

**Endpoint**

```
GET /v1/external-trackers/:entityType/:id
```

Ejemplo: `GET /v1/external-trackers/nps/671000000000000000000001`.

**Respuestas**

* `200 OK`: Trackers asignados a la herramienta.
* `400 Bad Request`: Tipo de herramienta no soportado.
* `403 Forbidden`: Clave inválida.

#### Asignar un valor de tracker a una herramienta

Crea o actualiza (upsert) el valor de un tracker en la herramienta.

**Endpoint**

```
POST /v1/external-trackers/:entityType/:id
```

**Body**

```json theme={null}
{
  "name": "trr",
  "value": "TX-2026-00043"
}
```

**Campos**

* `name` *(string, obligatorio, máx 60)*: Nombre del tracker definido en tu empresa.
* `value` *(string, obligatorio, máx 500)*: Valor del identificador externo (siempre se almacena como string).

**Respuestas**

* `201 Created`: Valor asignado o actualizado.
* `400 Bad Request`: Tipo no soportado, tracker inactivo o validación fallida.
* `403 Forbidden`: La herramienta pertenece a otra empresa.
* `404 Not Found`: La herramienta o el tracker no existen.

#### Eliminar un valor de tracker de una herramienta

**Endpoint**

```
DELETE /v1/external-trackers/:entityType/:id/:trackerName
```

**Respuestas**

* `200 OK`: Eliminado.
* `404 Not Found`: El tracker o la asignación no existen.

## Límites de ingesta y extracción

La API REST está documentada de forma interactiva en la pestaña **API
Reference** y aplica **límites de tasa y de volumen** tanto para la
**ingesta** (creación de wokus, reseñas, NPS, asignación de trackers) como
para la **extracción** (consulta de wokus, reportes y búsquedas). Los límites
cubren los dos modos de operación: **por evento** (una llamada por registro) y
**por lote** (cargas batch).

Los límites se aplican por **Clave de Compañía**:

| Operación                 | Modo          | Límite                                           |
| ------------------------- | ------------- | ------------------------------------------------ |
| Ingesta por evento        | Evento        | 600 solicitudes/minuto · hasta 50 eventos/seg    |
| Ingesta por lote          | Lote          | Hasta 5.000 registros por lote · 60 lotes/minuto |
| Volumen diario de ingesta | Evento + lote | 1.000.000 registros/día                          |
| Extracción (lectura)      | Evento        | 300 solicitudes/minuto                           |
| Extracción paginada       | Lote          | Hasta 200 registros por página                   |

<Note>
  Estos son los límites por defecto del plan **Corporate**. Si tu integración
  necesita ventanas mayores (picos estacionales, migraciones masivas),
  escríbenos para ampliarlos.
</Note>

### Manejo de 429 (Too Many Requests)

Cuando superas un límite de tasa, la API responde con `429 Too Many Requests`
e incluye encabezados que te indican cuándo reintentar:

* `Retry-After`: segundos a esperar antes del siguiente intento.
* `X-RateLimit-Limit`: tope de la ventana actual.
* `X-RateLimit-Remaining`: solicitudes restantes en la ventana.
* `X-RateLimit-Reset`: marca de tiempo en que se reinicia la ventana.

Implementa **reintentos con backoff exponencial** respetando `Retry-After`.
Para cargas batch, divide los lotes que excedan el máximo de registros en
lugar de reintentar el lote completo.

### Paginación en la extracción

Los endpoints de extracción que devuelven colecciones son **paginados**.
Controla la página con los query params `page` y `limit` (por ejemplo, en
`GET /v1/external-trackers` o `GET /v1/external-trackers/search`). Para
extraer grandes volúmenes, recorre las páginas de forma secuencial respetando
el límite de extracción por minuto y el máximo de registros por página.

```
GET /v1/external-trackers/search?name=trr&value=TX-2026-00043&page=1&limit=200
```

## Errores comunes

### URL de archivo inaccesible

Si usas `POST /v1/wokus` con `fileUrl`, asegúrate de que la URL sea **públicamente accesible**. Nuestro servicio descarga el archivo antes de crear el woku.

### Clave secundaria duplicada

`folderSecondaryKey` se usa para identificar una carpeta dentro de tu empresa. **No pueden existir dos carpetas con la misma clave** en una misma empresa. Si necesitas reutilizar una clave, primero elimina la carpeta existente desde el panel administrativo.

### 403 en todas las llamadas

Casi siempre significa que la clave es incorrecta, está caducada o pertenece a otra empresa. Vuelve a obtener la clave desde [admin.woku.app](https://admin.woku.app) → Información de la empresa → **Obtener Clave**.

## Contacto y soporte

* Diego Orrego Brito, CTO de woku.
* Correo: [diego@woku.app](mailto:diego@woku.app) (incluye el nombre de la empresa en el asunto y menciona que se trata de la API).
