SyntaxdocSyntaxdoc

API Reference

Complete API documentation for SyntaxDoc

Complete reference for all SyntaxDoc API endpoints.

Authentication

Include your API key in the X-API-Key header:

X-API-Key: sk_live_your_api_key

Alternatively, use the Authorization header with Bearer token:

Authorization: Bearer sk_live_your_api_key

Never expose your API key in client-side code. Always make API calls from your server.


PDF Generation

POST /pdf/generate

Generate a PDF from HTML files. This is the primary endpoint for PDF generation.

Endpoint: POST https://api.syntaxdoc.com/pdf/generate

Content-Type: multipart/form-data

Request Parameters

ParameterTypeRequiredDescription
filesFile[]YesHTML file(s) to convert. Must include index.html or at least one .html file
optionsJSON stringNoPDF generation options (see below)

Options Object

OptionTypeDefaultDescription
fileNamestring"document"Output filename (without .pdf extension)
formatstring"A4"Paper format: A4, Letter, Legal, Tabloid, A3, A5
orientationstring"portrait"portrait or landscape
widthstring-Custom width (e.g., "6in", "15cm") - overrides format
heightstring-Custom height (e.g., "9in", "20cm") - overrides format
marginobject{top:"1cm",...}Page margins
margin.topstring"1cm"Top margin
margin.rightstring"1cm"Right margin
margin.bottomstring"1cm"Bottom margin
margin.leftstring"1cm"Left margin
preferCSSPageSizebooleanfalseUse CSS @page size instead of format
hostbooleanfalseIf true, stores PDF and returns URL instead of binary
appointmentIdstring-Custom ID for caching (returns existing PDF if unchanged)
regeneratebooleanfalseForce regeneration even if appointmentId exists
userTypestring-"guest" or "registered" for access control
watermarkobject-Watermark configuration (see Watermarking)

Response

Without host: true - Returns PDF binary (application/pdf)

With host: true - Returns JSON:

{
  "url": "https://api.syntaxdoc.com/api/hosted-pdfs/abc123-uuid",
  "pdfId": "abc123-uuid",
  "expiresAt": "2024-12-12T14:32:00.000Z"
}

Example Request

const formData = new FormData();

// Add HTML file
const htmlContent = `
  <!DOCTYPE html>
  <html>
    <head>
      <style>
        body { font-family: Arial, sans-serif; padding: 40px; }
        h1 { color: #333; }
      </style>
    </head>
    <body>
      <h1>Invoice #1234</h1>
      <p>Thank you for your purchase!</p>
    </body>
  </html>
`;
formData.append('files', new Blob([htmlContent], { type: 'text/html' }), 'index.html');

// Add options
formData.append('options', JSON.stringify({
  fileName: 'invoice-1234',
  format: 'Letter',
  margin: { top: '0.5in', bottom: '0.5in', left: '0.75in', right: '0.75in' }
}));

const response = await fetch('https://api.syntaxdoc.com/pdf/generate', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sk_live_your_api_key',
  },
  body: formData
});

const blob = await response.blob();
curl -X POST https://api.syntaxdoc.com/pdf/generate \
  -H "X-API-Key: sk_live_your_api_key" \
  -F "files=@invoice.html" \
  -F 'options={"fileName": "invoice-1234", "format": "Letter"}' \
  --output invoice.pdf
import requests
import json

files = {
    'files': ('index.html', open('invoice.html', 'rb'), 'text/html')
}
data = {
    'options': json.dumps({
        'fileName': 'invoice-1234',
        'format': 'Letter',
        'margin': {'top': '0.5in', 'bottom': '0.5in'}
    })
}

response = requests.post(
    'https://api.syntaxdoc.com/pdf/generate',
    headers={'X-API-Key': 'sk_live_your_api_key'},
    files=files,
    data=data
)

with open('invoice.pdf', 'wb') as f:
    f.write(response.content)

POST /pdf/merge

Merge multiple PDF files into a single document.

Endpoint: POST https://api.syntaxdoc.com/pdf/merge

