# General Translation Platform: Webhooks
URL: https://generaltranslation.com/es/docs/platform/dashboard/reference/webhooks.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Configura endpoints de webhook, verifica firmas y gestiona eventos de traducción de General Translation. Referencia para webhooks.

Los webhooks envían eventos de traducción a tu backend mediante solicitudes HTTP POST firmadas. Úsalos para activar tus propios flujos de trabajo cuando cambien archivos o trabajos.

*Nota: los webhooks requieren un plan Team o Enterprise.*

## Crear un webhook [#create-webhook]

1. Ve a **Organization &gt; Developer &gt; Webhooks**.
2. Haz clic en **Agregar endpoint**.
3. Introduce la URL del endpoint en el que quieres recibir eventos. La URL debe usar HTTPS.
4. Selecciona los tipos de eventos a los que quieres suscribirte.
5. Haz clic en **Crear endpoint**.

Después de crear el endpoint, abre la página de detalles del webhook y copia el secreto de firma. Usa este secreto para verificar que las solicitudes entrantes provienen de General Translation.

Puedes crear hasta **5 endpoints de webhook** por Organization.

## Tipos de eventos [#event-types]

Cada endpoint puede suscribirse a uno o varios tipos de eventos. Puedes actualizar las suscripciones desde la página de detalles del webhook.

* `translated_file.completed` se activa cuando un archivo traducido se completa y queda listo para descargarse.
* `translated_file.edited` se activa cuando un usuario edita manualmente un archivo traducido en el Translation Editor.
* `translation_job.completed` se activa cuando finaliza un trabajo de traducción.

## Formato del payload [#payload-format]

Cada entrega de webhook se realiza mediante una solicitud HTTP POST con un cuerpo JSON:

```json
{
  "id": "evt_xxx",
  "type": "translated_file.completed",
  "created_at": "2026-04-30T12:00:00.000Z",
  "api_version": "2026-03-06.v1",
  "data": {
    "object": {
      "id": "file_xxx",
      "org_id": "org_xxx",
      "project_id": "project_xxx",
      "branch_id": "branch_xxx",
      "source_file_id": "src_xxx",
      "file_id": "file_xxx",
      "version_id": "ver_xxx",
      "locale": "fr",
      "file_format": "json",
      "data_format": null,
      "completed_at": "2026-04-30T12:00:00.000Z"
    }
  }
}
```

El `id` de nivel superior es un identificador de evento estable que puedes usar para eliminar entregas duplicadas.

## Verificar firmas [#verify-signatures]

Cada solicitud de webhook incluye tres cabeceras:

* `webhook-id` es el ID del evento, por ejemplo `evt_xxx`.
* `webhook-timestamp` es la marca de tiempo Unix, en segundos, en la que se envió la solicitud.
* `webhook-signature` es la firma `v1,<base64-hmac>`.

