API y servidor MCP
Cree tokens en su espacio, apartado Desarrolladores. Cada token tiene permisos limitados, se puede modificar (nombre y permisos) y revocar en cualquier momento.
Autenticación
Authorization: Bearer rl_live_…
Respuestas en JSON. Errores: { "error": { "code", "message" } }. Límite según el plan (Solo 20, Pro 60, Agence 120 peticiones por minuto) y 1 petición por segundo como máximo, indicados en las cabeceras X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Burst. Por encima: 429 con Retry-After. Servicio muy solicitado: 503 con Retry-After. Para crear muchos enlaces, use /v1/links/batch.
Modificar: POST o PATCH
Los tres puntos de acceso de modificación aceptan POST igual que PATCH, en la misma ruta y con el mismo cuerpo. Prefiera POST: algunas infraestructuras (cortafuegos, fachada del alojamiento, proxy de empresa) cortan las peticiones PATCH antes de que lleguen al servicio, y la conexión se reinicia sin respuesta HTTP. La cabecera X-HTTP-Method-Override: PATCH y el campo _method también se aceptan; no son necesarios.
curl -X POST https://api.reli.es/v1/links/42 \
-H "Authorization: Bearer rl_live_…" \
-H "Content-Type: application/json" \
-d '{"url": "https://exemple.fr/nouvelle-page"}'
Crear un enlace
curl https://api.reli.es/v1/links \
-H "Authorization: Bearer rl_live_…" \
-H "Content-Type: application/json" \
-d '{
"url": "https://exemple.fr/offre",
"slug": "offre-hiver",
"tags": ["sms"],
"utm": {"source": "sms", "campaign": "hiver"},
"expires_at": "2026-12-31T23:59:00+01:00"
}'
201 Created
{
"data": {
"id": 42,
"short_url": "https://reli.es/offre-hiver",
"domain": "reli.es",
"slug": "offre-hiver",
"destination": "https://exemple.fr/offre",
"title": null,
"status": "active",
"tags": ["sms"],
"utm": {"source": "sms", "campaign": "hiver"},
"protected": false,
"starts_at": null,
"ends_at": "2026-12-31T23:59:00+01:00",
"expired_url": null,
"clicks": 0,
"qr_svg": "https://api.reli.es/v1/links/42/qr.svg",
"created_at": "2026-09-29T10:12:04+02:00"
}
}
Nombres de los campos
La respuesta llama a la destinación «destination» y a la fecha de fin «ends_at». Al enviar se aceptan ambas formas: url o destination, expires_at o ends_at. Cualquier otro nombre se rechaza con un 422 que lo indica: un campo mal nombrado nunca se ignora en silencio.
422 Unprocessable Content
{ "error": {
"code": "unknown_field",
"message": "Champ inconnu : lien. Champs acceptés : url, destination, …",
"unknown": ["lien"],
"accepted": ["url", "destination", "title", "tags", "utm", "starts_at", "expires_at", "ends_at", "expired_url", "password"]
} }
Listar los enlaces
Filtros: tag, status (active, archived, blocked, review), domain, q, limit (100 como máximo) y cursor. El cursor de la página siguiente está en la raíz de la respuesta; vale null en la última página. Los enlaces de las páginas bio y de las campañas no aparecen en esta lista.
GET https://api.reli.es/v1/links?tag=sms&limit=50
{ "data": [ { "id": 42, … } ], "next_cursor": "42" }
Estadísticas
GET /v1/links/{id}/stats?days=30 (de 1 a 365 días). Un clic se registra al instante y aparece enseguida. Las aperturas repetidas del mismo visitante en 30 minutos cuentan en repeats, nunca en clicks. Una llamada procedente de un servidor (sin idioma de visualización, en HEAD o precargada por el navegador) cuenta en bots: una prueba por línea de comandos no aumenta clicks.
{ "data": {
"days": 30, "clicks": 128, "uniques": 96, "qr": 12, "bots": 31, "repeats": 7,
"previous_period_clicks": 88,
"daily": [ {"date": "2026-09-01", "clicks": 4}, … ],
"countries": [ {"label": "FR", "n": 101}, … ],
"cities": [ … ], "devices": [ … ], "sources": [ … ],
"link": { "id": 42, "short_url": "https://reli.es/offre-hiver" }
} }
Terminaciones de enlace
Terminación elegida (slug): de 2 a 64 caracteres, letras minúsculas, cifras y guiones, sin guion al principio ni al final. Las mayúsculas enviadas se pasan a minúsculas. Una terminación ya ocupada, reservada o prohibida devuelve un 422 cuyo mensaje propone una variante. Una terminación nunca se reasigna, ni siquiera tras archivarla.
Sin slug, el servicio asigna una de seis caracteres en minúsculas, sin caracteres ambiguos (ni 0 ni o, ni 1, l o i): legible bajo un código QR impreso y fácil de dictar por teléfono.
Endpoints
| Método | Ruta | Permiso | Rol |
|---|---|---|---|
| POST | /v1/links | links:write | Crear un enlace: url, domain, slug, title, tags, utm, starts_at, expires_at, expired_url, password |
| POST | /v1/links/batch | links:write | Crear hasta 100 enlaces: { "links": [ … ] }; respuesta 207 con una línea por enlace |
| GET | /v1/links | links:read | Listar: tag, status, domain, q, cursor, limit (100 como máximo) |
| GET | /v1/links/{id} | links:read | Leer un enlace |
| POST · PATCH | /v1/links/{id} | links:write | Modificar destino, título, etiquetas, fechas, UTM |
| DELETE | /v1/links/{id} | links:write | Archivar (el final del enlace nunca se reasigna) |
| GET | /v1/links/{id}/stats | stats:read | Estadísticas: days (de 1 a 365) |
| GET | /v1/links/{id}/qr.svg | links:read | Código QR SVG o PNG |
| GET | /v1/domains | domains:read | Dominios utilizables. Este permiso solo sirve aquí: crear un enlace en reli.es no lo necesita. |
| GET · POST · PATCH | /v1/pages/{handle} | pages:read · pages:write | Leer una página bio, modificar título y presentación |
| GET | /v1/account | — | Plan, límites y consumo |
| GET | /v1/managed-accounts | accounts:managed | Cuentas gestionadas, indicadas con la cabecera Relies-Account |
Campañas: un enlace por contacto
Reservado a las cuentas de agencia y a las cuentas que gestionan. Una campaña lleva una destinación, un dominio, parámetros de seguimiento y una fecha de fin; cada contacto recibe después su propia terminación de enlace, creada por lotes de 100 en una sola petición. La referencia de contacto (ref) es su identificador: de 1 a 64 caracteres, letras, cifras, punto, dos puntos, guion y guion bajo. Se conserva tal cual: no ponga en ella ni nombres, ni números de teléfono, ni direcciones de correo.
| Método | Ruta | Rol |
|---|---|---|
| GET · POST | /v1/campaigns | Listar, crear: name, url, domain, utm, expires_at, expired_url, kore_ref |
| GET · POST · PATCH | /v1/campaigns/{id} | Leer, modificar: name, url, expires_at, expired_url, kore_ref |
| POST | /v1/campaigns/{id}/contacts | Añadir de 1 a 100 contactos en una sola petición: { "contacts": [ {"ref": "c-1024"}, {"ref": "c-1025", "url": "https://exemple.fr/page-b"} ] } |
| GET | /v1/campaigns/{id}/contacts | Listar los contactos: clicked, clicked_since, limit (500 como máximo) |
| DELETE | /v1/campaigns/{id}/contacts/{ref} | Olvidar un contacto: su referencia se borra, el enlace se archiva |
curl https://api.reli.es/v1/campaigns/7/contacts \
-H "Authorization: Bearer rl_live_…" \
-H "Content-Type: application/json" \
-d '{"contacts": [{"ref": "c-1024"}, {"ref": "c-1025", "url": "https://exemple.fr/page-b"}]}'
200 OK (207 si una línea falla)
{ "data": [ { "index": 0, "ref": "c-1024", "ok": true, "created": true,
"link": { "id": 512, "short_url": "https://reli.es/k7m4qp", … } }, … ],
"created": 2, "existing": 0, "failed": 0 }
Una referencia que la campaña ya conoce devuelve el enlace existente (existing): el mismo envío puede repetirse sin crear duplicados. El primer clic de cada contacto dispara el webhook campaign.contact_clicked.
Permisos de los tokens
links:read · links:write · stats:read · pages:read · pages:write · domains:read · campaigns:read · campaigns:write · accounts:managed
Un permiso que falta devuelve un 403 «forbidden» que nombra el permiso esperado. Los permisos de un token se modifican en su espacio, apartado Desarrolladores, sin cambiar su valor: las herramientas ya conectadas siguen funcionando.
Webhooks
Eventos: link.created, link.blocked, link.clicked (agrupado por minuto), page.form_submitted, campaign.contact_clicked (cuentas gestionadas). Cada envío lleva la cabecera X-Relies-Signature: t=marca de tiempo,v1=firma, donde la firma es el HMAC-SHA256 de «marca_de_tiempo.cuerpo» con su secreto. Rechace los envíos de más de 5 minutos. Tres reintentos en caso de error: tras 1 minuto, 10 minutos y 1 hora.
$payload = file_get_contents('php://input');
[$t, $v1] = sscanf($_SERVER['HTTP_X_RELIES_SIGNATURE'], 't=%d,v1=%s');
$valid = abs(time() - $t) < 300
&& hash_equals(hash_hmac('sha256', $t.'.'.$payload, $secret), $v1);
Servidor MCP
Dirección: https://api.reli.es/mcp · transporte HTTP, mismo token que la API.
claude mcp add --transport http reli-es https://api.reli.es/mcp \ --header "Authorization: Bearer rl_live_…"
| Herramienta | Rol |
|---|---|
liens_creer | Crear uno o varios enlaces |
liens_chercher | Buscar por destino, etiqueta, estado |
liens_stats | Estadísticas de un enlace o de la cuenta |
lien_modifier | Modificar destino, título, etiquetas, fechas |
lien_archiver | Archivar, con confirmación explícita |
page_lire · page_modifier | Leer una página bio, añadir un botón de enlace |
qr_exporter | Dirección del código QR SVG o PNG |
compte_etat | Plan, límites y consumo |