QRFLOW.codes

chính thức

Tạo mã QR, trỏ lại mã động đã in, đặt tên liên kết trên tên miền của bạn và đọc phân tích quét.

Bạn có thể làm gì với QRFLOW Codes MCP?

  • Tạo mã QR động — Yêu cầu tạo một short_url có thể in được cho bất kỳ URL nào, với đích đến có thể thay đổi bất cứ lúc nào sau khi in.
  • Đổi hướng mã đã in — Yêu cầu cập nhật destination_data của mã sang một URL mới; các mã đã in vẫn hoạt động mà không cần in lại.
  • Xem số liệu phân tích lượt quét — Yêu cầu báo cáo Scans theo ngày, quốc gia hoặc thiết bị để biết mã in đang hoạt động như thế nào.
  • Tạm dừng hoặc đặt hạn mã — Hướng dẫn tạm dừng mã hoặc đặt ngày hết hạn khi chiến dịch hoặc ưu đãi kết thúc.
  • Đặt tên liên kết trên tên miền của bạn — Yêu cầu đặt một slug dễ đọc trên tên miền riêng để mã in ra dạng go.yourbrand.com/menu thay vì một đường dẫn ngẫu nhiên.

Máy chủ MCP được lưu trữ

npx add-mcp 'https://qrflow.codes/mcp'

Cài vào Claude Code, Codex, Cursor và nhiều công cụ khác

Tài liệu

QRFLOW.codes dành cho nhà phát triển

Bắt đầu tại đây

QRFLOW.codes tạo mã QR mà bạn có thể thay đổi sau khi in, trên tên miền của riêng bạn, có phân tích quét, và cho phép phần mềm cũng như trợ lý AI của bạn thực hiện tất cả thông qua một API duy nhất.

Mã QR là một hình ảnh của một chuỗi ký tự. Hầu hết các trình tạo mã đặt địa chỉ web của bạn vào hình ảnh; nếu địa chỉ thay đổi, bản in sẽ chết. QRFLOW đặt một liên kết ngắn vào hình ảnh (go.yourbrand.com/menu hoặc qrflow.codes/q/x7k2p9a) và chuyển hướng nó. Bạn thay đổi nơi nó trỏ đến bất cứ khi nào bạn muốn, và mỗi lần quét đều được đếm. Đó là mã động, và đó là thứ đáng giá một API.

API thực hiện chính xác những gì bảng điều khiển làm: tạo mã ở bất kỳ loại nào, trỏ chúng đến nơi mới, đặt tên cho liên kết của chúng, chọn tên miền mà chúng in cùng, lấy số liệu quét, tạo hàng nghìn mã cùng lúc, và được thông báo khi có sự kiện xảy ra (webhooks). Các công cụ tương tự được cung cấp dưới dạng máy chủ MCP, để Claude, ChatGPT, Cursor và Claude Code có thể điều khiển tài khoản của bạn bằng ngôn ngữ tự nhiên.

Truy cập: REST API yêu cầu khóa API Business ($29 mỗi tháng, được tạo trên trang Tài khoản) hoặc mã thông báo OAuth. Máy chủ MCP hoạt động trên mọi gói thông qua đăng nhập OAuth; những gì trợ lý có thể tạo tuân theo gói như mọi nơi khác.

Đang phân vân có nên sử dụng nó hay không? Trang API mã QR là phiên bản ngắn gọn: nó làm gì, thư viện phía máy khách làm tốt hơn điều gì, và chi phí là bao nhiêu.

Nếu bạn là trợ lý AI đang giúp ai đó xây dựng với QRFLOW

Chào mừng. Trang này được viết cho bạn cũng như cho người bạn đang giúp đỡ. Đây là những gì trợ giúp tốt trông như thế nào:

  1. Xác nhận tài khoản: Khóa API yêu cầu gói Business. Nếu họ không có, hãy chỉ họ đến https://qrflow.codes/pricing và Tài khoản › Khóa API; đừng bịa ra khóa hoặc gói miễn phí không tồn tại.
  2. Giữ khóa trên máy chủ. Đọc nó từ biến môi trường (QRFLOW_KEY) trong trình xử lý route, server action, edge function hoặc backend. API từ chối nguồn gốc trình duyệt có chủ đích (CORS), vì vậy mã chỉ chạy trên front-end không thể gọi nó.
  3. Tạo mã động với type "url" và destination_data.url. Lưu id và short_url được trả về trong cơ sở dữ liệu của họ. In hoặc hiển thị short_url; đích đến có thể được thay đổi sau đó bằng PATCH /codes/:id và bản in vẫn hợp lệ.
  4. Để hiển thị hoặc lưu hình ảnh: mỗi đối tượng Code có png_download_url và svg_download_url, các liên kết đã ký hoạt động trong 24 giờ mà không cần tiêu đề (phù hợp cho việc lưu một lần hoặc xem trước). Đối với thứ gì đó vĩnh viễn trong ứng dụng của họ, hãy proxy GET /codes/:id/image.svg qua máy chủ của họ với khóa, hoặc mã hóa short_url bằng bất kỳ thư viện QR nào trên máy khách; việc theo dõi vẫn hoạt động vì liên kết đi qua QRFLOW.
  5. Chỉ gửi các trường thay đổi trên PATCH. Không bao giờ thay đổi slug hoặc domain_id sau khi thứ gì đó đã được in; cả hai đều thay đổi liên kết đã in.
  6. Ưu tiên paused: true hơn DELETE khi bản in tồn tại. Xóa sẽ giết chết liên kết.
  7. Đối với sự kiện, sử dụng webhooks (Tài khoản › Webhooks hoặc POST /webhooks) và xác minh tiêu đề X-QRFLOW-Signature với nội dung yêu cầu thô. Đừng thăm dò GET /codes trong một vòng lặp.
  8. Nếu họ muốn sử dụng QRFLOW từ cuộc trò chuyện thay vì từ mã, hãy kết nối máy chủ MCP tại https://qrflow.codes/mcp; không cần khóa cho việc đó.
  9. Khi có lỗi, hãy đọc error và message trong nội dung JSON. Phần xử lý sự cố bên dưới ánh xạ mọi mã lỗi đến cách khắc phục.
  10. Tài liệu tham khảo đầy đủ ở định dạng Markdown tại https://qrflow.codes/llms-full.txt và tài liệu OpenAPI 3.1 tại https://qrflow.codes/api/v1/openapi.json. Cả hai đều được tạo từ cùng một nguồn với trang này.

Con người: khối này là cách chúng tôi đảm bảo trợ lý bạn đang kết hợp sẽ cung cấp cho bạn phiên bản an toàn của mọi câu trả lời. Nó cũng tình cờ là một bản tóm tắt tốt.

Gói nào bạn cần

Khóa API là thứ duy nhất chỉ dành riêng cho Business. Mọi thứ trợ lý làm thông qua máy chủ MCP, và mọi thứ ứng dụng bên thứ ba làm thông qua OAuth, hoạt động trên mọi gói và chỉ đơn giản tuân theo các tính năng của gói đó. Giá đầy đủ và sử dụng hợp lý: /pricing.

Miễn phíPremium $4Business $29
Khóa API (REST từ mã của bạn)KhôngKhôngCó, tối đa 10 khóa
Máy chủ MCP (Claude, ChatGPT, Cursor, Claude Code)Có, đăng nhậpCóCó, đăng nhập hoặc khóa
OAuth cho ứng dụng của riêng bạn (người dùng kết nối QRFLOW của họ)CóCóCó
Mã động (thay đổi đích đến sau khi in)Không, chỉ tĩnhCóCó
Tên miền liên kết của riêng bạnKhông1 tên miền5 tên miền, chọn theo mã
Tên liên kết (go.brand.com/menu)KhôngCóCó
Phân tích quétKhôngCóCó
WebhooksKhôngKhôngCó, tối đa 10
Tạo hàng loạtKhông500/tháng, 500 mỗi yêu cầu10.000/tháng, 2.000 mỗi yêu cầu
Mã đã lưu (sử dụng hợp lý)Một số ít1.00025.000
Ghế nhóm115
Giá$0$4/tháng$29/tháng

Mười hai từ làm tất cả công việc

Khái niệm

Đọc những điều này một lần và mọi endpoint bên dưới sẽ có ý nghĩa.

Static code

Nội dung nằm bên trong hình ảnh. Mã Wi-Fi, danh thiếp (vCard) và mã văn bản thuần túy luôn tĩnh, và trên gói Miễn phí mọi mã đều như vậy. Mã tĩnh không cần máy chủ và không bao giờ hết hạn, nhưng không thể thay đổi hoặc đếm được.

Dynamic code

Hình ảnh chứa một liên kết ngắn mà QRFLOW chuyển hướng. Mã url, phone, email, sms và location là động trên Premium và Business. Bạn có thể trỏ lại, tạm dừng, hết hạn, đổi tên và đếm chúng mà không cần chạm vào bản in.

short_url

Chuỗi chính xác được mã hóa trong mã động, và là thứ để in. Nó là https://qrflow.codes/q/<short_code> cho đến khi bạn kết nối một tên miền, sau đó là https://<your domain>/<slug or short_code>. Mọi đối tượng Code đều mang nó.

short_code

Bảy ký tự ngẫu nhiên, duy nhất cho mỗi mã, được gán khi tạo và không bao giờ thay đổi. Đường dẫn dự phòng khi mã không có tên liên kết.

slug (link name)

Một đường dẫn dễ đọc trên tên miền của riêng bạn: go.example.com/menu. 3 đến 40 chữ cái thường, chữ số và dấu gạch ngang, duy nhất trong tài khoản của bạn, chỉ với tên miền đã kết nối. Đặt nó trước khi bạn in: thay đổi nó sẽ thay đổi liên kết đã in.

Link domain

Một tên máy chủ bạn sở hữu (go.example.com) trỏ đến QRFLOW bằng CNAME và được xác minh trên trang Tài khoản. Premium có một; Business có năm và có thể chọn theo mã với domain_id. Tên miền trực tiếp lâu đời nhất là mặc định.

Kind, type and subtype

type là mã hóa: url, text, wifi, vcard, email, phone, sms, location. kind là tên thân thiện hơn cho những gì mọi người muốn (instagram, googlereview, whatsapp, pdf, menu, appstore,...). Hầu hết các kind là mã url với destination_data.subtype được đặt. GET /catalog liệt kê mọi kind với các trường của nó; kind trên một Code cho bạn biết nó là loại nào.

destination_data

Các trường cho type, dưới dạng chuỗi: { url } cho trang web, { ssid, password, encryption } cho Wi-Fi, { placeId } cho đánh giá Google, { handle } cho Instagram. Trên mã động, bạn có thể thay thế nó bất cứ lúc nào.

