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-IdyStyrar-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:
| Alcance | Acceso |
|---|---|
webhooks:read | Listar endpoints, entregas y tipos de evento |
webhooks:write | Crear, 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
- Inicia sesión y abre Configuración → Webhooks (
/settings/webhooks). - En Endpoints, ingresa tu URL de endpoint (el callback HTTPS público).
- Opcionalmente añade una Descripción (por ejemplo, "Sincronización de CRM en producción").
- Selecciona los Eventos que quieras (se requiere al menos uno). Opciones comunes:
link.clickedpara seguimiento de clicslink.created/link.updated/link.deletedpara el ciclo de vida del enlacepost.publishedycampaign.createdpara eventos del funnel
- 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
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"
]
}{
"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:
Authorization: Bearer sty_live_your_api_key{
"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:
| Problema | Qué revisar |
|---|---|
| Conexión rechazada / tiempo de espera agotado | La URL es HTTPS pública, el firewall permite a Styrar, el túnel está activo |
| HTTP 4xx/5xx de tu app | El manejador devuelve 2xx tras verificar; registra el cuerpo y las cabeceras sin procesar |
| Falla la verificación de firma | Usa el cuerpo sin procesar, el secreto correcto, comparación en tiempo constante |
| Endpoint deshabilitado | Vuelve 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:
- Analiza
Styrar-Signatureen la marca de tiempoty el resumenv1. - Rechaza si
tes más antiguo que tu tolerancia (se recomiendan 5 minutos). - Calcula el HMAC-SHA256 de
"{t}.{raw_body}"con el secreto de tu endpoint. - Compáralo con
v1usando una verificación en tiempo constante. - Analiza el JSON solo después de que la verificación se realice con éxito.
- 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
- Obtén acceso a la API con los alcances
webhooks:readywebhooks:write(clave de API u OAuth). - Expón un receptor HTTPS público y crea un endpoint en Configuración → Webhooks o mediante
POST /v1/webhooks/endpoints. - Copia el secreto de firma cuando se muestre y guárdalo de forma segura.
- Envía un evento de prueba y confirma que tu servidor verifica
Styrar-Signaturey devuelve 2xx. - 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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id único del evento. Mismo valor que la cabecera Styrar-Event-Id. |
type | string | Nombre del evento (por ejemplo, link.clicked). |
api_version | string | Versión del esquema del payload (2026-06-22). |
created_at | string | Marca de tiempo ISO 8601 de cuando se creó el evento. |
workspace.type | string | company o personal. |
workspace.company_id | string | null | Id de empresa cuando workspace.type es company. |
data.object | object | Payload del evento (documentado por evento más abajo). |
Ejemplo completo de entrega (envoltorio + payload de link.created):
{
"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
| Evento | Cuándo se dispara | Volumen típico |
|---|---|---|
link.created | Se crea un enlace corto (POST /v1/links, creación masiva o upsert masivo) | Bajo |
link.updated | Se actualiza un enlace corto (PATCH /v1/links/:id, actualización masiva o upsert masivo) | Bajo |
link.deleted | Un enlace corto se elimina de forma reversible (DELETE /v1/links/:id o eliminación masiva) | Bajo |
link.clicked | Se registra un clic con seguimiento (async, tras la redirección mediante el worker de clics) | Alto |
link.experiment.completed | Se completa un experimento A/B de enlace y se selecciona un ganador | Bajo |
campaign.created | Se crea una campaña (POST /v1/campaigns) | Bajo |
post.published | Una publicación social se publica con éxito en todos los destinos de plataforma | Bajo |
webhook.test | Ejecutas Enviar prueba en un endpoint | A 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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id del enlace |
short_code | string | Código corto público |
title | string | null | Título del enlace |
original_url | string | null | URL de destino |
is_active | boolean | Si el enlace está activo |
company_id | string | null | Empresa propietaria (espacio de empresa) |
campaign_id | string | null | Campaña vinculada, si existe |
link_group_id | string | null | Id de carpeta/grupo, si existe |
created_at | string | Hora de creación en ISO 8601 |
{
"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).
{
"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.
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id del enlace |
short_code | string | Código corto en el momento de la eliminación |
title | string | null | Título del enlace |
original_url | string | null | URL de destino |
is_active | boolean | false tras la eliminación reversible |
company_id | string | null | Empresa propietaria |
campaign_id | string | null | Campaña vinculada, si existe |
link_group_id | string | null | Id de carpeta/grupo, si existe |
created_at | string | Hora de creación original |
{
"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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id del enlace |
link_id | string | Igual que id |
short_code | string | Código corto que recibió el clic |
title | string | null | Título del enlace |
country | string | null | Código de país ISO (geolocalización) |
city | string | null | Ciudad según geolocalización |
device | string | null | Clase de dispositivo (por ejemplo, mobile, desktop) |
browser | string | null | Nombre del navegador |
os | string | null | Sistema operativo |
platform | string | null | Indicio de plataforma según el análisis del user agent |
referrer | string | null | URL de referencia, cuando esté disponible |
routing_rule_id | string | null | Regla de enrutamiento por geo/dispositivo que coincidió, si existe |
experiment_variant_id | string | null | Id de variante A/B cuando el clic pasó por un experimento |
clicked_at | string | Hora del clic en ISO 8601 |
{
"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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id del experimento |
link_id | string | Id del enlace padre |
short_code | string | null | Código corto del enlace padre |
status | string | completed |
assignment_mode | string | null | Cómo se dividió el tráfico (por ejemplo, ponderado) |
winning_variant_id | string | null | Id de la variante ganadora |
ended_at | string | null | Hora de finalización en ISO 8601 |
variants | array | Resultados por variante (ver abajo) |
Cada elemento en variants:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id de la variante |
label | string | Etiqueta legible |
weight | number | Peso de tráfico usado en la prueba |
destination_url | string | URL a la que esta variante envió tráfico |
clicks | number | Total de clics registrados para esta variante |
{
"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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id de la campaña |
name | string | Nombre de la campaña |
description | string | null | Descripción de la campaña |
company_id | string | null | Empresa propietaria |
user_id | string | null | Usuario que la creó (campañas personales) |
brand_id | string | null | Alcance de marca cuando esté definido |
created_at | string | Hora de creación en ISO 8601 |
{
"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:
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Id de la publicación |
post_id | string | Igual que id |
status | string | PUBLISHED |
company_id | string | null | Empresa propietaria |
user_id | string | null | Usuario propietario (espacio personal) |
brand_id | string | null | Alcance de marca cuando esté definido |
campaign_id | string | null | Campaña vinculada cuando esté definida |
published_at | string | Hora de publicación en ISO 8601 |
platform_count | number | Número de destinos de plataforma en la publicación |
{
"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:
| Campo | Tipo | Descripción |
|---|---|---|
endpoint_id | string | Endpoint que recibió la prueba |
message | string | Mensaje fijo: Styrar webhook test ping |
{
"endpoint_id": "wh_ep_abc123",
"message": "Styrar webhook test ping"
}
Ejemplos de la API
Listar endpoints
Authorization: Bearer sty_live_your_api_key[
{
"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:
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"
}
}
}{
"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:
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"
}
}
}Listar entregas recientes
Authorization: Bearer sty_live_your_api_key[
{
"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
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
| Campo | Descripción |
|---|---|
url | URL de callback HTTPS |
description | Etiqueta opcional |
eventTypes | Array de tipos de evento suscritos; vacío significa todos los eventos |
enabled | Por 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
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.
| Cabecera | Descripción |
|---|---|
Styrar-Event-Id | Id único del evento (úsalo para deduplicar) |
Styrar-Event-Type | p. ej. link.clicked |
Styrar-Signature | t={unix_ts},v1={hmac_sha256_hex} |
User-Agent | Styrar-Webhooks/1.0 |
Campos del envoltorio:
| Campo | Descripción |
|---|---|
id | Id del evento (coincide con Styrar-Event-Id) |
type | Cadena del tipo de evento |
api_version | Versión del esquema del payload |
created_at | Marca de tiempo ISO 8601 |
workspace | Alcance company o personal |
data.object | Payload 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.
- Analiza
Styrar-Signatureent(marca de tiempo unix) yv1(resumen hexadecimal). - Rechaza si
testá fuera de tu tolerancia (recomendamos 5 minutos). - Calcula el resumen esperado y compáralo con
v1usando una verificación en tiempo constante.
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-Ido eliddel 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
- Píxel de conversión — rastrea conversiones en páginas de destino que no controlas
- Enlaces cortos y códigos QR en el centro de ayuda
- Claves de API y apps conectadas