QRsvg

Free QR Code API for Developers: SVG via a Single URL

Generate QR codes from a URL with the free qrsvg.app API: every parameter explained, curl, img tag, fetch and Next.js examples, rate limits, caching and CORS.

8 min readUpdated

One GET request, one SVG

The qrsvg.app API is a single endpoint, https://qrsvg.app/api/qr, that returns a QR code as an SVG document. There is no API key, no signup and no SDK to install. You build a URL with query parameters, request it, and get back image/svg+xml. Anything that can fetch a URL can use it: a browser <img> tag, curl in a shell script, a server-side render in Node, a no-code tool with an image block, or a spreadsheet formula that concatenates strings.

The output is the same engine behind the [qrsvg.app generator](/): a clean SVG with a single merged path, so the file is small (typically 2-6 KB) and renders identically at any size. The same parameters that the web UI exposes for module shapes, eye shapes, colours, quiet zone and error correction are available as query parameters. This guide covers the parameters, worked examples in several environments, and the caching and rate-limit behaviour you should design around. The complete reference lives at /api-docs.

Parameters

All parameters are query-string values. Only data is required; everything else has a default that matches the web generator. Values are validated, and an invalid value returns a 400 with a JSON error message rather than a broken image.

  • data (required): the content to encode, URL-encoded. For a link, encode the whole URL, so https://example.com/?a=1 becomes https%3A%2F%2Fexample.com%2F%3Fa%3D1.
  • format: svg is the only format right now and the default. png is coming soon; until then, rasterise on your side if you need a bitmap.
  • size: rendered width and height in pixels, 64 to 2048, default 512. For SVG this sets the width, height and viewBox; the file stays scalable.
  • ecl: error correction level, L, M, Q or H, default M. See the error correction guide for when to raise it.
  • color: module colour as hex, default #000000. Encode the hash as %23, so black is color=%23000000 and navy is color=%231e3a8a.
  • bg: background colour as hex, or transparent, default #ffffff. Transparent is handy for dark-mode pages, but make sure the surrounding element gives enough contrast.
  • shape: module shape, one of square, rounded, dots, classy, classy-rounded, diamond, star, fluid. Default square.
  • eye: shape of the three finder patterns, one of square, rounded, circle, leaf, shield. Default square.
  • margin: quiet zone in modules, 0 to 8, default 2. Use 4 when the SVG will be placed against busy artwork; 0 only if you draw your own padding.
  • preset: the id of a design preset from the generator, which applies a curated combination of shape, eye and colours in one parameter. Explicit parameters override the preset's values.

Examples: curl, HTML, JavaScript, Node

The quickest test is curl. This saves a 512-pixel code for example.com to disk: curl -o qr.svg 'https://qrsvg.app/api/qr?data=https%3A%2F%2Fexample.com&size=512'. Open the file in a browser to check it, or pipe it straight into a build step that inlines assets.

In HTML, treat the endpoint like any image URL. A rounded 256-pixel code for a link: <img src='https://qrsvg.app/api/qr?data=https%3A%2F%2Fexample.com&shape=rounded&size=256' alt='QR code' width='256' height='256'>. Setting explicit width and height avoids layout shift while the image loads. Browsers render SVG in <img> fine, and the response is cacheable, so repeat visits cost nothing.

In client-side JavaScript you can fetch the SVG text and inline it in the DOM, which lets you style it with CSS or animate it: const svg = await fetch('https://qrsvg.app/api/qr?data=' + encodeURIComponent(url) + '&shape=dots&eye=circle').then(r => r.text()); container.innerHTML = svg;. CORS is *, so this works from any origin without a proxy. Only inline SVG from sources you trust; here the markup is generated deterministically from your parameters, but the same pattern with an untrusted source would be an XSS risk.

Server-side in Node or a Next.js route handler, fetch once and cache the result, then serve it from your own domain: export async function GET() { const res = await fetch('https://qrsvg.app/api/qr?data=' + encodeURIComponent('https://example.com') + '&ecl=Q', { next: { revalidate: 86400 } }); return new Response(await res.text(), { headers: { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'public, max-age=86400' } }); }. This keeps the third-party call off the browser, lets you attach your own headers, and means a burst of traffic to your page produces one upstream request per day rather than one per visitor.

HTML email: the SVG caveat

Email is the one place where linking directly to the API does not work today. Gmail, Outlook and Apple Mail either strip SVG images or refuse to render them, so a <img> pointing at the SVG endpoint will show a broken image or nothing at all in most inboxes. This is a limitation of email clients, not of the API.