Content-Type: multipart/form-data

Request Parameters

ParameterTypeRequiredDescription
filesFile[]YesPDF files to merge (in order)
optionsJSON stringNoMerge options

Options

OptionTypeDefaultDescription
fileNamestring"merged-document"Output filename
hostbooleanfalseStore PDF and return URL

Example

const formData = new FormData();
formData.append('files', pdf1File, 'page1.pdf');
formData.append('files', pdf2File, 'page2.pdf');
formData.append('files', pdf3File, 'page3.pdf');
formData.append('options', JSON.stringify({ fileName: 'combined-document' }));

const response = await fetch('https://api.syntaxdoc.com/pdf/merge', {
  method: 'POST',
  headers: { 'X-API-Key': 'sk_live_your_api_key' },
  body: formData
});

const mergedPdf = await response.blob();

POST /pdf/generate-batch

Generate multiple PDFs from an array of HTML documents and receive them as a ZIP file.

Endpoint: POST https://api.syntaxdoc.com/pdf/generate-batch

Content-Type: application/json

Batch generation is optimized for high performance with browser reuse and parallel processing. Can generate 100+ PDFs in seconds!

Request Body

{
  "documents": [
    { "fileName": "certificate-john", "htmlContent": "<html>...</html>" },
    { "fileName": "certificate-jane", "htmlContent": "<html>...</html>" }
  ],
  "batchName": "certificates-december",
  "options": {
    "format": "A4",
    "landscape": true
  },
  "stream": false,
  "host": false
}
ParameterTypeRequiredDescription
documentsarrayYesArray of document objects (max batch size depends on your plan)
documents[].fileNamestringYesOutput filename for this PDF (without .pdf extension)
documents[].htmlContentstringYesHTML content to convert
batchNamestringNoName for the ZIP file (default: "batch-{timestamp}")
optionsobjectNoPDF options (applied to all documents) - same as /pdf/generate
streambooleanNoIf true, returns batchId for progress tracking
hostbooleanNoIf true, stores ZIP file and returns URL instead of binary

Each PDF in the batch counts as 1 conversion toward your usage limit. The API validates you have enough conversions before starting.

Response Options

Standard (no stream, no host) - Returns ZIP file immediately (application/zip)

With stream: true - Returns batch ID for progress tracking:

{
  "batchId": "abc123-batch-uuid",
  "total": 50,
  "message": "Batch processing started. Poll /pdf/progress/{batchId} for updates."
}

With host: true (without stream) - Returns hosted ZIP info after completion:

{
  "success": true,
  "message": "Batch generation completed",
  "documentsGenerated": 50,
  "downloadUrl": "https://api.syntaxdoc.com/api/hosted-pdfs/zip-abc123-uuid",
  "zipId": "zip-abc123-uuid",
  "expiresAt": "2024-12-12T14:32:00.000Z"
}

With both stream: true and host: true - Returns batch ID, then poll for hosted ZIP:

{
  "batchId": "abc123-batch-uuid",
  "total": 50
}

GET /pdf/progress/:batchId

Poll for batch generation progress (when stream: true was used).

Endpoint: GET https://api.syntaxdoc.com/pdf/progress/:batchId

Response

{
  "total": 50,
  "current": 25,
  "status": "processing",
  "message": "Generated 25/50 PDFs"
}

Status Values:

  • processing - Generation in progress
  • completed - All PDFs generated successfully
  • error - An error occurred during generation
  • not_found - Batch ID not found or expired

When status: "completed":

Without host: true:

{
  "total": 50,
  "current": 50,
  "status": "completed",
  "message": "Download URL: https://api.syntaxdoc.com/pdf/download/batch-abc123"
}

With host: true:

{
  "total": 50,
  "current": 50,
  "status": "completed",
  "message": "{\"downloadUrl\":\"https://api.syntaxdoc.com/api/hosted-pdfs/zip-abc123\",\"zipId\":\"zip-abc123\",\"expiresAt\":\"2024-12-12T14:32:00.000Z\",\"documentsGenerated\":50}"
}

