DEV Community

PDF4me
PDF4me

Posted on

One Boolean, Three Spellings: What PDF4me's Read Barcode From PDF Actually Expects

A barcode inside a PDF is not something you photograph. It is data already rendered onto the page, the same way an invoice number or a customer name is. PDF4me's Read Barcode from PDF turns that into a single API call: send the PDF, get the decoded values back as structured JSON. No scanning app, no camera, no re-keying a tracking number by hand.

The endpoint is POST /api/v2/ReadBarcodes. Required fields are docContent (Base64 PDF), docName, a barcodeType array (["all"], or something narrower like ["qrCode", "code128"]), and a pages string (all, 1, 1,3,5, 2-5). The response is a barcodes array, and each entry carries type, text, page, and the x, y, width, height position on the page. That position data is what lets you tell "the tracking number barcode" apart from "the internal batch code" on the same page without guessing from decode order.

The field that has three names

Before wiring this into anything real, worth flagging: the fifth required field, the one that enables async processing on larger files, is spelled three different ways across three PDF4me-owned surfaces.

The REST documentation page lists it as IsAsync, capitalized. The interactive API Tester for the exact same endpoint lists the same field as lowercase async, and its own working curl example sends "async": true. The official Python sample in pdf4me-api-samples uses a third spelling again, isAsync, camelCase with a lowercase i. That sample is the one that actually runs end to end against the live endpoint. Here it is, trimmed to the request and response handling:

import base64, requests

url = "https://api.pdf4me.com/api/v2/ReadBarcodes"
with open("sample.pdf", "rb") as f:
    pdf_base64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docContent": pdf_base64,
    "docName": "output.pdf",
    "barcodeType": ["all"],
    "pages": "all",
    "isAsync": True
}
headers = {
    "Authorization": f"Basic {api_key}",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

if response.status_code == 200:
    barcode_data = response.json()
    for b in barcode_data["barcodes"]:
        print(f"{b['type']}: {b['text']} (page {b['page']})")
elif response.status_code == 202:
    # Async path: poll the Location header URL until it returns 200
    location_url = response.headers.get("Location")
Enter fullscreen mode Exit fullscreen mode

That is adapted from the sample's actual read_barcode_from_pdf.py, and it uses isAsync, not IsAsync, not async. Build a request strictly from the REST page's own parameter table and it will not match either the API Tester's version or the sample that actually works. When in doubt, follow the working sample.

Same operation, four different answers

Every one of PDF4me's four integration platforms also exposes Read Barcode from PDF, and each reshapes the output differently from the REST endpoint's structured barcodes[] array.

In Make, barcode type is not an array, it is a single dropdown: Select All, Code128, Code39, DataMatrix, PDF417, or QRCode. The output is Barcode Data, a flat array of plain text strings, no type, no page, no position. Make's own docs recommend an Iterator module to loop through multiple results.

In Power Automate, the type list is different again: QR Code, Code128, DataMatrix, Aztec, PDF417, Hanxin, or All. Aztec and Hanxin do not appear on the REST page's own documented type list, worth a quick check before assuming parity. The output lands in a single field called File Content, typed as a String, holding the extracted text, a strange name for a field that is not a file.

In Zapier, the type selector is typed as an Enum but explicitly supports multiple selections at once, a third distinct shape for what the REST endpoint already accepts as a native array. The output, again called File Content, is Base64 this time, shipped alongside File Name and File Extension fields more typical of a document-conversion action than a text-extraction one.

In n8n, the divergence runs deeper still. The node does not return barcode data inline. It returns a binary property containing a generated JSON file, whose own top-level fields (success, message, fileName, mimeType, fileSize, barcodeType, pages) are a status report about the extraction job, not the decoded values. Those live inside that binary JSON file, one more parsing step removed than any other platform here.

Five surfaces, five shapes: structured typed objects with coordinates (REST), a flat string array (Make), a lone oddly-named string (Power Automate), a Base64 "file" array with unrelated filename metadata (Zapier), and a nested binary JSON file (n8n). None of these are wrong for their own platform. If a workflow starts in one of these tools and later needs to call the REST API directly, budget real time for reconciling the two shapes.

Where this fits

The inverse operation is Add Barcode to PDF, stamping a barcode onto a document instead of extracting one already there, useful when a pipeline generates labeled documents upstream and reads them back downstream. If the real goal is routing a batch of scanned pages into separate files based on a section-break barcode, Split PDF by Barcode is the more direct tool, since it splits the document itself rather than extracting values. PDF4me's own barcode guide is worth a look if this whole feature area is new territory.

Authentication works the same way across the whole V2 API: see Connect to the PDF4me V2 API for the base URL, headers, and request format shared by every endpoint mentioned here.

Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com

Top comments (0)