Abundera QR Pro API
Tài liệu tham chiếu REST API cho pro.qr.abundera.ai. Tạo, chỉnh sửa và phân tích mã QR động theo chương trình. Tất cả đều là JSON qua HTTPS, xác thực bằng bearer token.
/docs/openapi.json, nhập vào Postman, Insomnia hoặc bất kỳ client OpenAPI 3.1 nào. Bao gồm 36 endpoint dành cho khách hàng trên Codes, Analytics, Groups, Teams, Webhooks và User. Endpoint Admin và Stripe-webhook được loại trừ có chủ ý (chỉ dùng giữa các dịch vụ).Giới thiệu
Abundera QR Pro API cho phép bạn tạo, chỉnh sửa và phân tích mã QR động theo chương trình, mọi thứ mà nhà phát triển muốn tự động hóa từ dashboard. Quản lý nhóm, thanh toán và luồng tài khoản vẫn ở giao diện dashboard; API này chỉ dành cho các thao tác mã cấp độ lập trình viên.
Base URL: https://pro.qr.abundera.ai/api
Định dạng yêu cầu: JSON (Content-Type: application/json) với POST / PATCH / DELETE.
Định dạng phản hồi: JSON (application/json; charset=utf-8).
Khả dụng: Truy cập API là tính năng dành cho Business trở lên. Gói Solo có thể dùng dashboard nhưng không dùng được API.
Xác thực
Mỗi yêu cầu mang một khóa API dưới dạng bearer token:
Authorization: Bearer abnd_qrpro_...Tạo và thu hồi khóa tại /account/keys (Business, Team hoặc Agency). Token abnd_qrpro_... thô chỉ hiển thị một lần khi tạo, hãy lưu lại ngay. Chúng tôi chỉ lưu hàm băm SHA-256 của nó; không có cách nào khôi phục khóa đã mất.
Yêu cầu chưa xác thực trả về 401 { "error": "not_signed_in" }. Khóa không hợp lệ hoặc đã thu hồi trả về 401 { "error": "invalid_api_key" }.
Khóa API được gắn với người dùng tạo ra chúng. Nếu người dùng đó là thành viên của một nhóm, các endpoint bên dưới sẽ tự động hoạt động trên mã của nhóm đó (ngữ cảnh nhóm hiện tại được lưu trên tài khoản người dùng và quản lý qua dashboard).
Giới hạn tốc độ
Được áp dụng theo từng khóa API. Mỗi phản hồi mang X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset (giây Unix khi cửa sổ được làm mới).
| Gói | Giới hạn | Cửa sổ |
|---|---|---|
| Business | 1.000 yêu cầu / ngày | Ngày UTC |
| Team | 10.000 yêu cầu / ngày | Ngày UTC |
| Agency | 50.000 yêu cầu / ngày | Ngày UTC |
| Solo | (403 insufficient_plan) | , |
Yêu cầu vượt ngưỡng trả về 429 { "error": "rate_limited", "window": "day", "retry_at": 1234567890 } kèm header Retry-After tính bằng giây.
Lượt quét không bị giới hạn tốc độ, đường dẫn chuyển hướng (aqr.net/{shortcode}) không cần xác thực và không có ngân sách theo lượt quét. Mỗi gói có giới hạn quét hàng tháng rõ ràng (100k / 1M / 10M / 30M). Vượt quá giới hạn thì chuyển hướng vẫn hoạt động; chúng tôi sẽ gửi email để bạn quyết định có nâng cấp không. Nếu dự kiến hơn ~10M lượt quét mỗi ngày, hãy liên hệ để phối hợp dung lượng.
Lỗi
Mỗi phản hồi lỗi là JSON với mã error đọc được bằng máy và thông tin ngữ cảnh bổ sung khi có:
{ "error": "plan_limit", "plan": "business", "limit": 500, "current": 500 }| Trạng thái | Mã | Ý nghĩa |
|---|---|---|
| 400 | validation_error | Trường body không qua kiểm tra. Phản hồi kèm field + message. |
| 401 | not_signed_in / invalid_api_key | Bearer token thiếu, không hợp lệ hoặc đã thu hồi. |
| 402 | plan_limit | Đạt giới hạn mã active+paused của gói. Phản hồi kèm plan, limit, current. |
| 402 | plan_expired | Tài khoản đã qua cửa sổ ân hạn 90 ngày; nâng cấp để tiếp tục. |
| 403 | insufficient_plan | Truy cập API yêu cầu Business hoặc cao hơn. Người dùng Solo sẽ gặp lỗi này. |
| 403 | insufficient_role | Vai trò nhóm của bạn không cho phép thay đổi này (yêu cầu admin trở lên). |
| 404 | not_found | Tài nguyên không tồn tại hoặc không trong phạm vi của bạn. |
| 409 | code_not_editable | Mã đang ở trạng thái ân hạn hoặc hết hạn; kích hoạt lại để chỉnh sửa. |
| 429 | rate_limited | Vượt ngân sách ngày theo gói. Xem Giới hạn tốc độ. |
| 500 | internal | Lỗi server không xử lý được, gửi email hỗ trợ nếu có thể tái hiện. |
Mã QR
Mã QR động: shortcode 7 ký tự Base58 chuyển hướng qua aqr.net/{shortcode}. Mỗi mã có QR tĩnh dự phòng tải về từ dashboard, nếu bạn ngừng thanh toán, phiên bản tĩnh vẫn phân giải mà không cần chuyển hướng của chúng tôi.
GET /api/codes
Liệt kê tất cả mã trong phạm vi hiện tại (cá nhân hoặc nhóm đang hoạt động). Trả về mảng kèm tổng hợp lượt quét 30 ngày mỗi mã.
$ curl -H "Authorization: Bearer abnd_qrpro_..." \
https://pro.qr.abundera.ai/api/codes
{
"codes": [
{ "id": "uuid", "shortcode": "aBc123x",
"url": "https://example.com/landing",
"label": "Q2 campaign", "tags": "q2,print",
"status": "active", "scans_30d": 1245,
"created_at": 1713288000, "updated_at": 1713370000 }
],
"plan": "business",
"plan_limit": 500,
"scope": { "type": "user" }
}POST /api/codes
Tạo mã động mới. Giới hạn mã active+paused của gói được kiểm tra trước khi chèn. Body tối thiểu:
{ "url": "https://example.com/landing" }Tùy chỉnh đầy đủ (tất cả tùy chọn):
{ "url": "https://example.com/landing",
"label": "Spring campaign",
"tags": "q2,print",
"qr_type": "url",
"style_json": "{...}",
"logo_key": "instagram",
"frame_style": "scan-me",
"frame_text": "SCAN ME" }Trả về 201 + hàng vừa tạo bao gồm shortcode được tạo và short_url để in.
GET /api/codes/{id}
Lấy một mã cụ thể. 404 nếu không trong phạm vi của bạn.
PATCH /api/codes/{id}
Cập nhật bất kỳ trường có thể thay đổi. Dùng phổ biến nhất: thay URL đích của mã đã in.
$ curl -X PATCH \
-H "Authorization: Bearer abnd_qrpro_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/new-landing"}' \
https://pro.qr.abundera.ai/api/codes/uuidThay đổi lan truyền đến chuyển hướng trong vài giây. Giá trị status hợp lệ cho PATCH: "active", "paused". Để xóa, dùng DELETE.
DELETE /api/codes/{id}
Xóa mềm. Chuyển sang status=grace với grace_until = now + 90 ngày. Chuyển hướng vẫn hoạt động trong toàn bộ cửa sổ ân hạn. Sau 90 ngày, mã trở thành expired và chuyển hướng trả về 410 Gone.
POST /api/codes/import
Tạo hàng loạt từ payload mảng (cũng dùng cho luồng "Lưu vào Pro" trên qr.abundera.ai). Chấp nhận một payload mã hoặc một mảng. Giới hạn gói được kiểm tra một lần trước khi xử lý lô.
Phân tích
GET /api/codes/{id}/analytics
Tham số truy vấn:
range=7d|30d|90d|1y|3y, giới hạn theo thời gian lưu trữ của gói (Solo 1y, Business 2y, Team/Agency 3y).granularity=day|hour, theo giờ chỉ dành cho Team và Agency; cửa sổ tối đa 7 ngày cho theo giờ.
{
"range": "30d", "days": 30, "granularity": "day",
"total": 4321,
"timeseries": [
{ "bucket": "2026-04-01", "scans": 142 },
{ "bucket": "2026-04-02", "scans": 178 },
...
],
"by_country": [
{ "key": "US", "total": 3012 },
{ "key": "CA", "total": 402 },
{ "key": "Other", "total": 108 }
],
"by_device": [
{ "key": "mobile", "total": 3850 },
{ "key": "tablet", "total": 312 },
{ "key": "desktop", "total": 159 }
]
}Các quốc gia có dưới 5 lượt quét trong cửa sổ được gộp vào "Other" để bảo vệ quyền riêng tư (xem Mô hình bảo mật).
Khóa API
Tạo và thu hồi khóa từ trang dashboard /account/keys. Quản lý theo chương trình chỉ là đọc qua API, bạn có thể liệt kê và thu hồi khóa, nhưng tạo khóa mới yêu cầu dashboard (gà-và-trứng: bạn cần khóa để tạo khóa).
GET /api/keys
Liệt kê khóa API của bạn. Không bao giờ trả về token thô, chỉ metadata.
{
"keys": [
{ "id": "uuid", "label": "Production server",
"created_at": 1713288000, "last_used_at": 1713370000 }
],
"allowed": true,
"plan": "business"
}DELETE /api/keys/{id}
Thu hồi. Khóa ngừng hoạt động ngay lập tức; mọi yêu cầu mang nó sau đó đều trả về 401 invalid_api_key.
Xuất dữ liệu
GET /api/user/export
Tải xuống ZIP chứa toàn bộ dữ liệu, codes.csv (mọi mã, kể cả grace + expired), scans.csv (tổng hợp theo ngày), và README.txt giải thích định dạng. Kho lưu trữ được phát ra dạng application/zip; chuyển vào tệp:
$ curl -H "Authorization: Bearer abnd_qrpro_..." \
-o abundera-qr-export.zip \
https://pro.qr.abundera.ai/api/user/exportNhập lại ở bất kỳ đâu. Đây là cam kết định dạng có thể di chuyển, không thể bị khóa nhà cung cấp nếu bạn sở hữu dữ liệu của mình.
Mô hình bảo mật
Tổng hợp quét là toàn bộ câu chuyện bảo mật. Những gì chúng tôi lưu mỗi lượt quét trên đường dẫn chuyển hướng:
code_id, mã nào của bạn được quétday_bucket, ngày UTC (YYYY-MM-DD). Không có độ chính xác dưới ngày trong tổng hợp trả về.country, ISO-3166-1 alpha-2 từ headerCF-IPCountrycủa Cloudflare. Không có thành phố, không có vùng, không tra cứu địa lý.device_type,mobile/tablet/desktop/unknown, phân loại từ regex User-Agent ngắn. Chuỗi UA thô bị loại bỏ sau khi phân loại.scan_count, bộ đếm tổng hợp, upsert mỗi lần quét.
Những gì chúng tôi không lưu: địa chỉ IP (đã băm hay chưa), chuỗi User-Agent thô, địa lý cấp thành phố, dấu thời gian dưới ngày, referer, cookie, pixel theo dõi lại hoặc bất kỳ vector nhận dạng cá nhân nào. Ngưỡng nhiễu 5 lượt ngăn chặn việc tái nhận dạng từ tổng hợp nhỏ.
Gói Team và Agency còn ghi thêm tổng hợp theo giờ song song với hour_bucket (YYYY-MM-DD-HH UTC). Cùng mô hình bảo mật, không có dấu thời gian dưới giờ, cùng ngưỡng nhiễu, cùng không có dữ liệu người quét cá nhân.
Đọc đầy đủ: /manifesto/ và /no-lock-in/ trên trang công cụ miễn phí.