Skip to content
CastPDF
API reference

Spreadsheets

Read a CSV or XLSX file with POST /v1/spreadsheets/parse and get its columns, a preview and a suggested mapping to a template's fields.

A spreadsheet is the easiest way to turn a list of people, orders or certificates into PDFs: one row becomes one PDF. POST /v1/spreadsheets/parse reads a CSV or XLSX file without making anything, so you can check what CastPDF sees in it, and which column will fill which template field, before you run it as a batch. The spreadsheets guide shows the whole flow, including how to prepare the file.

POST /v1/spreadsheets/parse

Reads a CSV or XLSX file and suggests which column fills which template field.

Request
curl https://api.castpdf.com/v1/spreadsheets/parse \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"filename\": \"people.csv\",
    \"content_base64\": \"$(base64 < people.csv | tr -d '\n')\",
    \"template_id\": \"8d1f2c3b-4a5e-4f60-9b7a-1c2d3e4f5a6b\"
  }"
import { readFile } from 'node:fs/promises';

const res = await fetch('https://api.castpdf.com/v1/spreadsheets/parse', {
  method: 'POST',
  headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    filename: 'people.csv',
    content_base64: (await readFile('people.csv')).toString('base64'),
    template_id: '8d1f2c3b-4a5e-4f60-9b7a-1c2d3e4f5a6b',
  }),
});
const sheet = await res.json();
console.log(sheet.row_count, sheet.mapping);
import base64
import requests

with open("people.csv", "rb") as f:
    content = base64.b64encode(f.read()).decode()

res = requests.post(
    "https://api.castpdf.com/v1/spreadsheets/parse",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "filename": "people.csv",
        "content_base64": content,
        "template_id": "8d1f2c3b-4a5e-4f60-9b7a-1c2d3e4f5a6b",
    },
    timeout=60,
)
sheet = res.json()
print(sheet["row_count"], sheet["mapping"])
200
{
  "format": "csv",
  "columns": ["Name", "Course", "Email"],
  "row_count": 248,
  "max_rows": 500,
  "preview": [{ "Name": "Ada Lovelace", "Course": "Safety training", "Email": "[email protected]" }],
  "fields": ["name", "course", "date"],
  "mapping": { "name": "Name", "course": "Course", "date": null }
}
FieldDescription
filenamestringRequiredThe file name, up to 255 characters, ending in .csv, .tsv, .txt or .xlsx.
content_base64stringRequiredThe file, base64-encoded, at most 5 MB before encoding.
template_idstring (UUID)Optional: the template to map to (the version renders use: the pinned one, or else the current one).

How the file is read:

  • The first row holds the column names; empty rows are skipped. CSV may use commas, semicolons or tabs and must be UTF-8. XLSX: the first sheet; cells formatted as dates become YYYY-MM-DD. Old .xls files are not supported (save as .xlsx or .csv).
  • Rows per file are limited like batch items: Free 25, Starter 500, Growth 1,000, Pro 2,500 and Scale 5,000. max_rows in the answer is your plan's number.
  • Template fields are the plain values in the template's sample data, by their dotted path (customer.name), up to 200; lists are not mapped, because one row cannot fill a list. A column matches a field when their names agree, ignoring case, spaces and punctuation, or when it matches the field's last part (name for customer.name).
  • Spreadsheet files are read in memory and not stored.
FieldDescription
formatstringcsv or xlsx.
columnsarray of stringsThe column names, in order.
row_countintegerThe data rows (without the header row).
max_rowsintegerThe most rows your plan runs at a time.
previewarray of objectsThe first 5 rows, column name to value.
fieldsarray of stringsThe template's fields; empty without template_id.
mappingobjectEach field's suggested column, or null when no column matches.

Running it. Send the same file as spreadsheet to POST /v1/batches, with mapping (field to column; without it, the suggested mapping is used, or every column under its own name when the template has no sample data) and, to email each PDF, email_column. Cells left empty are left out of that row's data, so the template's own fallbacks apply.

CodeWhen
invalid_request (400)Not valid base64, an unreadable file or an unsupported type, a header row without data rows, over 5 MB (details.limit: "spreadsheet_bytes"), too many rows ("spreadsheet_rows"), columns ("spreadsheet_columns") or cells ("spreadsheet_cells")
template_not_found (404)The template does not exist
payload_too_large (413)The request body is too large for a file of the allowed size
Updated Something unclear? [email protected], a real person replies.