面向开发者的 Mosaqo API
一套 REST API,操作的正是你在应用中使用的那个工作区。下面的一切只需一个 API 密钥和任意 HTTP 客户端。
你能做什么
- 从你自己的记录创建二维码——一次一个,或者从一个 CSV 一次一万个。
- 改变已印刷的码指向何处,一次调用即可,无需重新印刷。
- 把成品卡片下载为 PNG、SVG 或 PDF,并附加到 CRM 记录上。
- 读取扫描记录和聚合分析数据,并按工作区的隐私规则过滤。
- 在码被创建、发布、修改或归档时接收带签名的 webhook。
快速上手
在工作区的 Bulk & API 中创建一个密钥,勾选 qr:write 和 qr:read 权限范围,然后复制 secret——它只显示一次。
检查密钥,并确认它打开的是哪个工作区:
curl https://api.mosaqo.app/v1/public-api/me \
-H "Authorization: Bearer $MOSAQO_KEY"创建一个动态二维码:
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" }
}'发布它——重定向要发布之后才会生效——然后取回可以拿去印刷的图片:
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几个月后活动换了地方,无需重印,直接把同一个已印刷的码指向新目标:
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" }'认证
两种方式都可以发送你的 secret,整个 v1 期间都会支持。
Authorization: Bearer mosaqo_xxx
X-Mosaqo-API-Key: mosaqo_xxx一个密钥只属于一个工作区,因此路径里不需要工作区 id:/v1/public-api/qr 就够了。较早的 /v1/public-api/workspaces/{workspaceId}/qr 形式仍然可用。
| 权限范围 | 可以做什么 |
|---|---|
qr:read | 列出和读取二维码、文件夹和模板 |
qr:write | 创建、更新、重新指向、发布、归档和删除 |
exports:read | 下载渲染好的卡片 |
analytics:read | 聚合分析数据和单次扫描记录 |
bulk:write | 创建和读取批量任务 |
webhooks:write | 管理 webhook 订阅 |
密钥可以被吊销、设置过期日期,也可以限制在 IP 允许列表内。被允许列表拒绝的密钥会收到明确的说明,而不是看起来像是无效密钥。
分页
列表使用 keyset 分页。把 pagination.nextCursor 原样传回即可;不会因为同步过程中有内容被编辑就出现重复行或漏行——这对通宵运行的同步任务尤其重要。
curl "https://api.mosaqo.app/v1/public-api/qr?limit=50&cursor=$CURSOR" \
-H "Authorization: Bearer $MOSAQO_KEY"如果只想轮询变更而不是遍历全部,加上 updatedSince=2026-08-05T00:00:00Z。
错误
每个失败响应都带有一个稳定的 code 供你分支判断、一条给人看的 message,以及一个联系支持时值得一并提供的 requestId。
{
"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"
}| 状态码 | 错误码 | 该怎么做 |
|---|---|---|
| 401 | invalid_api_key | 密钥缺失、已吊销或已过期。请用户重新连接。 |
| 403 | insufficient_scope, ip_not_allowed, workspace_mismatch, quota_exceeded | 密钥有效,但没有权限做这件事。重新连接也没用。 |
| 404 | not_found | 这个工作区里没有这条记录。 |
| 409 | idempotency_conflict, idempotency_in_progress | 同一个键配上了不同的输入,或者第一次请求还在进行中。 |
| 422 | validation_failed, invalid_cursor, approval_required, contrast_check_failed | 修正输入。不要原样重试。 |
| 429 | rate_limited | 等待 Retry-After 指定的秒数。 |
速率限制
每个响应都会带上你当前的额度,而不只是被拒绝的那些:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 574
X-RateLimit-Reset: 1785942718这个限制是防滥用措施,不是套餐:它不涉及配额、计费或升级方案。
幂等性
Idempotency-Key 是可选的。带上一个——任意唯一字符串都行——24 小时内重试完全相同的请求会重放原来的响应,而不会执行两次。同一个键配上不同的输入会返回 409。不带这个头时请求就正常执行,没有重放保护。