Turn ERP or WMS Records into Barcode Label PDFs

Map receiving records and copy counts to a saved label template, generate a PDF, and return it to the right warehouse station.

G Gookit Team
· · 5 min read

Generate labels from the records your receiving system already holds. Your integration selects the products and copy counts; Gookit Label API applies a saved template and returns a PDF for the receiving station.

This example maps two fictional receiving lines to three labels. It uses the same name/SKU template as our verified batch tutorial. It does not require a particular ERP vendor or claim a native WMS connector.

Start with a receiving action

Put Generate labels beside the receiving lines that an operator has checked. Show the chosen records and total copies before submitting. A receipt of 24 units might need 24 unit labels, four carton labels, or one bin label; received quantity alone cannot choose that rule.

For this example, the operator selects two bottles and one tray:

receiving-lines.json
[
{"lineId":"RCV-001","itemName":"Trail Bottle","itemSku":"TB-1042","receivedUnits":24,"labelCopies":2},
{"lineId":"RCV-002","itemName":"Desk Tray","itemSku":"DT-2006","receivedUnits":6,"labelCopies":1}
]

Keep lineId and the receiving event in your system. The label request only needs the fields that appear on the label.

Map fields and validate quantities

Source fieldAPI fieldWhy
itemNameitems[].data.nameVisible product name
itemSkuitems[].data.skuCode 128 value and readable SKU
labelCopiesitems[].quantityDeliberate number of labels
lineIdYour internal print recordConnects the result to the receiving action

This server-side mapping rejects missing names, non-string SKUs and invalid copy counts before sending a request:

function mapReceivingLines(lines, templateId) {
const items = lines.map(line => {
if (typeof line.itemName !== 'string' || !line.itemName.trim() ||
typeof line.itemSku !== 'string' || !line.itemSku.trim() ||
!Number.isSafeInteger(line.labelCopies) || line.labelCopies < 1) {
throw new Error('Correct the selected receiving line before printing.');
}
return { quantity: line.labelCopies, data: {
name: line.itemName.trim(), sku: line.itemSku.trim()
}};
});
if (!items.length || items.reduce((sum, item) => sum + item.quantity, 0) > 1000) {
throw new Error('Choose between 1 and 1,000 labels for this batch.');
}
return { templateId, items };
}

Do not convert SKUs into numbers. An internal SKU such as 0001042 must keep its leading zeros. A Code 128 value is an internal identifier here; it does not create a registered retail GTIN.

For bin or asset tags, change the field mapping and the template together. Sending a bin field does not make it visible unless an element binds to bin.

Generate the PDF

Create the 50 × 30 mm template from the batch guide once. Use its ID in the mapped request and save that request as batch.json. Download one client below and set GOOKIT_API_KEY in your backend terminal.

Terminal window
node labels.mjs submit batch.json receiving-labels.pdf
# Or use Python instead:
# python3 labels.py submit batch.json receiving-labels.pdf

Run one client, once. It saves the returned job ID before polling. If polling or download stops, resume that job instead of submitting the receiving event again:

Terminal window
node labels.mjs resume receiving-labels.pdf.job.json receiving-labels.pdf

The expected output is Trail Bottle twice and Desk Tray once. The scripts use the independent developer-account path; keep the key on your server.

Return the file to the right station

Your receiving screen can show Preparing labels, then Download PDF when the saved job completes. Store the source line IDs, template ID, requested quantity and API job ID together so another shift can locate the result.

Downloading a PDF does not print it. Your print station still opens the file or passes it to its configured printing software. Test matching stock at Actual Size and scan the printed labels with the receiving device before enabling larger batches.

Make reprints deliberate

A damaged label should not require replaying the receipt. Offer a separate reprint action with its own copy count. Decide whether it should use the original data snapshot or current product data: the right choice for a historical lot may differ from a changed shelf price.

A timeout after submission leaves the result uncertain. Preserve the request record and any returned job ID; inspect the existing job before creating a replacement. Gookit’s public contract does not document an idempotency key for this POST.

The mapping above is a sample integration boundary, not a deployed ERP connection. Begin with one receiving station and validate its physical output before turning an event into an automatic trigger.