Quick answer

Open https://qr.lifestep.io/qr?data=Hello%20world to generate a PNG QR code immediately. The service is free to use without signup: there is no API key to request and no authorization header to add. Add format=svg for vector output, or control module size, quiet-zone width, and colors with the parameters below.

This convenience has a boundary. A hosted service fits public, non-sensitive values and occasional generation. Use a local QR library for secrets, personal information, offline work, large batches, or any system that cannot tolerate a third-party network dependency.

When do you need a QR API instead of a library?

A QR API is the shortest route when the caller can make an HTTPS request but you do not want to install, bundle, or maintain an encoder. It works well for a static site, one-off automation, spreadsheet formula, no-code HTTP step, or small serverless function. The response is already an image, so a browser can display it and a script can save it without understanding the QR specification.

A library is better once generation becomes core application behavior. Local code removes network latency, keeps input on the device, works offline, and lets you pin the encoder version. It also avoids depending on the availability or future terms of a free endpoint. For bulk labels, generate locally or generate once and cache the files; do not make a new hosted request on every page view.

Choose the smallest dependable generation method
SituationBetter choiceReason
Public URL in a prototypeHosted APINo dependency or account setup
Static page needs one imageAPI, then cache itSimple build-time generation
Thousands of labelsLocal libraryLower latency and fewer network failures
Offline or sensitive workflowLocal libraryInput never becomes a hosted request

Free QR code API URL parameters

The endpoint accepts GET query parameters at /qr. Always URL-encode data; otherwise an ampersand, question mark, space, or non-ASCII character can be interpreted as request syntax instead of content. GET parameters and a JSON POST body are supported. GET is convenient for an image URL, while POST is useful when application code already sends JSON.

Supported parameters and validated ranges
ParameterDefaultAccepted value
dataRequired1–2000 characters of text or a URL
formatpngpng or svg
scale6Integer from 1 through 20
border4Integer from 0 through 16 modules
dark000000Six-digit RGB hex without #
lightffffffSix-digit RGB hex without #

A navy-on-pale-blue SVG can use dark=172554 and light=eff6ff. The API validates color syntax, not scan reliability. Keep the foreground much darker than the background and test the final printed or displayed result on several devices.

Invalid or missing parameters return a structured HTTP 422 response rather than an image. That includes an empty data value, an unsupported format such as JPEG, a scale or border outside the documented range, and colors containing a hash mark or shorthand hex. Content can also be within the 2000-character request limit yet too large to encode. Check the status and Content-Type before saving a response, especially in scheduled jobs where an error document could otherwise be published with a .png filename.

Working curl, JavaScript, and Python examples

curl: save a PNG safely

curl --fail --show-error --location --get \
  'https://qr.lifestep.io/qr' \
  --data-urlencode 'data=https://example.com/check-in?guest=42' \
  --data 'format=png' \
  --data 'scale=8' \
  --data 'border=4' \
  --output check-in.png

--data-urlencode protects the embedded URL, while --fail stops an HTTP error body from being mistaken for a PNG. Add --data 'dark=172554' and --data 'light=eff6ff' for colors. Change both the format and filename when requesting SVG.

JavaScript fetch: display the image

const params = new URLSearchParams({
  data: "https://example.com/check-in?guest=42",
  format: "png",
  scale: "8",
  border: "4",
  dark: "172554",
  light: "eff6ff",
});

const response = await fetch(`https://qr.lifestep.io/qr?${params}`);
if (!response.ok) {
  throw new Error(`QR API failed with HTTP ${response.status}`);
}

const imageUrl = URL.createObjectURL(await response.blob());
const image = document.querySelector("#qr-code");
image.addEventListener("load", () => URL.revokeObjectURL(imageUrl), { once: true });
image.src = imageUrl;

URLSearchParams avoids hand-built query-string bugs. The object URL is revoked after the browser loads it. For a fixed destination, an <img> can point directly at the encoded API URL, but downloading and serving a cached copy removes the runtime dependency.

