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.
| Field | Required | Description |
|---|---|---|
templateId | Yes | A cloud-synced custom template owned by the API key account |
layout | Yes | Print arrangement using single, preset, or manual |
records | Yes | A non-empty array containing up to 250 records |
records[].variables | Yes | Template values; each value must be a string, number, boolean, or null |
records[].copies | No | Number of adjacent copies for this record; an integer from 1 to 250, with a default of 1 |
Print Layout
The template defines one label or card. The required layout object determines how those items become PDF pages.
| Mode | Choose it when | PDF result | What you provide |
|---|---|---|---|
single | You need one item per page, including cards, badges, certificates, or roll labels | Every item gets a page exactly the same size as the saved template | Only type; there is no paper grid |
preset | You print on a supported Avery or APLI-compatible sheet | Items fill the preset's validated paper, grid, margins, and gaps | presetId, plus optional startSlot for a partly used sheet |
manual | Your sheet stock or paper arrangement is not available as a preset | Items fill the exact paper, grid, margins, and gaps supplied in the request | Paper, 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: 99The 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);