Digitra Rentals para desarrolladores

Webhooks

Digitra le avisa a tu sistema, con un POST firmado a la URL que registres, cada vez que una reserva creada por la API avanza: registro de huéspedes, firma del contrato, reportes a TRA y SIRE, cambios y cancelaciones.


1. Registrar tu endpoint

curl -X POST https://digitra.rentals/api/partners/webhooks \
  -H "Authorization: Bearer $DIGITRA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://tu-servidor.com/webhooks/digitra",
    "events": ["*"],
    "include_guests": true
  }'

Respuesta 201:

{
  "id": "0b7e9f2a-1c3d-4e5f-8a9b-0c1d2e3f4a5b",
  "url": "https://tu-servidor.com/webhooks/digitra",
  "events": ["*"],
  "include_guests": true,
  "is_active": true,
  "created_at": "2026-09-30T15:04:05.000Z",
  "secret_rotated_at": null,
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Otras operaciones:

Operación Endpoint
Listar tus endpoints GET /api/partners/webhooks
Cambiar URL, eventos o include_guests PATCH /api/partners/webhooks/{id}
Desactivar DELETE /api/partners/webhooks/{id}
Rotar el secreto POST /api/partners/webhooks/{id}/rotate-secret
Enviar un evento de prueba (ping) POST /api/partners/webhooks/{id}/test
Historial de entregas GET /api/partners/webhooks/deliveries
Reenviar un evento POST /api/partners/webhooks/deliveries/{id}/redeliver

Al rotar, el secreto viejo deja de valer en ese instante. Todo lo que salga desde entonces, incluidos los reintentos de eventos anteriores, va firmado con el nuevo.


2. Qué recibe tu servidor

POST /webhooks/digitra HTTP/1.1
Content-Type: application/json
User-Agent: Digitra-Webhooks/1.0
X-Digitra-Event-Id: evt_3f9a1c2b4d5e6f708192a3b4c5d6e7f8
X-Digitra-Event: registration.completed
X-Digitra-Timestamp: 1727710000
X-Digitra-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
Header Contenido
X-Digitra-Event-Id Id único del evento. Es igual al campo id del cuerpo. Úsalo para deduplicar.
X-Digitra-Event Tipo de evento.
X-Digitra-Timestamp Momento del envío, en segundos Unix.
X-Digitra-Signature sha256= + HMAC-SHA256 en hexadecimal.

Cuerpo

Todos los eventos comparten la misma forma:

{
  "id": "evt_3f9a1c2b4d5e6f708192a3b4c5d6e7f8",
  "type": "registration.completed",
  "created_at": "2026-10-01T15:04:05.000Z",
  "api_version": "2026-10-01",
  "sandbox": false,
  "data": {
    "reservation_id": "manual-1727650000000",
    "external_id": "65a1b2c3d4e5f6a7b8c9d0e1",
    "source": "guesty",
    "property_id": "3f1c2b9a-0d4e-4a51-9a7e-2b6f0c8d1e23",
    "reservation_status": "confirmed",
    "status": "pending_compliance",
    "check_in": "2026-10-10",
    "check_out": "2026-10-12",
    "guests_count": 2,
    "checkin_url": "https://digitra.rentals/checkin/8b0c4f7e-2a1d-4c3b-9e5f-6a7b8c9d0e1f",
    "checkin_status": "completed",
    "guests_registered": 2,
    "contract_signed": false,
    "tra": { "status": "pending", "sends_on": "2026-10-12", "reported_at": null, "mincit_code": null },
    "sire": { "status": "pending", "foreign_guests": 1, "reported_at": null },
    "metadata": { "guesty_listing": "64f1a2b3c4d5e6f7a8b9c0d1", "canal": "airbnb" },
    "guests": [
      {
        "is_primary": true,
        "tipo_documento": "Pasaporte",
        "numero_documento": "X1234567",
        "nombre": "Ana",
        "apellido": "Ejemplo",
        "nacionalidad": "US",
        "fecha_nacimiento": "1990-01-01",
        "email": "huesped@ejemplo.com",
        "phone": "+15550000000",
        "address": null,
        "ciudad_residencia": "Miami",
        "pais_residencia": "US",
        "registered_at": "2026-10-01T15:03:58.000Z",
        "document_uploaded": true
      }
    ]
  }
}

Tipos de documento posibles en tipo_documento: Pasaporte, C.C, C.E, T.I, R.C, D.E (documento extranjero, Mercosur/CAN), C.D (carné diplomático), PPT (Permiso por Protección Temporal).


3. Catálogo de eventos

Evento Cuándo llega
reservation.created Se creó la reserva por la API.
reservation.updated Cambiaron las fechas o el número de huéspedes.
reservation.cancelled La reserva se canceló. Después de este evento no llega ninguno más para esa reserva.
registration.updated Se registró un huésped, pero todavía faltan otros.
registration.completed Se registraron todos los huéspedes. Si la propiedad exige contrato, status será pending_signature hasta que se firme.
contract.signed El huésped firmó el contrato.
tra.reported MinCIT aceptó el reporte TRA. data.tra.mincit_code trae el código asignado.
tra.failed MinCIT rechazó el TRA. data.tra.warning explica el motivo cuando lo conocemos.
sire.reported Migración Colombia aceptó el reporte SIRE de entrada.
sire.failed Migración Colombia rechazó el reporte SIRE.
ping Evento de prueba, cuando lo pides con /test. Llega siempre, sin importar los eventos suscritos.

Si en una misma revisión cambian varias cosas (por ejemplo, el huésped completa el registro y firma), recibes un evento por cada cambio.


4. Verificar la firma

Digitra calcula la firma así:

firma = "sha256=" + hex( HMAC_SHA256( secreto, "{X-Digitra-Timestamp}.{cuerpo crudo}" ) )

Tu receptor debe:

  1. Tomar el cuerpo crudo, exactamente como llegó. No lo parsees y lo vuelvas a serializar antes de verificar: cambiaría los bytes y la firma no coincidiría.
  2. Rechazar el evento si X-Digitra-Timestamp tiene más de 5 minutos de diferencia con tu reloj. Esto evita que alguien reenvíe un evento viejo interceptado.
  3. Calcular la firma esperada con tu secreto y compararla con X-Digitra-Signature en tiempo constante (crypto.timingSafeEqual en Node, hmac.compare_digest en Python).
  4. Si no coincide, responder 401 y descartar el evento.

Hay ejemplos probados en verificar-firma.js (Node.js) y verificar_firma.py (Python). Los verificamos contra firmas generadas por nuestro propio servidor.

Para probar tu verificación sin crear reservas, usa el evento de prueba:

curl -X POST https://digitra.rentals/api/partners/webhooks/{id}/test \
  -H "Authorization: Bearer $DIGITRA_KEY"
{ "event_id": "evt_...", "delivered": true, "http_status": 200, "duration_ms": 184 }

5. Entrega y reintentos

Orden y duplicados

Historial y reenvío

curl "https://digitra.rentals/api/partners/webhooks/deliveries?status=failed&limit=50" \
  -H "Authorization: Bearer $DIGITRA_KEY"

Filtros: status (pending, delivered, failed), event, external_id, limit (máx. 200). Cada entrega trae attempt_log con cada intento: fecha, código HTTP, duración y error.

Para reenviar un evento failed (o uno entregado que perdiste de tu lado):

curl -X POST https://digitra.rentals/api/partners/webhooks/deliveries/{id}/redeliver \
  -H "Authorization: Bearer $DIGITRA_KEY"

Sale con el mismo event_id y un ciclo de reintentos completo.


6. Ambiente de pruebas

Con la llave dgt_test_ registras endpoints de prueba, separados de los de producción. Los eventos traen "sandbox": true y los reportes vienen con "simulated": true. Para recibir tra.failed o sire.failed, crea la reserva con "sandbox_simulate": "tra_failed" o "sire_failed".