FastAPI Service · Generate · Customise · Track
A FastAPI service that generates, customises and tracks QR codes through a clean REST API. Render any URL or text to PNG or SVG, restyle it with your own colours and error-correction level, and — when you want analytics — mint a trackable code whose every scan is logged and counted.
What it is
QR Forge is a working FastAPI application backed by SQLite. You POST a payload and styling options; it persists the code, renders an image with qrcode + Pillow, and hands you back an id, image links and an inline PNG. Codes you mark as tracked encode a short redirect link instead of the raw URL, so the service can record each scan and report analytics.
This page is a static demo deployed on GitHub Pages, so the live preview below renders QR codes in your browser. The actual service is the FastAPI backend in this repo — run it with uvicorn app.api:app and you get the full create / track / analytics API documented here.
Try it
A browser-side render of what POST /qr produces. Change the payload, colours and module size — the equivalent API request is shown alongside.
API
| Method | Route | Purpose |
|---|---|---|
| POST | /qr | Create a code; returns metadata + inline base64 PNG. |
| GET | /qr | List all codes with scan counts. |
| GET | /qr/{id} | Fetch one code's metadata. |
| GET | /qr/{id}.png | Render as PNG. |
| GET | /qr/{id}.svg | Render as SVG. |
| GET | /qr/{id}/stats | Scan analytics for a tracked code. |
| GET | /r/{id} | Log a scan and 302-redirect to the target URL. |
Customisation
Any hex foreground and background — branded codes, light or dark.
Pixels per QR module (1–50) to scale the output up or down.
Width of the silent margin in modules (0–20) for reliable scanning.
L / M / Q / H — from ~7% to ~30% recovery for damaged or styled codes.
Raster for sharing, vector for print — same code, two endpoints.
Encode a redirect link so each scan is logged for analytics.
Tracking
Mark a code "tracked": true and the original URL becomes its stored target, while the image encodes …/r/{id}. Every scan walks this path:
A phone opens the encoded /r/{id} link.
The service records a scan row: timestamp, user-agent, referrer.
It returns a 302 to the real target URL — the user lands where intended.
GET /qr/{id}/stats aggregates total scans, first/last time and a per-user-agent breakdown.
Run it
# install & serve pip install -r requirements.txt uvicorn app.api:app --reload # create a tracked QR curl -X POST http://127.0.0.1:8000/qr \ -H 'Content-Type: application/json' \ -d '{"payload":"https://example.org","tracked":true,"error_correction":"Q"}' # a scan is logged, then redirected curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' \ http://127.0.0.1:8000/r/<id> # read analytics curl http://127.0.0.1:8000/qr/<id>/stats
Interactive OpenAPI docs are served at /docs.