GET /pdf/progress/:batchId/stream

Real-time progress updates via Server-Sent Events (SSE)

Endpoint: GET https://api.syntaxdoc.com/pdf/progress/:batchId/stream

Opens an SSE connection that pushes progress updates every 500ms.

Event Format

event: progress
data: {"total":50,"current":15,"status":"processing","message":"Generated 15/50 PDFs"}

event: progress
data: {"total":50,"current":32,"status":"processing","message":"Generated 32/50 PDFs"}

event: complete
data: {"total":50,"current":50,"status":"completed","message":"{\"downloadUrl\":\"...\"}"}

Event Types:

  • progress - Ongoing generation updates
  • complete - Batch finished (connection closes)
  • error - Error occurred (connection closes)

Example Usage

const eventSource = new EventSource(
  `https://api.syntaxdoc.com/pdf/progress/${batchId}/stream`
);

eventSource.addEventListener('progress', (event) => {
  const data = JSON.parse(event.data);
  console.log(`Progress: ${data.current}/${data.total} PDFs`);
  // Update your UI progress bar
});

eventSource.addEventListener('complete', (event) => {
  const data = JSON.parse(event.data);
  const result = JSON.parse(data.message);
  console.log('Download URL:', result.downloadUrl);
  eventSource.close();
});

eventSource.addEventListener('error', (event) => {
  console.error('Generation failed:', event.data);
  eventSource.close();
});
import EventSource from 'eventsource';

const eventSource = new EventSource(
  `https://api.syntaxdoc.com/pdf/progress/${batchId}/stream`
);

eventSource.addEventListener('progress', (event) => {
  const data = JSON.parse(event.data);
  console.log(`📄 Generated ${data.current}/${data.total} PDFs`);
});

eventSource.addEventListener('complete', (event) => {
  const data = JSON.parse(event.data);
  const result = JSON.parse(data.message);
  console.log('✅ Complete! Download:', result.downloadUrl);
  eventSource.close();
});

eventSource.on('error', (error) => {
  console.error('❌ Error:', error);
  eventSource.close();
});

Advanced Features: SyntaxDoc supports Webhooks for async batch notifications, Watermarking for document security, and QR Codes for verification and tracking.


QR Code Generation

POST /pdf/qrcode

Generate QR codes as standalone images or data URLs. Use this endpoint when you need QR codes outside of PDF generation.

For QR codes within PDFs, use the inline data-qr attribute instead - it's automatic! See QR Codes documentation.

Endpoint: POST https://api.syntaxdoc.com/pdf/qrcode

Content-Type: application/json

Request Body

{
  "data": "https://syntaxdoc.com/verify/cert-12345",
  "size": 300,
  "margin": 2,
  "errorCorrectionLevel": "H",
  "darkColor": "#000000",
  "lightColor": "#FFFFFF",
  "format": "png"
}
ParameterTypeRequiredDefaultDescription
datastringYes-URL or text to encode in the QR code
sizenumberNo200QR code size in pixels
marginnumberNo1White margin around QR code (0-10 modules)
errorCorrectionLevelstringNo"M"Error correction: L (~7%), M (~15%), Q (~25%), H (~30%)
darkColorstringNo"#000000"Dark modules color (hex format)
lightColorstringNo"#ffffff"Light modules color (hex format)
formatstringNo"png"Output format: png (binary) or dataUrl (base64 string)

Response

With format: "png" - Returns PNG image (image/png)

With format: "dataUrl" - Returns JSON with base64 data URL:

{
  "dataUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}

Example Request

// Get QR code as data URL
const response = await fetch('https://api.syntaxdoc.com/pdf/qrcode', {
  method: 'POST',
  headers: {
    'X-API-Key': 'sk_live_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    data: 'https://syntaxdoc.com/verify/cert-12345',
    size: 300,
    errorCorrectionLevel: 'H',
    format: 'dataUrl'
  })
});

