Webhooks
Los webhooks le permiten recibir notificaciones en tiempo real cuando ocurren eventos en su cuenta de LabelGrid. Use webhooks para automatizar flujos de trabajo e integrar con sistemas externos.
Para Desarrolladores: También puede gestionar webhooks programáticamente a través de la API. Consulte la Documentación de la API de LabelGrid para endpoints y ejemplos.
Cómo Funcionan los Webhooks
Sección titulada «Cómo Funcionan los Webhooks»- Configure un webhook** - Especifique una URL y qué eventos escuchar
- Ocurre un evento - Por ejemplo, un lanzamiento se entrega a una tienda
- LabelGrid envía una solicitud POST - Su servidor recibe los datos del evento
- Su sistema lo procesa - Automatiza flujos de trabajo basados en el evento
Accediendo a Webhooks
Sección titulada «Accediendo a Webhooks»- Haga clic en su ícono de perfil en la esquina superior derecha
- Seleccione Webhooks del menú desplegable
Creando un Webhook
Sección titulada «Creando un Webhook»- Haga clic en Create Webhook
- Ingrese un Name para identificar este webhook
- Ingrese la URL donde quiere recibir notificaciones
- Seleccione qué Events deben activar este webhook
- Haga clic en Create
Secreto del Webhook
Sección titulada «Secreto del Webhook»Cuando crea un webhook, recibirá una clave secreta. Úsala para verificar que las solicitudes entrantes son realmente de LabelGrid:
- Almacena el secreto de forma segura
- Verifique la firma en las solicitudes entrantes
- Si está comprometido, regenera el secreto
Eventos Disponibles
Sección titulada «Eventos Disponibles»Configure su webhook para escuchar estos eventos. El Identificador de Evento es el valor que verá en la propiedad event del payload y en el encabezado X-Webhook-Event:
| Identificador de Evento | Descripción |
|---|---|
delivery.completed | Se activa cuando un lanzamiento se entrega exitosamente a un outlet |
delivery.failed | Se activa cuando la entrega a un outlet falla |
takedown.completed | Se activa cuando una solicitud de retiro se completa |
release.review.status_changed | Se activa cuando el estado de revisión de un lanzamiento cambia |
release.preflight.report_ready | Se activa cuando el informe de Preflight QC de un lanzamiento en espera está listo para obtenerse |
stream_radar.flag_created | Se activa cuando se genera un aviso de Stream Radar, o cuando un aviso resuelto se reabre tras una nueva detección |
stream_radar.flag_resolved | Se activa cuando un aviso de Stream Radar se resuelve porque cesaron las detecciones |
release.distributed | Se activa cuando un lanzamiento es distribuido |
payment.statement_ready | Se activa cuando una declaración de pago está lista para visualizar |
transcode.completed | Se activa cuando la transcodificación de audio de una pista finaliza correctamente |
transcode.failed | Se activa cuando la transcodificación de una pista falla o termina incompleta |
distribution.outlet.status_changed | Se activa en cada transición del estado de distribución por outlet |
Puede seleccionar múltiples eventos para un solo webhook, o crear webhooks separados para diferentes tipos de eventos.
También puede leer está lista de forma programática: GET /api/public/webhooks/event-types devuelve cada evento junto con un esquema data que describe las claves y los tipos de su carga útil, de modo que los consumidores con esquema estricto pueden ampliar su validación de entrada con antelación.
Administrando Webhooks
Sección titulada «Administrando Webhooks»Viendo Sus Webhooks
Sección titulada «Viendo Sus Webhooks»La lista de webhooks muestra:
| Columna | Descripción |
|---|---|
| Name | El nombre del webhook que asignó |
| URL | Donde se envían las notificaciones |
| Events | Número de eventos configurados |
| Status | Activo o Inactivo |
| Success / Fail | Conteo de entregas exitosas y fallidas |
| Last Triggered | Cuándo se llamó al webhook por última vez |
Editando un Webhook
Sección titulada «Editando un Webhook»- Haga clic en la acción Edit en la fila del webhook
- Modifica el nombre, URL o eventos
- Haga clic en Save
Activando / Desactivando
Sección titulada «Activando / Desactivando»Cambie el estado activo de un webhook sin eliminarlo:
- Active - El webhook recibirá notificaciones
- Inactive - El webhook está pausado, no se envían notificaciones
Eliminando un Webhook
Sección titulada «Eliminando un Webhook»- Haga clic en la acción Delete en la fila del webhook
- Confirme la eliminación
Probando Webhooks
Sección titulada «Probando Webhooks»Antes de depender de un webhook en producción, pruébalo:
- Haga clic en la acción Test en su webhook
- LabelGrid envía una carga útil de prueba a su URL
- Verifique que su endpoint recibió y procesó correctamente
Viendo Registros de Webhook
Sección titulada «Viendo Registros de Webhook»Monitoree la actividad del webhook y soluciona problemas:
- Haga clic en la acción View Logs en un webhook
- Ve un historial de todas las entregas del webhook
Detalles del Registro
Sección titulada «Detalles del Registro»Cada entrada de registro muestra:
| Campo | Descripción |
|---|---|
| Event Type | Qué evento activó esta entrega |
| Response Status | Código de estado HTTP de su servidor |
| Duration | Cuánto tiempo tomó la solicitud |
| Attempt | Número de intento de reintento |
| Timestamp | Cuándo ocurrió la entrega |
Formato de Carga Útil del Webhook
Sección titulada «Formato de Carga Útil del Webhook»Cuando ocurre un evento, LabelGrid envía una solicitud POST a su URL con una carga útil JSON:
{ "event": "delivery.completed", "timestamp": "2026-05-05T10:00:00+00:00", "webhook_id": "123", "data": { // Datos específicos del evento }}El campo timestamp use el formato ISO 8601. webhook_id es el ID de su webhook configurado (coincide con el encabezado X-Webhook-Id).
Cargas Útiles de Eventos
Sección titulada «Cargas Útiles de Eventos»La estructura del objeto data depende del tipo de event. Todos los tipos de campos a continuación son tipos JSON tal como se serializan en la carga útil.
delivery.completed
Sección titulada «delivery.completed»Se activa una vez por outlet cuando la entrega de un lanzamiento alcanza un estado de éxito terminal.
{ "event": "delivery.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete" }}| Campo | Tipo | Descripción |
|---|---|---|
distro_queue_id | integer | ID interno de la cola para este intento de entrega |
release_id | integer | El lanzamiento que fue entregado |
label_id | integer | El sello propietario del lanzamiento, para que pueda enrutar el evento sin una consulta adicional |
release_cat | string | null | Su referencia de catálogo del lanzamiento |
outlet_id | integer | null | El ID del outlet de destino |
outlet_name | string | null | Nombre legible del outlet (por ejemplo, "Spotify") |
status | string | Siempre "complete" para este evento |
delivery.failed
Sección titulada «delivery.failed»Se activa una vez por outlet cuando la entrega de un lanzamiento alcanza un estado de fallo terminal. Misma carga útil que delivery.completed más un campo message.
{ "event": "delivery.failed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "error", "message": "Outlet rejected the delivery: missing ISRC." }}| Campo | Tipo | Descripción |
|---|---|---|
status | string | Uno de error, fault, rejected, batch_exception |
message | string | null | Motivo del fallo desde el outlet o el pipeline de distribución |
takedown.completed
Sección titulada «takedown.completed»Se activa una vez por outlet cuando una solicitud de retiro tiene éxito. Misma forma que delivery.completed más un indicador takedown: true.
{ "event": "takedown.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete", "takedown": true }}release.distributed
Sección titulada «release.distributed»Se activa una vez por lanzamiento cuando el lanzamiento transita al estado de entrega distributed. Solo se activa en la transición a distributed, no en guardados posteriores mientras el lanzamiento ya está distribuido.
{ "event": "release.distributed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "delivery_status": "distributed" }}release.review.status_changed
Sección titulada «release.review.status_changed»Se activa cuando un lanzamiento cambia entre estados de revisión.
{ "event": "release.review.status_changed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "previous_status": "to_review", "new_status": "approved" }}| Campo | Tipo | Descripción |
|---|---|---|
previous_status | string | Estado anterior. Uno de draft, to_review, approved, rejected, require_changes, audit |
new_status | string | Estado nuevo. El mismo conjunto de valores |
review_issues | array (opcional) | Presente solo en las transiciones a require_changes y rejected: los problemas que necesitan su atención. La clave se omite en cualquier otra transición, así que no asuma que siempre está presente |
release.preflight.report_ready
Sección titulada «release.preflight.report_ready»Se activa cuando el informe de calidad de Preflight QC para un lanzamiento en la espera previa a la revisión está listo para obtenerse. Requiere el complemento Preflight QC en su cuenta.
{ "event": "release.preflight.report_ready", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "release_cat": "ABC123", "release_title": "Summer EP", "generated_at": "2026-07-07T09:58:12+00:00", "profile": { "name": "quality_report", "version": 2 }, "counts": { "blocking": 1, "informational": 2, "requires_feedback": 1 } }}| Campo | Tipo | Descripción |
|---|---|---|
release_id | integer | El lanzamiento al que pertenece el informe |
label_id | integer | El sello propietario del lanzamiento |
release_cat | string | null | Su referencia de catálogo del lanzamiento |
release_title | string | null | El título del lanzamiento |
generated_at | string | Cuándo finalizaron las comprobaciones (ISO 8601). Coincide con el report.generated_at del endpoint del informe de calidad |
profile | object | El perfil de calidad con el que se calcularon los recuentos: {name, version} |
counts | object | Solo recuentos agregados: {blocking, informational, requires_feedback}. El recuento requires_feedback se solapa con los otros dos |
stream_radar.flag_created
Sección titulada «stream_radar.flag_created»Se activa cuando se genera un aviso de Stream Radar: ya sea un aviso completamente nuevo o un aviso previamente resuelto que se reabre tras una nueva detección. Requiere el complemento Stream Radar en su cuenta. El campo transition distingue los dos casos: published para un aviso nuevo, reopened para uno que ha vuelto a estar activo.
{ "event": "stream_radar.flag_created", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "flag_id": 4501, "dsp": "spotify", "isrc": "USRC12345678", "release_id": 789, "track_id": 654, "severity": "high", "status": "active", "transition": "published", "first_detected_at": "2026-07-06T00:00:00+00:00", "last_detected_at": "2026-07-07T00:00:00+00:00", "estimated_affected_streams": 12500, "published_at": "2026-07-07T09:58:12+00:00", "resolved_at": null }}| Campo | Tipo | Descripción |
|---|---|---|
flag_id | integer | El identificador estable del aviso; coincide con el id de los endpoints de Stream Radar |
dsp | string | La plataforma en la que se observó el patrón (p. ej. spotify) |
isrc | string | El ISRC de la grabación implicada |
release_id | integer | El lanzamiento al que pertenece la grabación |
track_id | integer | null | La pista concreta, cuando el ISRC corresponde de forma inequívoca a una de sus pistas |
severity | string | low, medium o high |
status | string | active para este evento |
transition | string | published para un aviso nuevo, reopened cuando un aviso resuelto ha vuelto a estar activo |
first_detected_at | string | null | Cuándo se detectó por primera vez el patrón para esta pista y plataforma (ISO 8601) |
last_detected_at | string | null | La detección más reciente (ISO 8601) |
estimated_affected_streams | integer | null | Una estimación de cuántas reproducciones están implicadas |
published_at | string | Cuándo se le comunicó el aviso por primera vez (ISO 8601) |
resolved_at | string | null | null mientras el aviso está activo |
stream_radar.flag_resolved
Sección titulada «stream_radar.flag_resolved»Se activa cuando un aviso de Stream Radar se resuelve porque cesaron las detecciones. Requiere el complemento Stream Radar. Los mismos campos que stream_radar.flag_created (sin transition), con status en resolved y resolved_at con valor.
{ "event": "stream_radar.flag_resolved", "timestamp": "2026-07-14T10:00:00+00:00", "webhook_id": "123", "data": { "flag_id": 4501, "dsp": "spotify", "isrc": "USRC12345678", "release_id": 789, "track_id": 654, "severity": "high", "status": "resolved", "first_detected_at": "2026-07-06T00:00:00+00:00", "last_detected_at": "2026-07-12T00:00:00+00:00", "estimated_affected_streams": 18700, "published_at": "2026-07-07T09:58:12+00:00", "resolved_at": "2026-07-14T09:55:03+00:00" }}payment.statement_ready
Sección titulada «payment.statement_ready»Se activa cuando se genera una declaración de pago y está lista para visualizar.
{ "event": "payment.statement_ready", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "payment_request_id": 1024, "invoice_number": "INV-2026-001", "period": "2026-04-30", "amount": 1234.56, "total_due_usd": 1234.56, "currency": "USD" }}| Campo | Tipo | Descripción |
|---|---|---|
payment_request_id | integer | ID interno de la solicitud de pago |
invoice_number | string | Referencia de factura para la declaración |
period | string | null | Fecha de fin de período (fecha ISO 8601, YYYY-MM-DD) |
amount | number | Monto de la declaración en la moneda currency |
total_due_usd | number | Total de la declaración convertido a USD |
currency | string | Código de moneda ISO 4217 (por defecto USD) |
transcode.completed y transcode.failed
Sección titulada «transcode.completed y transcode.failed»Se activa cuando la transcodificación de audio de una pista finaliza. transcode.completed se activa en caso de éxito; transcode.failed se activa cuando la transcodificación falla o termina incompleta. Ambos comparten la misma forma de carga útil.
{ "event": "transcode.completed", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "label_id": 321, "track_id": 654, "transcoder_queue_id": 987, "status": "complete", "status_message": "transcode_complete", "files": [ { "asset_type_id": 2, "status": "complete" } ] }}| Campo | Tipo | Descripción |
|---|---|---|
release_id | integer | El lanzamiento al que pertenece la pista |
label_id | integer | El sello propietario del lanzamiento |
track_id | integer | La pista que se transcodificó |
transcoder_queue_id | integer | ID interno de la cola de transcodificación |
status | string | Estado bruto de la cola: complete, error o incomplete |
status_message | string | Código de motivo seguro y enumerado: transcode_complete, transcode_error o transcode_incomplete |
files | array | Detalle por archivo de la pista: {asset_type_id, status} por cada archivo transcodificado |
distribution.outlet.status_changed
Sección titulada «distribution.outlet.status_changed»Se activa en cada transición del estado de distribución por outlet (por ejemplo, scheduled → transcoding → batched → complete), no solo en las terminales que cubren delivery.completed, delivery.failed y takedown.completed. Este evento es verboso por diseño: suscríbase a él solo si quiere la progresión completa por outlet.
{ "event": "distribution.outlet.status_changed", "timestamp": "2026-07-07T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "label_id": 321, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "previous_status": "transcoding", "status": "batched" }}| Campo | Tipo | Descripción |
|---|---|---|
distro_queue_id | integer | ID interno de la cola para esta entrega |
release_id | integer | El lanzamiento que se está distribuyendo |
label_id | integer | El sello propietario del lanzamiento |
release_cat | string | null | Su referencia de catálogo del lanzamiento |
outlet_id | integer | null | El ID del outlet de destino |
outlet_name | string | null | Nombre legible del outlet |
previous_status | string | null | El estado anterior; null cuando la fila no tenía un estado anterior reconocido |
status | string | El nuevo estado |
Verificando Firmas de Webhook
Sección titulada «Verificando Firmas de Webhook»Cada entrega de webhook está firmada para que pueda verificar que realmente proviene de LabelGrid. Siempre verifica la firma antes de procesar el evento.
Encabezados de la Solicitud
Sección titulada «Encabezados de la Solicitud»Cada solicitud POST de webhook incluye estos encabezados:
| Encabezado | Descripción |
|---|---|
X-Webhook-Signature | HMAC-SHA256 del cuerpo de la solicitud sin procesar, en hexadecimal en minúsculas, sin prefijo de algoritmo |
X-Webhook-Timestamp | Copia por comodidad de la propiedad timestamp del cuerpo. No está cubierta por la firma — no la use nunca para decidir si una entrega es reciente. |
X-Webhook-Event | Identificador del evento (por ejemplo, delivery.completed) |
X-Webhook-Id | El ID de la configuración del webhook que recibe la entrega (no un ID por entrega) |
User-Agent | LabelGrid-Webhooks/1.0 |
Content-Type | application/json |
Algoritmo
Sección titulada «Algoritmo»- Algoritmo: HMAC-SHA256
- Codificación: Hexadecimal en minúsculas
- Prefijo: Ninguno — el valor es solo el digest hexadecimal, no
sha256=... - Contenido firmado: El cuerpo JSON sin procesar completo de la solicitud — y nada más. Ningún encabezado se firma.
El cuerpo lleva su propia propiedad timestamp, así que ese valor sí está protegido por la firma. El encabezado X-Webhook-Timestamp es solo un duplicado suyo, enviado por comodidad, y un atacante que capture una entrega puede cambiar el encabezado a su antojo sin invalidar la firma. Por eso las comprobaciones de frescura deben leer timestamp del cuerpo ya parseado, nunca del encabezado.
Receta de Verificación
Sección titulada «Receta de Verificación»- Lea el cuerpo sin procesar de la solicitud antes de cualquier análisis o transformación JSON. Re-serializar el JSON ya parseado puede producir bytes diferentes y romper la firma.
- Calcule
HMAC-SHA256(cuerpo_sin_procesar, tu_secreto_de_webhook)y obtén el digest hexadecimal en minúsculas. - Compare con
X-Webhook-Signatureusando una comparación de tiempo constante. Deténgase aquí si no coincide. - Solo entonces parsee el cuerpo y rechace la solicitud si su propiedad
timestampes más antigua que su ventana de tolerancia de repetición — sugerimos 5 minutos. Como ese valor está firmado, un atacante no puede refrescarlo para que una entrega capturada parezca reciente.
Cada reintento se firma de nuevo con un timestamp nuevo, así que una ventana de 5 minutos nunca rechaza un reintento legítimo, por muy avanzado que esté en el calendario de reintentos.
Ejemplo en PHP
Sección titulada «Ejemplo en PHP»$rawBody = file_get_contents('php://input');$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $rawBody, $webhookSecret);
if (! hash_equals($expected, $signature)) { http_response_code(401); exit('Firma no válida');}
// Parsee solo después de comprobar que los bytes son auténticos.$payload = json_decode($rawBody, true);
// La frescura viene de la marca de tiempo FIRMADA del cuerpo,// nunca del encabezado X-Webhook-Timestamp.if (! isset($payload['timestamp']) || abs(time() - strtotime($payload['timestamp'])) > 300) { http_response_code(401); exit('Entrega obsoleta');}
// ... procesar el evento (vea "Manejando Entregas Repetidas" más abajo)http_response_code(200);Ejemplo en Node.js
Sección titulada «Ejemplo en Node.js»const crypto = require('crypto');
// Express: capturar el cuerpo sin procesar ANTES de cualquier middleware JSONapp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const rawBody = req.body; // Buffer const signature = req.header('X-Webhook-Signature') || '';
const expected = crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex');
const sigBuf = Buffer.from(signature, 'hex'); const expBuf = Buffer.from(expected, 'hex');
if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) { return res.status(401).send('Firma no válida'); }
// Parsee solo después de comprobar que los bytes son auténticos. const payload = JSON.parse(rawBody.toString('utf8'));
// La frescura viene de la marca de tiempo FIRMADA del cuerpo, // nunca del encabezado X-Webhook-Timestamp. const sentAt = new Date(payload.timestamp).getTime();
if (Number.isNaN(sentAt) || Math.abs(Date.now() - sentAt) > 5 * 60 * 1000) { return res.status(401).send('Entrega obsoleta'); }
// ... procesar el evento (vea "Manejando Entregas Repetidas" más abajo) res.sendStatus(200);});Ejemplo en Python
Sección titulada «Ejemplo en Python»import hmac, hashlib, jsonfrom datetime import datetime, timezone
raw_body = request.get_data() # Flask: bytes, antes de cualquier parseo JSONsignature = request.headers.get('X-Webhook-Signature', '')
expected = hmac.new( webhook_secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature): return ('Firma no válida', 401)
payload = json.loads(raw_body) # parsear solo con los bytes ya autenticados
delivery_time = datetime.fromisoformat(payload['timestamp']) # el valor FIRMADO, nunca el encabezadoif abs((datetime.now(timezone.utc) - delivery_time).total_seconds()) > 300: return ('Entrega obsoleta', 401)
return ('', 200) # procesar el evento, luego responderErrores Comunes
Sección titulada «Errores Comunes»- Comprobar la frescura con el encabezado
X-Webhook-Timestamp. El encabezado no está firmado. Cualquiera que capture una entrega puede reenviar el mismo cuerpo y la misma firma con un valor de encabezado reciente y superar para siempre una comprobación basada en el encabezado. Leatimestampdel cuerpo ya parseado — ese valor sí está firmado. - Re-serializar el cuerpo antes de hacer el hash. Los frameworks que parsean JSON automáticamente (Express
express.json(), el cuerpo de solicitud por defecto de Laravel) pierden los bytes originales. Captura primero el cuerpo sin procesar. - Usar una comparación que no sea de tiempo constante (
==,===). Es susceptible a ataques de temporización — siempre usahash_equals(PHP),crypto.timingSafeEqual(Node),hmac.compare_digest(Python), o el equivalente de su lenguaje. - Esperar un prefijo
sha256=. El valor del encabezado es solo el digest hexadecimal sin prefijo. - Omitir la comprobación de frescura. Sin ella, una entrega capturada puede repetirse indefinidamente contra su endpoint.
- Tomar
X-Webhook-Idpor un identificador de entrega. Identifica la configuración del webhook, no la entrega concreta, y tampoco está firmado.
Manejando Entregas Repetidas
Sección titulada «Manejando Entregas Repetidas»La entrega de webhooks es al menos una vez: una entrega que su endpoint ya procesó puede volver a llegar si su respuesta 2xx se perdió o llegó después del timeout de 10 segundos y LabelGrid la reintenta. Verificar la firma demuestra que una solicitud es auténtica — no demuestra que sea una que aún no haya atendido.
Las entregas no llevan un identificador único por entrega, así que construya su propia clave de idempotencia a partir de la carga útil firmada. El tipo de evento más los identificadores de data suelen bastar — por ejemplo, delivery.completed más distro_queue_id, o transcode.completed más track_id. Registre la clave cuando procese un evento e ignore todo lo que ya tenga registrado.
No use la firma ni el timestamp como esa clave. Cada intento se firma de nuevo en el momento de enviarlo, así que el reintento de un evento que ya atendió llega con un timestamp distinto y una firma distinta — la clave tiene que salir de los identificadores propios del evento.
Combine eso con la comprobación de frescura anterior: la frescura acota cuánto tiempo sigue siendo repetible una entrega capturada, y la idempotencia hace inofensiva una repetición, tanto si viene de un reintento como de un atacante dentro de la ventana.
Límites y Confiabilidad
Sección titulada «Límites y Confiabilidad»Límites de Solicitud
Sección titulada «Límites de Solicitud»| Límite | Valor |
|---|---|
| Timeout de solicitud | 10 segundos |
| Tamaño máximo de carga útil | 64 KB |
| Máximo de webhooks por usuario | 10 |
Si su endpoint no responde dentro de 10 segundos, la entrega se trata como un fallo y se reintenta.
Calendario de Reintentos
Sección titulada «Calendario de Reintentos»Si su endpoint retorna un estado no-2xx o sufre timeout, LabelGrid reintenta con backoff exponencial:
| Intento | Espere antes del reintento |
|---|---|
| 1 → 2 | 30 segundos |
| 2 → 3 | 1 minuto |
| 3 → 4 | 2 minutos |
| 4 → 5 | 4 minutos |
| 5 → 6 | 8 minutos |
| 6 → 7 | 16 minutos |
| 7 → 8 | 32 minutos |
| 8 → 9 | 64 minutos |
| 9 → 10 | 128 minutos |
Cada intervalo incluye 0–30 segundos de jitter. Después de 10 intentos (~4.5 horas de tiempo total transcurrido), la entrega se registra como fallida permanentemente y no se vuelve a reintentar.
Desactivación Automática
Sección titulada «Desactivación Automática»Si el endpoint de un webhook falla de forma repetida —entregas fallidas consecutivas sin ninguna entrega correcta entre ellas—, LabelGrid desactiva el webhook automáticamente para dejar de reintentar un endpoint que claramente no puede recibir eventos. El contador de fallos se restablece con cada entrega correcta, por lo que un fallo puntual nunca desactiva un webhook; solo lo hace un fallo sostenido e ininterrumpido.
Cuando un webhook se desactiva de este modo, su propietario recibe un email. El email indica el nombre del webhook y la URL de su endpoint, así como el tipo de fallo que provocó la desactivación (por ejemplo, un tiempo de espera de conexión agotado o errores HTTP repetidos).
La reactivación es de autoservicio: corrija su endpoint y vuelva a activar el webhook desde Perfil → Webhooks. Reactivar un webhook desactivado restablece su contador de fallos. La lista de webhooks muestra el estado activo y el número de fallos actual de cada webhook, para que pueda detectar de un vistazo un endpoint con problemas.
Mejores Prácticas para Confiabilidad
Sección titulada «Mejores Prácticas para Confiabilidad»- Retorna una respuesta 2xx rápidamente (dentro de 10 segundos)
- Procese los datos de forma asíncrona después de confirmar
- Verifique la firma en cada solicitud (consulte Verificando Firmas de Webhook)
- Haga que su manejador sea idempotente — la entrega es al menos una vez (consulte Manejando Entregas Repetidas)
- Monitoree su conteo de fallos en la lista de webhooks
- Revise los registros de entrega cuando investigues eventos perdidos
Casos de Uso
Sección titulada «Casos de Uso»Notificaciones Automatizadas
Sección titulada «Notificaciones Automatizadas»- Envíe mensajes a Slack cuando los lanzamientos están en vivo
- Envíe email a su equipo cuando las entregas fallan
- Actualice dashboards internos
Automatización de Flujos de Trabajo
Sección titulada «Automatización de Flujos de Trabajo»- Active campañas de marketing cuando los lanzamientos se distribuyen
- Actualice su sitio web cuando hay nuevo contenido disponible
- Sincronice el estado con herramientas externas de gestión de proyectos
Monitoreo y Alertas
Sección titulada «Monitoreo y Alertas»- Recibe alertas instantáneas por fallos de entrega
- Rastree el progreso de distribución en tiempo real
- Monitoree cambios en el estado de revisión
Solución de Problemas
Sección titulada «Solución de Problemas»El Webhook No Recibe Eventos
Sección titulada «El Webhook No Recibe Eventos»- Verifique el estado - ¿Está el webhook Activo?
- Verifique la URL - ¿Es accesible el endpoint desde internet?
- Verifique los eventos - ¿Están seleccionados los eventos correctos?
- Revise los registros - ¿Hay errores registrados?
Alto Conteo de Fallos
Sección titulada «Alto Conteo de Fallos»- Verifique su endpoint - ¿Está retornando 200 OK?
- Verifique el tiempo de respuesta - ¿Está respondiendo dentro del timeout?
- Revise los mensajes de error - ¿Qué está fallando?
- Pruebe manualmente - Envíe un webhook de prueba
Regenerando el Secreto
Sección titulada «Regenerando el Secreto»Si su secreto del webhook está comprometido:
- Haga clic en Regenerate Secret en la configuración del webhook
- Actualice su aplicación con el nuevo secreto
- El secreto antiguo deja de funcionar inmediatamente
¿Necesita Ayuda?
Sección titulada «¿Necesita Ayuda?»Si tiene preguntas sobre webhooks, contacte a nuestro equipo de soporte.
¿Aún no usas LabelGrid?
Todo lo que acabas de leer está disponible en nuestra plataforma.
Descubre lo que LabelGrid puede hacer →