https://txtfetch.com/docs/barcodes/
Do barcodes and QR codes come back?
No. txtfetch does not decode them. It reads the printed text near them. Here is what each case returns.
The short answer
No. txtfetch does not decode barcodes or QR codes. The engine reads printed text only. It has no barcode decoder.
The digits printed under a barcode do come back, because OCR reads them as text. They are the caption. They are not the encoded value.
A QR code next to text adds a few stray tokens to the result. An image that holds only a code fails with an error.
The engine is tika-server-standard 3.3.1.
Source: terraform/lambda-layers/build/versions.env (versions.env: TIKA_VERSION), accessed 2026-10-05.
What comes back, case by case
We sent each image to the production API. Every row shows its source. The inputs and the raw responses are in the repo.
| Input | What comes back | Source |
|---|---|---|
| A QR code alone | An error. The image holds no printed text, so OCR finds nothing. The QR code is not decoded, and its payload does not come back. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| An EAN-13 barcode with its digits printed below | The printed digits come back as text. OCR reads them. The bars are not decoded. Blank lines follow the digits. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| A Code 128 barcode with a caption | The caption comes back, again through OCR. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| The same Code 128 barcode with no caption | An error, the same as for a QR code alone. Nothing is printed, so nothing comes back. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| The same Code 128 barcode with the caption ORDER 9 | The caption comes back. The encoded value SHIP-4471-AB does not. So nothing reads the bars. Only the printed text returns. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| An invoice image with two text lines and a QR code | The text lines come back. The QR code turns into a few stray tokens next to them. The payload, PAYLOAD-SECRET-7781, does not come back. | Production API probe: POST /v1/extract accessed 2026-10-05 |
| The same invoice saved as a PDF | The same result. The text lines come back, and the QR code adds stray tokens. Strip them before you chunk the text. | Production API probe: POST /v1/extract accessed 2026-10-05 |
Real output
Each block is the full response body, as the API sent it. In the JSON, \\n is a line break inside the text.
A QR code alone
In
qr-alone.png
Out
{"status":"error","error":{"code":"extraction_failed","message":"extraction produced no text"}}An EAN-13 barcode with its digits printed below
In
ean13.png
Out
{"status":"success","extracted_text":"5901234123457\n\n\n","metadata":{"content_type":"image/png","bytes":5513,"chars":16,"ocr":true}}A Code 128 barcode with a caption
In
code128.png
Out
{"status":"success","extracted_text":"SHIP-4471-AB\n\n\n","metadata":{"content_type":"image/png","bytes":4694,"chars":15,"ocr":true}}The same Code 128 barcode with no caption
In
code128-nocaption.png
Out
{"status":"error","error":{"code":"extraction_failed","message":"extraction produced no text"}}The same Code 128 barcode with the caption ORDER 9
In
code128-order9.png
Out
{"status":"success","extracted_text":"ORDER 9\n\n\n","metadata":{"content_type":"image/png","bytes":4154,"chars":10,"ocr":true}}An invoice image with two text lines and a QR code
In
invoice-qr.png
Out
{"status":"success","extracted_text":"Invoice INV-20931\n\nTotal due: 412.50 EUR\n\nEla]\n[=]\n\n\n","metadata":{"content_type":"image/png","bytes":14858,"chars":53,"ocr":true}}The same invoice saved as a PDF
In
invoice-qr.pdf
Out
{"status":"success","extracted_text":"\nInvoice INV-20931\n\nTotal due: 412.50 EUR\n\nno)\n\noO\noO\n\n\n\n","metadata":{"content_type":"application/pdf","bytes":25593,"chars":57,"ocr":false}}What the stray tokens do to your index
The invoice came back with lines such as Ela] and [=] after the total. A chunker keeps them. An embedding model reads them. Run the checks in Quality checks and drop short lines that hold no word.
A failed request is easier to handle. Read the error code in Errors and skip the file or decode the code yourself.
How to read the codes yourself
Decode the code with an open-source library. Run it on the same file you send to txtfetch. The decoder gives you the encoded value. txtfetch gives you the printed text.
- zxing-cpp. A C++ decoder with a Python package, zxing-cpp. It reads QR codes, EAN, UPC, Code 128, Data Matrix and PDF417. We ran it on all six images. It decoded every code. Licence: Apache-2.0. Read the source → (accessed 2026-10-05)
- ZXing. The original Java library. Use it when your pipeline runs on the JVM. Licence: Apache-2.0. Read the source → (accessed 2026-10-05)
- pyzbar, on top of ZBar. A Python wrapper. It needs the ZBar shared library on your machine. The ZBar library has a different licence from the wrapper. Licence: pyzbar: MIT. ZBar: LGPL-2.1. Read the source → (accessed 2026-10-05)
Install
pip install zxing-cpp pillow requests
Python
import os
import requests
import zxingcpp
from PIL import Image
path = "label.png"
# 1. Decode the bars yourself.
codes = [(c.format.name, c.text) for c in zxingcpp.read_barcodes(Image.open(path))]
# 2. Extract the printed text with txtfetch.
with open(path, "rb") as f:
r = requests.post(
"https://api.txtfetch.com/v1/extract",
headers={"Authorization": f"Bearer {os.environ['TXTFETCH_KEY']}"},
files={"file": f},
)
text = r.json().get("extracted_text", "")
print(codes) # [('Code128', 'SHIP-4471-AB')]
print(text)A decoder reads images. For a PDF, render each page to an image first.
Photos, scans and the premium tier
We did not measure skewed photos, damaged codes or Data Matrix and PDF417 codes. We did not measure barcodes on the premium tier. We make no claim about them.
?quality=premium is sold as a tier, but it does not run today. VLM_ENABLED defaults to false, and no operator has switched the tier on in production. A premium request downgrades to the standard Tika path instead.
Scanned pages go through OCR. Read the image page for the formats it takes.
Frequently asked questions
- Does txtfetch decode barcodes and QR codes?
- No. The engine has no barcode decoder. It reads printed text only. A QR code or a barcode never returns its encoded value.
- Does the number printed under a barcode come back?
- Yes, when the image is clear enough for OCR. It comes back as ordinary text. It is the caption, not the encoded value. A label can print a different caption from the one it encodes, so do not trust it as the code.
- Why does my barcode image fail with extraction_failed?
- The image holds no printed text. OCR finds nothing, so the request fails with the error extraction_failed. A barcode with no caption and a QR code alone both fail this way.
- What does a QR code do to the text of an invoice?
- The text lines come back. The QR code adds a few stray tokens next to them. They reach your chunks and your embeddings, so check the text before you index it.
- How do I read the codes?
- Decode them with an open-source library before or next to the txtfetch call. Use zxing-cpp, ZXing or pyzbar. The snippet on this page runs zxing-cpp and txtfetch on the same file.
- Does the premium tier read barcodes?
- We did not measure barcodes on the premium tier. We make no claim about it. The premium tier does not run today, so a premium request downgrades to the standard Tika path.
Watch it run, then take a key.
The playground replays a real recorded response for every sample document.
Open the playground →