Developers
QR code API
One GET request, one clean SVG. No API key, CORS enabled, cache-friendly and free within a fair-use limit of 60 requests per minute.
Endpoint
GET https://qrsvg.app/api/qr?data=<url-encoded content>[&size=512&ecl=M&color=000000&bg=ffffff&shape=square&eye=square&margin=2&preset=<id>]The response is image/svg+xml. Output is deterministic: the same query string always produces the same bytes, which is what makes it safe to cache aggressively at every layer.
Live example
This image is served by the API right now. Change the parameters in the URL and reload to see the effect.
<img src="https://qrsvg.app/api/qr?data=https://qrsvg.app&shape=rounded&size=256">Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| data | string | required | The content to encode, URL-encoded. Up to 2,000 characters; long payloads produce dense codes (see the size guide). |
| format | svg | svg | Output format. SVG only at the moment; PNG is coming soon and will accept the same parameters. |
| size | integer 64–2048 | 512 | Width and height in CSS pixels written to the SVG root. The viewBox is always module-based, so the file scales losslessly regardless. |
| ecl | L | M | Q | H | M | Error-correction level: about 7%, 15%, 25% or 30% of the code can be damaged and still scan. Higher levels add modules. |
| color | hex | 000000 | Module colour as 3- or 6-digit hex without the # (e.g. 1e1b4b). A leading # is rejected with 400. |
| bg | hex | transparent | ffffff | Background colour (hex without #) or transparent for no background rect. |
| shape | enum | square | Module shape: square, rounded, dots, classy, classy-rounded, diamond, star, fluid. Finder patterns are never affected. |
| eye | enum | square | Finder-pattern (eye) frame shape: square, rounded, circle, leaf, shield. The eye ball follows the frame unless a preset says otherwise. |
| margin | integer 0–8 | 2 | Quiet zone in modules. Use 4 for print; 0 only when you add your own padding. |
| preset | string | — | Apply a named design preset from the generator (colours, shapes, gradients). Explicit parameters override preset values. |
Invalid values return 400 with a JSON body { "error": "...", "message": "..." }. Unknown parameters are ignored.
Examples
curl
curl -o qr.svg "https://qrsvg.app/api/qr?data=https%3A%2F%2Fexample.com%2Fmenu&size=1024&ecl=Q&shape=dots&eye=rounded&color=1e1b4b&margin=4"HTML image
<img
src="https://qrsvg.app/api/qr?data=https%3A%2F%2Fexample.com&shape=rounded&size=256"
width="256" height="256"
alt="QR code linking to example.com"
loading="lazy"
/>Fetch and inline the SVG
const params = new URLSearchParams({
data: 'https://example.com/ticket/8842',
size: '320',
shape: 'classy-rounded',
color: '4f46e5',
bg: 'transparent',
});
const res = await fetch(`https://qrsvg.app/api/qr?${params}`);
if (!res.ok) throw new Error(`QR API ${res.status}`);
const svg = await res.text();
// Inline it so it inherits page CSS and stays vector-sharp:
document.querySelector('#qr').innerHTML = svg;Server-side (Node / Next.js route handler)
export async function GET() {
const upstream = await fetch(
'https://qrsvg.app/api/qr?data=' + encodeURIComponent('https://example.com') + '&size=512',
{ next: { revalidate: 86400 } }, // cache for a day on your side
);
return new Response(upstream.body, {
headers: { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'public, max-age=86400' },
});
}Rate limits
Each IP address may make 60 requests per minute. Beyond that the API returns 429 Too Many Requests with a Retry-After header (seconds). The limit is generous for rendering codes on demand and far too low for generating them in a hot loop, which is intentional: cache the result, or generate once and store the SVG. IP addresses used for rate limiting are held in memory for one minute and never persisted.
CORS and caching
Access-Control-Allow-Origin: *— call it from any web page, includingfetch()from the browser.- Responses carry
Cache-Control: public, max-age=31536000, immutable. Because output is deterministic, CDNs and browsers can hold it indefinitely; a different design is a different URL. X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Resetheaders are sent on every response, plusX-QR-VersionandX-QR-Modulesdescribing the code.
Best practices
- Always URL-encode
data. A raw&or#in a URL will be interpreted as part of the query string and truncate your payload. - Prefer
ecl=Qandmargin=4for anything printed; keepMandmargin=2for on-screen codes. See error correction explained. - Dark modules on a light background scan best. If you pass a custom
color, keep the contrast ratio againstbgabove 4.5:1. - Email clients do not render SVG. For HTML emails, wait for
format=pngor rasterise on your side. - Need thousands of codes, private hosting or a guaranteed SLA? The project is open source at github.com/nsilviu/qr-code-app and the same endpoint runs on your own domain.
Status and roadmap
- Now: SVG output, all styling parameters above, presets, rate limiting, CORS, caching.
- Coming soon:
format=png(andjpeg,webp) with ascaleparameter, plus alogoparameter for same-origin images. - Changes are announced here and on the developer guide. Breaking changes will be versioned under a new path.