QR Code
REST API.
Generate beautiful QR codes from a URL. No SDK, no auth, no keys — just hit the endpoint with parameters and get a PNG or SVG back. Free for everyone.
# Try it right now
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&fg=4aff7a' -o qr.pngUse cases
01 / 06Google Sheets / Excel
Generate one QR per row from any cell using =IMAGE().
Email marketing
Per-recipient personalized QRs in your newsletter HTML.
CMS & blogs
Drop the URL anywhere images work — no plugin, no upload.
Custom apps
fetch() the URL and use the blob. Skip the QR library.
Print pipelines
Direct 2048×2048 PNG output, ready for vendor uploads.
Automation & scripts
curl > qr.png in any shell. Perfect for CI and bots.
Decode (scan) QR images
POST an image to /api/v1/scan and get back the decoded payload + type.
Endpoint
/api/v1/generateBoth methods accept the same parameters. GET takes them as URL query string; POST as JSON body. GET is cacheable; POST is for app code where building query strings is awkward.
Parameters
datastringrequiredThe text or URL to encode. Up to 4296 alphanumeric chars.
formatpng | svg | jpeg | webpOutput format. Default png. JPEG uses mozjpeg + 4:4:4 chroma so finder patterns stay crisp; WebP is lossless when quality=100.
size64..4096Output edge length in pixels. Default 1024. Use 2048+ for A4 / poster prints, or SVG for any size.
quality1..100JPEG / WebP encoder quality. Default 100. PNG / SVG ignore this.
margin0..20Quiet zone around the QR. Default 4.
eccL | M | Q | HError correction. Default M. Use H if embedding logos later.
fghexForeground color, 6-digit hex without `#`. Default 000000.
bghexBackground color, 6-digit hex without `#`. Default ffffff.
# Basic — encode a URL into a 1024×1024 PNG (default size)
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz' -o qr.png
# Print-quality — 2048px, max ECC for scan reliability
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&size=2048&ecc=H' -o qr.png
# Branded — neon-green dots on dark background, 4096px
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&fg=4aff7a&bg=0b100c&size=4096&ecc=Q' -o qr.png
# JPEG with max quality (mozjpeg + 4:4:4 chroma — no scan-breaking artifacts)
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&format=jpeg&size=2048&quality=100' -o qr.jpg
# Lossless WebP — smaller than PNG at the same quality
curl 'https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&format=webp&size=2048&quality=100' -o qr.webp
# SVG output — vector, prints at ANY size
curl 'https://generateqrcode.xyz/api/v1/generate?data=Hello%20World&format=svg' -o qr.svg# JSON POST body — same params, nicer for app code
curl -X POST 'https://generateqrcode.xyz/api/v1/generate' \
-H 'Content-Type: application/json' \
-d '{"data":"https://generateqrcode.xyz","fg":"4aff7a","size":1024,"ecc":"Q"}' \
-o qr.pngExamples
02 / 06// Browser fetch — get a Blob and assign to an <img>
const params = new URLSearchParams({
data: 'https://generateqrcode.xyz',
fg: '4aff7a',
bg: '0b100c',
size: '512',
ecc: 'Q',
});
const res = await fetch('https://generateqrcode.xyz/api/v1/generate?' + params);
const blob = await res.blob();
document.querySelector('#qr').src = URL.createObjectURL(blob);# Python — save a styled QR to disk
import urllib.parse, urllib.request
params = urllib.parse.urlencode({
'data': 'https://generateqrcode.xyz',
'fg': '4aff7a',
'bg': '0b100c',
'size': 1024,
'ecc': 'Q',
})
url = f'https://generateqrcode.xyz/api/v1/generate?{params}'
urllib.request.urlretrieve(url, 'qr.png')// Node.js — async/await, write to disk
import { writeFile } from 'node:fs/promises';
const params = new URLSearchParams({
data: 'https://generateqrcode.xyz',
fg: '4aff7a',
bg: '0b100c',
size: '1024',
});
const res = await fetch(`https://generateqrcode.xyz/api/v1/generate?${params}`);
const buffer = Buffer.from(await res.arrayBuffer());
await writeFile('qr.png', buffer);// Go — fetch and save
package main
import (
"io"
"net/http"
"os"
)
func main() {
url := "https://generateqrcode.xyz/api/v1/generate?data=https://generateqrcode.xyz&fg=4aff7a&size=1024"
res, _ := http.Get(url)
defer res.Body.Close()
out, _ := os.Create("qr.png")
defer out.Close()
io.Copy(out, res.Body)
}Google Sheets / Excel
03 / 06Bulk-generate QR codes for any spreadsheet. Drop the formula into a cell, point it at a column with URLs, drag down. One QR per row. Works in Google Sheets, Microsoft Excel, and any tool that supports the IMAGE() function.
- Encode the URL with
ENCODEURL(...)if it contains spaces or special chars. - Sheets caches images aggressively — change a cell and the QR updates within a few seconds.
- For high-res print (1024+ px), pass
size=1024. Sheets will downscale for display, but the image source stays sharp on print/export.
// Google Sheets / Excel — paste in any cell
=IMAGE("https://generateqrcode.xyz/api/v1/generate?data="&ENCODEURL(A2)&"&size=256&fg=4aff7a")
// Where A2 holds the URL or text. Drag the formula down for one
// QR per row — perfect for event tickets, product labels, member cards.Rate limiting
Every response carries rate-limit headers so your client can throttle gracefully:
X-RateLimit-LimitTotal requests allowed in the window (60).X-RateLimit-RemainingRequests left in the current window.X-RateLimit-ResetUnix timestamp when the window resets.Hitting the cap returns 429 with a Retry-After hint in the response body.
Errors
// 400 — missing required param
{
"error": "Missing required parameter `data`.",
"hint": "Pass any string to encode, e.g. ?data=https://example.com"
}
// 400 — invalid color
{
"error": "`fg` must be a 6-digit hex color, e.g. 4aff7a."
}
// 429 — rate limited
{
"error": "Rate limit exceeded.",
"hint": "Free tier allows 60 requests / minute. Try again in 24s."
}Scan / decode endpoint
/api/v1/scanReverse of /generate. Pass an image (file upload, JSON with url or base64 image, or raw image/* bytes) and get back the decoded payload + classified content type (URL, WiFi, vCard, email, SMS, phone, WhatsApp, Spotify, YouTube, App Store, crypto, geo, event, or text).
Request shapes
GET ?url=…— fetch a publicly-hosted image and decode it.POST multipart/form-datawith fieldimage— file upload.POST application/jsonwith{ url }or{ image }(base64 / data URL).POST image/png(or jpeg/webp/gif) with raw bytes in the body.
Max 8 MB · supports PNG, JPG, WebP, GIF, BMP, SVG · same 60 req/min/IP cap.
# Scan from URL (GET — easy to try in a browser too)
curl 'https://generateqrcode.xyz/api/v1/scan?url=https://generateqrcode.xyz/og-sample.png'
# Scan from file upload (POST — multipart/form-data)
curl -X POST 'https://generateqrcode.xyz/api/v1/scan' \
-F 'image=@./my-qr.png'
# Scan from base64 image (POST — application/json)
curl -X POST 'https://generateqrcode.xyz/api/v1/scan' \
-H 'Content-Type: application/json' \
-d '{"image":"data:image/png;base64,iVBORw0KGgoAAA…"}'// 200 — decoded WiFi QR
{
"type": "wifi",
"raw": "WIFI:T:WPA;S:GuestNet;P:hunter2;;",
"summary": "WiFi · GuestNet · WPA",
"fields": {
"ssid": "GuestNet",
"password": "hunter2",
"encryption": "WPA",
"hidden": false
},
"image": { "width": 720, "height": 720 }
}
// 422 — image had no QR
{
"error": "No QR code detected in image.",
"hint": "Try a higher-resolution, well-lit, uncropped image."
}// Browser — upload a file the user picked
const form = new FormData();
form.append('image', fileInput.files[0]);
const res = await fetch('https://generateqrcode.xyz/api/v1/scan', {
method: 'POST',
body: form,
});
const data = await res.json();
console.log(data.type, data.summary, data.fields);FAQ
04 / 06Do I need an API key?
No. The free tier is open to everyone with no auth. Future paid tiers will offer keys for higher rate limits and dynamic-QR features (analytics, editable destinations).
What are the rate limits?
60 requests / minute / IP on the free tier. Limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) accompany every response.
Can I use this commercially?
Yes. Generate QRs for products, marketing, events, anything. Don't redistribute the API itself as your own product.
Will the URL stay stable?
Yes. /api/v1/generate is versioned. Breaking changes will go to /api/v2.
Can I embed a logo?
Not in v1 — the public API supports basic styling only. Use the editor at /editor for logos and fancy dot/eye styles. Logo support in the API is on the v2 roadmap.
Are the responses cached?
Yes. We send Cache-Control: public, max-age=86400, immutable. The same URL always produces the same image, so CDNs and browsers can cache aggressively.
Ready to ship
Use the QR code API in your next build.
Free for everyone, no key required. Need a higher rate limit, dynamic destinations, or scan analytics? Pro tier lands in Phase 2.