Ir al contenido
Soporte

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.

  1. Configure un webhook - Especifique una URL y qué eventos escuchar
  2. Ocurre un evento - Por ejemplo, un lanzamiento se entrega a una tienda
  3. LabelGrid envía una solicitud POST - Su servidor recibe los datos del evento
  4. Su sistema lo procesa - Automatiza flujos de trabajo basados en el evento

  1. Haga clic en su ícono de perfil en la esquina superior derecha
  2. Seleccione Webhooks del menú desplegable

  1. Haga clic en Create Webhook
  2. Ingrese un Name para identificar este webhook
  3. Ingrese la URL donde quiere recibir notificaciones
  4. Seleccione qué Events deben activar este webhook
  5. Haga clic en Create

Cuando crea un webhook, recibirá una clave secreta. Úsela para verificar que las solicitudes entrantes son realmente de LabelGrid:

  • Copie el secreto de inmediato: LabelGrid lo muestra una sola vez y no guarda ninguna copia legible
  • Almacene el secreto de forma segura
  • Verifique la firma en las solicitudes entrantes
  • Si el secreto se ve comprometido o lo pierde, rótelo (consulte Rotar el secreto)

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 EventoDescripción
delivery.completedSe activa cuando un lanzamiento se entrega exitosamente a un outlet
delivery.failedSe activa cuando la entrega a un outlet falla
takedown.completedSe activa cuando una solicitud de retiro se completa
release.review.status_changedSe activa cuando el estado de revisión de un lanzamiento cambia
track.review.status_changedSe activa cuando el estado de revisión de una pista cambia
release.preflight.report_readySe activa cuando el informe de Preflight QC de un lanzamiento en espera está listo para obtenerse
stream_radar.flag_createdSe activa cuando se genera un aviso de Stream Radar, o cuando un aviso resuelto se reabre tras una nueva detección
stream_radar.flag_resolvedSe activa cuando un aviso de Stream Radar se resuelve porque cesaron las detecciones
release.distributedSe activa cuando un lanzamiento es distribuido
release.deletedSe activa cuando se elimina un lanzamiento; a partir de entonces, la API devuelve 404 para ese lanzamiento
payment.statement_readySe activa cuando una declaración de pago está lista para visualizar
transcode.completedSe activa cuando la transcodificación de audio de una pista finaliza correctamente
transcode.failedSe activa cuando la transcodificación de una pista falla o termina incompleta
distribution.outlet.status_changedSe 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.


La lista de webhooks muestra:

ColumnaDescripción
NameEl nombre del webhook que asignó
URLDonde se envían las notificaciones
EventsNúmero de eventos configurados
StatusActivo o Inactivo
Success / FailConteo de entregas exitosas y fallidas
Last TriggeredCuándo se llamó al webhook por última vez
  1. Haga clic en la acción Edit en la fila del webhook
  2. Modifique el nombre, la URL o los eventos
  3. Haga clic en Save

Cambie el estado activo de un webhook sin eliminarlo:

  • Active - El webhook recibirá notificaciones
  • Inactive - El webhook está pausado, no se envían notificaciones
  1. Haga clic en la acción Delete en la fila del webhook
  2. Confirme la eliminación

Antes de depender de un webhook en producción, pruébelo:

  1. Haga clic en la acción Test en su webhook
  2. LabelGrid envía una carga útil de prueba a su URL
  3. Verifique que su endpoint recibió y procesó correctamente

Monitoree la actividad del webhook y solucione problemas:

  1. Haga clic en la acción View Logs en un webhook
  2. Vea el historial de todas las entregas del webhook

Cada entrada de registro muestra:

CampoDescripción
Event TypeQué evento activó esta entrega
Response StatusCódigo de estado HTTP de su servidor
DurationCuánto tiempo tomó la solicitud
AttemptNúmero de intento de reintento
TimestampCuándo ocurrió la entrega

Cuando ocurre un evento, LabelGrid envía una solicitud POST a su URL con una carga útil JSON:

{
"event": "delivery.completed",
"event_id": "5f0c8a52-3d1e-4b7a-9c2f-6e8d1a4b7c90",
"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).

event_id identifica el evento en sí, no el intento de entrega. Cada reintento de una entrega lleva el mismo event_id, y lo mismo ocurre en cada webhook al que se envía el evento. Coincide con el encabezado X-Webhook-Event-Id. Los ejemplos de carga útil de cada evento que aparecen más abajo lo omiten para que sean más breves.


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.

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"
}
}
CampoTipoDescripción
distro_queue_idintegerID interno de la cola para este intento de entrega
release_idintegerEl lanzamiento que fue entregado
label_idintegerEl sello propietario del lanzamiento, para que pueda enrutar el evento sin una consulta adicional
release_catstring | nullSu referencia de catálogo del lanzamiento
outlet_idinteger | nullEl ID del outlet de destino
outlet_namestring | nullNombre legible del outlet (por ejemplo, "Spotify")
statusstringSiempre "complete" para este evento

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."
}
}
CampoTipoDescripción
statusstringUno de error, fault, rejected, batch_exception
messagestring | nullMotivo del fallo desde el outlet o el pipeline de distribución

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
}
}

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"
}
}

