Skip to content

POST /v1/batch/generate

POST /v1/batch/generate

Generates up to 10 documents in one request. Each item is processed sequentially. Individual failures do not abort the batch.

HeaderRequiredDescription
AuthorizationYesBearer gk_your_api_key
Content-TypeYesapplication/json
{
"items": [
{
"data": { "client": { "name": "Acme Corp" }, "lineItems": [...] },
"template": "auto",
"modifications": ["Add a DRAFT watermark"],
"format": "pdf",
"style": "stripe-clean",
"options": {
"pageSize": "letter",
"orientation": "portrait",
"scale": 1
}
}
]
}
ParameterTypeRequiredDefaultDescription
itemsarrayYesArray of 1-10 item objects
FieldTypeRequiredDefaultDescription
dataobjectYesDocument data. Must have at least one key.
templatestringNo"auto"Template ID. "auto" selects based on data structure.
modificationsstring[]No[]AI modification prompts, applied sequentially. Max 1,000 chars each.
format"pdf" | "png"No"pdf"Output format
stylestringNoAuto-detected"stripe-clean", "bold", "minimal", or "corporate"
options.pageSizestringNo"letter""A4", "letter", or "legal"
options.orientationstringNo"portrait""portrait" or "landscape"
options.marginobjectNoCustom margins with top, bottom, left, right (CSS strings)
options.scalenumberNo1Scale factor, 0.1 to 3
{
"results": [
{
"index": 0,
"status": "success",
"url": "data:application/pdf;base64,JVBERi0...",
"filename": "invoice-0-1706000000000.pdf",
"size": 45230,
"format": "pdf",
"processingTimeMs": 2340
},
{
"index": 1,
"status": "error",
"error": "Data object cannot be empty",
"errorCode": "ITEM_GENERATION_FAILED",
"processingTimeMs": 12
}
],
"totalTimeMs": 4820,
"successCount": 1,
"failCount": 1
}
FieldTypePresentDescription
indexnumberAlwaysPosition in the input items array
status"success" | "error"AlwaysItem outcome
urlstringSuccessBase64 data URL of the generated file
filenamestringSuccessSuggested filename ({docType}-{index}-{timestamp}.{ext})
sizenumberSuccessFile size in bytes
formatstringSuccess"pdf" or "png"
processingTimeMsnumberAlwaysTime spent processing this item in milliseconds
errorstringErrorHuman-readable error message
errorCodestringErrorMachine-readable error code
FieldTypeDescription
resultsarrayOne result per input item, in order
totalTimeMsnumberTotal batch processing time in milliseconds
successCountnumberNumber of items that succeeded
failCountnumberNumber of items that failed
ConstraintValue
Max items per request10
Max modification prompt length1,000 characters
ProcessingSequential (not parallel)

Returned when the request body fails schema validation (before any items are processed).

{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": [
{ "path": ["items"], "message": "At least one item is required" }
]
}

Returned on unexpected server errors.

{
"error": "Unexpected error message",
"code": "BATCH_ERROR"
}

Items that fail get "status": "error" with errorCode: "ITEM_GENERATION_FAILED". The batch continues processing remaining items.

Failed modifications within an item are skipped silently — the document generates using the last successful HTML state.

Terminal window
curl -X POST https://api.glyph.you/v1/batch/generate \
-H "Authorization: Bearer gk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"data": {
"client": { "name": "Acme Corp" },
"lineItems": [{ "description": "Consulting", "quantity": 10, "unitPrice": 150, "total": 1500 }],
"totals": { "subtotal": 1500, "total": 1500 }
},
"style": "stripe-clean",
"modifications": ["Add a watermark saying DRAFT"]
},
{
"data": {
"client": { "name": "Globex Inc" },
"lineItems": [{ "description": "License", "quantity": 1, "unitPrice": 12000, "total": 12000 }],
"totals": { "subtotal": 12000, "total": 12000 }
},
"style": "corporate"
}
]
}'
const response = await fetch('https://api.glyph.you/v1/batch/generate', {
method: 'POST',
headers: {
'Authorization': 'Bearer gk_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: invoices.map(invoice => ({
data: invoice,
style: 'stripe-clean',
format: 'pdf',
})),
}),
});
const { results, successCount, failCount } = await response.json();
for (const result of results) {
if (result.status === 'success') {
console.log(`Item ${result.index}: ${result.filename} (${result.size} bytes)`);
} else {
console.error(`Item ${result.index} failed: ${result.error}`);
}
}
import { writeFileSync, mkdirSync } from 'fs';
mkdirSync('output', { recursive: true });
const response = await fetch('https://api.glyph.you/v1/batch/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GLYPH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: invoices.map(inv => ({ data: inv, format: 'pdf' })),
}),
});
const { results } = await response.json();
for (const result of results) {
if (result.status === 'success') {
const buffer = Buffer.from(result.url.split(',')[1], 'base64');
writeFileSync(`output/${result.filename}`, buffer);
}
}