QR code SVG API: encode text as a scannable SVG image
Need a QR code you can drop straight into a page or email? Pass the text and get back an SVG. Use the URL as an <img src>, or fetch it from a script. Same generator as Tooltern's browser QR tool — including the error-correction levels that let a centre logo survive.
/v1/qr.svg?text=hello&ec=M returns image/svg+xml. No key, CORS on, 60 requests a minute./v1/qr.svg
QR code as SVG (usable as an <img src>). Change the values and press Send request to call the live API.
Parameters
| Name | Type | What it does | Default |
|---|---|---|---|
text required | string | Payload to encode (URL or text), up to 1200 UTF-8 bytes | — |
ec | string | Error correction: L≈7%, M≈15%, Q≈25%, H≈30% | M |
border | integer | Quiet-zone modules, 1–8 | 2 |
box | integer | Module size 1–20 (affects SVG millimetre scale) | 10 |
fg | string | Dark-module hex colour like 000000 or #1f6f5c | — |
bg | string | Light-module / background hex colour | — |
Example
Request:
GET https://api.oddlathe.com/v1/qr.svg?text=hello&ec=M
Response (generated by the real code when these docs were last built):
<?xml version='1.0' encoding='UTF-8'?> <svg width="25mm" height="25mm" version="1.1" viewBox="0 0 25 25" xmlns="http://www.w3.org/2000/svg"><rect fill="#ffffff" x="0" y="0" width="100%" height="100%" /><path d="M2,2H3V3H2zM3,2H4V3H3zM4,2H5V3H4zM5,2H6V3H5zM6,2H7V3H6zM7,2H8V3H7zM8,2H9V3H8zM11,2H12V3H11zM12,2H13V3H12zM16,2H17V3H16zM17,2H18V3H17zM18,2H19V3H18zM19,2H20V3H19zM20,2H21V3H20zM21,2H22V3H21zM22,2H23V3H22zM2,3H3V4H2zM8,3H9V4H8zM10,3H11V4H10zM11,3H12V4H11zM16,3H17V4H16zM22,3H23V4H22zM2,4H3V5H2zM4,4H5V5H4zM5,4H6V5H5zM6,4H7V5H6zM8,4H9V5H8zM11,4H12V5H11 …
Code examples
curl 'https://api.oddlathe.com/v1/qr.svg?text=hello&ec=M'const params = new URLSearchParams({
text: "hello",
ec: "M"
});
const res = await fetch(`https://api.oddlathe.com/v1/qr.svg?${params}`);
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();
console.log(data);import json, urllib.parse, urllib.request
params = urllib.parse.urlencode({"text": "hello", "ec": "M"})
url = "https://api.oddlathe.com/v1/qr.svg?" + params
# Send a User-Agent: the edge network refuses Python's default one.
req = urllib.request.Request(url, headers={"User-Agent": "my-script/1.0"})
with urllib.request.urlopen(req, timeout=10) as r:
data = json.load(r)
print(data)When it's useful
- Embedding a scannable link in docs, emails or static sites without a tracking redirect
- CI or build scripts that need a deterministic SVG for a URL
- Teaching how error correction (L/M/Q/H) lets a QR code survive damage or a centre logo
- Brand-coloured codes via <code>fg</code> / <code>bg</code> hex colours
Good to know
- Response
Content-Typeisimage/svg+xml— not JSON. Point an<img>at the URL, or use the JSON twin/v1/qrwhen you need the SVG as a string. textis required, max 1200 UTF-8 bytes. Longer payloads need more modules; if encoding fails, shorten the text or drop to a lowerec.ecis error correction: L ≈7%, M ≈15% (default), Q ≈25%, H ≈30%. Higher levels survive more damage (and centre logos) but make denser codes.border(1–8, default 2) is the quiet-zone modules around the code.box(1–20, default 10) scales module size in the SVG (10 ≈ 1 mm per module).fg/bgaccept 3- or 6-digit hex with or without#(encode#as%23). Keep contrast high — pale-on-pale codes often will not scan.- Text travels in the URL. Don't encode secrets. Nothing is stored or logged.
- Browser UI: Tooltern QR code generator (logo preview, SVG/PNG download). How error correction works: Wirebook device heat / QR centre-logo demo and the Tooltern QR not scanning guide.
Encode text into a QR code and return image/svg+xml. Same generator as Tooltern's /api/qr and /qr-code page. Text travels in the URL — don't put secrets here. Nothing is stored or logged.
Errors
Errors are JSON like {"error": {"code": "…", "message": "…"}}. The ones this endpoint can return:
missing_param(400): a required parameter is missing or emptybad_param(400): a value is the wrong type or out of range (the message says which)too_long(413): text is over 1200 bytesrate_limited(429): over 60 requests a minute; wait for Retry-After seconds
Questions
Do these QR codes expire?
No. The content is in the code itself; there is no redirect that can be switched off.
Why would a phone fail to scan it?
Usually too small on screen/print, low contrast, missing quiet zone, or a centre logo that covers more than the chosen ec can rebuild. Try H, a larger box, and a white border.
Is there a JSON version?
Yes — <code>/v1/qr</code> returns the same SVG inside a JSON object, plus version/module metadata.
Is anything stored?
Never. Generation only; the text is not logged.
Related endpoints
/v1/qrQR code as JSON wrapping the SVG string/v1/colorColour formats (hex, RGB, HSL, OKLCH) and WCAG contrast/v1/slugTurn a title into a clean URL slug
Prefer a page to an API?
- QR code generator (SVG/PNG, logo preview) on Tooltern: same job, nothing leaves your browser.
- Guide: QR code not scanning / error correction
Published · OpenAPI 3.1 spec · Limits and privacy