Saltar al contenido

API de Mosaqo para desarrolladores

Una API REST sobre el mismo espacio de trabajo que usas en la aplicación. Todo lo de abajo funciona con una sola llave de API y cualquier cliente HTTP.

Qué puedes hacer

  • Crear códigos QR a partir de tus 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 volver a imprimir nada.
  • Descargar la tarjeta final en PNG, SVG o PDF y adjuntarla a un registro del CRM.
  • Leer escaneos y analíticas agregadas, filtrados por las reglas de privacidad de tu espacio.
  • Recibir webhooks firmados cuando se crea, publica, modifica o archiva un código.

Inicio rápido

Crea una llave en Bulk & API dentro de tu espacio, marca los scopes qr:write y qr:read y copia el secreto: solo se muestra una vez.

Verifica la llave y averigua qué espacio abre:

curl https://api.mosaqo.app/v1/public-api/me \
  -H "Authorization: Bearer $MOSAQO_KEY"

Crea 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ícalo, que es lo que hace funcionar la redirección, y luego obtén 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.png

Meses después, cuando la campaña cambie, redirige 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ía tu secreto de cualquiera de las dos formas. Ambas valen durante toda la v1.

Authorization: Bearer mosaqo_xxx
X-Mosaqo-API-Key: mosaqo_xxx

Una llave 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.

ScopePermite
qr:readListar y leer códigos QR, carpetas y plantillas
qr:writeCrear, modificar, redirigir, publicar, archivar y eliminar
exports:readDescargar tarjetas renderizadas
analytics:readAnalíticas agregadas y escaneos individuales
bulk:writeCrear y leer trabajos por lotes
webhooks:writeAdministrar suscripciones de webhooks

Las llaves se pueden revocar, darles fecha de vencimiento y restringirlas a una lista de IP permitidas. Si es esa lista la que rechaza la llave, lo decimos de forma explícita en lugar de hacerla parecer inválida.

Paginación

Las listas usan paginación por llave. Devuelve pagination.nextCursor sin modificarlo: las filas nunca se repiten ni desaparecen porque algo se haya editado a media sincronización, lo cual 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, agrega updatedSince=2026-08-05T00:00:00Z.

Errores

Cada falla lleva un code estable sobre el cual 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"
}
EstadoCódigosQué hacer
401invalid_api_keyFalta la llave, se revocó o venció. Pide a la persona que se vuelva a conectar.
403insufficient_scope, ip_not_allowed, workspace_mismatch, quota_exceededLa llave es válida pero no tiene ese permiso. Volver a conectarse no ayuda.
404not_foundNo existe ese registro en este espacio.
409idempotency_conflict, idempotency_in_progressSe reutilizó una llave con datos distintos, o el primer intento sigue en curso.
422validation_failed, invalid_cursor, approval_required, contrast_check_failedCorrige la entrada. Nunca reintentes sin cambios.
429rate_limitedEspera los segundos que indique Retry-After.

Límites de uso

Cada respuesta lleva tu presupuesto actual, no solo las que se rechazan:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 574
X-RateLimit-Reset: 1785942718

El límite es una protección contra abusos, no un plan: no implica cuota, facturación ni cambio de suscripción.

Idempotencia

Idempotency-Key es opcional. Envía 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 llave con datos distintos devuelve 409. Sin llave la petición simplemente se ejecuta, sin protección contra repeticiones.

Siguiente