> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ovac.councilbox.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ovac.councilbox.com/_mcp/server.

# Integración de Webhooks - OVAC

Los webhooks de OVAC notifican en tiempo real a sistemas externos los cambios de estado y acciones producidas sobre las citas y salas de videoconferencia.

## 1. Requisitos previos para la activación

Para configurar y activar los envíos, el cliente/integrador debe proporcionar:

1. **Endpoint URL:** Dirección HTTPS pública accesible para recibir los eventos.

2. **Tipo de API / Método:** Recepción mediante protocolo HTTP/HTTPS (típicamente `POST`).

3. **Mecanismo de seguridad:**

   * Sin autenticación (no recomendado).

   * Basic Auth / Bearer Token estático en cabecera `Authorization`.

   * API Key en cabecera personalizada (ej. `X-API-Key`).

   * Firma HMAC (secreto compartido).

## 2. Política de reintentos

Si el endpoint del cliente responde con un código de estado HTTP distinto a `2xx`, el sistema ejecutará hasta un máximo de **5 intentos** con el siguiente intervalo:

* **Intento 1:** a los 5 segundos de la primera comunicación.

* **Intento 2:** 10 segundos después del intento anterior.

* **Intento 3:** 20 segundos después del intento anterior.

* **Intento 4:** 30 minutos después del intento anterior.

* **Intento 5:** 6 horas después del intento anterior.

> **Nota de consistencia:** Si ante un reintento de un webhook fallido la cita ya ha avanzado de estado, OVAC responderá adecuadamente enviando el estado real y actualizado de la cita.

## 3. Diccionario de estados (`state`)

Cada webhook incluye el estado actual de la cita en el campo numérico `state`. El mapa de valores es el siguiente:

| Valor    | Estado              | Descripción                                                        |
| -------- | ------------------- | ------------------------------------------------------------------ |
| **`-1`** | **Cancelado**       | La cita ha sido anulada.                                           |
| **`10`** | **Confirmado**      | La cita está agendada y confirmada.                                |
| **`20`** | **Sala abierta**    | La sala de videoconferencia/gestión está habilitada.               |
| **`25`** | **Pausada**         | La celebración de la cita se ha interrumpido temporalmente.        |
| **`40`** | **Finalizada**      | La reunión o cita ha concluido.                                    |
| **`45`** | **Procesando acta** | El sistema está generando la documentación/evidencias.             |
| **`60`** | **Completa**        | El proceso ha terminado con éxito y el acta está disponible.       |
| **`65`** | **Incompleta**      | La cita finalizó pero falta información o no se completó el flujo. |

## 4. Ejemplos de payload por evento (`type`)

Las peticiones recibidas en el endpoint del cliente tendrán formato JSON plano. El evento disparado se identifica en el campo `"type"`.

A continuación, se documenta la estructura exacta de cada evento emitido por el sistema:

### 4.1. Creación y convocatoria (`CONVENE_COUNCIL_WITH_NOTICE`)

Se genera la cita y se notifica a los participantes.

```json
{
  "councilId": 606618,
  "state": 10,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-08T11:34:36.096Z",
  "userId": 5336,
  "type": "CONVENE_COUNCIL_WITH_NOTICE"
}
```

### 4.2. Asignación de profesional (`COUNCIL_ASSIGNED`)

Se asigna un usuario gestor/profesional a la cita. Incluye los campos extra `appointedTo` y `appointedBy`.

```json
{
  "councilId": 603496,
  "state": 10,
  "name": "Obtención del Número de Seguridad Social",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-02T06:55:58.706Z",
  "userId": 4680,
  "appointedTo": 5456,
  "appointedBy": 4680,
  "type": "COUNCIL_ASSIGNED"
}
```

### 4.3. Reagendar cita (`APPOINTMENT_RESCHEDULED`)

Se modifica la fecha/hora de celebración. Incluye `rescheduledBy` y `userType`.

```json
{
  "councilId": 603496,
  "state": 10,
  "name": "Obtención del Número de Seguridad Social",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-02T06:55:58.825Z",
  "userId": 4680,
  "rescheduledBy": 4680,
  "userType": "admin",
  "type": "APPOINTMENT_RESCHEDULED"
}
```

### 4.4. Cancelación de cita (`APPOINTMENT_CANCELLED`)

Se anula la cita. El `state` pasa a `-1` e incluye `cancelledBy` y `userType`. Dependiendo de quién realice la acción, los campos de identificación variarán:

