API REST
Gestiona tus enlaces y consulta analytics desde tus propios sistemas. La API está incluida en todos los planes — lo que escala con el plan son los límites de volumen y de peticiones.
Autenticación
Crea una API key en Ajustes → API de tu cuenta y envíala en cada petición. La key determina tu organización: solo ves y modificas tus enlaces.
Authorization: Bearer qr_live_xxxxxxxxxxxxxxxxURL base: https://qr-top.com/api/v1 — respuestas en JSON, envueltas en { "data": … }; los errores devuelven { "error": "mensaje" } con su código HTTP.
Endpoints
| Método y ruta | Qué hace |
|---|---|
| GET /links | Lista los enlaces con contador de escaneos |
| POST /links | Crea un enlace (destinationUrl obligatorio; title, slug*, routingRules*, expiresAt*, expiredUrl, utmParams opcionales) |
| POST /links/bulk | Crea hasta 200 enlaces en una llamada ({ items: [...] }, mismos campos que POST /links). Todo-o-nada: si un item falla la validación, no se crea ninguno y la respuesta detalla los errores por índice. Cuenta como una sola petición del rate limit |
| GET /links/:id | Detalle de un enlace |
| PATCH /links/:id | Actualiza destino, título, estado o smart routing* |
| DELETE /links/:id | Elimina el enlace y sus escaneos (irreversible) |
| GET /links/:id/stats | Analytics: totales, hoy, 7 días, dispositivos y serie diaria |
| GET /me | Organización, plan, uso frente a límites y features |
* Slug personalizado y smart routing (reglas por dispositivo/idioma/país/horario, A/B, límite de escaneos, expiración) requieren plan Pro o superior. El campo backupUrl (salvaguarda 404: monitorizamos tu destino y conmutamos al respaldo si cae, con aviso por email) requiere Business. Fuera de plan devuelven 403 con un mensaje claro.
Passthrough de parámetros (todos los planes): cualquier query string en la URL corta viaja al destino final — q-r.top/promo?utm_source=email entrega utm_source=email a tu web. Un solo enlace sirve para atribuir varios canales, y en colisiones gana el parámetro entrante sobre los UTMs fijos del enlace.
Ejemplo: crear un enlace con regla horaria
Terminal
curl -X POST https://qr-top.com/api/v1/links \
-H "Authorization: Bearer qr_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"destinationUrl": "https://ejemplo.com/carta",
"title": "Carta del restaurante",
"routingRules": [
{ "hours": { "from": "08:00", "to": "12:00", "tz": "Europe/Madrid" },
"to": "https://ejemplo.com/desayunos" }
]
}'Creación masiva
¿1000 QRs para un catálogo, un evento o un lote de packaging? POST /links/bulk acepta hasta 200 enlaces por llamada con los mismos campos que la creación individual. Es todo-o-nada: si algún item no valida, no se crea ninguno y la respuesta indica el error de cada índice — nunca un lote a medias. Cada llamada cuenta una sola vez para el límite de peticiones, así que el bulk es siempre el camino eficiente.
Terminal
curl -X POST https://qr-top.com/api/v1/links/bulk \
-H "Authorization: Bearer qr_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "destinationUrl": "https://tienda.com/p/001", "title": "Producto 001" },
{ "destinationUrl": "https://tienda.com/p/002", "title": "Producto 002" }
]
}'
# → 201 { "data": [ ...enlaces completos en el orden enviado... ], "count": 2 }
# → 400 { "error": "...", "errors": [ { "index": 1, "error": "..." } ] }Límites de peticiones
Por organización y minuto, con ventana deslizante: 30 en Free, 100 en Pro y Business. Al superarlo recibirás un 429 con cabeceras X-RateLimit-*; reintenta con backoff. Los escaneos de tus QRs no consumen este límite — son ilimitados en todos los planes.
Webhooks de escaneo (Business)
Configura una URL en Ajustes → API y cada escaneo registrado enviará un POST JSON en tiempo real — ideal para Zapier, Make, n8n o tu propio backend. El body va firmado con HMAC-SHA256 en la cabecera X-QRTop-Signature para que verifiques la autenticidad. Sin reintentos: si tu receptor no responde, el evento se pierde (los datos siguen en Analytics).
Payload
{
"event": "scan",
"link": { "id": "k3j2h1g4f5d6", "slug": "promo", "shortUrl": "https://q-r.top/promo" },
"scan": {
"scannedAt": "2026-07-25T12:34:56.000Z",
"country": "ES", "city": "Madrid", "region": "MD",
"deviceType": "mobile", "referer": null
}
}Verificación
// Verificación de la firma (Node.js)
const crypto = require("crypto");
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.QRTOP_WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
const valid = expected === req.headers["x-qrtop-signature"];Códigos de estado
| Código | Significado |
|---|---|
| 200 / 201 | OK / recurso creado |
| 400 | Petición inválida (URL no http/https, regla mal formada…) |
| 401 | API key ausente, inválida o caducada |
| 403 | Función o límite no incluido en tu plan |
| 404 | El recurso no existe o no es de tu organización |
| 409 | Slug ya en uso |
| 429 | Rate limit superado |
¿Prefieres no escribir código? Conecta tu asistente de IA por MCP y pídeselo con palabras.