Developers & agents
Decode a QR code programmatically
POST image bytes to https://useqr.app/api/v1/decode (raw body, multipart file or JSON url field) to get back every decoded code as JSON — no API key. For local or private decoding, use zxing-cpp or pyzbar in Python, or the zbarimg command line tool. Decoding returns the payload text only, never the styling.
The API route
UseQR's decode endpoint is keyless and accepts an image three ways:
# raw bytes
curl -X POST --data-binary @qr.png -H "Content-Type: image/png" \
https://useqr.app/api/v1/decode
# multipart form
curl -F "file=@qr.png" https://useqr.app/api/v1/decode
# by URL (GET or JSON body)
curl "https://useqr.app/api/v1/decode?url=https%3A%2F%2Fexample.com%2Fqr.png"
The response is JSON:
{ "count": 1, "codes": [ { "text": "https://example.com", "format": "QRCode" } ] }
Three numbers worth knowing: images are capped at 10 MB, the decoder finds up to 8 codes in one image, and URL fetches time out after 8 seconds. Only public http(s) URLs are fetched — internal and private-range addresses are refused, so you cannot use the endpoint to probe a network. If no code is found you get a 422 with concrete fixes (sharper image, crop closer, keep the quiet zone visible) rather than an empty array.
The engine behind it is zxing-wasm — a WebAssembly build of zxing-cpp — running with
tryHarder enabled, which costs a little latency and recovers noticeably more damaged
codes. The in-browser scanner uses the same decoder, entirely client-side.
The local route
Sending images to any server is wrong when they contain credentials or personal data. Decode locally instead:
Python, zxing-cpp (the actively maintained choice):
import zxingcpp, cv2
img = cv2.imread("qr.png")
for result in zxingcpp.read_barcodes(img):
print(result.text)
Python, pyzbar (wraps zbar, needs the zbar shared library installed):
from pyzbar.pyzbar import decode
from PIL import Image
for code in decode(Image.open("qr.png")):
print(code.data.decode())
Command line, zbarimg (apt install zbar-tools, brew install zbar):
zbarimg --raw -q qr.png
The trade-offs between these engines are covered in ZXing vs quirc vs zbar.
Batch decoding
A directory of images is just a loop:
for f in scans/*.png; do
printf '%s\t' "$f"
zbarimg --raw -q "$f" || echo "DECODE FAILED"
done > decoded.tsv
The same pattern against the API works when you cannot install anything locally — the
endpoint is keyless, so there is no credential plumbing, and failures arrive as
application/problem+json with a fix field instead of a bare error string.
What decoding tells you — and what it cannot
A decoder returns the payload text and the symbology. It does not return:
- the error correction level or version in most library APIs (some expose them, many do not);
- anything about styling — colours, module shapes, logos are invisible to the decoder;
- whether the code barely decoded or decoded with margin to spare.
That last gap is why decoding alone is a weak quality gate. A styled code can pass a
clean digital decode and still fail on paper. The stronger pattern — render, rasterise,
decode, compare, and score the margin — is the
decode-verify loop, available as a
service at GET /api/v1/verify.
FAQ
How do I decode a QR code from an image in Python?
Install zxing-cpp (pip install zxing-cpp) and call zxingcpp.read_barcodes on the loaded image, or use pyzbar with Pillow. Both return the decoded text for every code found in the image.
Is there an API to decode QR codes?
Yes. POST the image bytes, a multipart file or a JSON url field to https://useqr.app/api/v1/decode. It needs no API key and returns JSON with the decoded text of up to 8 codes per image, with a 10 MB size limit.
Can I decode a QR code from the command line?
zbarimg from the zbar-tools package decodes image files directly: zbarimg --raw -q qr.png prints the payload. It installs from apt and Homebrew and handles most common image formats.
Should I decode QR codes locally or via an API?
Decode locally whenever the image may contain credentials, payment details or personal data — the bytes never leave your machine. Use the API when you cannot install native libraries, such as in a restricted CI runner or a no-dependency script.
Try it — free, no signup
Related
- A free QR code API with no key — UseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight…
- ZXing vs quirc vs zbar — The three open-source QR decoding engines compared — heritage, licences, platform reach and maintenance reality. Which decoder to build on in 2026.
- Building a decode-verify loop — The engineering pattern that proves a QR code scans: render, rasterise, decode with a real decoder, compare. How to build it, and the report fields that matter.
- Read QR codes from a webcam in the browser — Scan QR codes live in the browser with the BarcodeDetector API, a zxing-wasm fallback for Firefox and Safari, and getUserMedia camera constraints that work.