**Alternativa A: Cancelado por el participante (o sistema externo)**
Los identificadores del usuario activo devuelven `-1`.

```json
{
  "councilId": 606694,
  "state": -1,
  "name": "Obtención del Número de Seguridad Social",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-12T07:40:02.265Z",
  "userId": -1,
  "cancelledBy": -1,
  "userType": "admin",
  "type": "APPOINTMENT_CANCELLED"
}
```

**Alternativa B: Cancelado por un usuario/admin identificado**
Se devuelven los IDs del gestor o administrador que efectuó la cancelación desde la plataforma.

```json
{
  "councilId": 605735,
  "state": -1,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T15:55:39.602Z",
  "userId": 5345,
  "cancelledBy": 5345,
  "userType": "admin",
  "type": "APPOINTMENT_CANCELLED"
}
```

### 4.5. Apertura de sala (`OPEN_COUNCIL_ROOM`)

La sala virtual queda abierta para el acceso de los participantes. El `state` avanza a `20`.

```json
{
  "councilId": 606618,
  "state": 20,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T11:20:22.705Z",
  "userId": 5457,
  "type": "OPEN_COUNCIL_ROOM"
}
```

### 4.6. Inicio de cita (`START_COUNCIL`)

Comienza formalmente la sesión o reunión.

```json
{
  "councilId": 606618,
  "state": 20,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T11:22:09.042Z",
  "userId": 5457,
  "type": "START_COUNCIL"
}
```

### 4.7. Fin de cita (`END_COUNCIL`)

Concluye la reunión. El `state` avanza a `40`.

```json
{
  "councilId": 606618,
  "state": 40,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T11:28:17.063Z",
  "userId": 5457,
  "type": "END_COUNCIL"
}
```

### 4.8. Procesando acta (`PROCESSING_ACT`)

El sistema inicia la generación de evidencias. El `state` avanza a `45`. Este estado está vinculado a clientes que tengan activo sistema de insercción de footer en el acta de OVAC.

```json
{
  "councilId": 606618,
  "state": 45,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T11:28:23.044Z",
  "userId": 5457,
  "type": "PROCESSING_ACT"
}
```

### 4.9. Acta procesada (`PROCESSED_ACT_UPLOADED`)

El acta final queda firmada y disponible. El `state` avanza a `60` (Completa).

```json
{
  "councilId": 606618,
  "state": 60,
  "name": "Comunicación o modificación de datos de contacto",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2026-10-13T11:28:28.882Z",
  "userId": 5181,
  "type": "PROCESSED_ACT_UPLOADED"
}
```

### 4.10. Aprobación de acta (`APPROVE_COUNCIL_ACT`)

El documento/acta es aprobado formalmente por parte de un agente, en este caso no existe integración para insercción de footer del cliente en el acta de OVAC.

```json
{
  "councilId": 508545,
  "state": 60,
  "name": "Cambio NIE a DNI",
  "organizationId": 1440,
  "externalId": null,
  "companyId": 1453,
  "date": "2025-06-17T08:08:38.312Z",
  "userId": 4627,
  "type": "APPROVE_COUNCIL_ACT"
}
```

### 4.11. Acción del participante en un paso (`PARTICIPANT_STEP_ACTION`)

Se dispara cuando un participante (ciudadano) realiza una acción dentro de un paso específico de la cita (por ejemplo, aceptar condiciones, etc.). El `state` siempre es `20` ya que requiere que la sala esté activa.

En este evento, el campo `userId` corresponde al identificador interno de OVAC del participante. Además, incluye detalles específicos de la acción como el ID de la agenda/paso (`agendaId`) y el resultado de la acción (`value` y `valueText`).

```json
{
  "councilId": 70353,
  "state": 20,
  "name": "[TEST GESTIÓN]  Gestión sin videoatención",
  "organizationId": 1581,
  "companyId": 1590,
  "date": "2026-10-14T09:59:10.257Z",
  "userId": 162451,
  "agendaId": 94786,
  "participantId": 162451,
  "type": "PARTICIPANT_STEP_ACTION",
  "value": 1,
  "valueText": "ACCEPT"
}
```

## 5. Ejecución de reintentos bajo demanda (Batch)

OVAC dispone de un endpoint para forzar la ejecución de los webhooks erróneos de manera periódica.

* **Autenticación:** Requiere petición previa de login para obtener el Token temporal.

* **Endpoint:** Consultar la sección "Webhooks Batch" en la documentación de la API de OVAC.