Blog/Use cases

Generate a shipping label or packing slip PDF

Use cases··6 min read

Use POST /v1/pdf as the shipping label pdf api. Send HTML or a published Handlebars template, then set a tight page with options.format or options.width plus options.height. Tracking marks are a second call: POST /v1/barcodes returns PNG or SVG; it does not stamp bars onto the PDF. Compose the image in the HTML, or stamp it later. Stock logistics layouts already exist: Shipping Label (4×6 in), Packing Slip (A4), Bill of Lading (A4 landscape), and Delivery Note (Letter).

RelayPDF is not a carrier integration. There is no UPS, FedEx, or USPS label endpoint. You print a page you already designed. Chromium does the print. Host: https://api.relaypdf.com. Authorization: Bearer pdf_live_…. Provide exactly one of html, url, markdown, or templateId. HTML is UTF-8 JSON, not Base64. Query-string keys are rejected.

Tight page sizes

Default format is letter. Documented named values on https://relaypdf.com/docs/options are letter, A4, legal, tabloid, or another named Chromium format. There is no published format token named 4x6. For a thermal label, send custom width and height. The options table lists those two fields as “Custom page size.” Pair them with margin set to zero or a few millimeters so the face is not inset like a letterhead. landscape is a boolean and defaults to false. printBackground defaults to true; keep it on if the label uses a filled service chip or a dark rule.

preferCSSPageSize defaults to false. Set it true when the HTML already declares @page { size: … } and you want Chromium to honor that size instead of the format field. Request options on POST /v1/pdf override saved PDF options on a template for that job. scale is 0.1–2 and defaults to 1; do not use scale as a substitute for a 4×6 page. headerTemplate and footerTemplate exist for multi-page reports. Leave them off a 4×6 label. pageRanges is for subsetting; a single-face label does not need it.

Wait fields are the same as any other /v1/pdf job: waitUntil defaults to networkidle0; waitForSelector is a CSS selector or { selector, timeout, visible }; waitForTimeout max 30000; timeout is the Chromium budget, max 60000. Failed renders return render_failed and are not billed. url sources must be public; private, loopback, and metadata hosts are rejected.

DocumentPublic pagePaper on the live page
Shipping Label/pdf-templates/shipping-label/shipping-label4×6 in
Packing Slip/pdf-templates/logistics/packing-slipA4
Bill of Lading/pdf-templates/logistics/bill-of-ladingA4 (landscape on the layout)
Delivery Note/pdf-templates/delivery-note/delivery-noteLetter

Stock logistics templates

Shipping Label (galleryId shipping-label) is a ZIP-hero 4×6 face: destination postal code at display size, from and service on the head rule, tracking on the floor. Amber is reserved for the service chip. Sample keys: carrier, service, trackingNumber, shipFrom.{name,address,city,region,postalCode}, shipTo with the same address shape. The live page states it is a label, not a letterhead packing slip. Clone body: name plus galleryId shipping-label.

Packing Slip (galleryId packing-slip) is A4, crate-grid: ship-from and ship-to as facing cells, each SKU in a qty tile, tracking on the floor rail. Sample keys: orderNumber, shippedOn, carrier, trackingNumber, shipFrom, shipTo, items[].{sku,name,quantity}, notes. Bill of Lading (galleryId bill-of-lading) is an A4 landscape port-pair sheet: bolNumber, issuedOn, vessel, voyage, portOfLoading, portOfDischarge, shipper, consignee, cargo[{marks,description,packages,weightKg}]. Delivery Note (galleryId delivery-note) is Letter with ordered vs shipped columns: number, issuedOn, org.name, shipFrom, shipTo, items[{sku,name,ordered,shipped}], carrier, note.

None of those four stock samples include a barcode image field. The shipping-label page does not expose payment.qrImage. If you need Code 128 under the tracking rail, generate the image first and add an <img> to your own draft. Do not invent extra templateData keys on the stock layout and expect bars to appear.

Barcodes are a separate endpoint

Compose path one: embed the PNG or SVG in HTML (data URL, or the 24-hour file URL from response url) and POST /v1/pdf. Compose path two: POST /v1/pdf/stamp with exactly one of text or image after the PDF exists. Stamp position defaults to center. Product: https://relaypdf.com/pdf-tools/stamp. There is no pages or position field on CreateBarcodeRequest. Mixing stamp fields into a barcode body is invalid_request. Successful tools jobs, including barcode, are $0.005 on the published rate card. Failed jobs are not billed.

Render the label

Two documented sources for the same PDF endpoint. One-off HTML: send html plus options.width and options.height (and usually margin zeros). Repeatable face: clone the gallery item, publish, send templateId plus templateData. Request options override the stored page size for that job if you need to. filename must end with .pdf. response is binary (default), url, or async. url returns JSON with a public GET /v1/files/:id that expires in 24 hours and does not take a key. async returns 202; poll GET /v1/jobs/:id or set callbackUrl (https).

