Business API

Generate PDF

Request and response reference for POST /api/v1/generate-pdf

Endpoint

POST https://sheetstolabels.com/api/v1/generate-pdf
Content-Type: application/json
Authorization: Bearer <api_key>

Generate from one record

{
  "templateId": "custom-1234567890",
  "layout": { "type": "single" },
  "records": [
    {
      "variables": {
        "code": "ag193",
        "qrUrl": "https://example.com/ag193",
        "name": "Test Ambassador"
      }
    }
  ]
}

Single and batch generation use the same request shape. For one label, card, certificate, or other document, send one element in records.

Generate a batch

{
  "templateId": "custom-1234567890",
  "layout": {
    "type": "preset",
    "presetId": "avery-5160-compatible"
  },
  "records": [
    {
      "variables": {
        "code": "ag193",
        "qrUrl": "https://example.com/ag193",
        "name": "Alice Morgan"
      },
      "copies": 2
    },
    {
      "variables": {
        "code": "ag194",
        "qrUrl": "https://example.com/ag194",
        "name": "Ben Carter"
      }
    }
  ]
}

This example produces three output items in one PDF: two copies for Alice followed by one for Ben. Records remain in request order and are placed using the selected Avery-compatible preset. The request does not modify the saved template.

FieldRequiredDescription
templateIdYesA cloud-synced custom template owned by the API key account
layoutYesPrint arrangement using single, preset, or manual
recordsYesA non-empty array containing up to 250 records
records[].variablesYesTemplate values; each value must be a string, number, boolean, or null
records[].copiesNoNumber of adjacent copies for this record; an integer from 1 to 250, with a default of 1

The template defines one label or card. The required layout object determines how those items become PDF pages.

ModeChoose it whenPDF resultWhat you provide
singleYou need one item per page, including cards, badges, certificates, or roll labelsEvery item gets a page exactly the same size as the saved templateOnly type; there is no paper grid
presetYou print on a supported Avery or APLI-compatible sheetItems fill the preset's validated paper, grid, margins, and gapspresetId, plus optional startSlot for a partly used sheet
manualYour sheet stock or paper arrangement is not available as a presetItems fill the exact paper, grid, margins, and gaps supplied in the requestPaper, rows, columns, all margins and gaps, and optional startSlot

Start with single for a card or one-label-per-page workflow. Use preset whenever the matching sheet is available because it avoids copying physical measurements into your integration. Use manual only when you know the stock's exact measurements or need a custom paper size. All three modes affect only the current request; none of them changes the saved template.

Single label or card

{ "type": "single" }

The template width and height become the PDF page size. Each output item uses one page.

Avery or APLI preset

{
  "type": "preset",
  "presetId": "avery-5160-compatible",
  "startSlot": 1
}

The preset supplies the paper, expected label dimensions, grid, margins, and gaps. The template dimensions must match the selected preset. startSlot is optional and starts at 1; use it to skip previously used positions on a partial sheet.

Manual sheet layout

{
  "type": "manual",
  "paper": { "size": "Letter" },
  "grid": { "rows": 10, "columns": 3 },
  "spacingMm": {
    "top": 12.7,
    "right": 4.7625,
    "bottom": 12.7,
    "left": 4.7625,
    "gapX": 3.175,
    "gapY": 0
  },
  "startSlot": 1
}

Use Letter or A4, or provide custom paper dimensions:

{ "size": "Custom", "widthMm": 102, "heightMm": 76 }

Rows, columns, and all six spacing values are required in manual mode. The API rejects layouts that do not fit the template dimensions on the selected paper.

One request uses one template and returns one merged PDF. After copies are applied, a request can contain up to 250 output items and generate up to 25 pages. The JSON request body can be up to 1 MB. Split larger jobs into multiple requests. Trial requests may contain multiple records only when the requested layout keeps the final PDF to one page.

Successful response

HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="sheets-to-labels-ag193.pdf"
X-Request-Id: 6d70...
X-Record-Count: 1
X-Item-Count: 1
X-Page-Count: 1
X-Credits-Consumed: 1
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99

The response body is the complete PDF binary. X-Record-Count is the number of elements supplied in records; X-Item-Count includes copies. Business requests consume one Credit per generated PDF page, not per record or copy. Trial requests report X-Credits-Consumed: 0 and must fit on one page.

JavaScript example

import { writeFile } from 'node:fs/promises';

const response = await fetch('https://sheetstolabels.com/api/v1/generate-pdf', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SHEETS_TO_LABELS_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    templateId,
    layout: { type: 'single' },
    records: [
      { variables: firstCustomer },
      { variables: secondCustomer, copies: 2 },
    ],
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const pdf = Buffer.from(await response.arrayBuffer());
await writeFile('customer-batch.pdf', pdf);