← Inicio
⌕
Pregunta en el Discord
General ER:LC FiveM API
Desarrolladores
DOCUMENTACIÓN/API pública v1

Webhooks

Recibe en tu URL los eventos de tu servidor, firmados con X-Blixye-Signature: cómo verificar la firma, reintentos y apagado.

Un webhook es una URL tuya a la que Blixye manda un POST cada vez que pasa algo a lo que te has suscrito: una llamada nueva, una citación, un ban, un ascenso… La lista de eventos y su ámbito está en API v1: eventos. Se dan de alta, se cambian y se borran con /v1/webhooks y el ámbito webhooks:manage (API v1: webhooks); una llave solo puede suscribirse a los eventos de sus propios ámbitos.
OJO Un webhook es una URL tuya a la que Blixye manda un POST cada vez que pasa algo a lo que te has suscrito: una llamada nueva, una citación, un ban, un ascenso… La lista de eventos y su ámbito está en API v1: eventos. Se dan de alta, se cambian y se borran con /v1/webhooks y el ámbito webhooks:manage (API v1: webhooks); una llave solo puede suscribirse a los eventos de sus propios ámbitos.
El destino
OJO El destino
OJO
Solo https, sin usuario ni contraseña en la URL, y de 500 caracteres como mucho.
Todas las IP a las que resuelve el nombre tienen que ser públicas: ni privadas, ni de loopback, ni de enlace local, ni reservadas. Se comprueba al guardar y otra vez en cada entrega.
No se siguen redirecciones: un 3xx cuenta como fallo.
Cuántos destinos puedes tener depende del plan: 1 con Plus, 5 con Premium y 20 con Business.
Lo que llega
OJO Lo que llega
OJO
Un POST con el sobre del evento en JSON: {"id", "type", "created_at", "data"}. Es el mismo sobre, con el mismo id, que da GET /v1/events.
X-Blixye-Signature: t=<hora unix>,v1=<HMAC-SHA256 en hexadecimal>.
X-Blixye-Event: el tipo de evento.
X-Blixye-Delivery: el id de la entrega, el mismo en todos sus reintentos. Úsalo, o el id del evento, para no procesar nada dos veces.
User-Agent: siempre Blixye-Webhooks/1.0.
Verificar la firma
OJO Verificar la firma
El secreto (whsec_…) se enseña una sola vez, al dar de alta el webhook o al rotar su secreto. La firma es el HMAC-SHA256, con ese secreto, de la hora t, un punto y el cuerpo TAL CUAL llega, byte a byte: no lo vuelvas a serializar. Compara en tiempo constante y rechaza la entrega si t está a más de 5 minutos de tu hora.
OJO El secreto (whsec_…) se enseña una sola vez, al dar de alta el webhook o al rotar su secreto. La firma es el HMAC-SHA256, con ese secreto, de la hora t, un punto y el cuerpo TAL CUAL llega, byte a byte: no lo vuelvas a serializar. Compara en tiempo constante y rechaza la entrega si t está a más de 5 minutos de tu hora.
En Node.js, sin dependencias:
OJO En Node.js, sin dependencias:
const http = require('node:http'); const crypto = require('node:crypto'); const SECRET = process.env.BLIXYE_WEBHOOK_SECRET; function verify(header, rawBody) { const m = /^t=([0-9]+),v1=([a-f0-9]{64})$/.exec(header || ''); if (!m) return false; if (Math.abs(Math.floor(Date.now() / 1000) - Number(m[1])) > 300) return false; const expected = crypto.createHmac('sha256', SECRET) .update(m[1] + '.') .update(rawBody) .digest('hex'); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2])); } http.createServer((req, res) => { const chunks = []; req.on('data', (c) => chunks.push(c)); req.on('end', () => { const rawBody = Buffer.concat(chunks); if (!verify(req.headers['x-blixye-signature'], rawBody)) { res.writeHead(400).end(); return; } const event = JSON.parse(rawBody.toString('utf8')); res.writeHead(204).end(); console.log(event.type, event.id, req.headers['x-blixye-delivery']); }); }).listen(3000);
const http = require('node:http'); const crypto = require('node:crypto'); const SECRET = process.env.BLIXYE_WEBHOOK_SECRET; function verify(header, rawBody) { const m = /^t=([0-9]+),v1=([a-f0-9]{64})$/.exec(header || ''); if (!m) return false; if (Math.abs(Math.floor(Date.now() / 1000) - Number(m[1])) > 300) return false; const expected = crypto.createHmac('sha256', SECRET) .update(m[1] + '.') .update(rawBody) .digest('hex'); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2])); } http.createServer((req, res) => { const chunks = []; req.on('data', (c) => chunks.push(c)); req.on('end', () => { const rawBody = Buffer.concat(chunks); if (!verify(req.headers['x-blixye-signature'], rawBody)) { res.writeHead(400).end(); return; } const event = JSON.parse(rawBody.toString('utf8')); res.writeHead(204).end(); console.log(event.type, event.id, req.headers['x-blixye-delivery']); }); }).listen(3000);
OJO const http = require('node:http'); const crypto = require('node:crypto'); const SECRET = process.env.BLIXYE_WEBHOOK_SECRET; function verify(header, rawBody) { const m = /^t=([0-9]+),v1=([a-f0-9]{64})$/.exec(header || ''); if (!m) return false; if (Math.abs(Math.floor(Date.now() / 1000) - Number(m[1])) > 300) return false; const expected = crypto.createHmac('sha256', SECRET) .update(m[1] + '.') .update(rawBody) .digest('hex'); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2])); } http.createServer((req, res) => { const chunks = []; req.on('data', (c) => chunks.push(c)); req.on('end', () => { const rawBody = Buffer.concat(chunks); if (!verify(req.headers['x-blixye-signature'], rawBody)) { res.writeHead(400).end(); return; } const event = JSON.parse(rawBody.toString('utf8')); res.writeHead(204).end(); console.log(event.type, event.id, req.headers['x-blixye-delivery']); }); }).listen(3000);
En PHP:
OJO En PHP:
<?php $secret = getenv('BLIXYE_WEBHOOK_SECRET'); $rawBody = file_get_contents('php://input'); $header = $_SERVER['HTTP_X_BLIXYE_SIGNATURE'] ?? ''; if (!preg_match('/^t=([0-9]+),v1=([a-f0-9]{64})$/', $header, $m) || abs(time() - (int) $m[1]) > 300 || !hash_equals(hash_hmac('sha256', $m[1] . '.' . $rawBody, $secret), $m[2])) { http_response_code(400); exit; } $event = json_decode($rawBody, true); http_response_code(204); error_log($event['type'] . ' ' . $event['id']);
<?php $secret = getenv('BLIXYE_WEBHOOK_SECRET'); $rawBody = file_get_contents('php://input'); $header = $_SERVER['HTTP_X_BLIXYE_SIGNATURE'] ?? ''; if (!preg_match('/^t=([0-9]+),v1=([a-f0-9]{64})$/', $header, $m) || abs(time() - (int) $m[1]) > 300 || !hash_equals(hash_hmac('sha256', $m[1] . '.' . $rawBody, $secret), $m[2])) { http_response_code(400); exit; } $event = json_decode($rawBody, true); http_response_code(204); error_log($event['type'] . ' ' . $event['id']);
OJO <?php $secret = getenv('BLIXYE_WEBHOOK_SECRET'); $rawBody = file_get_contents('php://input'); $header = $_SERVER['HTTP_X_BLIXYE_SIGNATURE'] ?? ''; if (!preg_match('/^t=([0-9]+),v1=([a-f0-9]{64})$/', $header, $m) || abs(time() - (int) $m[1]) > 300 || !hash_equals(hash_hmac('sha256', $m[1] . '.' . $rawBody, $secret), $m[2])) { http_response_code(400); exit; } $event = json_decode($rawBody, true); http_response_code(204); error_log($event['type'] . ' ' . $event['id']);
Contesta rápido con un 2xx y haz el trabajo después: Blixye espera 5 segundos como mucho.
OJO Contesta rápido con un 2xx y haz el trabajo después: Blixye espera 5 segundos como mucho.
Reintentos y apagado
OJO Reintentos y apagado
OJO
Las entregas salen en una pasada que corre cada minuto: un evento llega en cuestión de un minuto, no al instante.
Un 2xx es una entrega hecha. Cualquier otra cosa (un 3xx, un 4xx, un 5xx, un timeout o un fallo de red) es un fallo.
Una entrega fallida se reintenta a los 1 min, 5 min, 30 min, 2 h, 6 h, 12 h y 24 h: 8 intentos en total. Después se da por perdida.
10 fallos SEGUIDOS del mismo destino, de cualquier entrega, lo apagan: queda con disabled_reason too_many_failures y sus entregas pendientes se dan por perdidas. Un solo éxito pone la cuenta a cero.
Para volver a encenderlo: PATCH /v1/webhooks/{id} con {"is_active": true}. Empieza de cero, pero lo que se perdió mientras estaba apagado no se vuelve a mandar: recupéralo con GET /v1/events.
No se garantiza el orden: un reintento puede llegar después de eventos más nuevos. Ordena por created_at.
El historial de entregas se guarda 30 días.
Al rotar el secreto (POST /v1/webhooks/{id}/rotate-secret), el viejo deja de firmar al momento: todas las entregas siguientes, reintentos incluidos, van con el nuevo. Cámbialo en tu receptor enseguida.
OJO Al rotar el secreto (POST /v1/webhooks/{id}/rotate-secret), el viejo deja de firmar al momento: todas las entregas siguientes, reintentos incluidos, van con el nuevo. Cámbialo en tu receptor enseguida.
Si no puedes recibir webhooks (detrás de un NAT, o un script que corre de vez en cuando), sondea GET /v1/events: son los mismos eventos (API v1: eventos).
OJO Si no puedes recibir webhooks (detrás de un NAT, o un script que corre de vez en cuando), sondea GET /v1/events: son los mismos eventos (API v1: eventos).
← Anterior
Idempotencia
Siguiente →
API v1: servidor
36 / 54 Falta algo aquí →
PASO 1 · PLAN ×
Elige el plan de tu servidor
Después del pago le pones nombre y lo configuramos juntos. Puedes cambiar de plan cuando quieras.
FREE1 DE 1 LIBRE 500 personajes y el CAD completo. Para probarlo. 0 €
PLUSAL MES CAD completo, moderación, actividad y economía. 5,99 €
PREMIUMER:LC Y FIVEM Todo lo de PLUS, FiveM incluido y límites más altos. 12,99 €
ENTERPRISEPERMANENTE Todo PREMIUM para siempre, hospedado por ti y sin cuotas nunca. Consultar
Continuar al pago
Cancelas cuando quieras · 14 días de desistimiento, salvo que pidas empezar al momento
Confirmar y pagar
ER:LC PREMIUM
Mensual · una licencia
12,99 €
CORREO
TARJETA
Atrás
En desarrollo — no disponible
Blixye está en desarrollo: todavía no se pueden contratar servicios.Pago seguro · IVA incluido
Ponle nombre a tu servidor
Es el nombre que verán tus jugadores en el launcher y en Discovery. Lo puedes cambiar cuando quieras.
NOMBRE DEL SERVIDOR
Le daremos un código corto, tipo SKY-T2Q, para vincular el launcher.
SIGUIENTE Al crearlo abrimos la guía de configuración: launcher, Discord y módulos en tres pasos.
Atrás
Crear el servidor
Escribe al menos 3 letras.
PASO 1 DE 3 · GUÍA ×
1. Pásale el launcher a tu gente
Es lo único que instalan, y solo una vez. Entran con Discord, verificamos su cuenta de Roblox y el overlay aparece sobre la partida.
Ir a la descarga
2. Crea tus departamentos
Policía, sheriff, bomberos o lo que uses. Cada uno con sus rangos y permisos: eso decide quién puede sancionar, fichar o ver expedientes.
3. Abre el servidor
Con el primer turno de servicio empiezan a llenarse las llamadas, la actividad y la economía. A partir de ahí solo ajustas.
Atrás
Siguiente
⌕ ESC
Overlay in-game Radio, ficha y despacho encima de la partida, sin alt-tab. ER:LC CAD y departamentos Llamadas en cola, unidades con estado y rosters con rangos. ER:LC Moderación y apelaciones Sanciones con contexto, logs y apelaciones que no se pierden. ER:LC Actividad del staff Cuotas por rango, turnos y un informe semanal automático. ER:LC Economía y negocios Cuentas, nóminas, negocios de jugadores e inventario. ER:LC Blixye Framework El núcleo: personajes, permisos, base de datos y bridge QBCore y ESX. FiveM Inventario Peso, contenedores e intercambios seguros entre jugadores. FiveM MDT policial Fichas, multas, órdenes de busca y consultas de matrícula. FiveM Banca Cuentas, transferencias, nóminas y cuentas de empresa. FiveM Trabajos Turnos, nóminas y jerarquía por empresa. FiveM Garajes Propiedad de vehículos, daños persistentes y depósito. FiveM Casas Compra, alquiler, muebles y almacenamiento propio. FiveM Teléfono Mensajes, llamadas, apps y redes sociales del rol. FiveM Médico Heridas por zona, tratamientos y hospital con camas. FiveM Todos los scripts Los ocho scripts sin límite, en un pago permanente o por suscripción. FiveM Instalar Blixye en ER:LC Del servidor vacío al primer turno de servicio, sin tocar un archivo del juego. Documentación Instalar el framework de FiveM El zip, el SQL y el bridge de tu base actual, en el orden correcto. Documentación Tu primera semana Qué configurar cada día para no acabar con veinte cosas a medias. Documentación CAD y despacho Llamadas, unidades y prioridades dentro del overlay. Documentación Moderación y apelaciones Sanciones con pruebas, apelaciones y el registro que te cubre. Documentación Actividad y turnos Horas, cuotas y quién está patrullando de verdad. Documentación Scripts y versión gratis Qué limita la versión gratis de cada script y qué abre la completa. Documentación Bridge con QBCore y ESX Convivir con tu base actual sin duplicar jugadores ni dinero. Documentación Rendimiento Dónde mirar cuando el servidor va a tirones. Documentación
Nada con ese nombre. Prueba con «inventario», «CAD» o «licencias».
↵ abrir CTRL K buscar 37 resultados
ROTAR LA KEY ×
! La key actual deja de valer en el momento en que confirmes. Esto no se puede deshacer.
key actual → key nueva al confirmar
Pega la key nueva en el config del script.
Reinicia el recurso: refresh y ensure.
Mientras no lo hagas, el script no cargará.
Sí, rotar la key Cancelar
Qué incluye cada plan ×
FREE
DISCORD
PLUS
PREMIUM
ENTERPRISE
Precio
Gratis
2,99 €/mes
5,99 €/mes
12,99 €/mes
Consultar
GENERAL
Personajes guardados
500
—
5000
∞
∞
Código de invitación propio
—
✓
✓
✓
✓
CAD
Corporaciones máx.
2
—
6
∞
∞
Subdivisiones máx.
0
—
6
∞
∞
Borrado de datos MDT
1 mes
—
1 año
Nunca
Nunca
Acceso al MDT
Completo
—
Completo
Completo
Completo
Historial de logs
7 días
—
90 días
∞
∞
Exportar datos
—
—
✓
✓
✓
Investigaciones
—
—
✓
✓
✓
Almacenamiento de pruebas
—
—
Sin límite
Sin límite
Sin límite
Leyes propias
50
—
150
∞
∞
Mapa en tiempo real
—
—
✓
✓
✓
Bodycam
—
—
✓
✓
✓
Ubicación en el mapa en vivo
—
—
✓
✓
✓
Búsqueda avanzada
—
—
✓
✓
✓
Canales de radio (Discord VC)
10
—
50
100
∞
Roles por corporación
15
—
50
∞
∞
BANK
Cuentas bancarias
1 por pj
—
3 por pj
6 por pj
12 por pj
Transferencias
✓
—
✓
✓
✓
Historial de movimientos
✓
—
✓
✓
✓
Tarjetas por cuenta
1
—
2
3
5
Tarjetas temporales
Duración fija
—
✓
✓
✓
Tarjetas por usos
—
—
Máx. 5 por pj
✓
✓
Recompensas por rol
✓
—
✓
✓
✓
Permitir saldo negativo
—
—
✓
✓
✓
Transferencias programadas
—
—
✓
✓
✓
Deudas entre jugadores
—
—
✓
✓
✓
Límites por operación
—
—
✓
✓
✓
Cuentas compartidas
Máx. 2 miembros
—
Máx. 5 miembros
∞
∞
ADMIN
Mapa de calor de jugadores
—
—
✓
✓ más preciso
✓ más preciso
Formularios máx.
3
5
10
∞
∞
Tu servidor en el teléfono
—
—
✓
✓
✓
Roles de admin máx.
owner +2
owner +5
owner +10
∞
∞
Soporte prioritario
—
✓
✓
✓
✓
Historial de auditoría de staff
7 días
30 días
90 días
∞
∞
Funciones beta
—
✓
✓
✓
✓
Crear servidor
Los addons de personajes y almacenamiento se añaden sobre cualquier plan.
Cookies SOLO ESENCIALES
Solo usamos las imprescindibles: tu sesión, la seguridad al entrar y tu idioma. No hay analítica ni publicidad, así que no hay nada que aceptar ni rechazar.
Entendido
Política de cookies