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

# Webhooks

> Te avisamos cuando un documento termina, para que te lo lleves a tu sistema.

Registra una URL HTTPS de tu aplicación y te enviaremos un `POST` firmado cada vez que un documento de ese proyecto
termine. Es la forma de llevarte cada documento a tu sistema antes de que acabe su [retención](/guides/retention), sin
consultar la API cada poco.

## Registrar un endpoint

En el panel, **Webhooks → Añadir endpoint**, o con la API:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl https://api.eu.doconda.com/v1/webhook-endpoints \
  -H "Authorization: Bearer $DOCONDA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tu-app.com/webhooks/doconda" }'
```

La respuesta trae el `secret` (`whsec_…`) **solo una vez**: guárdalo. La URL tiene que ser HTTPS y estar en una
dirección pública. Cada endpoint es de un proyecto. `GET /webhook-endpoints` los lista y
`DELETE /webhook-endpoints/{id}` borra uno.

## Qué te enviamos

Los eventos finales: `document.ready`, `document.failed` y `document.canceled` (con `event_types` puedes quedarte solo
con algunos). Nunca el contenido del documento: pídelo con `GET /documents/{id}` y descarga sus ficheros. [Leer un
fichero](/guides/extract) no avisa: es una lectura y su respuesta ya trae el texto.

```json theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "type": "document.ready",
  "timestamp": "2026-10-04T12:00:00.000Z",
  "data": {
    "document_id": "doc_01J…",
    "status": "ready",
    "operation": "create",
    "format": "docx",
    "retention": "30d",
    "expires_at": "2026-11-03T12:00:00.000Z",
    "error": null
  }
}
```

## Comprobar la firma

Seguimos [Standard Webhooks](https://www.standardwebhooks.com): cabeceras `webhook-id`, `webhook-timestamp` y
`webhook-signature` (`v1,` + HMAC-SHA256 en base64 de `{id}.{timestamp}.{cuerpo}`, con la clave que va tras `whsec_`,
decodificada de base64). Con el SDK:

```ts theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { verifyWebhook } from "@doconda/sdk"

const event = await verifyWebhook(rawBody, request.headers, process.env.DOCONDA_WEBHOOK_SECRET)
if (event.type === "document.ready") {
  const files = await doconda.documents.outputs(event.data.document_id)
}
```

Usa el cuerpo tal cual llega (sin volver a serializar el JSON). `verifyWebhook` rechaza una firma que no cuadra y un
mensaje de hace más de 5 minutos.

## Reintentos

Responde con un `2xx` en menos de 20 segundos. Si no, reintentamos durante unas 10 horas: a los 5 s, 30 s, 2 min,
10 min, 30 min, 1 h, 3 h y 6 h. Un mismo evento puede llegarte más de una vez: deduplica por `webhook-id`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.