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

# Guía de Implementación

## Requisitos del endpoint receptor

* Debe aceptar solicitudes HTTP POST.
* Debe leer el cuerpo como JSON (Content-Type: application/json).
* Debe responder con HTTP 200 para confirmar la recepción.
* Debe ser accesible públicamente desde Internet. La URL debe usar HTTPS.

### 💻 Ejemplos

<CodeGroup>
  ```javascript Node.js (Express) theme={null}
  const express = require('express');
  const app = express();
  app.use(express.json());
  app.post('/webhook-handler', (req, res) => {
    const { event_type, task_id, status, participation } = req.body;
    console.log('Evento recibido:', event_type);
    console.log('Tarea ID:', task_id, '| Estado:', status);
    if (event_type === 'PARTICIPATION_STATUS_CHANGED' && participation) {
      console.log('Participante:', participation.participant_email);
      if (participation.biometrics?.requires_manual_review) {
        // Lógica para revisión manual
      }
    }
    res.sendStatus(200); // Confirmar recepción
  });
  app.listen(3000);
  ```

  ```python Python (Flask) theme={null}
  from flask import Flask, request
  app = Flask(__name__)
  @app.route('/webhook-handler', methods=['POST'])
  def webhook():
      data = request.get_json()
      event_type = data.get('event_type')
      task_id    = data.get('task_id')
      status     = data.get('status')
      participation = data.get('participation')
      print(f'Evento: {event_type} | Tarea: {task_id} | Estado: {status}')
      if event_type == 'PARTICIPATION_STATUS_CHANGED' and participation:
          needs_review = participation.get('biometrics', {}).get('requires_manual_review')
          if needs_review:
              pass  # Lógica para revisión manual
      return '', 200
  if __name__ == '__main__':
      app.run(port=3000)
  ```
</CodeGroup>

***

## Buenas prácticas

* Diseñar el modelo de datos de forma flexible: no rechazar payloads por tener campos desconocidos.
* Responder 200 siempre y rápido: procesar el evento de forma asíncrona si la lógica es costosa.
* Implementar idempotencia: usar task\_id + participation\_id como clave de deduplicación.
* Registrar todos los payloads recibidos antes de procesarlos para facilitar la depuración.
* No bloquear el hilo de procesamiento: delegar la lógica de negocio a una cola de tareas.

***

## Limitaciones y consideraciones

* El webhook solo puede configurarse al crear la tarea; no es modificable después.
* Cada tarea tiene un único webhook. No es posible configurar múltiples URLs.
* El evento PARTICIPATION\_STATUS\_CHANGED actualmente solo se emite cuando la participación requiere validación manual.
* No existe reintento automático documentado en caso de fallo del endpoint receptor.