For now, generate the PNG on your side: fetch the SVG at build or send time, rasterise it with a library such as sharp or resvg, upload the PNG to your own storage or CDN, and reference that URL in the email. When format=png ships you will be able to skip the rasterising step and point the email at the API directly. Either way, keep the code at least 300 pixels wide in the PNG so it scans when the email is viewed on a phone.

Rate limits, caching and CORS

The endpoint allows 60 requests per minute per IP. Over the limit you receive a 429 response with a Retry-After header telling you how many seconds to wait. Well-behaved clients should honour the header rather than retrying immediately. If you render QR codes on your server for many users, remember that all those requests share your server's IP, which is exactly why caching matters.

Responses are designed to be cached aggressively. The output is deterministic: identical parameters always produce byte-identical SVG, and every response carries Cache-Control: public, max-age=…, immutable. Browsers, CDNs and proxies such as Cloudflare or Vercel's edge will therefore serve repeat requests without hitting the origin. If you generate the same code in many places, normalise the parameter order in your URL builder so the cache key stays stable.

CORS is open (Access-Control-Allow-Origin: *), so fetch from any web page works without a server proxy. No credentials are involved, no cookies are set, and the API stores nothing about the content you encode.

Best practices

Most integration problems come from a handful of avoidable mistakes. The list below is what we would check in a code review of any client that talks to the API.

  • Always URL-encode data. Use encodeURIComponent in JavaScript, urllib.parse.quote in Python or --data-urlencode with curl -G. An unencoded & in your link silently truncates the QR content.
  • Cache on your side. Generate once per distinct value and store the SVG in your database, object storage or build output. QR codes for fixed URLs never need to be regenerated.
  • Do not call the API inside a render loop or on every page view of a dynamic list. Fetch when the record is created, or memoise by URL.
  • Prefer inline SVG in the DOM for web UIs: it is resolution-independent, can inherit CSS colours and is a few kilobytes. Use <img> when you need the browser cache to do the work.
  • Fall back to a static image. If the fetch fails, show a pre-rendered code or a link, so a network hiccup never leaves the user with an empty box.
  • Test the scan, not just the render. Point a phone at the result on screen after every change to shape, color or bg; see size and print guidelines for contrast and minimum size.
  • Attribution is appreciated but not required. A small “QR by qrsvg.app” link helps keep the service free.

High volume and self-hosting

The public endpoint is meant for websites, internal tools, scripts and small products. If you need thousands of codes per minute, want to run inside a private network, or have compliance rules about third-party calls, run your own instance. The whole application, including the API route, is open source at github.com/nsilviu/qr-code-app and deploys as a standard Next.js app on Vercel, a Docker host or any Node runtime. Your copy behaves identically, minus the shared rate limit.

If your need is a one-off batch rather than an API integration, the bulk generator turns a CSV of URLs into a ZIP of SVGs from the browser with no code at all. For codes whose destination may change later, generate a dynamic QR code with a free account and encode the short https://qrsvg.app/r/<code> link through the API; the printed or embedded code stays valid while you update the target. The full parameter table, response headers and error codes are documented at /api-docs.

Frequently asked questions

Is the qrsvg.app QR code API really free, and do I need an API key?
Yes, it is free and there is no API key or signup. The only restriction is a rate limit of 60 requests per minute per IP, returned as a 429 with a Retry-After header. For higher volume you can self-host the open-source project.
Can I get a PNG from the API?
Not yet. format=svg is the only output today; format=png is on the roadmap. Until then, fetch the SVG and rasterise it on your side with a library such as sharp or resvg, which also gives you full control over the pixel size.
Can I use the API from a browser without a backend?
Yes. CORS is set to allow any origin, so a plain fetch from your web page works, and an img tag pointing at the endpoint works as well. Cache the result if you show the same code repeatedly.
Does the API store the data I encode?
No. The endpoint generates the SVG from the query parameters and returns it; nothing about the content is logged or stored. Responses are cacheable by browsers and CDNs, so avoid encoding secrets you would not want in an intermediate cache.
How do I add a logo through the API?
Logo overlays are not an API parameter at the moment. Use the web generator, which supports logos at 10-35% of the width with knockout and padding, or fetch the SVG from the API and composite your logo on top in your own code, raising ecl to Q or H.

Free, no signup

Make this QR code now

Clean SVG, PNG or PDF in seconds. Style it, add a logo, download.

Try the generator