Като разработчик не искате да създавате QR кодове ръчно през табло — искате да ги генерирате автоматично, да ги интегрирате в своя build pipeline и да реагирате на сканирания чрез webhooks. Точно за това е създаден qr3.app.
Стекът
qr3.app е изцяло Cloudflare-native:
- API Worker: Hono върху Cloudflare Workers (V8 runtime, нула Node.js зависимости)
- Redirect Worker: Изключително олекотен worker, KV-кеширани пренасочвания за < 5ms p50
- База данни: Cloudflare D1 (SQLite) с multi-tenancy чрез
workspace_id - Опашка: Събитията от сканиране са декоплирани чрез Cloudflare Queues
Удостоверяване
Всички API заявки изискват Bearer токен и workspace ID:
POST https://qr3.app/v1/codes
Authorization: Bearer qr3_sk_...
Content-Type: application/json
Създайте API ключове на app.qr3.app/dashboard/api-keys.
TypeScript SDK
npm install @qr3/sdk
# или
pnpm add @qr3/sdk
import { QR3 } from "@qr3/sdk";
const client = new QR3({
apiKey: process.env.QR3_API_KEY!,
workspaceId: process.env.QR3_WORKSPACE_ID!,
});
// Създаване на QR код
const { data: code } = await client.codes.create({
type: "url",
url: "https://my-shop.com/product/42",
title: "Product 42",
tags: ["shop", "product"],
});
console.log(code.short_code); // "r7f3Kx"
console.log(code.image_svg_url); // URL на SVG изображение
console.log(code.redirect_url); // https://qr3.app/r7f3Kx
// Промяна на URL по-късно (само за динамични кодове)
await client.codes.update(code.id, {
url: "https://my-shop.com/product/42-new",
});
// Заявка за анализи
const stats = await client.codes.stats(code.id, {
from: "2026-01-01",
to: "2026-03-31",
});
console.log(stats.data.total_scans); // напр. 1247
Директно през REST API
Без зависимост от SDK? REST API е директно използваемо:
# Създаване на QR код
curl -X POST https://qr3.app/v1/codes \
-H "Authorization: Bearer $QR3_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "url",
"url": "https://my-site.com",
"title": "My Site",
"is_dynamic": true
}'
# Списък на всички QR кодове
curl https://qr3.app/v1/codes?limit=20 \
-H "Authorization: Bearer $QR3_API_KEY"
# Качване на лого — вгражда се автоматично в SVG и PNG оттук нататък
curl -X POST https://qr3.app/v1/codes/qr_abc123/logo \
-H "Authorization: Bearer $QR3_API_KEY" \
-F "[email protected]"
# Изтегляне на QR код като SVG (вече включва логото)
curl "https://qr3.app/v1/codes/r7f3Kx/qr.svg?size=8" \
-o qrcode.svg
CLI
За скриптове и CI/CD има @qr3/cli:
npm install -g @qr3/cli
qr3 login
# Създаване на QR код и запазване като SVG
qr3 codes create --url "https://my-site.com" --title "CI Deploy" --output qr.svg
# Пакетно създаване от CSV
qr3 codes batch import urls.csv --format svg --output ./qr-codes/
Webhooks: реагирайте на сканирания
Webhooks са най-мощната функция: можете да реагирате в реално време на всяко сканиране.
// Регистриране на webhook
const { data: webhook } = await client.webhooks.create({
url: "https://your-app.com/webhooks/qr3",
events: ["qr.scanned", "qr.updated"],
});
Webhook Payload
{
"id": "evt_4f0c2a91d7e84b3c9a1f",
"type": "qr.scanned",
"created": "2026-03-15T14:30:00.000Z",
"data": {
"code_id": "qr_abc123",
"short_code": "r7f3Kx",
"scanned_at": "2026-03-15T14:30:00.000Z",
"country": "DE",
"device_type": "mobile",
"os": "iOS",
"browser": "Safari",
"language": "de",
"ab_variant": null,
"redirected_to": "https://example.com/landing"
}
}
Проверка на Webhooks (HMAC)
import { createHmac, timingSafeEqual } from "crypto";
export async function verifyWebhook(
payload: string,
signature: string,
secret: string,
): Promise<boolean> {
const expected = createHmac("sha256", secret)
.update(payload)
.digest("hex");
const expectedBytes = Buffer.from(`sha256=${expected}`);
const receivedBytes = Buffer.from(signature);
return (
expectedBytes.length === receivedBytes.length &&
timingSafeEqual(expectedBytes, receivedBytes)
);
}
Ограничаване на честотата (Rate Limiting)
Всеки API ключ може да изпраща по 60 заявки в минута, при всеки план. Създаването на кодове също има дневен лимит за работно пространство, еднакъв за всеки план: POST /v1/codes приема нови кодове, докато не бъдат създадени 200 за деня, а POST /v1/codes/batch – до 10 000.
Всеки удостоверен отговор съдържа X-RateLimit-Limit. Отговор 429 също така посочва кога да опитате отново:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710510060
Retry-After: 60
Формат на грешките (RFC 7807)
Всички грешки следват RFC 7807 Problem Details:
{
"type": "https://docs.qr3.app/errors/validation",
"title": "Validation Error",
"status": 422,
"detail": "url is required for type 'url'",
"errors": [
{ "field": "url", "message": "Required" }
]
}
Заключение
qr3.app е изграден изцяло като инструмент за разработчици: отворено REST API, TypeScript-first SDK, CLI, webhooks и пълна OpenAPI документация. Разгледайте API документацията или започнете в таблото.