Scans

Mỗi lần chuyển hướng ghi lại loại thiết bị, quốc gia, thành phố, người giới thiệu, trình duyệt, hệ điều hành và ngôn ngữ từ chính yêu cầu, cộng với một hàm băm hàng ngày một chiều để đếm khách truy cập duy nhất. Không có cookie nào được đặt và địa chỉ IP không được lưu trữ. scans trên một Code là tổng số trọn đời; GET /codes/:id/scans phân tích chi tiết nó.

Source

Mỗi mã ghi nhớ thứ đã tạo ra nó: dashboard, api:<key name>, mcp, canva hoặc bulk. Nó hiển thị trong bảng điều khiển và trong payload webhook, để bạn có thể phân biệt mã của tích hợp của mình với mã làm thủ công.

Workspace

Chủ sở hữu Business có thể mời tối đa bốn đồng nghiệp. Khóa và webhook thuộc về tài khoản của chủ sở hữu; mã do bất kỳ ai trong không gian làm việc tạo ra đều hiển thị cho toàn nhóm.

Năm phút

Bắt đầu nhanh

Lấy khóa

  1. Trên gói Business, mở Tài khoản › Khóa API.
  2. Đặt tên theo thứ nó dùng cho ("Shop backend", "Reporting") và chọn phạm vi của nó. Phạm vi không thể thay đổi sau đó; tạo khóa mới nếu bạn cần thêm.
  3. Sao chép nó một lần. Nó trông giống như qrf_live_…. Đặt nó trong biến môi trường tên là QRFLOW_KEY.
  4. Gửi nó dưới dạng Authorization: Bearer $QRFLOW_KEY trên mọi yêu cầu. Đó là toàn bộ câu chuyện xác thực.

Khóa dành cho máy chủ. Không bao giờ đặt nó trong trang web, ứng dụng di động hoặc bảng tính dùng chung; thu hồi và cấp lại nếu nó bị rò rỉ.

Năm bước tương tự trong curl, TypeScript và Python. Mỗi bước tạo một mã động, tải xuống hình ảnh của nó, thay đổi nơi nó trỏ đến, và đọc số lần quét của nó.

export QRFLOW_KEY=qrf_live_...   # from Account › API keys

# 1. Who am I, what can this key do?
curl https://qrflow.codes/api/v1/me -H "Authorization: Bearer $QRFLOW_KEY"

# 2. Make a dynamic code. Print what comes back as short_url.
curl -X POST https://qrflow.codes/api/v1/codes \
  -H "Authorization: Bearer $QRFLOW_KEY" -H "Content-Type: application/json" \
  -d '{ "type": "url", "destination_data": { "url": "https://example.com/menu" }, "label": "Table tents" }'

# 3. The print-ready image (SVG, with your colors and frame).
curl "https://qrflow.codes/api/v1/codes/$CODE_ID/image.svg?size=1024" \
  -H "Authorization: Bearer $QRFLOW_KEY" -o menu.svg

# 4. Fall menu. The printed code keeps working.
curl -X PATCH https://qrflow.codes/api/v1/codes/$CODE_ID \
  -H "Authorization: Bearer $QRFLOW_KEY" -H "Content-Type: application/json" \
  -d '{ "destination_data": { "url": "https://example.com/menu-fall" } }'

# 5. How did it do?
curl "https://qrflow.codes/api/v1/codes/$CODE_ID/scans?group=day" -H "Authorization: Bearer $QRFLOW_KEY"

TypeScript (Node 18+, Bun, Deno, Workers)

// npm install qrflow   (zero dependencies; ESM + CommonJS; full types)
import { QRFlow, QRFlowError } from "qrflow";

const qr = new QRFlow(process.env.QRFLOW_KEY!);

const { code } = await qr.createCode({
  type: "url",
  destination_data: { url: "https://example.com/menu" },
  label: "Table tents",
});
console.log(code.id, code.short_url);        // save both; print short_url

await qr.updateCode(code.id, { destination_data: { url: "https://example.com/menu-fall" } });

const stats = await qr.scans(code.id, { group: "day" });
console.log(stats.total, stats.rows);         // [{ key: "2026-09-21", scans: 18 }, ...]

try {
  await qr.updateCode(code.id, { slug: "menu" });
} catch (e) {
  if (e instanceof QRFlowError) console.log(e.status, e.code, e.message); // 400 no_domain: connect a domain first
}
# Download https://qrflow.codes/sdk/qrflow.py next to your code.
import os
from qrflow import QRFlow, QRFlowError

qr = QRFlow(os.environ["QRFLOW_KEY"])

code = qr.create_code(type="url", destination_data={"url": "https://example.com/menu"}, label="Table tents")["code"]
print(code["id"], code["short_url"])          # save both; print short_url

qr.update_code(code["id"], destination_data={"url": "https://example.com/menu-fall"})

stats = qr.scans(code["id"], group="day")
print(stats["total"], stats["rows"])

try:
    qr.update_code(code["id"], slug="menu")
except QRFlowError as e:
    print(e.status, e.code, e)                # 400 no_domain: connect a domain first

Xác thực

Khóa API (Business)

Tối đa 10 mỗi tài khoản, 600 yêu cầu mỗi phút mỗi khóa, được lưu trữ dưới dạng băm, hiển thị một lần. Một khóa mang các phạm vi mà nó được tạo ra:

Phạm viCho phép
profileGET /me: gói, tính năng, giới hạn. Mọi khóa đều có nó.
codes:readLiệt kê và đọc mã, tải xuống hình ảnh.
codes:writeTạo, thay đổi, làm động, xóa, tạo hàng loạt.
analytics:readGET /codes/:id/scans.
domains:readGET /domains (cần thiết để sử dụng domain_id một cách hợp lý).
webhooks:manageLiệt kê, tạo, kiểm tra và xóa webhooks.

OAuth 2.0 (mọi gói, cho ứng dụng và trợ lý)

Khi mã nên thuộc về tài khoản của người dùng của bạn thay vì của bạn, hoặc khi trợ lý trò chuyện là máy khách, hãy sử dụng OAuth. Máy khách tự đăng ký; PKCE S256 là bắt buộc cho máy khách công khai; mã thông báo có thể được liên kết với máy chủ MCP bằng resource=. Công thức OAuth hướng dẫn chi tiết.

EndpointURLGhi chú
Ủy quyềnhttps://qrflow.codes/oauth/authorizeGửi người dùng đến đây; họ đăng nhập và nhấn Cho phép.
Mã thông báohttps://qrflow.codes/api/oauth/tokenCấp authorization_code và refresh_token. Mã thông báo truy cập tồn tại 1 giờ, mã thông báo làm mới 90 ngày.
Thu hồihttps://qrflow.codes/api/oauth/revokeRFC 7009. Người dùng cũng có thể ngắt kết nối trên Tài khoản › Ứng dụng đã kết nối.
Đăng ký máy kháchhttps://qrflow.codes/api/oauth/registerĐăng ký động RFC 7591, không cần tài khoản. Máy khách công khai nhận dyn_ client_id và phải sử dụng PKCE S256.
Khám pháhttps://qrflow.codes/.well-known/oauth-authorization-serverRFC 8414. Tài liệu tài nguyên MCP nằm tại /.well-known/oauth-protected-resource.

Mã thông báo truy cập tồn tại 1 giờ, mã thông báo làm mới 90 ngày. Người dùng thấy các ứng dụng đã kết nối trên Tài khoản › Ứng dụng đã kết nối và có thể ngắt kết nối bất cứ lúc nào. Mã thông báo được tạo cho https://qrflow.codes/mcp bị từ chối trên /api/v1, và ngược lại.

Những thứ mọi người thực sự yêu cầu

Công thức xây dựng

Mỗi công thức đều hoàn chỉnh và được sao chép trực tiếp từ mã hoạt động. Chọn công thức phù hợp với ngăn xếp của bạn; hình dạng luôn giống nhau: một cuộc gọi phía máy chủ với khóa, lưu id và short_url, hiển thị hình ảnh.

Next.js: một route tạo mã và một route hiển thị nó

