API REST
Todo lo que hace el panel se puede hacer desde la API. Base: https://short.xterraengine.com/api. Respuestas en JSON. Errores: {"error":"mensaje en español"} con el código HTTP correspondiente.
Autenticación
Crea una clave en Panel › Claves API y envíala en cada petición:
Authorization: Bearer atj_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Las cuentas se crean solo desde el panel con una passkey; la API no registra usuarios.
Enlaces
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/links?q=&tag=&limit=&offset= | Lista tus enlaces con contadores. |
| POST | /api/links | Crea un enlace. Solo destination es obligatorio. |
| GET | /api/links/:id | Enlace completo con mapeos, reglas y variantes. |
| PUT | /api/links/:id | Actualiza campos. Si envías mappings, rules o variants sustituyen la lista completa; si los omites, se conservan. |
| DELETE | /api/links/:id | Elimina el enlace y su analítica. |
| POST | /api/links/:id/mappings | Añade o actualiza mapeos sin tocar los demás (acepta un objeto o una lista). |
| DELETE | /api/links/:id/mappings/:key | Borra un mapeo. |
| GET | /api/slug-available/:slug | Comprueba si un alias está libre. |
| GET | /qr/:slug?format=svg|png&size=512&dark=0b1220&light=ffffff&u=clave | Código QR (público). |
Crear un enlace con plantilla, mapeos y una regla
curl -X POST https://short.xterraengine.com/api/links \
-H "Authorization: Bearer $ATAJO_KEY" -H "Content-Type: application/json" \
-d '{
"slug": "promo",
"destination": "https://ejemplo.com/landing?ref={u}&camp={c}",
"title": "Promoción de otoño",
"tags": ["otoño"],
"default_params": {"utm_source": "atajo", "utm_medium": "qr"},
"passthrough": true,
"mappings": [
{"key": "maria", "label": "María", "params": {"c": "vip"}},
{"key": "juan", "destination": "https://ejemplo.com/juan"}
],
"rules": [
{"kind": "device", "match": {"values": ["mobile"]}, "destination": "https://m.ejemplo.com/{u}", "label": "móvil"}
],
"variants": [],
"expires_at": "2026-12-31T23:59:00Z",
"max_clicks": null,
"password": null,
"redirect_code": 302,
"webhook_url": null
}'
Cómo se resuelve un clic
/promo/mariao/promo?u=mariabusca el mapeomaria. Con clave en la ruta y sin mapeo → 404.- Se evalúan las reglas en orden; la primera que coincide fija el destino. Tipos:
device(mobile, tablet, desktop, tv),os,lang,country,referer,date({"from","to"}),param({"name","value"}),bot. - Si ninguna regla coincide y hay variantes, se elige una al azar según su
weight. - Si el mapeo tiene
destinationpropio, manda sobre lo anterior. - Se rellenan las plantillas
{nombre}con: valores del mapeo > query recibida >default_params.{u}es la clave del mapeo. Las plantillas sin valor se eliminan de la query. - Se anexan
default_params, los valores del mapeo y, conpassthrough, la query recibida (salvou). - Se responde 302 con
Cache-Control: no-storey se registra el clic de forma asíncrona.
Analítica
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/stats?range=30d&bots=0 | Totales de todos tus enlaces, serie temporal y top de enlaces. |
| GET | /api/links/:id/stats?range=24h|7d|30d|90d|365d&from=&to=&bucket=hour|day&bots=0|1 | Totales, comparación con el periodo anterior, serie, desgloses (referers, navegadores, SO, dispositivos, países, idiomas, mapeos, variantes, reglas, destinos, parámetros), hora del día y día de la semana. |
| GET | /api/links/:id/clicks?limit=50&before=<id>&bots=1 | Clics individuales, paginados hacia atrás. |
| GET | /api/links/:id/clicks.csv?range=365d | Exportación CSV (UTF-8 con BOM, abre bien en Excel). |
| GET | /api/stream?link=:id | Server-Sent Events: un evento click por clic (omite link para todos tus enlaces). |
Campos de cada clic
ts, country (si hay base geo local), referer_host, referer, browser, browser_version, os, device, bot, lang, mapping_key, variant, rule, params (query recibida), destination (URL final). Nunca la IP: solo un hash con sal diaria para contar visitantes únicos, que no se expone.
Webhook por clic
Si el enlace tiene webhook_url, en cada clic se envía un POST JSON con los campos anteriores más event: "click" y slug. Cabeceras: User-Agent: Atajo-Webhook/1.0 y X-Atajo-Signature: sha256=<HMAC-SHA256 del cuerpo con tu clave de webhook>. La clave de webhook de tu cuenta se muestra en Cuenta. Timeout de 5 s, sin reintentos, sin seguir redirecciones, sin destinos en redes privadas.
Claves API
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/keys | Lista (sin las claves). |
| DELETE | /api/keys/:id | Revoca una clave. |
Las claves nuevas se crean solo desde el panel con sesión de passkey.
Límites
Autenticación: 30 peticiones/min por IP. Creación de enlaces: 120/min. Contraseña de enlace protegido: 10 intentos cada 5 min. Al superar un límite la API responde 429.
Acortador de Xterra Engine