---
title: "Get a QR code for a link"
method: GET
path: "/api/links/{id}/qr"
tags: ["QR Codes"]
---

# Get a QR code for a link

`GET /api/links/{id}/qr`

## Request

- Base URL: `https://www.flyn.to`
- URL: `https://www.flyn.to/api/links/{id}/qr`
- Auth: HTTP bearer

Renders a QR image for a link in the caller's workspace. The image encodes the short URL with `?flyn_qr=1` appended so scans are counted in `qrScans`; the response reports the clean shortUrl.

**Auth:** API key (`Bearer flyn_sk_live_...`) or an MCP OAuth access token (`Bearer flyn_mcp_at_...`). The dashboard session cookie is not accepted.

**Plan:** PNG in the default colours on every plan. `format=svg` or any colour other than fg #14532D on bg #FFFFFF needs Pro, Lifetime or Team (a member of a paying owner's workspace has the effective plan `team`); Free gets 403 `UPGRADE_REQUIRED`. Any team role.

**Rate limit:** 60 requests per 60 s per client IP, fixed window, in memory per server instance, checked before authentication.

In a query string the `#` of a colour must be sent as `%23`.

## Query parameters

- `format` 'png' | 'svg'
- `size` number
- `margin` number
- `level` 'L' | 'M' | 'Q' | 'H'
- `fg` string
- `bg` string

## Response `200`

The rendered QR code.

- LinkQrResponse
  - `shortUrl` string, uri, required: The clean short URL. The image itself encodes this URL plus `?flyn_qr=1`, the scan marker behind `qrScans`.
  - `qrDataUrl` string, required: `data:image/png;base64,...`, or `data:image/svg+xml;base64,...` for SVG.
  - `svg` string: SVG markup; present only when format=svg.
  - `qr` QrApplied, required: The render options actually applied. `size` is the real pixel width after snapping to whole modules.
    - `size` integer, required
    - `margin` integer, required
    - `level` 'L' | 'M' | 'Q' | 'H', required
    - `fg` string, required
    - `bg` string, required
    - `format` 'png' | 'svg', required
    - `moduleSize` integer, required: Pixels per module.
    - `symbolModules` integer, required: Modules per side of the QR symbol, quiet zone excluded.

## Other responses

- `400`: A malformed option or too much data. Messages include "format must be 'png' or 'svg'.", "level must be one of 'L', 'M', 'Q', 'H'.", "size must be a number.", "margin must be a number.", "fg must be a 6-digit hex colour such as #14532D.".
- `401`: Missing header, wrong prefix, unknown or revoked key, expired key, or an invalid MCP OAuth token. Messages: "Missing or invalid API key. Use: Authorization: Bearer flyn_sk_live_...", "Invalid or revoked API key", "API key has expired", "Invalid or expired OAuth token".
- `403`: SVG or custom colours on Free (code `UPGRADE_REQUIRED`), or a suspended account.
- `404`: Not found in the workspace.
- `429`: More than 60 requests in the window. Counted per client IP. Retry-After gives the seconds until the window resets.
- `500`: Unexpected render error.

---

[API](https://skmtc.dev/flyn/apis/flyn-api.md) · [All operations](https://skmtc.dev/flyn/apis/flyn-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flyn/apis/flyn-api/revisions/977962a98ccb?raw)