Se activa una sola vez cuando se elimina un lanzamiento. Después de este evento, la API devuelve 404 para ese lanzamiento, así que no intente volver a consultarlo.

{
"event": "release.deleted",
"timestamp": "2026-05-18T10:00:00+00:00",
"webhook_id": "123",
"data": {
"release_id": 789,
"label_id": 321,
"barcode_number": "0123456789012",
"release_cat": "ABC123",
"release_title": "Summer EP"
}
}

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"
}
}
CampoTipoDescripción
previous_statusstringEstado anterior. Uno de draft, to_review, approved, rejected, require_changes, audit, pending_customer_review
new_statusstringEstado nuevo. El mismo conjunto de valores
review_issuesarray (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

Se activa cuando una pista concreta cambia de estado de revisión, y solo cuando el estado cambia de verdad.

{
"event": "track.review.status_changed",
"timestamp": "2026-05-18T10:00:00+00:00",
"webhook_id": "123",
"data": {
"track_id": 456,
"release_id": 789,
"label_id": 321,
"previous_status": "to_review",
"new_status": "require_changes"
}
}
CampoTipoDescripción
track_idintegerLa pista cuyo estado de revisión cambió
previous_statusstringEstado anterior. Los mismos valores que en release.review.status_changed
new_statusstringEstado nuevo. El mismo conjunto de valores

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 }
}
}
CampoTipoDescripción
release_idintegerEl lanzamiento al que pertenece el informe
label_idintegerEl sello propietario del lanzamiento
release_catstring | nullSu referencia de catálogo del lanzamiento
release_titlestring | nullEl título del lanzamiento
generated_atstringCuándo finalizaron las comprobaciones (ISO 8601). Coincide con el report.generated_at del endpoint del informe de calidad
profileobjectEl perfil de calidad con el que se calcularon los recuentos: {name, version}
countsobjectSolo recuentos agregados: {blocking, informational, requires_feedback}. El recuento requires_feedback se solapa con los otros dos

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
}
}
CampoTipoDescripción
flag_idintegerEl identificador estable del aviso; coincide con el id de los endpoints de Stream Radar
dspstringLa plataforma en la que se observó el patrón (p. ej. SPOTIFY)
isrcstringEl ISRC de la grabación implicada
release_idintegerEl lanzamiento al que pertenece la grabación
track_idinteger | nullLa pista concreta, cuando el ISRC corresponde de forma inequívoca a una de sus pistas
severitystringmedium o high
statusstringactive para este evento
transitionstringpublished para un aviso nuevo, reopened cuando un aviso resuelto ha vuelto a estar activo
first_detected_atstring | nullCuándo se detectó por primera vez el patrón para esta pista y plataforma (ISO 8601)
last_detected_atstring | nullLa detección más reciente (ISO 8601)
estimated_affected_streamsinteger | nullUna estimación de cuántas reproducciones están implicadas
published_atstringCuándo se le comunicó el aviso por primera vez (ISO 8601)
resolved_atstring | nullnull mientras el aviso está activo

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"
}
}

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"
}
}
CampoTipoDescripción
payment_request_idintegerID interno de la solicitud de pago
invoice_numberstringReferencia de factura para la declaración
periodstring | nullFecha de fin de período (fecha ISO 8601, YYYY-MM-DD)
amountnumberMonto de la declaración en la moneda currency
total_due_usdnumberTotal de la declaración convertido a USD
currencystringCódigo de moneda ISO 4217 (por defecto USD)

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" }
]
}
}
CampoTipoDescripción
release_idintegerEl lanzamiento al que pertenece la pista
label_idintegerEl sello propietario del lanzamiento
track_idintegerLa pista que se transcodificó
transcoder_queue_idintegerID interno de la cola de transcodificación
statusstringEstado bruto de la cola: complete, error o incomplete
status_messagestringCódigo de motivo seguro y enumerado: transcode_complete, transcode_error o transcode_incomplete
filesarrayDetalle por archivo de la pista: {asset_type_id, status} por cada archivo transcodificado

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"
}
}
CampoTipoDescripción
distro_queue_idintegerID interno de la cola para esta entrega
release_idintegerEl lanzamiento que se está distribuyendo
label_idintegerEl sello propietario del lanzamiento
release_catstring | nullSu referencia de catálogo del lanzamiento
outlet_idinteger | nullEl ID del outlet de destino
outlet_namestring | nullNombre legible del outlet
previous_statusstring | nullEl estado anterior; null cuando la fila no tenía un estado anterior reconocido
statusstringEl nuevo estado

Cada entrega de webhook está firmada para que pueda verificar que realmente proviene de LabelGrid. Verifique siempre la firma antes de procesar el evento.

Cada solicitud POST de webhook incluye estos encabezados:

EncabezadoDescripción
X-Webhook-SignatureHMAC-SHA256 del cuerpo de la solicitud sin procesar, en hexadecimal en minúsculas, sin prefijo de algoritmo
X-Webhook-TimestampCopia 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-EventIdentificador del evento (por ejemplo, delivery.completed)
X-Webhook-IdEl ID de la configuración del webhook que recibe la entrega (no un ID por entrega)
X-Webhook-Event-IdEl event_id del evento, igual en cada reintento
User-AgentLabelGrid-Webhooks/1.0
Content-Typeapplication/json
  • 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.

  1. 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.
  2. Calcule HMAC-SHA256(cuerpo_sin_procesar, su_secreto_de_webhook) y obtenga el digest hexadecimal en minúsculas.
  3. Compare con X-Webhook-Signature usando una comparación de tiempo constante. Deténgase aquí si no coincide.
  4. Solo entonces parsee el cuerpo y rechace la solicitud si su propiedad timestamp es 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.

$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);
const crypto = require('crypto');
// Express: capturar el cuerpo sin procesar ANTES de cualquier middleware JSON
app.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);
});
import hmac, hashlib, json
from datetime import datetime, timezone
raw_body = request.get_data() # Flask: bytes, antes de cualquier parseo JSON
signature = 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 encabezado
if abs((datetime.now(timezone.utc) - delivery_time).total_seconds()) > 300:
return ('Entrega obsoleta', 401)
return ('', 200) # procesar el evento, luego responder
  • 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. Lea timestamp del 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. Capture primero el cuerpo sin procesar.
  • Usar una comparación que no sea de tiempo constante (==, ===). Es susceptible a ataques de temporización: use siempre hash_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-Id por un identificador de entrega. Identifica la configuración del webhook, no la entrega concreta, y tampoco está firmado.

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.

Use event_id como clave de idempotencia: no cambia en ningún reintento de un evento. Regístrelo cuando procese un evento e ignore cualquier entrega cuyo event_id ya tenga registrado. Como forma parte del cuerpo firmado, una firma válida también lo avala.

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ímiteValor
Timeout de solicitud10 segundos
Tamaño máximo de carga útil64 KB
Máximo de webhooks por usuario10

Si su endpoint no responde dentro de 10 segundos, la entrega se trata como un fallo y se reintenta.

Si su endpoint retorna un estado no-2xx o sufre timeout, LabelGrid reintenta con backoff exponencial:

IntentoEspere antes del reintento
1 → 230 segundos
2 → 31 minuto
3 → 42 minutos
4 → 54 minutos
5 → 68 minutos
6 → 716 minutos
7 → 832 minutos
8 → 964 minutos
9 → 10128 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.

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 Webhooks, en el menú de la cuenta (su avatar, arriba a la derecha). 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.

  • Devuelva 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 investigue eventos perdidos

  • 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
  • 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
  • Reciba alertas instantáneas por fallos de entrega
  • Rastree el progreso de distribución en tiempo real
  • Monitoree cambios en el estado de revisión

  1. Verifique el estado - ¿Está el webhook Activo?
  2. Verifique la URL - ¿Es accesible el endpoint desde internet?
  3. Verifique los eventos - ¿Están seleccionados los eventos correctos?
  4. Revise los registros - ¿Hay errores registrados?
  1. Verifique su endpoint - ¿Está retornando 200 OK?
  2. Verifique el tiempo de respuesta - ¿Está respondiendo dentro del timeout?
  3. Revise los mensajes de error - ¿Qué está fallando?
  4. Pruebe manualmente - Envíe un webhook de prueba

Si el secreto de su webhook se ha visto comprometido o lo ha perdido, rótelo. LabelGrid no puede volver a mostrarle el secreto actual, así que rotarlo es la única forma de obtener uno que pueda copiar.

  1. Abra el menú del webhook (⋮) y haga clic en Edit
  2. Junto a Webhook Secret, haga clic en Rotate
  3. Haga clic en Rotate secret para confirmar
  4. Haga clic en Copy en el panel Copy it now y guarde el nuevo secreto en su aplicación
  5. Haga clic en I’ve copied it

El secreto antiguo deja de funcionar en el momento en que lo rota, y la verificación de firmas en su endpoint fallará hasta que guarde el nuevo, así que actualice su endpoint en ese mismo momento. El nuevo secreto entra en vigor de inmediato; no necesita hacer clic en Save Changes.

LabelGrid muestra el nuevo secreto una sola vez. Si intenta cerrar el cuadro de diálogo antes de hacer clic en I’ve copied it, LabelGrid le pide primero que lo confirme, porque cerrarlo es la última oportunidad de copiarlo. Si lo pierde más adelante, vuelva a rotarlo.


Si tiene preguntas sobre webhooks, contacte a nuestro equipo de soporte.

¿Aún no usa LabelGrid?

Todo lo que acaba de leer está disponible en nuestra plataforma.

Descubra lo que LabelGrid puede hacer →