const { dataUrl } = await response.json();
// Use dataUrl in <img src="..." />
# Download as PNG
curl -X POST https://api.syntaxdoc.com/pdf/qrcode \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"data":"https://syntaxdoc.com/verify/cert-12345","size":300}' \
  --output qrcode.png

# Get as data URL
curl -X POST https://api.syntaxdoc.com/pdf/qrcode \
  -H "X-API-Key: sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"data":"https://syntaxdoc.com/verify/cert-12345","format":"dataUrl"}'
import requests
import json

# Get as PNG buffer
response = requests.post(
    'https://api.syntaxdoc.com/pdf/qrcode',
    headers={'X-API-Key': 'sk_live_your_api_key'},
    json={
        'data': 'https://syntaxdoc.com/verify/cert-12345',
        'size': 300,
        'errorCorrectionLevel': 'H'
    }
)

with open('qrcode.png', 'wb') as f:
    f.write(response.content)

# Get as data URL
response = requests.post(
    'https://api.syntaxdoc.com/pdf/qrcode',
    headers={'X-API-Key': 'sk_live_your_api_key'},
    json={
        'data': 'https://syntaxdoc.com/verify/cert-12345',
        'format': 'dataUrl'
    }
)

data_url = response.json()['dataUrl']

Prefer inline QR codes: For PDFs, use <img data-qr="..." /> in your HTML instead of this endpoint. It's simpler and automatic!


PDF Retrieval

GET /pdf/view/:id

View a PDF in the browser.

GET https://api.syntaxdoc.com/pdf/view/abc123-uuid

Returns PDF with Content-Disposition: inline.


GET /pdf/download/:id

Download a PDF file.

GET https://api.syntaxdoc.com/pdf/download/abc123-uuid

Returns PDF with Content-Disposition: attachment.


GET /pdf/metadata/:id

Get metadata for a shared PDF.

{
  "userType": "guest",
  "expires": "2024-12-12T14:32:00.000Z",
  "fileName": "invoice",
  "originalName": "invoice.pdf",
  "requiresAuth": false,
  "isShared": true
}

Hosted PDFs

GET /api/hosted-pdfs/:pdfId

View or download a hosted PDF.

GET https://api.syntaxdoc.com/api/hosted-pdfs/abc123-uuid

No authentication required for public PDFs. Increments download counter.


GET /api/hosted-pdfs/:pdfId/metadata

Get metadata for a hosted PDF (no authentication required).

{
  "id": "mongodb-id",
  "pdfId": "abc123-uuid",
  "originalName": "invoice.pdf",
  "fileSize": 125000,
  "url": "https://api.syntaxdoc.com/api/hosted-pdfs/abc123-uuid",
  "expiresAt": "2024-12-12T14:32:00.000Z",
  "isPublic": true,
  "downloads": 15,
  "createdAt": "2024-12-05T14:32:00.000Z"
}

GET /api/hosted-pdfs/list

List your hosted PDFs (requires authentication via session cookie).

Query Parameters:

ParameterTypeDefaultDescription
pagenumber1Page number
limitnumber20Items per page

Response:

{
  "success": true,
  "data": {
    "pdfs": [...],
    "total": 45
  },
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

GET /api/hosted-pdfs/stats

Get your hosted PDF statistics (requires session).

{
  "success": true,
  "data": {
    "totalHosted": 25,
    "totalDownloads": 150,
    "totalSize": 52428800
  }
}

DELETE /api/hosted-pdfs/:pdfId

Delete a hosted PDF (requires session).

{
  "success": true,
  "message": "PDF deleted successfully"
}

Error Response Format

All errors return JSON:

{
  "statusCode": 400,
  "code": "BAD_REQUEST",
  "message": "No files uploaded. Please upload at least one HTML file with key \"files\"."
}
StatusCodeDescription
400BAD_REQUESTInvalid request parameters
401UNAUTHORIZEDInvalid or missing API key
404NOT_FOUNDResource not found
429QUOTA_EXCEEDEDAPI usage limit exceeded
429HOSTED_PDF_LIMIT_REACHEDHosted PDF storage limit reached
500INTERNAL_SERVER_ERRORServer error

On this page