Skip to content
pdfconversionapi

Read QR codes from PNG API

POST a PNG to /v2/convert/png/to/qrdata and get back the text of each QR code in it as {"codes": [...]}. The sample sticker's code, 29 modules at 3 pixels each on a white panel, decodes to https://example.com/garden/plot-14 in a 61-byte JSON file.

Endpoint
POST /v2/convert/png/to/qrdata
Accepts
png
Sample timing
3 ms median of 5 runsHow we measure
Request size
Up to 10 MB on the Free plan or 100 MB on paid plans, all files together

Request and response

Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.

curl -sS -X POST \
  https://api.pdfconversionapi.com/v2/convert/png/to/qrdata \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@garden-plot-badge.png \
  -o response.json

# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
  mkdir -p converted
  name=$(jq -r '.Files[0].FileName' response.json)
  jq -r '.Files[0].FileData' response.json \
    | base64 --decode > "converted/$name"
else
  cat response.json
fi
200 OK3 ms median1 file, 61 bytes
{
  "ConversionCost": 1,
  "ConversionTime": 0.003,
  "Files": [
    {
      "FileName": "garden-plot-badge.json",
      "FileExt": "json",
      "FileSize": 61,
      "FileData": "ewogICJjb2RlcyI6IFsKICAg…"
    }
  ]
}

Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.

The sample, converted

The same file the code sends. Download the input and the output and compare them yourself.

garden-plot-badge.json, 5 lines

{  "codes": [    "https://example.com/garden/plot-14"  ]}
Input
garden-plot-badge.png (39 KB)
Output
garden-plot-badge.json (61 bytes)
Source
A round garden-plot sticker with a QR code, a transparent background and a soft drop shadow, drawn by us for these pages. (CC0-1.0). How it was made
Made by
2026-11-04, API build 9eeeb0640aba

Parameters

Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.

ParameterWhat it does
FileNamestringBase name for the returned .json; the sticker's result is garden-plot-badge.json without it.
StoreFileboolean, default falsetrue stores the result for 3 hours and sends back Files[].Url instead of the inline data.

What carries over, and what doesn't

Kept

  • Every decodable code in the image: two codes side by side came back as two strings
  • Palette and 16-bit PNGs, which are read like 8-bit color
  • Codes at an angle: copies of the sticker turned 30°, 45°, 90°, 135°, 180° and 200° all decoded
  • Text with accents and symbols, returned as UTF-8 JSON

Lost or not yet supported

  • Alpha. Transparency is ignored and each pixel counts by its stored color: a code whose light modules were clear pixels stored as black returned 422, while the same code stored with white clear pixels decoded.
  • Frames after the first of an animated PNG. A code that appeared only on frame two returned 422.
  • Inverted codes (light modules on dark) are not found; qrcode-to-data reads them with IncludeInverted=true.
  • Anything about where a code is: there are no coordinates, sizes or versions in the result.

Limits

  • Exactly one PNG per request.
  • Total request size 10 MB on the Free plan or 100 MB on paid plans.
  • Images above 100,000,000 pixels return 413 before decoding.
  • At most 50 detected codes are decoded.
  • An image with no readable QR code returns 422.
  • 120 seconds per request.

Where teams use it

Checking generated codes before they ship

If your system renders QR codes into PNG labels, stickers or tickets, decode each finished PNG and compare the text with what you meant to encode. The sample sticker is that case: a code placed in artwork, read back.

Screenshots and exported images

People share codes as screenshots or exported PNGs. Read the link or ID on the server instead of asking them to scan it with a phone.

Sheets with several codes

A PNG holding more than one code returns every text it decodes, so a contact sheet of labels can be checked in one request.

Questions

My PNG has a transparent background and no code is found. Why?

The reader converts the image to gray and ignores alpha, so a transparent pixel counts as whatever color is stored under it. If your file stores its clear pixels as black, the background is as dark as the modules. Flatten it first: our black-stored test code failed here, went through png-to-jpg (white background by default) and then decoded.

What comes back for the sample?

A 61-byte JSON file in Files[0].FileData: {"codes": ["https://example.com/garden/plot-14"]}. Each decoded code adds one string to the array.

Can it read barcodes that aren't QR codes?

No. A Code 128 image returned 422 on this route. barcode-to-data reads Code 128, EAN, Data Matrix and other kinds; it decoded the same image as PLOT-14-WILLOW.

Does the route accept options such as DetectMultiple?

No options change the result. Every code found is returned anyway: DetectMultiple=false still gave both texts from a two-code PNG. FileName and StoreFile are the only parameters read.

Convert your first PNG file in a minute.