curl -X POST https://api.relaypdf.com/v1/barcodes
  -H "Authorization: Bearer pdf_live_…"
  -H "Content-Type: application/json"
  -d '{
    "type": "code128",
    "text": "OSM88412101842",
    "format": "png",
    "includetext": true,
    "scale": 3,
    "filename": "tracking.png"
  }'
  --output tracking.png
curl -X POST https://api.relaypdf.com/v1/pdf
  -H "Authorization: Bearer pdf_live_…"
  -H "Content-Type: application/json"
  -d '{
    "html": "<!doctype html><html><body style=\"margin:0;font:12px sans-serif\">
      <div style=\"padding:8px\"><strong>SHIP TO</strong><br>Westmere Gallery<br>
19 Crosby Street<br>New York NY 10013</div>
      <img src=\"https://example.com/tracking.png\" width=\"280\" /></body></html>",
    "filename": "label.pdf",
    "options": {
      "width": "4in",
      "height": "6in",
      "margin": { "top": "0", "right": "0", "bottom": "0", "left": "0" },
      "printBackground": true
    }
  }'
  --output label.pdf
curl -X POST https://api.relaypdf.com/v1/templates
  -H "Authorization: Bearer pdf_live_…"
  -H "Content-Type: application/json"
  -d '{
    "name": "Shipping Label Template",
    "galleryId": "shipping-label"
  }'
curl -X POST https://api.relaypdf.com/v1/pdf
  -H "Authorization: Bearer pdf_live_…"
  -H "Content-Type: application/json"
  -d '{
    "templateId": "shipping-label",
    "templateData": {
      "carrier": "OSM FREIGHT",
      "service": "GROUND",
      "trackingNumber": "OSM 8841 210 1842",
      "shipFrom": {
        "name": "Hearth & Cup Roastery",
        "address": "11 Court Street",
        "city": "Hudson",
        "region": "NY",
        "postalCode": "12534"
      },
      "shipTo": {
        "name": "Westmere Gallery",
        "address": "19 Crosby Street",
        "city": "New York",
        "region": "NY",
        "postalCode": "10013"
      }
    },
    "filename": "shipping-label.pdf"
  }'
  --output shipping-label.pdf
curl -X POST https://api.relaypdf.com/v1/pdf
  -H "Authorization: Bearer pdf_live_…"
  -H "Content-Type: application/json"
  -d '{
    "templateId": "packing-slip",
    "templateData": {
      "orderNumber": "PK-40931",
      "shippedOn": "2026-08-21",
      "carrier": "OSM FREIGHT",
      "trackingNumber": "OSM 8841 210 1842",
      "shipTo": {
        "name": "Westmere Gallery",
        "address": "19 Crosby Street",
        "city": "New York",
        "region": "NY",
        "postalCode": "10013"
      },
      "items": [
        { "sku": "FK-MUG-12OZ", "name": "12oz kiln mug", "quantity": 24 }
      ]
    },
    "filename": "packing-slip.pdf",
    "options": { "format": "A4", "printBackground": true }
  }'
  --output packing-slip.pdf

Packing slips vs labels

A packing slip is a pick document. Use format A4 (stock packing-slip) or letter (stock delivery-note). Keep printBackground true for the navy or crate-grid header. A shipping label is a small face. Use width and height, not letter. Do not send the packing-slip template and expect a 4×6 PDF because the live packing-slip page is A4. Do not send the shipping-label template and expect a SKU grid; that layout has no items array.

If you print both for one order, that is two /v1/pdf calls (or two async jobs). Merge afterwards with POST /v1/pdf/merge if you want one file for the pack station. Merge is a tools job. It does not change page size of either source. A 4×6 page and an A4 page in one PDF stay those sizes.

What this is not

This is not a carrier API, not rate shopping, and not postage. It is not OCR and not barcode read. POST /v1/pdf/text extracts an existing text layer only. It is not e-sign, PDF/A, or HIPAA. It is not POST /v1/images (screenshots) and not POST /v1/convert (Office). wkhtmltopdf is not a substitute for the Chromium page options on /v1/pdf.

CTA: start from the live 4×6 Shipping Label at https://relaypdf.com/pdf-templates/shipping-label/shipping-label or the A4 Packing Slip at https://relaypdf.com/pdf-templates/logistics/packing-slip. Page fields: https://relaypdf.com/docs/options. PDF body: https://relaypdf.com/docs/pdf. Barcodes: https://relaypdf.com/docs/barcodes. Hub: https://relaypdf.com/docs.

Ready to generate?

One API for HTML, Markdown, URLs, and Office. REST, SDK, CLI, or MCP.