REST API · Session Auth · JSON

# API Reference

Complete reference for the QRknit REST API. Manage links, generate QR codes, pull analytics, and administer users — all from your own code.

Base URL: https://your-instance.com · Format: application/json

## Authentication

All write endpoints require an active session. Log in via the web UI or call `POST /api/auth/login` with `{"username": "…", "password": "…"}` — the server sets an HttpOnly session cookie valid for 30 days. Include that cookie in all subsequent requests. Endpoints marked Admin additionally require the authenticated user to have admin privileges.

Auth

Session-based login. A successful login sets a 30-day HttpOnly cookie used for all authenticated requests.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
POST | /api/auth/login | — | Login — body: `{"username": "…", "password": "…"}`. Sets session cookie and returns `plan`, `plan_limits`, and `org_id`.
POST | /api/auth/logout | Session | Clear the current session and invalidate the cookie.
GET | /api/auth/me | Session | Returns `{"authenticated": true, "username": "…", "is_admin": bool, "org_id": int|null, "plan": "…", "plan_limits": {…}}`.

Links

Create, read, update, and delete short links. Org members see all links within their org. Admin accounts see only their own links by default, with optional `?user=` filtering.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
POST | /api/shorten | Session | Create a short link. Body: `{"url": "…", "code": "…", "title": "…", "expires_at": "…", "tags": […], "is_pinned": bool}`. `code` is optional — omit for a random code.
GET | /api/links | Session | List links. Query params: `?q=` (search), `?tag=`, `?page=`, `?per_page=`. Admin can add `?user=<username>` to filter by user.
GET | /api/links/:code | Session | Link detail — includes `created_by` username.
PATCH | /api/links/:code | Session | Edit link — updatable fields: `url`, `title`, `expires_at`, `tags`, `is_pinned`.
DELETE | /api/links/:code | Session | Delete a link.
GET | /api/links/:code/analytics | Session | Click analytics. Query: `?days=7|30|90` (capped to plan's max window). Returns `daily`, `referrers`, `devices`, `browsers`, `countries`, `heatmap` (7×24 array), and `max_days`.
GET | /api/links/:code/clicks/export | Session | Download raw click events as CSV. Columns: `timestamp`, `referrer`, `device`, `browser`, `country`.

Utilities

Stats, plan usage, tags, QR code generation, bulk operations, and CSV import/export.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
GET | /api/stats | Session | Dashboard stats: total links, total clicks, clicks in last 7 days, top 5 links, and a 30-day `daily` click array.
GET | /api/plan | Session | Current user's effective plan, limits, and live usage — `{plan, limits: {max_links, monthly_clicks, analytics_days}, usage: {active_links, monthly_clicks}}`. Org members see pooled usage across all org members.
GET | /api/tags | Session | Tags scoped to the requesting user — own tags for solo users and admins; all org member tags for org members.
GET | /api/fetch-title | Session | Server-side page title fetch. Query: `?url=<url>`. Returns `{"title": "…"}`.
GET | /api/qr/:code | — | QR PNG for a short link. Query params: `?fg=`, `?bg=`, `?size=`, `?style=`.
GET | /api/qr/custom | — | QR PNG for any URL. Query: `?url=`, `?fg=`, `?bg=`, `?size=`, `?style=`. Styles: `square`, `rounded`, `dots`, `vertical`, `horizontal`.
POST | /api/qr/custom | — | QR PNG with logo overlay. Body: `{url, fg, bg, size, style, logo}` where `logo` is a base64-encoded image string.
POST | /api/links/bulk | Session | Bulk operations. Body: `{"action": "delete"|"tag"|"expire", "codes": […]}`.
GET | /api/links/export | Session | Download all links as CSV.
POST | /api/links/import | Session | Import links from CSV. Body: `{"csv": "…"}`.
GET | /api/health | — | Health check — returns `{"status": "ok"}`. Used by Docker and uptime monitors.
GET | /api/config | — | Public deployment config — returns non-sensitive values like `app_name` and `base_url`.

Admin

All Admin endpoints require an authenticated admin session. These manage users, organizations, and the message inbox.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
GET | /api/admin/users | Admin | List all users with link counts, plan, org name, and org plan.
POST | /api/admin/users | Admin | Create user. Body: `{"username": "…", "password": "…", "is_admin": bool, "plan": "…"}`.
PATCH | /api/admin/users/:id | Admin | Update plan, admin status, and/or org. Body: `{plan?, is_admin?, org_id?}`. Set `org_id: null` to remove from org.
DELETE | /api/admin/users/:id | Admin | Delete user. Cannot delete yourself.
PATCH | /api/admin/users/:id/password | Admin | Change user password. Body: `{"password": "…"}`.
GET | /api/admin/organizations | Admin | List all organizations with member counts and plan.
POST | /api/admin/organizations | Admin | Create organization. Body: `{"name": "…", "plan": "…"}`.
PATCH | /api/admin/organizations/:id | Admin | Update organization name and/or plan. Body: `{name?, plan?}`.
DELETE | /api/admin/organizations/:id | Admin | Delete organization. Members are unassigned but not deleted.
GET | /api/admin/messages | Admin | List all contact/portal messages, newest first.
DELETE | /api/admin/messages/:id | Admin | Delete a message.
PATCH | /api/admin/messages/:id/read | Admin | Mark a message as read.

Contact

Public endpoint for submitting contact and support messages. No authentication required.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
POST | /api/contact | — | Submit a contact message. Body: `{"name": "…", "email": "…", "subject": "…", "body": "…"}`.

Public Redirects

Short link redirection and SEO endpoints. No authentication required.

Method | Endpoint | Auth | Description
--- | --- | --- | ---
GET | /:code | — | Redirect to the destination URL for a short code. Records click analytics (referrer, device, browser, country).
GET | /robots.txt | — | Standard robots.txt for crawler directives.
GET | /sitemap.xml | — | Auto-generated XML sitemap.