API de Mosaqo para desarrolladores
Una API REST sobre el mismo espacio de trabajo que usa en la aplicación. Todo lo que sigue funciona con una sola clave de API y cualquier cliente HTTP.
Qué puede hacer
- Crear códigos QR a partir de sus propios registros: de uno en uno o diez mil desde un CSV.
- Cambiar a dónde apunta un código ya impreso, en una sola llamada y sin reimprimir nada.
- Descargar la tarjeta final en PNG, SVG o PDF y adjuntarla a una ficha del CRM.
- Leer escaneos y analíticas agregadas, filtrados por las reglas de privacidad de su espacio.
- Recibir webhooks firmados cuando se crea, publica, modifica o archiva un código.
Inicio rápido
Cree una clave en Bulk & API dentro de su espacio, marque los scopes qr:write y qr:read y copie el secreto: solo se muestra una vez.
Compruebe la clave y averigüe qué espacio abre:
curl https://api.mosaqo.app/v1/public-api/me \
-H "Authorization: Bearer $MOSAQO_KEY"Cree un código QR dinámico:
curl -X POST https://api.mosaqo.app/v1/public-api/qr \
-H "Authorization: Bearer $MOSAQO_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Autumn campaign",
"mode": "dynamic",
"contentType": "url",
"content": { "targetUrl": "https://example.com/autumn" }
}'Publíquelo, que es lo que hace funcionar la redirección, y obtenga después la imagen lista para imprimir:
curl -X POST https://api.mosaqo.app/v1/public-api/qr/$QR_ID/publish \
-H "Authorization: Bearer $MOSAQO_KEY"
curl https://api.mosaqo.app/v1/public-api/qr/$QR_ID/image?format=png&size=2048 \
-H "Authorization: Bearer $MOSAQO_KEY" -o campaign.pngMeses más tarde, cuando la campaña cambie, redirija el mismo código impreso sin volver a imprimirlo:
curl -X POST https://api.mosaqo.app/v1/public-api/qr/$QR_ID/destination \
-H "Authorization: Bearer $MOSAQO_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/winter" }'Autenticación
Envíe su secreto de cualquiera de las dos formas. Ambas valen durante toda la v1.
Authorization: Bearer mosaqo_xxx
X-Mosaqo-API-Key: mosaqo_xxxUna clave pertenece exactamente a un espacio de trabajo, así que las rutas no necesitan su identificador: basta con /v1/public-api/qr. La forma anterior /v1/public-api/workspaces/{workspaceId}/qr sigue funcionando.
| Scope | Permite |
|---|---|
qr:read | Listar y leer códigos QR, carpetas y plantillas |
qr:write | Crear, modificar, redirigir, publicar, archivar y eliminar |
exports:read | Descargar tarjetas renderizadas |
analytics:read | Analíticas agregadas y escaneos individuales |
bulk:write | Crear y leer trabajos por lotes |
webhooks:write | Gestionar suscripciones de webhooks |
Las claves se pueden revocar, caducar y restringir a una lista de IP permitidas. Si es esa lista la que rechaza la clave, lo decimos explícitamente en lugar de hacerla parecer inválida.
Paginación
Las listas usan paginación por clave. Devuelva pagination.nextCursor sin modificarlo: las filas nunca se repiten ni desaparecen porque algo se haya editado a mitad de la sincronización, lo que importa en una sincronización nocturna.
curl "https://api.mosaqo.app/v1/public-api/qr?limit=50&cursor=$CURSOR" \
-H "Authorization: Bearer $MOSAQO_KEY"Para consultar cambios en lugar de recorrerlo todo, añada updatedSince=2026-08-05T00:00:00Z.
Errores
Cada fallo lleva un code estable sobre el que ramificar, un message legible y un requestId que conviene citar al soporte.
{
"error": "This API key does not have the qr:write scope.",
"message": "This API key does not have the qr:write scope.",
"code": "insufficient_scope",
"details": { "required": "qr:write", "granted": ["qr:read"] },
"requestId": "req-42"
}| Estado | Códigos | Qué hacer |
|---|---|---|
| 401 | invalid_api_key | Falta la clave, se revocó o caducó. Pida al usuario que vuelva a conectarse. |
| 403 | insufficient_scope, ip_not_allowed, workspace_mismatch, quota_exceeded | La clave es válida pero no tiene ese permiso. Volver a conectarse no ayudará. |
| 404 | not_found | No existe ese registro en este espacio. |
| 409 | idempotency_conflict, idempotency_in_progress | Se reutilizó una clave con datos distintos, o el primer intento sigue en curso. |
| 422 | validation_failed, invalid_cursor, approval_required, contrast_check_failed | Corrija la entrada. No reintente nunca sin cambios. |
| 429 | rate_limited | Espere los segundos que indique Retry-After. |
Límites de uso
Cada respuesta lleva su presupuesto actual, no solo las que se rechazan:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 574
X-RateLimit-Reset: 1785942718El límite es una protección contra abusos, no un plan: no implica cuota, facturación ni mejora de suscripción.
Idempotencia
Idempotency-Key es opcional. Envíe una —cualquier cadena única— y reintentar la misma petición dentro de 24 horas reproduce la respuesta original en lugar de actuar dos veces. La misma clave con datos distintos devuelve 409. Sin clave la petición simplemente se ejecuta, sin protección frente a repeticiones.
Siguiente
- Webhooks: el catálogo de eventos y cómo verificar una entrega.
- Recetas: patrones para Make, Zapier, n8n y CRM.
- Referencia de la API: cada endpoint, con consola en vivo.