How to Print Labels From a Web Service API: A Developer Walkthrough
Your application already knows what the label should say — the order number, the SKU, the barcode value, the packing list. The annoying part has never been the data. It’s the output: drivers, printer languages, spoolers, and one warehouse printer that insists on rendering your font two points too large.
This walkthrough skips that stack entirely. You’ll learn how to print labels from a web service API: register your external system once, design the label once in a browser, then submit print jobs — or pull rendered PDFs and PNGs — from your own code. No printer driver, no SDK, no raw printer commands.
What You’ll Build: Printing Labels From a Web Service API
There are two outcomes you’ll typically want, and the good news is they share the same request shape:
- Submit a print job. Your app sends a label reference plus a data payload. The job enters a queue and is dispatched to the configured printer.
- Render a single label. The same label and data come back as a PDF or PNG — for previews in your UI, email attachments, approvals, or an audit archive.
Next Generation Label Printing System (LPSNG) exposes exactly this as a managed web service API. You call an endpoint; the service owns the print stack. The same API surface also covers direct print (straight to a device, past the queue) and electronic shelf label updates, so the integration you build today keeps working when your requirements grow.
Here’s the path we’ll take:
- Register the external system with OAuth2.
- Design the label once in the label studio.
- Submit a print job from your app.
- Render a single label as PDF or PNG.
- Verify the job actually landed on paper.
The exact endpoint paths and parameter names live in the Web Service Interface and External Application Integration docs — this article gives you the shape and the order of operations, and the docs give you the byte-level details.
Prerequisites Before You Call the API
Before the first request, line up the following:
- An LPSNG account or edition that includes the web service interface. The Cloud Solution, the Embedded Edition on a single-board computer, and the multi-user Enterprise Features all carry the same core functionality described in Use Cases — web UI, label studio, job queue, PDF generation, and the web service interface.
- A label layout that already exists in the label studio, with fields mapped to the data you intend to send. The API references the layout by identifier; it does not build layouts on the fly.
- OAuth2 credentials from the registration flow used to connect external systems.
- Any HTTPS-capable HTTP client. Python, Node, Go, curl — the protocol doesn’t care.
- Optional: a test printer, or the LPSNG Player if you want a local rendering path before wiring up a device.
Step 1: Register Your External System With OAuth2
LPSNG uses a simplified OAuth2 registration protocol that connects external systems with a single URL. This is the part most integrations get wrong when they roll it themselves: hand-rolling token refresh and device authentication against a raw print protocol is weeks of work that has nothing to do with labels.
The managed flow is one step:
# 1. Open the registration URL that LPSNG generates for your external system.
# You complete the consent step once, in a browser.
open "$REGISTRATION_URL"
# 2. Store the credentials LPSNG hands back for that registered system.
export LPSNG_CLIENT_ID="<client-id>"
export LPSNG_CLIENT_SECRET="<client-secret>"
# 3. Exchange them for a token your API calls will use.
# Exact parameter names: see https://lpsng.rsj.de/en/oauth2.md
Two things worth noting:
- Consent is a one-time step. After registration, your application uses the resulting credentials on every subsequent API call — you’re not sending a human through a browser flow per print job.
- It’s the same model used for ESL base stations. If you later connect shelf labels, you’ll recognize the pattern immediately. Details are in the ESL and ESL Interface docs.
Store the token the way you’d store any other secret: environment variable or secret manager, never in the repo.
Step 2: Design the Label Once in the Label Studio
Open the web UI and build the layout like you’d build a document: text blocks, images, barcodes, and field placeholders where the API data will land.
A few decisions that pay off later:
- Use supported barcode symbologies. LPSNG renders 1D and 2D formats natively — the Barcode Formats page lists what’s available. If you pick a supported format, the API renders it without any extra work on your side.
- Attach Python script blocks to fields when you need logic. The Field Script API lets a script block access and modify a field’s value before printing — handy for formatting dates, truncating long supplier names, or deriving a check digit.
# Example: a script block attached to a field, formatting a raw value
# before it reaches the printer. See https://lpsng.rsj.de/api.html
value = str(value).strip().upper()
if len(value) > 30:
value = value[:27] + "..."
- Save the layout and note its identifier. That identifier is what your API call references — treat it like a config value, not a magic string buried in code.
- Keep layout separate from data. The layout defines how a label looks; the request defines what it says. That separation is what lets one layout serve thousands of jobs.
Step 3: Submit a Print Job From Your Application
Now the call itself. The shape is always the same: authenticate, reference the label, pass the data payload for the fields.
import os
import requests
BASE = os.environ["LPSNG_BASE_URL"] # your LPSNG instance
TOKEN = os.environ["LPSNG_ACCESS_TOKEN"] # from the OAuth2 registration
job = {
"label": "shipping-label-4x6", # identifier from the label studio
"printer": "warehouse-01", # a printer configured in LPSNG
"data": {
"order_no": "SO-10432",
"customer": "Nordwind Handel GmbH",
"sku": "HND-2200-BLK",
"qty": "12",
"barcode": "SO-10432-HND-2200-BLK",
},
}
resp = requests.post(
f"{BASE}/<print-job-endpoint>", # exact path: see the Web Service Interface docs
json=job,
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=30,
)
resp.raise_for_status()
print(resp.json()) # job identifier + status
Server-side, the job enters the queue and is dispatched to the configured printer. Your application doesn’t hold a connection open to a device, and it doesn’t need to know whether that printer speaks ZPL, EPL, or something else.
Variants worth knowing:
- Direct print. When you want the label to go straight to a device rather than wait its turn in the queue, the interface exposes a direct print path.
- Batching. Each call is a label reference plus data, so looping over order lines is just a loop in your code — one job per line, in the order your packing station needs them.
For exact endpoints, parameter names, and response fields, use the Web Service Interface and External Application Integration references.
Step 4: Render a Single Label as PDF or PNG
Rendering beats printing when a human needs to look at the label first, or when you need a record that it existed:
- Previews inside your own UI before someone commits to a run.
- Email attachments for suppliers or customers.
- Approval steps where a reviewer signs off on artwork.
- Audit archives that survive independently of a printer.
The call looks like the print job, except it returns bytes instead of enqueueing work:
# PDF for archiving or attaching
curl -sS -X POST "$LPSNG_BASE_URL/<render-endpoint>" \
-H "Authorization: Bearer $LPSNG_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label":"shipping-label-4x6","format":"pdf",
"data":{"order_no":"SO-10432","sku":"HND-2200-BLK"}}' \
-o label-SO-10432.pdf
# PNG for a preview thumbnail — same layout, same data, same output geometry
curl -sS -X POST "$LPSNG_BASE_URL/<render-endpoint>" \
-H "Authorization: Bearer $LPSNG_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label":"shipping-label-4x6","format":"png",
"data":{"order_no":"SO-10432","sku":"HND-2200-BLK"}}' \
-o label-SO-10432.png
Because both paths use the same layout and the same data, what you preview is what you print. That’s the whole point of doing it in one system rather than stitching a PDF library to a printer driver.
Two practical notes:
- Offline or embedded rendering. The LPSNG Player is a standalone command-line print engine that takes a package and data in and produces PDF, PNG, JSON, print output, or an ESL update. It’s the right tool when you need output without a server round trip.
- Cache aggressively. Repeat labels — the same shelf tag, the same pallet ID — don’t need a fresh render every time. Store the PDF keyed on layout + data hash and skip the API call.
Step 5: Verify the Print Job Worked
An HTTP 200 means the job was accepted. It doesn’t mean a label came out of a printer. Verify in this order:
- Check the job queue in the web UI. Confirm the job was accepted and completed, and that it went to the printer you expected.
- Compare render against reality. Put the PDF or PNG next to the physical label. This is where scaling problems and barcode quiet-zone issues show up, and they’re much cheaper to catch now than at a customer site.
- Scan the barcode. A reader is the only honest test of whether the data round-trips — check that the scanned value matches what your application sent, character for character.
- Log the response and job identifier. Store both against your internal order or shipment record. When someone asks “did this ship with a label?”, you want an answer from a database, not a guess.
- If you use ESL, check the display too. An updated shelf display is an independent second signal that the same data reached the service. The ESL Interface and ESL Binding API cover that side.
Troubleshooting Common Issues
Authentication failures. If calls start returning auth errors, the token was likely revoked or the external system’s registration changed. Re-run the OAuth2 registration — it’s a one-step flow by design, so recovery is cheap. See the OAuth2 page.
Blank or missing fields on the label. Almost always a key mismatch: the keys in your data payload must match the field names in the layout exactly, including case. Render the label to PNG and inspect it before blaming the printer.
Wrong barcode output. Check two things: that the format you chose is in the supported Barcode Formats list, and that the data type matches what the symbology expects. Numeric-only formats will happily render garbage from a string with letters in it.
Printer not receiving jobs. The job can only be dispatched to a printer that is configured and online in LPSNG. If the queue shows the job sitting there, the target is the problem, not your request.
Rendering looks different from the print. Compare DPI and label size between the layout and the physical media. A layout designed for one size and sent to differently sized stock will scale in ways that break barcode readability.
FAQ
Do I need a printer driver or SDK on my server to print labels from the web service API?
No. Next Generation Label Printing System handles the print stack for you: you submit a job or request a render through the web service API, and the managed service takes care of the rest. The LPSNG Player is available if you need a standalone command-line engine for local output.
What is the difference between submitting a print job and rendering a single label?
Submitting a print job sends the label to the configured printer through the job queue. Rendering returns the label as a PDF or PNG so you can preview, archive, or attach it without printing. Both use the same layout and the same data, so the output is consistent.
How does OAuth2 registration work for external systems?
LPSNG uses a simplified OAuth2 registration protocol that connects external systems with a single URL. You complete the consent step once, and the resulting credentials are used for subsequent API calls. The same model is used for ESL base stations, so the pattern is consistent across integrations.
Can the same API also update electronic shelf labels?
Yes. LPSNG includes a vendor-neutral JSON interface (ESLSEND) and a binding API for ESL tags, so you can manage both printed labels and electronic shelf labels from the same integration. For a deeper look, see our companion articles on the ESL Binding API and electronic shelf label integration APIs.
Conclusion
The pattern is short enough to hold in your head: register once with OAuth2, design the label once in the label studio, then submit a job or fetch a render from your application. Everything that used to be a printer-specific problem — drivers, command languages, font scaling, barcode libraries — is handled behind one API surface that covers print jobs, direct print, PDF and PNG rendering, and ESL updates.
Next Generation Label Printing System is the managed service that makes this the whole integration instead of one part of it. Start with the Web Service Interface docs for the exact endpoints, design your first layout in the label studio, and send a test job to a single printer before you automate the rest. If you’re still weighing your options, our Zebra Designer alternative comparison is a reasonable next read.
Related posts
- Zebra Designer Alternative: Label Printing Software to Compare
- ESL Binding API: Documentation and Examples
- Understanding Electronic Shelf Label Integration APIs
