Back to docs

Webhooks

Webhooks

Recibe notificaciones HTTP firmadas cuando cambian enlaces, campañas y publicaciones en tu espacio de trabajo.

Los webhooks de Styrar envían notificaciones HTTP firmadas cuando cambian los recursos de tu espacio de trabajo. Úsalos para sincronizar enlaces y clics con un CRM, activar automatizaciones en tu stack o transmitir eventos del funnel a un data warehouse.

Esto sustituye a la antigua API de webhooks solo para enlaces (/v1/link-webhooks), que ha sido retirada. Las nuevas integraciones deben usar únicamente /v1/webhooks/*.

Configurar un webhook

Sigue estos pasos para pasar de cero a un endpoint verificado y listo para producción.

1. Prepara tu URL receptora

Tu servidor necesita una URL HTTPS pública que acepte solicitudes POST con un cuerpo JSON. En producción, las URLs de callback deben usar HTTPS.

Tu manejador debe:

  • Leer el cuerpo de la solicitud sin procesar como string o buffer (no analices el JSON antes de verificar la firma).
  • Leer las cabeceras Styrar-Signature, Styrar-Event-Id y Styrar-Event-Type.
  • Verificar la firma (consulta la sección Verificación de firmas más abajo).
  • Devolver 2xx rápidamente una vez aceptado el evento. Encola el trabajo pesado de forma asíncrona.

URL de ejemplo: https://your-app.com/webhooks/styrar

Styrar no puede entregar a direcciones privadas o loopback como localhost.

2. Obtén acceso a la API (para configuración programática)

Si creas endpoints mediante la API en lugar del panel, necesitas un token Bearer con:

AlcanceAcceso
webhooks:readListar endpoints, entregas y tipos de evento
webhooks:writeCrear, actualizar, eliminar, probar, rotar el secreto, reintentar entregas

Crea una clave de API en Configuración → Claves de API con webhooks:read y webhooks:write, o usa un token de acceso OAuth de una app conectada con los mismos alcances.

Para espacios de trabajo de empresa, pasa companyId en las solicitudes de listado y creación.

3. Crea un endpoint en el panel

  1. Inicia sesión y abre Configuración → Webhooks (/settings/webhooks).
  2. En Endpoints, ingresa tu URL de endpoint (el callback HTTPS público).
  3. Opcionalmente añade una Descripción (por ejemplo, "Sincronización de CRM en producción").
  4. Selecciona los Eventos que quieras (se requiere al menos uno). Opciones comunes:
    • link.clicked para seguimiento de clics
    • link.created / link.updated / link.deleted para el ciclo de vida del enlace
    • post.published y campaign.created para eventos del funnel
  5. Haz clic en Añadir endpoint.

Después de crearlo, Styrar muestra tu secreto de firma (whsec_live_… o whsec_test_…). Cópialo de inmediato y guárdalo en tu gestor de secretos. Solo se muestra una vez. Si lo pierdes, usa Rotar secreto en el endpoint y actualiza tu servidor.

4. Crea un endpoint mediante la API

RequestPOST
Authorization: Bearer sty_live_your_api_key
Content-Type: application/json

{
  "companyId": "cmxyz_company",
  "url": "https://your-app.com/webhooks/styrar",
  "description": "Production CRM sync",
  "eventTypes": [
    "link.clicked",
    "link.created"
  ]
}
Response201 Created
{
  "id": "wh_ep_abc123",
  "url": "https://your-app.com/webhooks/styrar",
  "description": "Production CRM sync",
  "enabled": true,
  "eventTypes": [
    "link.clicked",
    "link.created"
  ],
  "secretPrefix": "whsec_l",
  "companyId": "cmxyz_company",
  "userId": null,
  "disabledAt": null,
  "createdAt": "2026-06-22T12:00:00.000Z",
  "updatedAt": "2026-06-22T12:00:00.000Z",
  "secret": "whsec_live_abc123onlyShownOnce"
}

Guarda secret de inmediato. No se devuelve en solicitudes GET posteriores. Un array eventTypes vacío suscribe a todos los tipos de evento; el panel exige al menos un evento explícito.

5. Envía un evento de prueba

Confirma que tu servidor es accesible antes de depender del tráfico real.

Panel: En la fila del endpoint, haz clic en Enviar prueba. Styrar entrega un evento webhook.test. Deberías ver una notificación de éxito con el código de estado HTTP.

API:

RequestPOST
Authorization: Bearer sty_live_your_api_key
Response200 OK
{
  "ok": true,
  "statusCode": 200
}

Cuando la prueba se realiza con éxito, tu servidor debería haber recibido un evento webhook.test (consulta Recibir un evento en tu servidor más abajo).

Revisa Entregas recientes en el panel (o GET /v1/webhooks/deliveries) si la prueba falla. Problemas comunes:

ProblemaQué revisar
Conexión rechazada / tiempo de espera agotadoLa URL es HTTPS pública, el firewall permite a Styrar, el túnel está activo
HTTP 4xx/5xx de tu appEl manejador devuelve 2xx tras verificar; registra el cuerpo y las cabeceras sin procesar
Falla la verificación de firmaUsa el cuerpo sin procesar, el secreto correcto, comparación en tiempo constante
Endpoint deshabilitadoVuelve a habilitarlo en el panel o corrige lo que causó el HTTP 410

6. Verifica y procesa las entregas

En cada POST a tu URL:

  1. Analiza Styrar-Signature en la marca de tiempo t y el resumen v1.
  2. Rechaza si t es más antiguo que tu tolerancia (se recomiendan 5 minutos).
  3. Calcula el HMAC-SHA256 de "{t}.{raw_body}" con el secreto de tu endpoint.
  4. Compáralo con v1 usando una verificación en tiempo constante.
  5. Analiza el JSON solo después de que la verificación se realice con éxito.
  6. Deduplica usando Styrar-Event-Id (entrega al menos una vez).

Consulta la sección Verificación de firmas más abajo para un ejemplo en Node.js.

7. Pasa a producción

  • Mantén el endpoint Habilitado en el panel.
  • Suscríbete solo a los eventos que necesites (reduce el ruido y el costo).
  • Supervisa Entregas recientes en busca de fallos y usa Reintentar cuando sea necesario.
  • Rota el secreto si pudiera haberse filtrado (Rotar secreto en el panel o POST …/rotate-secret).

Inicio rápido

  1. Obtén acceso a la API con los alcances webhooks:read y webhooks:write (clave de API u OAuth).
  2. Expón un receptor HTTPS público y crea un endpoint en Configuración → Webhooks o mediante POST /v1/webhooks/endpoints.
  3. Copia el secreto de firma cuando se muestre y guárdalo de forma segura.
  4. Envía un evento de prueba y confirma que tu servidor verifica Styrar-Signature y devuelve 2xx.
  5. Procesa eventos en vivo con deduplicación basada en Styrar-Event-Id.

Autenticación

La gestión de webhooks requiere un token Bearer con los alcances indicados en el paso 2 anterior. Las claves de API con los alcances correspondientes funcionan igual que los tokens de acceso OAuth.

Tipos de evento

Llama a GET /v1/webhooks/event-types para obtener el catálogo en vivo de tu entorno. Suscríbete a tipos específicos por endpoint, o pasa un array eventTypes vacío para recibir todos los eventos.

webhook.test solo se envía cuando haces clic en Enviar prueba; no se emite por la actividad normal del espacio de trabajo.

Envoltorio del evento

Cada entrega usa la misma estructura de nivel superior. Los campos específicos del evento están bajo data.object:

CampoTipoDescripción
idstringId único del evento. Mismo valor que la cabecera Styrar-Event-Id.
typestringNombre del evento (por ejemplo, link.clicked).
api_versionstringVersión del esquema del payload (2026-06-22).
created_atstringMarca de tiempo ISO 8601 de cuando se creó el evento.
workspace.typestringcompany o personal.
workspace.company_idstring | nullId de empresa cuando workspace.type es company.
data.objectobjectPayload del evento (documentado por evento más abajo).

Ejemplo completo de entrega (envoltorio + payload de link.created):

JSON
{
  "id": "evt_outbox_abc123",
  "type": "link.created",
  "api_version": "2026-06-22",
  "created_at": "2026-06-22T12:00:00.000Z",
  "workspace": {
    "type": "company",
    "company_id": "cmxyz_company"
  },
  "data": {
    "object": {
      "id": "clink_abc123",
      "short_code": "summer",
      "title": "Summer sale",
      "original_url": "https://example.com/sale",
      "is_active": true,
      "company_id": "cmxyz_company",
      "campaign_id": "ccamp_abc",
      "link_group_id": null,
      "created_at": "2026-06-22T12:00:00.000Z"
    }
  }
}

Para espacios de trabajo personales, workspace.type es personal y workspace.company_id es null. El payload puede incluir company_id: null en los objetos de enlace.

Resumen de eventos

EventoCuándo se disparaVolumen típico
link.createdSe crea un enlace corto (POST /v1/links, creación masiva o upsert masivo)Bajo
link.updatedSe actualiza un enlace corto (PATCH /v1/links/:id, actualización masiva o upsert masivo)Bajo
link.deletedUn enlace corto se elimina de forma reversible (DELETE /v1/links/:id o eliminación masiva)Bajo
link.clickedSe registra un clic con seguimiento (async, tras la redirección mediante el worker de clics)Alto
link.experiment.completedSe completa un experimento A/B de enlace y se selecciona un ganadorBajo
campaign.createdSe crea una campaña (POST /v1/campaigns)Bajo
post.publishedUna publicación social se publica con éxito en todos los destinos de plataformaBajo
webhook.testEjecutas Enviar prueba en un endpointA demanda

link.created

Se dispara cuando se guarda un nuevo enlace corto en tu espacio de trabajo.

Usos comunes: Sincronizar nuevos enlaces con un CRM, activar automatizaciones de bienvenida o indexar enlaces en un almacén de búsqueda externo.

Campos de data.object:

CampoTipoDescripción
idstringId del enlace
short_codestringCódigo corto público
titlestring | nullTítulo del enlace
original_urlstring | nullURL de destino
is_activebooleanSi el enlace está activo
company_idstring | nullEmpresa propietaria (espacio de empresa)
campaign_idstring | nullCampaña vinculada, si existe
link_group_idstring | nullId de carpeta/grupo, si existe
created_atstringHora de creación en ISO 8601
JSON
{
  "id": "clink_abc123",
  "short_code": "summer",
  "title": "Summer sale",
  "original_url": "https://example.com/sale",
  "is_active": true,
  "company_id": "cmxyz_company",
  "campaign_id": "ccamp_abc",
  "link_group_id": null,
  "created_at": "2026-06-22T12:00:00.000Z"
}

link.updated

Se dispara cuando se modifica un enlace corto existente (destino, título, etiquetas, carpeta, configuración UTM, etc.).

Usos comunes: Mantener sincronizados los sistemas externos cuando un enlace cambia sin recrearlo.

Campos de data.object: Igual que link.created (ver arriba).

JSON
{
  "id": "clink_abc123",
  "short_code": "summer",
  "title": "Summer sale (updated)",
  "original_url": "https://example.com/sale-v2",
  "is_active": true,
  "company_id": "cmxyz_company",
  "campaign_id": "ccamp_abc",
  "link_group_id": "lgrp_promos",
  "created_at": "2026-06-22T12:00:00.000Z"
}

link.deleted

Se dispara cuando un enlace corto se elimina de forma reversible (isActive se pone en false). El enlace deja de resolverse públicamente, pero permanece en el historial de tu espacio de trabajo.

Usos comunes: Eliminar enlaces de catálogos externos o pausar automatizaciones ligadas a ese código corto.

Campos de data.object: Misma forma que link.created, con is_active siempre en false.

CampoTipoDescripción
idstringId del enlace
short_codestringCódigo corto en el momento de la eliminación
titlestring | nullTítulo del enlace
original_urlstring | nullURL de destino
is_activebooleanfalse tras la eliminación reversible
company_idstring | nullEmpresa propietaria
campaign_idstring | nullCampaña vinculada, si existe
link_group_idstring | nullId de carpeta/grupo, si existe
created_atstringHora de creación original
JSON
{
  "id": "clink_abc123",
  "short_code": "summer",
  "title": "Summer sale",
  "original_url": "https://example.com/sale",
  "is_active": false,
  "company_id": "cmxyz_company",
  "campaign_id": "ccamp_abc",
  "link_group_id": null,
  "created_at": "2026-06-22T12:00:00.000Z"
}

link.clicked

Se dispara después de que se registra el clic de un visitante. Se entrega de forma asíncrona (no en la ruta de redirección), por lo que puede haber un ligero retraso bajo carga.

Usos comunes: Analítica de clics en tiempo real, enrutamiento por geolocalización en tu stack, feeds de actividad de CRM o ingesta en un data warehouse.

Privacidad: Los payloads incluyen dimensiones de geolocalización y dispositivo, no direcciones IP sin procesar.

Campos de data.object:

CampoTipoDescripción
idstringId del enlace
link_idstringIgual que id
short_codestringCódigo corto que recibió el clic
titlestring | nullTítulo del enlace
countrystring | nullCódigo de país ISO (geolocalización)
citystring | nullCiudad según geolocalización
devicestring | nullClase de dispositivo (por ejemplo, mobile, desktop)
browserstring | nullNombre del navegador
osstring | nullSistema operativo
platformstring | nullIndicio de plataforma según el análisis del user agent
referrerstring | nullURL de referencia, cuando esté disponible
routing_rule_idstring | nullRegla de enrutamiento por geo/dispositivo que coincidió, si existe
experiment_variant_idstring | nullId de variante A/B cuando el clic pasó por un experimento
clicked_atstringHora del clic en ISO 8601
JSON
{
  "id": "clink_abc123",
  "link_id": "clink_abc123",
  "short_code": "summer",
  "title": "Summer sale",
  "country": "NL",
  "city": "Amsterdam",
  "device": "mobile",
  "browser": "Chrome",
  "os": "iOS",
  "platform": null,
  "referrer": "https://instagram.com/",
  "routing_rule_id": null,
  "experiment_variant_id": null,
  "clicked_at": "2026-06-22T12:00:00.000Z"
}

link.experiment.completed

Se dispara cuando una prueba A/B de un enlace corto se marca como completa y se selecciona una variante ganadora.

Usos comunes: Registrar resultados de experimentos, actualizar paneles o activar campañas de seguimiento según la variante ganadora.

Campos de data.object:

CampoTipoDescripción
idstringId del experimento
link_idstringId del enlace padre
short_codestring | nullCódigo corto del enlace padre
statusstringcompleted
assignment_modestring | nullCómo se dividió el tráfico (por ejemplo, ponderado)
winning_variant_idstring | nullId de la variante ganadora
ended_atstring | nullHora de finalización en ISO 8601
variantsarrayResultados por variante (ver abajo)

Cada elemento en variants:

CampoTipoDescripción
idstringId de la variante
labelstringEtiqueta legible
weightnumberPeso de tráfico usado en la prueba
destination_urlstringURL a la que esta variante envió tráfico
clicksnumberTotal de clics registrados para esta variante
JSON
{
  "id": "lexp_abc123",
  "link_id": "clink_abc123",
  "short_code": "summer",
  "status": "completed",
  "assignment_mode": "weighted",
  "winning_variant_id": "lvar_b",
  "ended_at": "2026-06-22T14:00:00.000Z",
  "variants": [
    {
      "id": "lvar_a",
      "label": "Control",
      "weight": 50,
      "destination_url": "https://example.com/a",
      "clicks": 120
    },
    {
      "id": "lvar_b",
      "label": "Variant B",
      "weight": 50,
      "destination_url": "https://example.com/b",
      "clicks": 184
    }
  ]
}

campaign.created

Se dispara cuando se crea una nueva campaña en tu espacio de trabajo.

Usos comunes: Provisionar carpetas de campaña en herramientas externas, iniciar flujos de atribución o notificar a los gestores de cuenta.

Campos de data.object:

CampoTipoDescripción
idstringId de la campaña
namestringNombre de la campaña
descriptionstring | nullDescripción de la campaña
company_idstring | nullEmpresa propietaria
user_idstring | nullUsuario que la creó (campañas personales)
brand_idstring | nullAlcance de marca cuando esté definido
created_atstringHora de creación en ISO 8601
JSON
{
  "id": "ccamp_abc123",
  "name": "Summer launch",
  "description": "Q2 product push",
  "company_id": "cmxyz_company",
  "user_id": null,
  "brand_id": "cbrand_abc",
  "created_at": "2026-06-22T12:00:00.000Z"
}

post.published

Se dispara cuando una publicación programada o inmediata se publica con éxito en todos los destinos de plataforma configurados.

Usos comunes: Notificar a sistemas externos que el contenido está en vivo, cerrar el ciclo de las automatizaciones de campaña o sincronizar el estado de publicación con un data warehouse.

Nota: Solo se emite cuando todos los destinos tienen éxito. Los fallos parciales no emiten este evento por ahora.

Campos de data.object:

CampoTipoDescripción
idstringId de la publicación
post_idstringIgual que id
statusstringPUBLISHED
company_idstring | nullEmpresa propietaria
user_idstring | nullUsuario propietario (espacio personal)
brand_idstring | nullAlcance de marca cuando esté definido
campaign_idstring | nullCampaña vinculada cuando esté definida
published_atstringHora de publicación en ISO 8601
platform_countnumberNúmero de destinos de plataforma en la publicación
JSON
{
  "id": "cpost_abc123",
  "post_id": "cpost_abc123",
  "status": "PUBLISHED",
  "company_id": "cmxyz_company",
  "user_id": null,
  "brand_id": "cbrand_abc",
  "campaign_id": "ccamp_abc123",
  "published_at": "2026-06-22T12:00:00.000Z",
  "platform_count": 3
}

webhook.test

Ping sintético enviado solo cuando haces clic en Enviar prueba en el panel o llamas a POST /v1/webhooks/endpoints/:id/test.

Usos comunes: Validar la URL de tu receptor, TLS, verificación de firma y manejo de respuesta antes de pasar a producción.

Campos de data.object:

CampoTipoDescripción
endpoint_idstringEndpoint que recibió la prueba
messagestringMensaje fijo: Styrar webhook test ping
JSON
{
  "endpoint_id": "wh_ep_abc123",
  "message": "Styrar webhook test ping"
}

Ejemplos de la API

Listar endpoints

RequestGET
Authorization: Bearer sty_live_your_api_key
Response200 OK
[
  {
    "id": "wh_ep_abc123",
    "url": "https://your-app.com/webhooks/styrar",
    "description": "Production CRM sync",
    "enabled": true,
    "eventTypes": ["link.clicked", "link.created"],
    "secretPrefix": "whsec_l",
    "companyId": "cmxyz_company",
    "userId": null,
    "disabledAt": null,
    "createdAt": "2026-06-22T12:00:00.000Z",
    "updatedAt": "2026-06-22T12:00:00.000Z"
  }
]

Recibir un evento en tu servidor

Cuando se dispara un evento suscrito, Styrar hace un POST a la URL de tu endpoint. Este es el payload que recibe tu manejador:

RequestPOST
Content-Type: application/json
Styrar-Event-Id: evt_outbox_abc123
Styrar-Event-Type: link.clicked
Styrar-Signature: t=1719052800,v1=8f4b2c1a9e0d3f7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3
User-Agent: Styrar-Webhooks/1.0

{
  "id": "evt_outbox_abc123",
  "type": "link.clicked",
  "api_version": "2026-06-22",
  "created_at": "2026-06-22T12:00:00.000Z",
  "workspace": {
    "type": "company",
    "company_id": "cmxyz_company"
  },
  "data": {
    "object": {
      "id": "clink_abc123",
      "link_id": "clink_abc123",
      "short_code": "summer",
      "title": "Summer sale",
      "country": "NL",
      "city": "Amsterdam",
      "device": "mobile",
      "browser": "Chrome",
      "os": "iOS",
      "referrer": "https://instagram.com/",
      "routing_rule_id": null,
      "experiment_variant_id": null,
      "clicked_at": "2026-06-22T12:00:00.000Z"
    }
  }
}
Response200 OK
{
  "received": true
}

El cuerpo de tu respuesta puede estar vacío. Devuelve cualquier estado 2xx después de verificar la firma y aceptar el evento. Styrar reintenta en respuestas que no sean 2xx.

Payload del ping de prueba

Una acción de Enviar prueba entrega webhook.test con un payload más pequeño:

RequestPOST
Content-Type: application/json
Styrar-Event-Id: evt_test_abc123
Styrar-Event-Type: webhook.test
Styrar-Signature: t=1719052800,v1=...

{
  "id": "evt_test_abc123",
  "type": "webhook.test",
  "api_version": "2026-06-22",
  "created_at": "2026-06-22T12:00:00.000Z",
  "workspace": {
    "type": "company",
    "company_id": "cmxyz_company"
  },
  "data": {
    "object": {
      "endpoint_id": "wh_ep_abc123",
      "message": "Styrar webhook test ping"
    }
  }
}
Response200 OK

Listar entregas recientes

RequestGET
Authorization: Bearer sty_live_your_api_key
Response200 OK
[
  {
    "id": "wh_del_abc123",
    "endpointId": "wh_ep_abc123",
    "outboxEventId": "wh_out_abc123",
    "eventType": "link.clicked",
    "status": "delivered",
    "attemptCount": 1,
    "lastStatusCode": 200,
    "lastError": null,
    "durationMs": 142,
    "nextAttemptAt": null,
    "deliveredAt": "2026-06-22T12:00:01.000Z",
    "createdAt": "2026-06-22T12:00:00.500Z"
  }
]

Gestión de endpoints

Plain text
GET    /v1/webhooks/endpoints?companyId={id}
POST   /v1/webhooks/endpoints
GET    /v1/webhooks/endpoints/:id
PATCH  /v1/webhooks/endpoints/:id
DELETE /v1/webhooks/endpoints/:id
POST   /v1/webhooks/endpoints/:id/test
POST   /v1/webhooks/endpoints/:id/rotate-secret
CampoDescripción
urlURL de callback HTTPS
descriptionEtiqueta opcional
eventTypesArray de tipos de evento suscritos; vacío significa todos los eventos
enabledPor defecto true

El secreto de firma (whsec_live_… / whsec_test_…) se devuelve exactamente una vez al crear y al rotar (rotate-secret). Puedes registrar hasta 25 endpoints por alcance de espacio de trabajo.

Entregas

Plain text
GET  /v1/webhooks/deliveries?endpointId={id}
GET  /v1/webhooks/deliveries/:id
POST /v1/webhooks/deliveries/:id/retry

Cada fila de entrega registra status, attemptCount, nextAttemptAt, lastStatusCode, lastError y deliveredAt. Revisa los fallos en el panel bajo Configuración → Webhooks o reinténtalos mediante la API.

Formato de entrega

Cada evento en vivo es un POST HTTP a tu URL de callback. Las cabeceras y el cuerpo se muestran en Recibir un evento en tu servidor más arriba.

CabeceraDescripción
Styrar-Event-IdId único del evento (úsalo para deduplicar)
Styrar-Event-Typep. ej. link.clicked
Styrar-Signaturet={unix_ts},v1={hmac_sha256_hex}
User-AgentStyrar-Webhooks/1.0

Campos del envoltorio:

CampoDescripción
idId del evento (coincide con Styrar-Event-Id)
typeCadena del tipo de evento
api_versionVersión del esquema del payload
created_atMarca de tiempo ISO 8601
workspaceAlcance company o personal
data.objectPayload específico del evento

Los payloads de clics incluyen dimensiones de geolocalización y dispositivo, no direcciones IP sin procesar.

Verificación de firmas

La firma sigue un esquema similar al de Stripe. Firma "{timestamp}.{raw_body}" con HMAC-SHA256 usando el secreto de tu endpoint.

  1. Analiza Styrar-Signature en t (marca de tiempo unix) y v1 (resumen hexadecimal).
  2. Rechaza si t está fuera de tu tolerancia (recomendamos 5 minutos).
  3. Calcula el resumen esperado y compáralo con v1 usando una verificación en tiempo constante.
JavaScript
import crypto from 'node:crypto'

function verifyStyrarWebhook(secret, signatureHeader, rawBody, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((part) => part.trim().split('=')),
  )

  const timestamp = Number(parts.t)
  const receivedDigest = parts.v1 || ''

  if (!Number.isFinite(timestamp)) return false
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false

  const expectedDigest = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')

  try {
    return crypto.timingSafeEqual(
      Buffer.from(expectedDigest, 'utf8'),
      Buffer.from(receivedDigest, 'utf8'),
    )
  } catch {
    return false
  }
}

Verifica siempre contra el cuerpo de la solicitud sin procesar antes de analizar el JSON.

Confiabilidad

  • Las entregas son al menos una vez. Deduplica usando Styrar-Event-Id o el id del envoltorio.
  • Las entregas fallidas se reintentan con retroceso exponencial hasta el éxito o el máximo de intentos.
  • Si tu servidor devuelve HTTP 410, Styrar deshabilita el endpoint automáticamente.
  • Responde con 2xx en cuanto hayas aceptado el evento; procesa el trabajo pesado de forma asíncrona.

Límites

  • HTTPS obligatorio en producción para las URLs de callback.
  • 25 endpoints por alcance de espacio de trabajo personal o de empresa.
  • Los secretos de firma se muestran una sola vez al crear y al rotar; guárdalos en tu gestor de secretos.

Relacionado

Join the beta waitlist

By signing up you agree to receive marketing email. See our Privacy Policy.