ATAJO

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étodoRutaDescripción
GET/api/links?q=&tag=&limit=&offset=Lista tus enlaces con contadores.
POST/api/linksCrea un enlace. Solo destination es obligatorio.
GET/api/links/:idEnlace completo con mapeos, reglas y variantes.
PUT/api/links/:idActualiza campos. Si envías mappings, rules o variants sustituyen la lista completa; si los omites, se conservan.
DELETE/api/links/:idElimina el enlace y su analítica.
POST/api/links/:id/mappingsAñade o actualiza mapeos sin tocar los demás (acepta un objeto o una lista).
DELETE/api/links/:id/mappings/:keyBorra un mapeo.
GET/api/slug-available/:slugComprueba si un alias está libre.
GET/qr/:slug?format=svg|png&size=512&dark=0b1220&light=ffffff&u=claveCó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

  1. /promo/maria o /promo?u=maria busca el mapeo maria. Con clave en la ruta y sin mapeo → 404.
  2. 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.
  3. Si ninguna regla coincide y hay variantes, se elige una al azar según su weight.
  4. Si el mapeo tiene destination propio, manda sobre lo anterior.
  5. 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.
  6. Se anexan default_params, los valores del mapeo y, con passthrough, la query recibida (salvo u).
  7. Se responde 302 con Cache-Control: no-store y se registra el clic de forma asíncrona.

Analítica

MétodoRutaDescripción
GET/api/stats?range=30d&bots=0Totales 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|1Totales, 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=1Clics individuales, paginados hacia atrás.
GET/api/links/:id/clicks.csv?range=365dExportación CSV (UTF-8 con BOM, abre bien en Excel).
GET/api/stream?link=:idServer-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étodoRutaDescripción
GET/api/keysLista (sin las claves).
DELETE/api/keys/:idRevoca 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