FastAPI Service · Generate · Customise · Track

QR Forge

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.

PythonFastAPIqrcode + Pillow SQLitePydanticREST

What it is

A real backend, not a wrapper

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

Live preview

A browser-side render of what POST /qr produces. Change the payload, colours and module size — the equivalent API request is shown alongside.


      

API

Endpoints

MethodRoutePurpose
POST/qrCreate a code; returns metadata + inline base64 PNG.
GET/qrList all codes with scan counts.
GET/qr/{id}Fetch one code's metadata.
GET/qr/{id}.pngRender as PNG.
GET/qr/{id}.svgRender as SVG.
GET/qr/{id}/statsScan analytics for a tracked code.
GET/r/{id}Log a scan and 302-redirect to the target URL.

Customisation

Style every code

fill_color / back_color

Colours

Any hex foreground and background — branded codes, light or dark.

box_size

Module size

Pixels per QR module (1–50) to scale the output up or down.

border

Quiet zone

Width of the silent margin in modules (0–20) for reliable scanning.

error_correction

EC level

L / M / Q / H — from ~7% to ~30% recovery for damaged or styled codes.

format

PNG & SVG

Raster for sharing, vector for print — same code, two endpoints.

tracked

Trackable

Encode a redirect link so each scan is logged for analytics.

Tracking

How scan-tracking works

Mark a code "tracked": true and the original URL becomes its stored target, while the image encodes …/r/{id}. Every scan walks this path:

  1. Scan

    A phone opens the encoded /r/{id} link.

  2. Log

    The service records a scan row: timestamp, user-agent, referrer.

  3. Redirect

    It returns a 302 to the real target URL — the user lands where intended.

  4. Analyse

    GET /qr/{id}/stats aggregates total scans, first/last time and a per-user-agent breakdown.

Run it

From clone to API

# 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.