La firma sigue la convención de [Standard Webhooks](https://www.standardwebhooks.com/).

Para verificar una solicitud:

1. Concatena `{webhook-id}.{webhook-timestamp}.{raw request body}`.
2. Decodifica el secreto en Base64 después de quitar el prefijo `whsec_` para obtener la clave de firma.
3. Calcula el HMAC-SHA256 de la cadena concatenada usando la clave de firma decodificada.
4. Codifica el resultado en Base64.
5. Compáralo con el valor de la firma después del prefijo `v1,`.
6. Comprueba que la marca de tiempo esté dentro de los 5 minutos con respecto a la hora actual para evitar ataques de repetición.

### Ejemplo: Node.js

```js
import crypto from "crypto";

function verifyWebhook(payload, headers, secret) {
  const msgId = headers["webhook-id"];
  const timestamp = headers["webhook-timestamp"];
  const signature = headers["webhook-signature"];

  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    throw new Error("Timestamp too old");
  }

  const signingKey = Buffer.from(secret.replace("whsec_", ""), "base64");
  const signedContent = `${msgId}.${timestamp}.${payload}`;
  const expected = crypto
    .createHmac("sha256", signingKey)
    .update(signedContent)
    .digest("base64");

  const received = signature.split(",")[1];
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
    throw new Error("Invalid signature");
  }

  return JSON.parse(payload);
}
```

También puedes usar la biblioteca [Standard Webhooks](https://www.standardwebhooks.com/) para tu lenguaje de programación, que se encarga de verificar automáticamente.

## Gestiona los reintentos y la entrega [#handle-retries-delivery]

Los webhooks usan **entrega con garantía de al menos una vez**.

Si tu endpoint no devuelve una respuesta `2xx` en un plazo de 10 segundos, la entrega se vuelve a intentar con backoff exponencial hasta un máximo de **10 intentos**.

Puedes volver a intentar manualmente una entrega fallida desde **Organization &gt; Developer &gt; Webhook Events** en el panel de control. Selecciona el evento en la lista, luego coloca el cursor sobre una fila en **Intentos de entrega** y haz clic en **Reintentar**.

Expande un intento fallido para inspeccionar su campo **Error**. Si la respuesta no es `2xx`, el error incluye el estado HTTP y puede incluir un extracto depurado del cuerpo de la respuesta del endpoint. General Translation lee hasta 4,096 bytes de la respuesta y almacena como máximo 500 caracteres para diagnóstico.

## Ver eventos e intentos de entrega [#view-events]

1. Ve a **Organization &gt; Developer &gt; Webhook Events**.
2. Selecciona un evento de la lista de eventos activados en tu Organization.
3. Revisa los **intentos de entrega** de ese evento.

Cada intento muestra un estado, una URL de endpoint y una marca de tiempo. Expande un intento con un resultado registrado para comprobar si fue **Automático** o **Manual**, su latencia de ida y vuelta y un resumen de **Error** en caso de fallos de transporte, como errores de conexión o tiempos de espera. Los intentos pendientes sin un resultado registrado no se pueden expandir.

Los reintentos automáticos aparecen como entregas **Automáticas**. Los reintentos iniciados desde el panel de control aparecen como **Manuales**.

## Gestiona eventos duplicados [#handle-duplicate-events]

Como la entrega se realiza al menos una vez, tu endpoint puede recibir el mismo evento más de una vez. Usa el campo `id` del payload para deduplicarlos.

```js
app.post("/webhooks/gt", (req, res) => {
  const eventId = req.body.id;

  if (alreadyProcessed(eventId)) {
    return res.status(200).send("OK");
  }

  // Procesar el evento...
  markProcessed(eventId);
  res.status(200).send("OK");
});
```

## Gestionar endpoints [#manage-endpoints]

Desde **Organization &gt; Developer &gt; Webhooks**, puedes:

* Habilitar o deshabilitar un endpoint sin eliminarlo
* Actualizar los tipos de eventos a los que está suscrito
* Mostrar el secreto de firma
* Eliminar el endpoint

Desde **Organization &gt; Developer &gt; Webhook Events**, puedes ver el historial de entregas, inspeccionar intentos de entrega individuales y reintentar una entrega fallida.

## Buenas prácticas [#best-practices]

* Responde rápido con una respuesta `2xx` y luego procesa el evento de forma asíncrona.
* Verifica la cabecera `webhook-signature` antes de confiar en el payload.
* Almacena los IDs de los eventos ya procesados y omite los duplicados.
* Usa HTTPS para los endpoints de webhook en producción.
* Supervisa **Webhooks &gt; Events** para detectar fallos persistentes en las entregas.

## Permisos [#permissions]

Para gestionar endpoints de webhook y reintentar entregas, se requiere el permiso `org:webhooks:write`.

Para ver eventos e intentos de entrega, se requiere `org:webhooks:read`.

De forma predeterminada, los roles **Admin** y **Developer** tienen ambos permisos. (Consulta [roles y permisos](/docs/platform/dashboard/reference/roles-and-permissions) para más detalles).

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