Python: download an SVG without extra packages

from pathlib import Path
from urllib.parse import urlencode
from urllib.request import Request, urlopen

params = urlencode({
    "data": "https://example.com/check-in?guest=42",
    "format": "svg", "scale": 6, "border": 4,
    "dark": "172554", "light": "eff6ff",
})
request = Request(
    f"https://qr.lifestep.io/qr?{params}",
    headers={"Accept": "image/svg+xml"},
)

with urlopen(request, timeout=10) as response:
    if response.headers.get_content_type() != "image/svg+xml":
        raise RuntimeError("Unexpected QR API response type")
    Path("check-in.svg").write_bytes(response.read())

This standard-library example applies a timeout and checks the response type before writing. Production code should also catch network and HTTP errors, limit retries, and avoid replacing a valid file when a request fails.

SVG vs PNG: which format should you request?

Choose SVG when the QR code may be resized, placed in a PDF, or printed. Vector geometry stays sharp at different physical sizes. Serve it as image/svg+xml, and treat SVG received from any external service under your normal content-security rules.

Choose PNG for the broadest, simplest image handling. Email clients, social tools, document editors, and image pipelines usually accept it without special handling. PNG is raster output, so generate it near the size you need and avoid resizing that places module edges between pixels. The right source scale produces cleaner edges than later interpolation.

Error correction, sizing, and quiet-zone pitfalls

QR codes define four error-correction levels: L, M, Q, and H. Higher levels add redundancy so more damaged modules can be recovered, at the cost of a denser or larger symbol. This API generates standard QR codes at level M and does not expose an error-correction parameter. M is a sound general default, but it is not permission to cover the center with a logo. Damage location, density, glare, print quality, and the scanner all affect the result.

scale is pixels per module, not a fixed image width. A longer value needs more modules, so two requests with the same scale can have different pixel dimensions. Keep destinations short, generate at the intended size, and test at the real viewing distance. Long tracking URLs produce denser patterns that are less forgiving when printed small.

The quiet zone is the empty border around the symbol. The default border is four modules and is the safe ordinary choice. Although zero is accepted, removing the quiet zone can make nearby text, a card edge, or a dark page look like part of the code. Do not crop the border after download. If the design uses a colored background, set light so the quiet zone is rendered consistently with strong contrast.

When not to use a hosted QR code API

Do not send passwords, access tokens, private Wi-Fi credentials, medical or customer data, internal document links, or other PII to a public QR endpoint. GET parameters may appear in browser history, access logs, reverse-proxy logs, monitoring systems, and referrer data. A stateless application does not prove every surrounding network layer stores nothing. Generate sensitive QR codes locally.

A hosted API is also the wrong dependency for an offline app, emergency workflow, factory line, or paid feature with a strict uptime requirement unless you add caching and a fallback. Free and no-signup do not mean unlimited, permanent, or covered by a service-level agreement. Save stable outputs under your control and consult the machine-readable OpenAPI document before relying on the interface.

Common questions

Is this QR code API really free with no signup?

Yes. The public endpoint used here requires no account, API key, or authorization header. That describes the current interface, not unlimited capacity or permanent availability. Handle non-200 responses and cache outputs that matter.

Can it encode a URL with its own query string?

Yes, when the whole value is URL-encoded as data. Use --data-urlencode, URLSearchParams, or urllib.parse.urlencode rather than joining strings manually.

Does the 2000-character limit mean every value fits?

No. It is an input ceiling, not a guarantee that every Unicode value fits a QR symbol. Capacity depends on encoded bytes and error correction. Unencodable content returns HTTP 422, so verify the status before treating the body as an image.

Can I use brand colors?

Yes, with six-digit dark and light RGB values without the hash mark. Strong contrast matters more than brand fidelity. Avoid pale foregrounds, busy backgrounds, and inverted designs unless device testing proves them reliable.

Documentation and resources