Saltar al contenido

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.png

Meses 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_xxx

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

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:writeGestionar 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"
}
EstadoCódigosQué hacer
401invalid_api_keyFalta la clave, se revocó o caducó. Pida al usuario que vuelva a conectarse.
403insufficient_scope, ip_not_allowed, workspace_mismatch, quota_exceededLa clave es válida pero no tiene ese permiso. Volver a conectarse no ayudará.
404not_foundNo existe ese registro en este espacio.
409idempotency_conflict, idempotency_in_progressSe reutilizó una clave con datos distintos, o el primer intento sigue en curso.
422validation_failed, invalid_cursor, approval_required, contrast_check_failedCorrija la entrada. No reintente nunca sin cambios.
429rate_limitedEspere 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: 1785942718

El 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