Khi nào: Bạn có một ứng dụng Next.js (App Router) và muốn một nút tạo mã QR và một trang hiển thị nó.

  1. Đặt khóa của bạn trong .env.local dưới dạng QRFLOW_KEY. Không bao giờ thêm tiền tố NEXT_PUBLIC_ vào nó.
  2. Thêm trình xử lý route POST tạo mã và trả về id và short_url.
  3. Thêm route GET proxy hình ảnh để trình duyệt không bao giờ thấy khóa.
  4. Lưu trữ id và short_url trên bản ghi của riêng bạn (đơn hàng, bàn, sản phẩm, sự kiện).
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const { url, label } = await req.json();
  const r = await fetch("https://qrflow.codes/api/v1/codes", {
    method: "POST",
    headers: { Authorization: \`Bearer ${process.env.QRFLOW_KEY}\`, "Content-Type": "application/json" },
    body: JSON.stringify({ type: "url", destination_data: { url }, label }),
  });
  const data = await r.json();
  if (!r.ok) return NextResponse.json(data, { status: r.status }); // { error, message }
  return NextResponse.json({ id: data.code.id, short_url: data.code.short_url });
}
// Proxies the SVG so the key stays on the server. Check that the signed-in
// user owns this id before you serve it, or anyone with an id can fetch it.
export async function GET(_: Request, { params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const r = await fetch(\`https://qrflow.codes/api/v1/codes/${id}/image.svg?size=1024\`, {
    headers: { Authorization: \`Bearer ${process.env.QRFLOW_KEY}\` },
  });
  return new Response(r.body, {
    status: r.status,
    headers: { "Content-Type": "image/svg+xml", "Cache-Control": "private, max-age=3600" },
  });
}
<img src={\`/api/qr/${code.id}/image\`} alt={\`QR code for ${code.label}\`} width={256} height={256} />
<a href={code.short_url}>{code.short_url}</a>
  • Server Actions hoạt động theo cách tương tự: gọi fetch với khóa bên trong action.
  • Đối với Pages Router, cùng mã đó đi vào pages/api/qr.ts với req/res.

Hiển thị QR mà không cần proxy: tự render short_url

Khi nào: Bạn muốn hình ảnh trong trình duyệt ngay lập tức và không cần khung hoặc logo của QRFLOW trên đó. Bất kỳ thư viện QR nào cũng hoạt động, vì mã QR chính là liên kết ngắn

import QRCode from "qrcode"; // npm i qrcode

// short_url came back from POST /codes. Encode it as-is.
const dataUrl = await QRCode.toDataURL(code.short_url, { width: 512, margin: 2 });
// <img src={dataUrl} />  scans go through QRFLOW, so analytics and re-pointing still work.
  • Đây là cách nhanh nhất để xem trước. Đối với bản in, hãy tải xuống /codes/:id/image.svg: nó mang theo màu sắc, khung, chú thích và logo đã lưu, đồng thời là vector.
  • Nếu sau này bạn đổi slug hoặc domain_id, short_url sẽ thay đổi; hãy kết xuất lại.

Express hoặc bất kỳ máy chủ Node nào

Khi nào: Backend Node đơn giản.

import express from "express";
const app = express();
app.use(express.json());
const H = { Authorization: \`Bearer ${process.env.QRFLOW_KEY}\`, "Content-Type": "application/json" };

app.post("/qr", async (req, res) => {
  const r = await fetch("https://qrflow.codes/api/v1/codes", {
    method: "POST", headers: H,
    body: JSON.stringify({ type: "url", destination_data: { url: req.body.url }, label: req.body.label }),
  });
  res.status(r.status).json(await r.json());
});

app.get("/qr/:id.svg", async (req, res) => {
  const r = await fetch(\`https://qrflow.codes/api/v1/codes/${req.params.id}/image.svg\`, { headers: H });
  res.status(r.status).type("image/svg+xml").send(await r.text());
});

app.listen(3000);

Cloudflare Workers, Vercel Edge, Deno Deploy, Supabase Edge Functions

Khi nào: Runtime chỉ dùng fetch, không có built-in của Node.

export default {
  async fetch(req: Request, env: { QRFLOW_KEY: string }) {
    const { url, label } = await req.json();
    const r = await fetch("https://qrflow.codes/api/v1/codes", {
      method: "POST",
      headers: { Authorization: \`Bearer ${env.QRFLOW_KEY}\`, "Content-Type": "application/json" },
      body: JSON.stringify({ type: "url", destination_data: { url }, label }),
    });
    return new Response(r.body, { status: r.status, headers: { "Content-Type": "application/json" } });
  },
};
Deno.serve(async (req) => {
  const { url, label } = await req.json();
  const r = await fetch("https://qrflow.codes/api/v1/codes", {
    method: "POST",
    headers: { Authorization: \`Bearer ${Deno.env.get("QRFLOW_KEY")}\`, "Content-Type": "application/json" },
    body: JSON.stringify({ type: "url", destination_data: { url }, label }),
  });
  return new Response(await r.text(), { status: r.status, headers: { "Content-Type": "application/json" } });
});
// supabase secrets set QRFLOW_KEY=qrf_live_...
  • Gói npm qrflow\ chỉ dùng fetch và WebCrypto, nên chạy được trên tất cả các môi trường này mà không cần thay đổi.

Python: FastAPI, Flask, Django, hoặc một script

Khi nào: Backend của bạn là Python.

import os
from fastapi import FastAPI, HTTPException, Response
from qrflow import QRFlow, QRFlowError   # https://qrflow.codes/sdk/qrflow.py

app = FastAPI()
qr = QRFlow(os.environ["QRFLOW_KEY"])

@app.post("/qr")
def make_qr(url: str, label: str | None = None):
    try:
        code = qr.create_code(type="url", destination_data={"url": url}, label=label)["code"]
    except QRFlowError as e:
        raise HTTPException(e.status, {"error": e.code, "message": str(e)})
    return {"id": code["id"], "short_url": code["short_url"]}

@app.get("/qr/{code_id}.svg")
def qr_image(code_id: str):
    import urllib.request
    req = urllib.request.Request(qr.image_url(code_id), headers={"Authorization": f"Bearer {os.environ['QRFLOW_KEY']}"})
    with urllib.request.urlopen(req) as r:
        return Response(r.read(), media_type="image/svg+xml")

Một mã QR cho mỗi đơn hàng, bàn, sản phẩm, vé hoặc sự kiện

Khi nào: Mỗi dòng trong một bảng của bạn cần mã riêng, được tạo tự động.

  1. Thêm hai cột vào bảng của bạn: qrflow_code_id (uuid) và qr_short_url (text).
  2. Khi một dòng được tạo, hãy POST /codes với URL công khai của dòng và một nhãn đặt tên cho dòng ("Order 10432", "Table 7"). Lưu id và short_url.
  3. Khi trang của dòng di chuyển (domain mới, đường dẫn mới), hãy PATCH destination_data. Các mã đã in vẫn hoạt động.
  4. Khi dòng ngừng sử dụng, hãy PATCH { paused: true } nếu đã in bất kỳ mã nào; chỉ DELETE nếu chưa in gì.
  5. Cần hàng nghìn mã cùng lúc (một menu cho mỗi bàn của 300 nhà hàng)? Dùng POST /codes/bulk theo từng phần và ánh xạ các mã trả về với dòng của bạn theo nhãn hoặc theo thứ tự.
const { code } = await qr.createCode({
  type: "url",
  destination_data: { url: \`https://example.com/orders/${order.id}\` },
  label: \`Order ${order.number}\`,
});
await db.orders.update(order.id, { qrflow_code_id: code.id, qr_short_url: code.short_url });
  • Sử dụng hợp lý là 25.000 mã đã lưu trên gói Business; API dừng ở mức gấp đôi con số đó. Nếu bạn cần một mã cho mỗi hóa đơn vĩnh viễn, hãy liên hệ với chúng tôi trước: hello@qrflow.codes.

Thay đổi nơi mã đã in trỏ đến

Khi nào: Một chiến dịch kết thúc, một trang di chuyển, một PDF được thay thế, một mùa thay đổi.

curl -X PATCH https://qrflow.codes/api/v1/codes/$CODE_ID \
  -H "Authorization: Bearer $QRFLOW_KEY" -H "Content-Type: application/json" \
  -d '{ "destination_data": { "url": "https://example.com/spring" } }'

Tạm dừng mã, hoặc đặt ngày kết thúc cho mã

# Scans show a "paused" page instead of redirecting
curl -X PATCH https://qrflow.codes/api/v1/codes/$CODE_ID -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" -d '{ "paused": true }'

# Stops working after the date; null clears it
curl -X PATCH https://qrflow.codes/api/v1/codes/$CODE_ID -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" -d '{ "expires_at": "2026-12-31T23:59:59Z" }'
  • Chỉ mã động mới có thể đổi điểm đến. Mã url tạo trên tài khoản Free, hoặc mã Wi-Fi/vCard/text, trả về 400 not_dynamic. Đối với mã url/phone/email/sms/location trên gói trả phí, POST /codes/:id/dynamic sẽ chuyển đổi mã, và bạn phải kết xuất lại và in lại vì hình ảnh thay đổi.
  • Máy quét sẽ thấy điểm đến mới ở lần quét tiếp theo. Không có bộ nhớ đệm nào phải chờ.

In mã trên domain của riêng bạn

Khi nào: Bạn muốn go.example.com/menu trong mã thay vì qrflow.codes/q/x7k2p9a.

  1. Trên trang Account, trong mục Your own link domain, thêm go.example.com và tạo CNAME mà trang hiển thị cho bạn tại nhà cung cấp DNS. Việc xác minh thường hoàn tất trong vài phút.
  2. Từ đó, mọi short_url của mã động mới đều dùng domain đó. Các mã hiện có cũng chuyển đổi: hình ảnh của chúng mã hóa qrflow.codes/q/..., vốn vẫn tiếp tục chuyển hướng, nên không có gì đã in bị hỏng.
  3. Đặt tên dễ đọc cho mã bằng slug: PATCH { "slug": "menu" } tạo go.example.com/menu. Làm việc này trước khi in.
  4. Trên gói Business với nhiều domain, GET /domains liệt kê chúng kèm id; truyền domain_id khi POST hoặc PATCH để chọn theo từng mã.

Đặt tên liên kết và chọn domain

curl https://qrflow.codes/api/v1/domains -H "Authorization: Bearer $QRFLOW_KEY"
# { "default_base": "https://go.example.com", "domains": [ { "id": "…", "host": "go.example.com", "is_default": true, … }, { "id": "…", "host": "qr.example.fr", … } ] }

curl -X PATCH https://qrflow.codes/api/v1/codes/$CODE_ID -H "Authorization: Bearer $QRFLOW_KEY" -H "Content-Type: application/json" \
  -d '{ "slug": "menu", "domain_id": "<id of qr.example.fr>" }'
# short_url is now https://qr.example.fr/menu

Biểu đồ quét trong admin của riêng bạn

Khi nào: Bạn muốn số lần quét mỗi ngày, mỗi quốc gia hoặc mỗi thiết bị bên cạnh số liệu của riêng bạn.

const stats = await qr.scans(code.id, { from: "2026-09-01", to: "2026-09-30", group: "day" });
// stats.total -> 412
// stats.rows  -> [{ key: "2026-09-01", scans: 18 }, { key: "2026-09-02", scans: 25 }, ...]
// Feed rows straight into Recharts, Chart.js, or a <table>.

const byCountry = await qr.scans(code.id, { group: "country" });   // [{ key: "US", scans: 300 }, { key: "MX", scans: 41 }]
const byDevice  = await qr.scans(code.id, { group: "device" });    // mobile, desktop, tablet
  • Một yêu cầu bao phủ tối đa 92 ngày; lặp lại cho khoảng thời gian dài hơn. Ngày tháng theo UTC.
  • Để có số liệu trực tiếp mà không cần polling, hãy đăng ký webhook cho sự kiện scan: bạn nhận mọi lần quét kèm chi tiết theo lô vài phút một lần.

Nhận webhook trong Next.js và xác minh chúng

Khi nào: Bạn muốn biết khi mã được quét hoặc thay đổi, trong cơ sở dữ liệu của riêng bạn, gần như theo thời gian thực.

  1. Tạo webhook tại Account › Webhooks hoặc bằng POST /webhooks. Sao chép secret (whsec_...) một lần vào QRFLOW_WEBHOOK_SECRET.
  2. Đọc raw body dưới dạng text trước khi phân tích cú pháp; chữ ký bao phủ chính xác các byte đó.
  3. Xác minh, sau đó chuyển theo event. Trả lời 2xx nhanh; làm việc nặng sau khi phản hồi hoặc trong hàng đợi.
  4. Nhấn Test trên webhook để nhận ping có chữ ký và xác nhận kết nối.
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(raw: string, header: string, secret: string): boolean {
  const t = /t=(\d+)/.exec(header)?.[1], v1 = /v1=([a-f0-9]+)/.exec(header)?.[1];
  if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = createHmac("sha256", secret).update(\`${t}.${raw}\`).digest("hex");
  return expected.length === v1.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

export async function POST(req: Request) {
  const raw = await req.text();
  if (!verify(raw, req.headers.get("x-qrflow-signature") ?? "", process.env.QRFLOW_WEBHOOK_SECRET!)) {
    return new Response("bad signature", { status: 401 });
  }
  const evt = JSON.parse(raw) as { id: string; event: string; created_at: string; data: any };
  // evt.id is stable across retries: store it and skip duplicates.

  switch (evt.event) {
    case "scan":          // evt.data.scans[]: code_id, label, slug, scanned_at, device, country, city, referrer, browser, os, language
      break;
    case "code.created":  // evt.data.code, evt.data.source
    case "code.updated":  // evt.data.code, evt.data.changed[]
    case "code.deleted":  // evt.data.code { id, label, short_code, slug }
      break;
    case "ping":          // the Test button
      break;
  }
  return new Response(null, { status: 204 });
}
  • Cục bộ, hãy phơi máy chủ dev của bạn qua tunnel (cloudflared tunnel --url http://localhost:3000, hoặc ngrok) và dùng URL https đó cho webhook trong khi xây dựng.
  • Gói npm làm việc này cho bạn: import { parseWebhook } from "qrflow"\ xác minh và phân tích cú pháp trong một lần gọi (WebCrypto, nên cũng chạy trong Workers và Deno). Client Python đi kèm verify_webhook.

Nhận webhook trong Python

Khi nào: Flask, FastAPI hoặc Django nhận các sự kiện tương tự.

import os, json
from flask import Flask, request, abort
from qrflow import verify_webhook   # https://qrflow.codes/sdk/qrflow.py

app = Flask(__name__)

@app.post("/qrflow")
def hook():
    raw = request.get_data()  # bytes, before any parsing
    if not verify_webhook(raw, request.headers.get("X-QRFLOW-Signature", ""), os.environ["QRFLOW_WEBHOOK_SECRET"]):
        abort(401)
    evt = json.loads(raw)
    if evt["event"] == "scan":
        for s in evt["data"]["scans"]:
            print(s["code_id"], s["scanned_at"], s["country"], s["device"])
    return "", 204

Hàng nghìn mã từ CSV

Khi nào: Một mã cho mỗi SKU, mỗi chỗ ngồi, mỗi thẻ tài sản, mỗi thư quảng cáo.

import { parse } from "csv-parse/sync";
import { readFileSync } from "node:fs";

const rows = parse(readFileSync("skus.csv"), { columns: true }) as Array<{ sku: string; url: string }>;
const out: Array<{ sku: string; id: string; short_url: string }> = [];

for (let i = 0; i < rows.length; i += 2000) {                 // Business: 2,000 per request
  const chunk = rows.slice(i, i + 2000);
  const { codes, rejected, remaining_this_month } = await qr.bulkCreate(
    chunk.map((r) => ({ destination: r.url, label: r.sku })),
  );
  codes.forEach((c, j) => out.push({ sku: chunk[j].sku, id: c.id, short_url: c.short_url }));
  if (rejected.length) console.warn(rejected);                  // rows that were not web addresses
  console.log(remaining_this_month, "left this month");
}
  • Bulk chỉ tạo mã url động, tất cả cùng màu. Các mã trả về theo đúng thứ tự bạn gửi, trừ các dòng bị từ chối; khớp theo nhãn nếu nghi ngờ.
  • Webhook nhận một sự kiện code.created cho mỗi yêu cầu bulk với codes[] thay vì một sự kiện cho mỗi mã.

Để người dùng của bạn kết nối tài khoản QRFLOW của riêng họ (OAuth)

Khi nào: Bạn đang xây dựng sản phẩm cho người khác và muốn mã nằm trong tài khoản QRFLOW của họ, không phải của bạn.

  1. Đăng ký client một lần: POST https://qrflow.codes/api/oauth/register với client_name và redirect_uris. Bạn nhận client_id (và client_secret cho confidential clients).
  2. Gửi người dùng đến /oauth/authorize với response_type=code, client_id, redirect_uri, scope, state và PKCE (code_challenge, code_challenge_method=S256).
  3. Trao đổi code tại /api/oauth/token. Lưu refresh token; access token có thời hạn một giờ.
  4. Gọi /api/v1 với Authorization: Bearer <access_token>. Mọi thứ hoạt động chính xác như với key, dưới gói của người dùng.
curl -X POST https://qrflow.codes/api/oauth/register -H "Content-Type: application/json" \
  -d '{ "client_name": "Acme Menus", "redirect_uris": ["https://app.example.com/oauth/qrflow"], "token_endpoint_auth_method": "none" }'
# { "client_id": "dyn_…", "redirect_uris": [...], "grant_types": ["authorization_code","refresh_token"], … }
https://qrflow.codes/oauth/authorize?response_type=code&client_id=dyn_…&redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fqrflow
  &scope=profile%20codes%3Aread%20codes%3Awrite%20analytics%3Aread&state=…&code_challenge=…&code_challenge_method=S256
  • Scopes giống hệt sáu scopes của API keys. Chỉ yêu cầu những gì tối thiểu bạn cần; màn hình đồng ý sẽ liệt kê chúng.
  • Nếu ứng dụng của bạn là trợ lý trò chuyện hoặc agent, hãy thêm resource=https://qrflow.codes/mcp vào yêu cầu authorize và nói chuyện với MCP server thay thế; token sẽ được gắn với nó.

Zapier, Make, n8n: không cần code

Khi nào: Bạn muốn số lần quét hoặc mã mới nằm trong bảng tính, kênh Slack hoặc CRM.

  1. Tạo trigger catch-hook (Zapier: Webhooks by Zapier › Catch Hook; Make: Custom webhook; n8n: Webhook node) và sao chép URL https của nó.
  2. Tại Account › Webhooks, thêm URL đó và chọn các sự kiện. Nhấn Test; ping hiện lên trong công cụ và cung cấp hình dạng payload.
  3. Ánh xạ data.scans[] (cho scan) hoặc data.code (cho code.*) vào bảng tính, tin nhắn hoặc bản ghi của bạn.
  4. Để tạo mã từ các công cụ đó, dùng mô-đun HTTP của chúng với POST /codes và header Authorization. Giữ key trong kho lưu trữ thông tin xác thực của công cụ.
  • Các công cụ này không thể xác minh chữ ký. URL chúng cung cấp là không thể đoán trước, đó là biện pháp bảo vệ bạn có; đừng đăng nó ở bất kỳ đâu.

Vibe coding

Lời nhắc để dán

Trợ lý lập trình xây dựng đúng thứ khi được nêu rõ các quy tắc từ đầu. Những lời nhắc này mang theo các quy tắc. Dán một lời nhắc, điền vào chỗ trong ngoặc, và trợ lý sẽ đọc tài liệu tham khảo Markdown trước khi viết một dòng nào.

Thêm mã QR vào ứng dụng của tôi

Claude, ChatGPT, Cursor, Codex, Windsurf, Copilot Chat: dán vào khung trò chuyện

Add QR codes to this project using the QRFLOW.codes API.

Read https://qrflow.codes/llms-full.txt before writing code; it is the complete reference.

Rules:
- The API key is in the environment variable QRFLOW_KEY. It must only be used server-side (route handler, server action, edge function). Never expose it to the browser.
- Create dynamic codes: POST https://qrflow.codes/api/v1/codes with { "type": "url", "destination_data": { "url": ... }, "label": ... }.
- Save the returned code.id and code.short_url on my record. short_url is what gets printed or displayed.
- Show the image by proxying GET /codes/:id/image.svg through my server, or by encoding short_url with a QR library on the client.
- Handle errors from the JSON body: { "error", "message" }. Map 402 to "upgrade needed", 429 to a retry with the Retry-After header.

What I want: [describe the feature, e.g. "every event in my events table gets a QR code that opens its public page; show it on the event admin page with a download button"].

Dạy kho lưu trữ của bạn về QRFLOW

Đặt vào CLAUDE.md, AGENTS.md, .cursorrules hoặc .github/copilot-instructions.md

## QR codes (QRFLOW.codes)
- Docs: https://qrflow.codes/llms-full.txt (Markdown), https://qrflow.codes/api/v1/openapi.json (OpenAPI 3.1).
- Base URL https://qrflow.codes/api/v1, header Authorization: Bearer $QRFLOW_KEY. Server-side only.
- Codes are created with POST /codes { type: "url", destination_data: { url }, label }. Store code.id and code.short_url.
- Change the destination with PATCH /codes/:id { destination_data: { url } }. Never change slug/domain_id after printing.
- Image: GET /codes/:id/image.svg (needs the key). Prefer paused: true over DELETE when a print exists.
- Webhooks arrive as POST with X-QRFLOW-Signature (t=,v1=HMAC-SHA256 of "t.rawBody"); verify with the raw body.

Trong Lovable, Bolt, v0, Replit và các trình xây dựng ứng dụng khác

Các trình xây dựng ưu tiên front-end cung cấp cho bạn backend (Supabase, serverless functions)

Integrate QRFLOW.codes QR codes. The API refuses browser calls, so create a backend function (Supabase Edge Function / serverless function) that holds the secret QRFLOW_KEY and calls POST https://qrflow.codes/api/v1/codes with { "type": "url", "destination_data": { "url": "<the page URL>" }, "label": "<name>" }. Return code.id and code.short_url to the UI and save them in the database. Render the QR in the UI by encoding short_url with a QR library; add a "Download for print" button that fetches /codes/:id/image.svg through the same backend function. Reference: https://qrflow.codes/llms-full.txt

Một GPT tùy chỉnh quản lý mã của tôi

ChatGPT › Create a GPT › Actions

Import from URL: https://qrflow.codes/api/v1/openapi.json
Authentication: API Key › Bearer › paste a Business key with the scopes you want the GPT to have.
Then the GPT can list, create, re-point and report on your codes. For a no-setup version, add the MCP connector instead (Developer mode › Plugins › https://qrflow.codes/mcp).

Những điều nên nói khi bộ kết nối đã hoạt động

Claude, ChatGPT, Claude Code với MCP server QRFLOW đã kết nối

"Make a QR code for https://example.com/fall-menu, call it Fall menu, frame caption 'Scan for menu'."
"Which of my codes got the most scans this month? Show a breakdown by country for the top one."
"Point the 'Lobby poster' code at https://example.com/events/october."
"Name the 'Business card' code's link 'hi' on my domain."
"Pause every code with 'Summer' in the label."
"Make 40 codes, one per table, going to https://example.com/order?table=1 through 40."
"Show me the PNG of the 'Front door' code."

MCP server

Sử dụng từ Claude, ChatGPT, Cursor và Claude Code

QRFLOW là một MCP server tại https://qrflow.codes/mcp. Kết nối một lần, đăng nhập, rồi nói những câu như "tạo mã QR cho trang menu mùa thu của chúng tôi, đặt tên menu trên domain của tôi", "trỏ mã của poster ở sảnh đến trang mới" hoặc "tuần trước tờ rơi có bao nhiêu lượt quét, theo quốc gia?". Trợ lý nhận các công cụ giống như API này cung cấp, theo cùng các quy tắc, và các mã nằm trong bảng điều khiển của bạn với mcp là nguồn.

Không phải nhà phát triển? Phiên bản ngôn ngữ đơn giản, với các cú nhấp chính xác cho từng trợ lý, nằm tại Tạo mã QR với trợ lý AI của bạn.

Kết nối

Customize › Connectors › Add custom connector › dán địa chỉ, hoặc nhấn Connect trên danh sách thư mục của QRFLOW. Claude mở trang đăng nhập QRFLOW; nhấn Allow. Hoạt động trên mọi gói.

https://qrflow.codes/mcp

Settings › Security and login › bật Developer mode, rồi Settings › Plugins › + › dán địa chỉ; đăng nhập khi được yêu cầu. Plus, Pro, Team, Enterprise và Edu.

https://qrflow.codes/mcp

Một lệnh, rồi /mcp để đăng nhập. Thêm key Business làm header để bỏ qua bước đăng nhập.

claude mcp add --transport http qrflow https://qrflow.codes/mcp
# or, with a key:
claude mcp add --transport http qrflow https://qrflow.codes/mcp --header "Authorization: Bearer $QRFLOW_KEY"

Cursor, Windsurf, VS Code, bất kỳ MCP client nào

Thêm một HTTP server tại URL. Đăng nhập OAuth diễn ra trong trình duyệt; hoặc truyền header Authorization kèm key.

{
  "mcpServers": {
    "qrflow": { "type": "http", "url": "https://qrflow.codes/mcp" }
  }
}

Agent của riêng bạn (Anthropic hoặc OpenAI SDK)

Trỏ bộ kết nối hoặc công cụ MCP đến URL với key Business làm bearer; không cần luồng trình duyệt.

// Anthropic Messages API, MCP connector
mcp_servers: [{ type: "url", url: "https://qrflow.codes/mcp", name: "qrflow", authorization_token: process.env.QRFLOW_KEY }]

Trợ lý có thể làm gì

Công cụChức năngPhạm vi
list_code_kindsMọi loại mã kèm trường và gói cần thiết. Trợ lý gọi công cụ này trước khi tạo thứ gì bất thường.profile
list_domainsCác domain liên kết của bạn, domain mặc định và id của chúng.domains:read
get_qr_imagePNG mà trợ lý có thể hiển thị hoặc lưu, cùng URL SVG để in.codes:read
get_accountAi đang đăng nhập, gói, giới hạn.profile

Cách hệ thống giữ an toàn

  • Trợ lý chỉ giữ token cho tài khoản của bạn, được cấp sau khi bạn nhấn Allow trên trang QRFLOW. Ngắt kết nối bất kỳ lúc nào tại Account › Connected apps.
  • Token được gắn với MCP server; chúng không thể phát lại với REST API.
  • Mọi thao tác ghi đều qua cùng quy trình xác thực như bảng điều khiển: danh sách trắng điểm đến, kiểm tra gói, trần sử dụng hợp lý.
  • Các công cụ phá hủy tự mô tả cẩn thận: delete_qr_code hướng dẫn mô hình ưu tiên tạm dừng khi có bản in.
  • Tài liệu khám phá nằm tại /.well-known/oauth-authorization-server và /.well-known/oauth-protected-resource; đăng ký theo RFC 7591; chỉ dùng PKCE S256.

SDK và đặc tả OpenAPI

  • TypeScript / JavaScript: npm install qrflow (npm). Không phụ thuộc, ESM và CommonJS, đầy đủ kiểu; chạy trên Node 18+, Bun, Deno và Workers. Tự động thử lại 429 cho bạn và đi kèm verifyWebhook / parseWebhook.
  • Python 3.9+, chỉ dùng thư viện chuẩn: qrflow.py.
  • OpenAPI 3.1: /api/v1/openapi.json. Nhập vào Postman hoặc Insomnia, tạo client bằng bất kỳ ngôn ngữ nào, hoặc đính kèm vào ChatGPT Action.
  • Cả hai client đều ném lỗi có kiểu (QRFlowError với status, code, message, retryAfter) và đi kèm trình xác minh webhook. Mã nguồn TypeScript một tệp vẫn nằm tại /sdk/qrflow.ts nếu bạn muốn tự nhúng.
TypeScriptPythonLời gọi
me()me()GET /me
catalog()catalog()GET /catalog
listCodes({ limit, q })list_codes(limit, q)GET /codes
getCode(id)get_code(id)GET /codes/:id
createCode(input)create_code(**fields)POST /codes
updateCode(id, patch)update_code(id, **patch)PATCH /codes/:id
deleteCode(id)delete_code(id)DELETE /codes/:id
makeDynamic(id)make_dynamic(id)POST /codes/:id/dynamic
scans(id, { from, to, group })scans(id, from_, to, group)GET /codes/:id/scans
bulkCreate(rows, colors)bulk_create(rows, **colors)POST /codes/bulk
domains()domains()GET /domains
listWebhooks() / createWebhook() / testWebhook(id) / deleteWebhook(id)list_webhooks() / create_webhook() / test_webhook(id) / delete_webhook(id)/webhooks
imageUrl(id, size)image_url(id, size)Địa chỉ hình ảnh (tải bằng key)
verifyWebhook(raw, header, secret)verify_webhook(raw, header, secret)Kiểm tra chữ ký cho các lần giao

Tham chiếu endpoint

Base URL https://qrflow.codes/api/v1. Phần thân và phản hồi đều là JSON. Ngày tháng theo chuẩn ISO 8601 theo giờ UTC. Chỉ gửi các trường thay đổi khi dùng PATCH.

GETprofile

Gói dịch vụ, các cờ tính năng và giới hạn áp dụng cho tài khoản này, cùng với phạm vi quyền của khóa.

curl https://qrflow.codes/api/v1/me \
  -H "Authorization: Bearer $QRFLOW_KEY"
{ "id": "…", "email": "ops@example.com", "plan": "business", "paid": true,
  "features": { "dynamic_codes": true, "custom_domain": true, "link_names": true, "gs1": true, "api_keys": true },
  "limits": { "saved_codes": 25000, "bulk_per_month": 10000, "bulk_per_request": 2000, "link_domains": 5, "requests_per_minute": 600 },
  "auth": "api_key", "scopes": ["codes:read", "codes:write"] }

GETpublic

Các loại gốc (url, wifi, vcard, email, phone, sms, text, location) và hơn 50 loại phụ (Instagram, Google review, Wi-Fi, app store…), mỗi loại có các trường cần thiết và gói dịch vụ yêu cầu. Không cần khóa.

curl https://qrflow.codes/api/v1/catalog

GETcodes:read

Mới nhất trước.?limit= lên đến 100,?q= tìm kiếm theo nhãn.

curl "https://qrflow.codes/api/v1/codes?limit=20&q=menu" \
  -H "Authorization: Bearer $QRFLOW_KEY"

POSTcodes:write

Cùng quy tắc như Save trên trang web: mã url, phone, email, sms và location là động trên các gói trả phí; Wi-Fi, vCard và text mang nội dung trong pattern. Đặt id loại phụ trong destination_data.subtype để tạo, ví dụ, mã Google review. domain_id tùy chọn chọn miền liên kết nào của bạn mà mã sẽ in ra (GET /domains liệt kê chúng).

curl -X POST https://qrflow.codes/api/v1/codes \
  -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "url", "destination_data": { "url": "https://example.com/menu" }, "label": "Table tents", "frame_style": "caption-below", "frame_caption": "Scan for menu" }'
{ "code": { "id": "…", "label": "Table tents", "kind": "url", "dynamic": true, "short_code": "x7k2p9a",
  "short_url": "https://go.example.com/x7k2p9a", "scans": 0, "image_url": "https://qrflow.codes/api/v1/codes/…/image.svg", … } }

GETcodes:read

Mã cùng với số lần quét, liên kết ngắn và địa chỉ hình ảnh.

curl https://qrflow.codes/api/v1/codes/$ID \
  -H "Authorization: Bearer $QRFLOW_KEY"

PATCHcodes:write

Bất kỳ trường nào trong: destination_data (chỉ mã động, bản in vẫn hợp lệ), label, paused, expires_at (ISO hoặc null), slug (tên liên kết trên miền của bạn), domain_id (miền liên kết nào của bạn mà mã này in ra; null = mặc định của tài khoản), fg_color, bg_color, frame_style, frame_caption, frame_caption2. Chỉ gửi các trường bạn đang thay đổi.

curl -X PATCH https://qrflow.codes/api/v1/codes/$ID \
  -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "destination_data": { "url": "https://example.com/menu-fall" }, "slug": "menu" }'

DELETEcodes:write

Xóa vĩnh viễn, bao gồm cả lịch sử quét. Liên kết in của mã động ngừng hoạt động. Ưu tiên paused: true nếu bản in vẫn còn ngoài kia.

curl -X DELETE https://qrflow.codes/api/v1/codes/$ID \
  -H "Authorization: Bearer $QRFLOW_KEY"
204 No Content

POSTcodes:write

Pattern in thay đổi (giờ nó mã hóa liên kết ngắn), vì vậy hãy kết xuất lại hình ảnh sau đó.

curl -X POST https://qrflow.codes/api/v1/codes/$ID/dynamic \
  -H "Authorization: Bearer $QRFLOW_KEY"

GETcodes:read

SVG sẵn sàng in với khung và màu sắc.?size= đặt chiều rộng lưới mô-đun theo px; tệp vẫn mở rộng không mất chất lượng.

curl https://qrflow.codes/api/v1/codes/$ID/image.svg \
  -H "Authorization: Bearer $QRFLOW_KEY" -o code.svg

GETanalytics:read

?from= và?to= (ngày ISO, tối đa 92 ngày, mặc định 30 ngày gần nhất) và?group= day, device, country, city, browser, os hoặc referrer. Các số liệu tương tự như trang phân tích.

curl "https://qrflow.codes/api/v1/codes/$ID/scans?from=2026-09-01&to=2026-09-21&group=day" \
  -H "Authorization: Bearer $QRFLOW_KEY"
{ "code_id": "…", "from": "…", "to": "…", "group": "day", "total": 412,
  "rows": [ { "key": "2026-09-01", "scans": 18 }, { "key": "2026-09-02", "scans": 25 }, … ] }

POSTcodes:write

Tối đa 2.000 mã URL trong một lần gọi, tất cả đều động. Tính vào cùng hạn mức hàng tháng như trang Bulk (10.000 trên gói Business). Các hàng không phải địa chỉ web sẽ bị trả về trong rejected; phần còn lại được tạo.

curl -X POST https://qrflow.codes/api/v1/codes/bulk \
  -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "rows": [ { "destination": "https://example.com/t/1", "label": "Table 1" }, { "destination": "https://example.com/t/2", "label": "Table 2" } ] }'
{ "codes": [ … ], "rejected": [], "remaining_this_month": 9998 }

GETdomains:read

Các miền đã kết nối của bạn, trạng thái của chúng và miền nào mã động in ra theo mặc định (default_base). Truyền id của miền làm domain_id trên mã để in mã đó với miền khác.

curl https://qrflow.codes/api/v1/domains \
  -H "Authorization: Bearer $QRFLOW_KEY"

GETwebhooks:manage

Các webhook của bạn với sự kiện, trạng thái cuối và số lần thất bại.

curl https://qrflow.codes/api/v1/webhooks \
  -H "Authorization: Bearer $QRFLOW_KEY"

POSTwebhooks:manage

url phải là https trên máy chủ công khai; events là bất kỳ sự kiện nào trong scan, code.created, code.updated, code.deleted. Bí mật ký được trả về một lần.

curl -X POST https://qrflow.codes/api/v1/webhooks \
  -H "Authorization: Bearer $QRFLOW_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/hooks/qrflow", "events": ["scan", "code.updated"] }'
{ "webhook": { "id": "…", "url": "…", "events": ["scan", "code.updated"], "active": true, "secret": "whsec_…" } }

POSTwebhooks:manage

Gửi một ping đã ký ngay bây giờ và báo cáo phản hồi.

curl -X POST https://qrflow.codes/api/v1/webhooks/$WEBHOOK_ID \
  -H "Authorization: Bearer $QRFLOW_KEY"

DELETEwebhooks:manage

Dừng tất cả các lần gửi, bao gồm cả các lần thử lại đang chờ.

curl -X DELETE https://qrflow.codes/api/v1/webhooks/$WEBHOOK_ID \
  -H "Authorization: Bearer $QRFLOW_KEY"
204 No Content

GETpublic

ID khung và những gì mỗi khung cần (chú thích, dòng thứ hai), được nhóm như trình tùy chỉnh. Không cần khóa.

curl https://qrflow.codes/api/v1/frames

Đối tượng Code

Mọi endpoint chạm vào mã đều trả về cùng một cấu trúc. Bỏ qua các trường bạn không biết; các trường mới được thêm theo thời gian.

TrườngLoạiÝ nghĩa
iduuidID ổn định. Dùng nó trong mọi lệnh gọi khác.
labelstring | nullTên trong bảng điều khiển. Tối đa 120 ký tự. Có thể tìm kiếm bằng?q=.
kindstringID danh mục: url, wifi, instagram, googlereview,... kind_label là tên hiển thị cho con người.
typestringKiểu mã hóa: url, text, wifi, vcard, email, phone, sms, location.
destination_dataobjectCác trường bạn đã gửi (cộng với subtype cho các loại). destination là tóm tắt một dòng của nó.
dynamicbooleanĐúng khi các lần quét đi qua QRFLOW và đích có thể thay đổi. dynamic_capable cho biết loại này có thể động trên gói trả phí hay không.
short_codestringBảy ký tự, không bao giờ thay đổi.
short_urlstringNội dung để in cho mã động. Bao gồm miền và slug của bạn khi được đặt.
domain_iduuid | nullMiền liên kết nào mã này in ra; null nghĩa là mặc định của tài khoản.
fg_color, bg_colorhexMàu mô-đun và màu nền.
has_logobooleanMột logo đã được thêm trong bảng điều khiển; image.svg bao gồm nó.
frame_style, frame_caption, frame_caption2string | nullID khung và chú thích, như trong trình tùy chỉnh.
scansintegerSố lần quét trong suốt vòng đời.
created_at, updated_atISO 8601UTC.
manage_urlurlTrang của mã trong bảng điều khiển, cho liên kết 'Open in QRFLOW'.
image_urlurlGET /codes/:id/image.svg. Cần header Authorization; không phải URL hình ảnh công khai.
svg_download_url, png_download_urlurlCùng SVG (khung, màu sắc, logo) và PNG đơn giản qua các liên kết đã ký hoạt động trong 24 giờ không cần header: cho <img> tags, script và trợ lý lưu tệp. download_expires_at cho biết khi nào chúng hết hạn; bất kỳ lần đọc mã nào cũng trả về các liên kết mới.

Các cấu trúc khác: Scans (code_id, from, to, group, total, rows[key, scans]), Domain (id, host, status, active, is_default, verified_at, grace_until), Webhook (id, url, events, active, last_status, last_delivery_at, consecutive_failures, cộng với secret một lần), Me (id, email, plan, paid, features, limits, auth, scopes) và Error (error, message). Tài liệu OpenAPI có mọi thuộc tính được định kiểu.

Business

Webhooks

QRFLOW gọi URL https của bạn khi có sự kiện xảy ra. Tạo một webhook trên Account › Webhooks hoặc bằng POST /webhooks; bạn nhận được bí mật ký một lần. Tối đa 10 webhook mỗi tài khoản.

Sự kiệnKhi nàodữ liệu
scanTheo lô: vài phút một lần, tất cả các lần quét mới kể từ lần gửi trước, tối đa 500 mỗi lần gọi.count, from, to, scans[] với code_id, label, short_code, slug, scanned_at, device, country, city, referrer, browser, os, language
code.createdNgay lập tức từ API và trợ lý; trong vài phút từ bảng điều khiển. Một yêu cầu hàng loạt gửi một sự kiện với bulk: true và codes[].code, source
code.updatedCùng thời điểm. Bao gồm đích, nhãn, tạm dừng, hết hạn, tên liên kết, miền, màu sắc, khung và chuyển đổi sang động.code, changed[] (tên các trường đã thay đổi)
code.deletedCùng thời điểm.code: { id, label, short_code, slug }
pingKhi bạn nhấn Test.webhook_id, message

Nội dung đến

Mọi tải trọng là { id, event, created_at, data }. id ổn định qua các lần thử lại của một lần gửi, vì vậy bạn có thể loại bỏ trùng lặp dựa trên nó.

{
  "id": "9b1c6d2e-…",
  "event": "scan",
  "created_at": "2026-09-21T18:05:00.000Z",
  "data": {
    "count": 2,
    "from": "2026-09-21T18:00:00.000Z",
    "to": "2026-09-21T18:04:12.331Z",
    "scans": [
      { "code_id": "…", "label": "Table tents", "short_code": "x7k2p9a", "slug": "menu", "scanned_at": "2026-09-21T18:03:40.101Z",
        "device": "mobile", "country": "US", "city": "Las Vegas", "referrer": null, "browser": "Safari", "os": "iOS", "language": "en-US" },
      { "code_id": "…", "label": "Table tents", "short_code": "x7k2p9a", "slug": "menu", "scanned_at": "2026-09-21T18:04:12.331Z",
        "device": "mobile", "country": "MX", "city": "Tijuana", "referrer": null, "browser": "Chrome", "os": "Android", "language": "es-MX" }
    ]
  }
}
{
  "id": "2f0a…",
  "event": "code.updated",
  "created_at": "2026-09-21T18:06:00.000Z",
  "data": {
    "code": { "id": "…", "label": "Table tents", "kind": "url", "dynamic": true, "short_url": "https://go.example.com/menu", "scans": 412, "…": "…" },
    "changed": ["destination_data"]
  }
}
POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: QRFLOW-Webhooks/1.0 (+https://qrflow.codes/developers)
X-QRFLOW-Event: scan
X-QRFLOW-Signature: t=1758477900,v1=5f1c…e9

Xác minh chữ ký

X-QRFLOW-Signature: t=<unix seconds>,v1=<hex>. Tính HMAC-SHA256 trên ${t}.${rawBody} với bí mật của bạn và so sánh với v1 trong thời gian không đổi; từ chối nếu t cũ hơn năm phút. Sử dụng byte thô bạn nhận được, không bao giờ dùng đối tượng được tuần tự hóa lại. Các bộ thu hoạt động cho Next.js và Python có trong recipes, và cả hai SDK đều bao gồm trình trợ giúp.

Quy tắc gửi

  • Trả lời bất kỳ 2xx nào trong vòng 8 giây. Làm công việc sau khi bạn phản hồi.
  • Bất kỳ điều gì khác được thử lại sau 1, 5, 15, 60, 240 và 720 phút.
  • Hai mươi lần thất bại liên tiếp tắt webhook và gửi email cho chủ tài khoản. Bật lại sau khi bộ thu được sửa; các lần thử lại đang chờ tiếp tục.
  • URL phải là https trên máy chủ công khai. localhost, dải địa chỉ riêng và chính qrflow.codes bị từ chối. Dùng tunnel trong khi phát triển.
  • Nhấn Test để nhận ping đã ký và xem trạng thái máy chủ của bạn đã trả lời.

Lỗi

Mọi lỗi là { "error": "<code>", "message": "<what to do>" } với trạng thái bên dưới. Thông báo được viết cho con người; hiển thị nó.

Trạng tháierrorÝ nghĩa

Triệu chứng, nguyên nhân, cách khắc phục

Xử lý sự cố

401 invalid_token trên mọi lệnh gọi

Tại saoHeader sai hoặc khóa không còn hoạt động.

Cách khắc phụcGửi chính xác Authorization: Bearer qrf_live_… (một khoảng trắng, không phải dấu hai chấm). Kiểm tra khóa chưa bị thu hồi trên Account › API keys. Nếu bạn sao chép từ chat hoặc tài liệu, hãy để ý dấu chấm cuối hoặc dấu ngoặc kép thông minh.

401 trên /api/v1 với token hoạt động trên máy chủ MCP

Tại saoTokens được tạo cho https://qrflow.codes/mcp bị ràng buộc với nó.

Cách khắc phụcDùng API key cho REST, hoặc chạy luồng OAuth thứ hai không có resource= để lấy token cho REST API.

402 upgrade_required khi tạo khóa hoặc webhook

Tại saoCả hai đều là tính năng Business.

Cách khắc phụcNâng cấp trên /pricing, hoặc dùng máy chủ MCP, hoạt động trên mọi gói qua đăng nhập.

402 trên POST /codes từ ứng dụng OAuth

Tại saoGói của người dùng không bao gồm những gì ứng dụng yêu cầu (mã động, miền).

Cách khắc phụcĐọc GET /me features trước và thích ứng: tạo mã dù vậy (nó sẽ tĩnh trên Free) hoặc cho người dùng biết gói cần gì.

403 insufficient_scope

Tại saoPhạm vi quyền được cố định khi khóa được tạo.

Cách khắc phụcTạo khóa mới với các phạm vi bạn cần và thu hồi khóa cũ. Với OAuth, yêu cầu phạm vi trong yêu cầu ủy quyền.

400 not_dynamic khi tôi PATCH destination_data

Tại saoMã là tĩnh: được tạo trên Free, hoặc loại Wi-Fi/vCard/text.

Cách khắc phụcVới url/phone/email/sms/location trên gói trả phí, POST /codes/:id/dynamic, sau đó tải lại và in lại (hình ảnh thay đổi). Wi-Fi, vCard và text không bao giờ động; thay vào đó hãy tạo mã url mở một trang.

400 no_domain khi tôi đặt slug

Tại saoTên liên kết nằm trên miền của bạn.

Cách khắc phụcKết nối và xác minh miền trên trang Account trước. Trên qrflow.codes/q đường dẫn luôn là short_code.

409 conflict trên slug

Tại saoMột mã khác của bạn đã có tên đó.

Cách khắc phụcGET /codes?q= để tìm nó, hoặc chọn tên khác. Tên theo tài khoản, không phải toàn cầu.

Lỗi CORS trong console trình duyệt

Tại saoAPI chỉ chấp nhận các lệnh gọi máy chủ-tới-máy chủ (và Canva). Điều này có chủ đích: khóa trong trang web là khóa bị rò rỉ.

Cách khắc phụcDi chuyển lệnh gọi vào route handler, server action, edge function hoặc backend và gọi từ trang đó.

Hình ảnh hiển thị hình mờ QRFLOW

Tại saoTài khoản đang ở gói Free.

Cách khắc phụcCác gói trả phí loại bỏ nó. Free dành cho trình tạo của chính trang web.

short_url vẫn nói qrflow.codes/q/… sau khi tôi thêm miền

Tại saoMiền chưa được xác minh, hoặc CNAME của nó sai.

Cách khắc phụcKiểm tra trạng thái trên trang Account hoặc GET /domains (trạng thái phải là verified). Các mã hiện có tự động chuyển đổi khi nó được xác minh.

image_url trả về 401 trong thẻ <img>

Tại saoNó cần header Authorization, mà <img> không thể gửi.

Cách khắc phụcDùng svg_download_url hoặc png_download_url từ cùng đối tượng Code: các liên kết đã ký hoạt động trong 24 giờ không cần header. Để có thứ gì đó vĩnh viễn, ủy quyền image_url qua máy chủ của bạn (xem recipe Next.js) hoặc tự mã hóa short_url.

Tôi cần PNG, không phải SVG

Tại saoSVG mang khung và logo; PNG là mã đơn giản.

Cách khắc phụcGET /codes/:id/image.png (bearer hoặc png_download_url đã ký) trả về PNG, 256 đến 2048 px. Để có PNG với khung, chuyển đổi SVG bằng sharp hoặc resvg (sharp(svgBuffer).png().toBuffer()).

Trợ lý của tôi nói endpoint hình ảnh từ chối và tự vẽ mã

Tại saoNó tìm nạp image_url, cần bearer.

Cách khắc phụcMọi mã giờ mang png_download_url và svg_download_url, và get_qr_image trả về chúng; trợ lý có thể curl chúng mà không cần đăng nhập. Mã vẽ cục bộ mã hóa cùng short_url vẫn hoạt động và vẫn đếm lần quét, nhưng thiếu khung và logo.

Webhook không bao giờ đến

Tại saoQuy tắc URL hoặc bộ thu.

Cách khắc phụcURL phải là https trên máy chủ công khai (không localhost, không IP riêng, không qrflow.codes). Nhấn Test trên webhook: kết quả hiển thị trạng thái máy chủ của bạn đã trả lời. Sự kiện quét được gộp theo lô và có thể mất tối đa khoảng năm phút; sự kiện code.* từ bảng điều khiển cũng xếp hàng vài phút, trong khi ghi từ API và MCP gửi ngay lập tức.

Chữ ký không bao giờ xác minh

Tại saoBạn đã ký một phần thân được tuần tự hóa lại. FixVerify dựa trên chính xác các byte thô bạn nhận được, trước khi phân tích cú pháp JSON. Trong Express, hãy dùng express.raw({ type: 'application/json' }) trên route đó; trong Next.js App Router, dùng await req.text(); trong Flask, dùng request.get_data(). Sau đó tính HMAC-SHA256 của ${t}.${raw}\.

Webhook tự tắt

Tại saoHai mươi lần thất bại liên tiếp.

Cách khắc phụcSửa receiver, sau đó đặt nó hoạt động lại (Account › Webhooks, hoặc xóa và tạo lại). Bạn đã được gửi email khi điều đó xảy ra. Các lần thử lại trong hàng đợi sẽ tiếp tục.

Giao nhận webhook trùng lặp

Tại saoMột phản hồi 2xx chậm (trên 8 giây) được tính là thất bại và được thử lại.

Cách khắc phụcPhản hồi trước, xử lý sau. Loại bỏ trùng lặp dựa trên id của payload, id này ổn định qua các lần thử lại.

429 rate_limited trong quá trình nhập

Tại sao600 yêu cầu mỗi phút cho mỗi key.

Cách khắc phụcDùng POST /codes/bulk (2.000 mã trong một yêu cầu) thay vì một POST cho mỗi mã, hoặc chờ trong Retry-After giây.

Tôi đã xóa một mã và poster in ra giờ hiển thị 'Code not found'

Tại saoXóa là vĩnh viễn và làm hỏng liên kết.

Cách khắc phụcKhông có cách hoàn tác. Lần tới hãy PATCH { paused: true }; một mã bị tạm dừng hiển thị trang thân thiện và có thể được tiếp tục.

Key của tôi ngừng hoạt động sau khi tôi hạ cấp

Tại saoKeys vẫn hoạt động 30 ngày sau khi rời Business, sau đó trả về 402.

Cách khắc phụcĐăng ký lại; không có gì bị xóa, và các key tương tự hoạt động trở lại.

Có gì đó không có trong danh sách? hello@qrflow.codes, kèm yêu cầu chính xác và lỗi JSON bạn nhận được. Tài khoản Business được ưu tiên.

Giới hạn và sử dụng hợp lý

Giới hạn
Yêu cầu mỗi phút, mỗi key600. 429 với Retry-After ngoài mức đó.
Keys mỗi tài khoản10
Webhooks mỗi tài khoản10
Mã đã lưu (sử dụng hợp lý)1.000 Premium, 25.000 Business; API dừng ở mức gấp đôi.
Bulk500/tháng (500 mỗi yêu cầu) Premium; 10.000/tháng (2.000 mỗi yêu cầu) Business.
Tên miền liên kết1 Premium, 5 Business
Lượt quétKhông giới hạn. Email kiểm tra ở 100.000 lượt quét mỗi mã mỗi tháng trên Premium, 1.000.000 trên Business; không có gì bị giới hạn tốc độ.
Cửa sổ phân tích lượt quét92 ngày mỗi yêu cầu
Kích thước trang danh sách100 (?limit=)
Nhãn / chú thích / slug120 / 60 / 40 ký tự
Thời gian chờ và thử lại webhook8 giây; thử lại sau 1, 5, 15, 60, 240 và 720 phút; tắt sau 20 lần thất bại liên tiếp.
Sau khi rời BusinessKeys và webhooks vẫn hoạt động 30 ngày, sau đó 402. Không có gì bị xóa.

Sử dụng hợp lý là những gì gói được định giá. Không có gì bị giới hạn tốc độ ở con số đó; API dừng ở mức gấp đôi và một người sẽ gửi email cho bạn trước. Khối lượng cao hơn: hello@qrflow.codes.

Bảo mật, cho bạn và cho những người quét

QRFLOW bảo vệ tài khoản của bạn như thế nào

  • Keys được hiển thị một lần và được lưu dưới dạng băm SHA-256. Không ai tại QRFLOW có thể đọc lại key; nếu bạn mất nó, hãy tạo một cái mới.
  • Mọi yêu cầu được giới hạn trong tài khoản mà key thuộc về. Một mã id từ tài khoản khác là 404, không bao giờ là rò rỉ.
  • Phạm vi được cố định cho mỗi key, vì vậy một key cho bảng điều khiển báo cáo không thể tạo hoặc xóa mã.
  • 600 yêu cầu mỗi phút cho mỗi key; vượt quá là 429 rõ ràng, không phải làm chậm cho mọi người.
  • Đích đến được cho phép theo danh sách: http, https, mailto, tel, sms, geo và một danh sách ngắn các scheme ứng dụng (whatsapp, tg, signal, spotify, cửa hàng ứng dụng). javascript:, data: và file: bị từ chối tại thời điểm tạo, vì vậy một tích hợp bị xâm phạm không thể biến mã của bạn thành một cuộc tấn công.
  • URL webhook phải là https trên máy chủ công khai; QRFLOW không bao giờ gọi mạng riêng hoặc chính nó. Mỗi lần giao nhận được ký và mỗi payload có một id ổn định.
  • Máy khách OAuth đăng ký với PKCE S256 và token được ràng buộc với máy chủ mà chúng được cấp; một token cho máy chủ MCP không thể phát lại trên REST API.
  • Bất kỳ ai cũng có thể thu hồi key hoặc ngắt kết nối ứng dụng trên trang Account; hiệu lực ngay lập tức.

Những gì bạn nên làm phía mình

  • Biến môi trường, không bao giờ trong mã nguồn. Nếu một key lọt vào lịch sử git, hãy thu hồi nó.
  • Chỉ phía máy chủ. API từ chối nguồn gốc trình duyệt, nhưng các endpoint của riêng bạn bao quanh nó cũng cần xác thực, nếu không bất kỳ ai cũng có thể tạo mã trên hóa đơn của bạn.
  • Cấp cho mỗi tích hợp một key riêng với các phạm vi cần thiết, đặt tên theo tích hợp đó. Thu hồi một key sau đó chỉ ảnh hưởng đến một thứ.
  • Xác minh chữ ký webhook và từ chối timestamp cũ hơn năm phút.
  • Nếu dữ liệu người dùng của bạn đi vào nhãn hoặc đích đến, hãy nhớ QRFLOW lưu trữ chúng; giữ dữ liệu cá nhân ngoài nhãn khi có thể.

Lượt quét ghi lại gì, và không ghi lại gì

  • Mỗi lần chuyển hướng lưu loại thiết bị, quốc gia, thành phố, referrer, trình duyệt, hệ điều hành và ngôn ngữ, được suy ra từ yêu cầu, và một băm một chiều của mã + ngày + IP + user agent để chủ sở hữu có thể đếm khách truy cập duy nhất. Băm không thể chuyển ngược thành địa chỉ.
  • Không có cookie nào được đặt trên người quét và bản thân địa chỉ IP không được lưu cùng lượt quét. Bot đã biết và trình thu thập xem trước liên kết bị bỏ qua.
  • Xóa một mã sẽ xóa lượt quét của nó. Xóa tài khoản sẽ xóa mọi thứ.
  • Toàn văn: https://qrflow.codes/privacy và https://qrflow.codes/terms.

Phiên bản và tính ổn định

API được đánh phiên bản trong đường dẫn: /api/v1. Trong v1, chúng tôi thêm trường, endpoint, loại và sự kiện; chúng tôi không xóa hoặc đổi tên bất cứ điều gì, và các trường không xác định trong phản hồi nên được mã của bạn bỏ qua.

Nếu một thay đổi phải phá vỡ v1, nó sẽ ra mắt dưới dạng /api/v2 và v1 tiếp tục chạy ít nhất mười hai tháng. Chủ sở hữu key được gửi email về việc ngừng sử dụng 90 ngày trước.

Máy chủ MCP tuân theo cùng quy tắc cho các công cụ của nó: đối số chỉ được thêm, và mọi công cụ giữ tên của nó.

Tài liệu OpenAPI tại /api/v1/openapi.json và Markdown tại /llms-full.txt được tạo từ mã phục vụ API, vì vậy chúng mô tả những gì đang hoạt động hôm nay.

Câu hỏi nhà phát triển thường hỏi

Tôi có phải trả phí để sử dụng QRFLOW API không?

API keys đi kèm với gói Business, $29 mỗi tháng, theo tháng. Máy chủ MCP (Claude, ChatGPT, Cursor, Claude Code) và OAuth cho ứng dụng của riêng bạn hoạt động trên mọi gói thông qua đăng nhập, và những gì chúng có thể tạo tuân theo gói. GET /catalog, GET /frames và /preview.svg không cần key nào cả.

Tôi có thể tạo mã QR miễn phí qua API không?

Không với key. Đối với hình ảnh tĩnh đơn giản, trình tạo miễn phí tại qrflow.codes hoặc bất kỳ thư viện QR mã nguồn mở nào đều làm được. API dành cho mã động, tên miền của riêng bạn, phân tích, bulk và webhook, đó là những gì tài khoản trả phí dành cho.

Tôi có thể gọi API từ trình duyệt không?

Không. Nó từ chối nguồn gốc trình duyệt để key không bao giờ có thể xuất hiện trên trang web. Hãy gọi nó từ route handler, server action, edge function hoặc backend, và gọi cái đó từ trang của bạn.

Tôi nhận được những định dạng hình ảnh nào?

SVG với màu sắc, khung, chú thích và logo của bạn (GET /codes/:id/image.svg, 256 đến 4096 px danh nghĩa) và PNG đơn giản (GET /codes/:id/image.png, 256 đến 2048 px). Cả hai đều nhận bearer, hoặc svg_download_url / png_download_url đã ký mà mọi đối tượng Code mang theo, hoạt động trong 24 giờ mà không cần header. Công cụ MCP get_qr_image trả về PNG nội tuyến cùng cả hai liên kết.

Tôi có thể thay đổi mã QR sau khi đã in không?

Có, nếu nó là động (url, phone, email, sms, location trên gói trả phí). PATCH /codes/:id với destination_data mới; hình ảnh không thay đổi, lượt quét tiếp theo đi đến nơi mới. Mã Wi-Fi, vCard và text mang nội dung trong hình ảnh và không thể thay đổi.

Sự khác biệt giữa short_url và đích đến là gì?

short_url là liên kết bên trong hình ảnh (go.example.com/menu). Đích đến là nơi liên kết đó chuyển hướng đến (https://example.com/menu-fall). Bạn in short_url một lần và thay đổi đích đến bao nhiêu lần tùy thích.

Mã có thể dùng tên miền của riêng tôi không?

Có. Premium kết nối 1 tên miền, Business 5; bạn thêm CNAME và xác minh trên trang Account. Business chọn một tên miền cho mỗi mã với domain_id. Tên liên kết (slug) tạo đường dẫn dễ đọc trên đó.

Lượt quét ghi lại gì về người quét?

Loại thiết bị, quốc gia, thành phố, referrer, trình duyệt, hệ điều hành và ngôn ngữ, từ yêu cầu, cộng với băm hàng ngày một chiều để đếm khách truy cập duy nhất. Không có cookie, và địa chỉ IP không được lưu. Đủ cho một biểu đồ, không đủ để nhận dạng bất kỳ ai. Chi tiết: https://qrflow.codes/privacy#scans

Có gói npm hoặc PyPI không?

npm: npm install qrflow\ (https://www.npmjs.com/package/qrflow), không phụ thuộc, ESM và CommonJS, đầy đủ kiểu TypeScript, chạy trên Node 18+, Bun, Deno và Workers; nó bao quanh mọi endpoint, thử lại 429, và bao gồm verifyWebhook/parseWebhook. Python: một máy khách tệp đơn tại https://qrflow.codes/sdk/qrflow.py (chỉ thư viện chuẩn) với verify_webhook; một gói PyPI sẽ theo sau.

Nó có hoạt động với Claude, ChatGPT, Cursor và Claude Code không?

Có. QRFLOW là một máy chủ MCP tại https://qrflow.codes/mcp. Thêm nó như một connector, đăng nhập một lần, và hỏi bằng lời nói thường. Mười một công cụ bao phủ tạo, chỉnh sửa, tạm dừng, đặt tên, bulk, phân tích, hình ảnh và tên miền.

Người dùng của tôi có thể kết nối tài khoản QRFLOW của họ với ứng dụng của tôi không?

Có, với OAuth 2.0. Đăng ký một máy khách tại /api/oauth/register (không cần tài khoản), gửi người dùng đến /oauth/authorize với PKCE, và gọi API với token của họ. Mã nằm trong tài khoản của họ theo gói của họ.

Làm thế nào để tôi kiểm tra webhook trên localhost?

Phơi bày máy chủ dev của bạn với một tunnel (cloudflared hoặc ngrok) và dùng địa chỉ https của nó làm URL webhook, sau đó nhấn Test trên Account › Webhooks để nhận một ping đã ký. URL webhook phải là https công khai; localhost và địa chỉ riêng bị từ chối.

Điều gì xảy ra với tích hợp của tôi nếu tôi hủy Business?

Keys và webhooks vẫn hoạt động trong 30 ngày, sau đó trả về 402. Mã, lượt quét và tên miền vẫn ở trong tài khoản. Đăng ký lại bật mọi thứ trở lại với cùng các key.

Làm thế nào để tôi tạo mã Google review, Instagram, Wi-Fi hoặc PDF qua API?

GET /catalog liệt kê mọi loại với các trường của nó. Sau đó POST /codes với type và fields của loại, thêm subtype cho các loại: { type: 'url', destination_data: { subtype: 'googlereview', placeId: 'ChIJ…' } }, { type: 'wifi', destination_data: { ssid, password, encryption: 'WPA' } }, { type: 'url', destination_data: { subtype: 'instagram', handle: 'acme' } }.

API có thể tải logo lên mã không?

Chưa. Thêm logo trong dashboard; image.svg bao gồm nó và has_logo cho bạn biết nó ở đó. Màu sắc, khung và chú thích đều có thể đặt qua API.

API có ổn định không?

v1 chỉ thêm; nó không bao giờ xóa hoặc đổi tên. Một thay đổi phá vỡ sẽ ra mắt dưới dạng v2 với v1 được giữ sống ít nhất mười hai tháng và thông báo 90 ngày qua email.

Cho các agent, công cụ và trợ lý đang đọc tài liệu này

Có thể đọc bằng máy

Mọi thứ trên trang này tồn tại dưới dạng phần mềm có thể tải. Tất cả được tạo từ mã phục vụ API, vì vậy nó không bao giờ lỗi thời.

URLNội dung
llms-full.txthttps://qrflow.codes/llms-full.txtToàn bộ tài liệu tham khảo này dưới dạng Markdown: khái niệm, mọi endpoint, mọi công cụ MCP, công thức, xử lý sự cố, FAQ. Được tạo từ cùng nguồn với trang này.
developers.mdhttps://qrflow.codes/developers.mdTài liệu tương tự, dành cho các công cụ tìm nạp tệp .md.
llms.txthttps://qrflow.codes/llms.txtChỉ mục trang web dành cho trợ lý, trỏ đến đây.
API trong một tranghttps://qrflow.codes/qr-code-apiAPI làm gì, khi nào thư viện phía máy khách là giải pháp tốt hơn và chi phí là bao nhiêu. Phiên bản ngắn gọn của tài liệu tham khảo này, để quyết định thay vì xây dựng.
openapi.jsonhttps://qrflow.codes/api/v1/openapi.jsonOpenAPI 3.1. Nhập vào Postman, Insomnia, trình tạo mã hoặc ChatGPT Action.
MCP serverhttps://qrflow.codes/mcpStreamable HTTP, OAuth với đăng ký động hoặc khóa Business dạng bearer.
server.jsonhttps://qrflow.codes/.well-known/mcp/server.jsonTệp kê khai đăng ký MCP.
Khám phá OAuthhttps://qrflow.codes/.well-known/oauth-authorization-serverSiêu dữ liệu RFC 8414; tài liệu tài nguyên được bảo vệ nằm bên cạnh.
gói npmhttps://www.npmjs.com/package/qrflownpm install qrflow. Máy khách có kiểu dữ liệu, không phụ thuộc, xác minh webhook. Máy khách Python một tệp tại https://qrflow.codes/sdk/qrflow.py.
GitHubhttps://github.com/nativecodeapps/qrflow-sdkMáy khách, ảnh chụp OpenAPI và ví dụ chạy được cho webhook Next.js, Workers, Express, FastAPI và Flask. Hoan nghênh các vấn đề và yêu cầu kéo.

Câu hỏi, ý tưởng, loại mã nên thêm: hello@qrflow.codes. Điều khoản: /terms. Quyền riêng tư: /privacy.