The official Node.js SDK for the Parselyze document parsing API.
npm install parselyzeFirst, get your API key from your Parselyze dashboard.
import { Parselyze } from 'parselyze';
const parselyze = new Parselyze('plz_your_api_key_here');Recommended: Async Processing
import { Parselyze } from 'parselyze';
const parselyze = new Parselyze('plz_your_api_key_here');
// Submit document for async processing
const job = await parselyze.documents.parseAsync({
file: './invoice.pdf',
templateId: 'your-template-id'
});
console.log(job.jobId); // Save this for later
// Get result when ready (or use webhooks)
const result = await parselyze.jobs.get(job.jobId);
if (result.status === 'completed') {
console.log(result.result);
}Synchronous Processing
const result = await parselyze.documents.parse({
files: ['./invoice.pdf'],
templateId: 'your-template-id'
});
console.log(result);The SDK accepts multiple input types:
For Async Processing (Recommended):
// Single file - File path (recommended for Node.js)
file: './document.pdf'
// Buffer object
file: bufferData // e.g., fs.readFileSync('./document.pdf')
// File object (browser)
file: fileInput.files[0]
// Blob object
file: new Blob([data], { type: 'application/pdf' })For Sync Processing:
// Multiple files as array
files: ['./document.pdf', './receipt.jpg']
// Mixed types
files: ['./invoice.pdf', bufferData, fileObject]The SDK is fully typed:
import { Parselyze, AsyncJobResponse, JobDetailResponse, JobStatus, WebhookPayload } from 'parselyze';
const parselyze = new Parselyze('plz_your_api_key_here');
// Async processing
const job: AsyncJobResponse = await parselyze.documents.parseAsync({
file: './invoice.pdf',
templateId: 'template-id',
language: 'en' // optional
});
const result: JobDetailResponse = await parselyze.jobs.get(job.jobId);
// result.status is typed as JobStatus: 'pending' | 'processing' | 'completed' | 'failed'
// Webhook payload with typed result
interface InvoiceData { number: string; total: number; }
const event: WebhookPayload<InvoiceData> = parselyze.webhooks.constructEvent<InvoiceData>(body, signature);
// event.result is InvoiceData | undefinedimport { ParselyzeError } from 'parselyze';
try {
const job = await parselyze.documents.parseAsync({
file: './document.pdf',
templateId: 'template-id'
});
const result = await parselyze.jobs.get(job.jobId);
if (result.status === 'failed') {
console.error('Processing failed:', result.error);
}
} catch (error) {
if (error instanceof ParselyzeError) {
console.error('Parselyze Error:', error.message);
}
}For large documents or when you don't need immediate results, use asynchronous processing. Results will be delivered via webhooks or can be retrieved later.
const job = await parselyze.documents.parseAsync({
file: './large-invoice.pdf', // Single file only
templateId: 'your-template-id',
language: 'en' // optional
});
console.log(job.jobId); // Save this for later: "job_abc123"
console.log(job.status); // "pending"const jobDetails = await parselyze.jobs.get('job_abc123');
console.log(jobDetails.status); // 'pending', 'processing', 'completed', or 'failed'
if (jobDetails.status === 'completed') {
console.log(jobDetails.result); // Parsed data
console.log(jobDetails.pageCount); // Number of pages processed
} else if (jobDetails.status === 'failed') {
console.error(jobDetails.error); // Error message
}Instead of polling for job status, configure webhooks in your Parselyze dashboard to receive real-time notifications when jobs complete.
Webhook Payload:
{
"eventId": "evt_123",
"eventType": "document.completed",
"jobId": "job_abc123",
"status": "completed",
"result": { ... },
"pageCount": 3,
"timestamp": "2026-02-15T12:00:00Z"
}Handle Webhooks with constructEvent (Recommended):
constructEvent verifies the signature and returns a typed payload in one step. It throws a ParselyzeError if the signature is invalid, making error handling explicit.
import { Parselyze, ParselyzeError, WebhookPayload } from 'parselyze';
const parselyze = new Parselyze('plz_your_api_key', process.env.PARSELYZE_WEBHOOK_SECRET);
// Express — use express.raw() to preserve the raw body for signature verification
app.post('/webhooks/parselyze', express.raw({ type: 'application/json' }), (req, res) => {
let event: WebhookPayload;
try {
event = parselyze.webhooks.constructEvent(
req.body.toString(),
req.headers['x-webhook-signature'] as string
);
} catch (err) {
if (err instanceof ParselyzeError) {
return res.status(err.status ?? 400).send(err.message);
}
return res.status(400).send('Webhook error');
}
if (event.eventType === 'document.completed') {
console.log('Job completed:', event.jobId, event.result);
} else if (event.eventType === 'document.failed') {
console.error('Job failed:', event.jobId, event.error);
}
res.json({ received: true });
});Type the result with a generic:
interface InvoiceData { number: string; total: number; }
const event = parselyze.webhooks.constructEvent<InvoiceData>(body, signature);
// event.result is InvoiceData | undefined
if (event.eventType === 'document.completed') {
console.log(event.result?.number); // fully typed
}Verify signature only (low-level):
// Returns true/false without throwing
const isValid = parselyze.webhooks.verifySignature(req.body, signature);Submit a document for asynchronous processing. Use this for large documents or when you don't need immediate results.
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
File|Blob|Buffer|string |
✅ | Single file to parse (path, File, Buffer, or Blob) |
templateId |
string |
✅ | Template ID for data extraction |
language |
string |
❌ | OCR language code (e.g., 'en', 'fr', 'de') |
Returns:
{
jobId: string;
status: JobStatus; // 'pending' | 'processing' | 'completed' | 'failed'
message: string; // Status message
createdAt: string; // ISO 8601 timestamp
}Get the status and result of an asynchronous job.
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId |
string |
✅ | Job ID from parseAsync() |
Returns:
{
jobId: string;
status: JobStatus; // 'pending' | 'processing' | 'completed' | 'failed'
fileName: string; // Original filename
templateId: string; // Template used
result: T; // Parsed data (null if not completed)
error: string | null; // Error message (null if no error)
pageCount: number | null;
attempts: number; // Number of processing attempts
createdAt: string; // ISO 8601 timestamp
startedAt: string | null;
completedAt: string | null;
}Parse documents synchronously using a template to extract structured data.
| Parameter | Type | Required | Description |
|---|---|---|---|
files |
Array |
✅ | Files to parse (paths, File, Buffer, or Blob) |
templateId |
string |
✅ | Template ID for data extraction |
language |
string |
❌ | OCR language code (e.g., 'en', 'fr', 'de') |
Returns:
Single document:
{
result: any; // Extracted data
pageCount: number; // Pages processed
pageUsed: number; // Pages consumed
pageRemaining: number; // Pages remaining
}Multiple documents:
{
results: Array<{ // Array of results
filename: string;
result: any;
}>;
pageCount: number; // Total pages processed
pageUsed: number; // Pages consumed
pageRemaining: number; // Pages remaining
source?: 'zip'; // Present if from ZIP
}Verify the webhook signature and parse the payload into a typed event. Throws a ParselyzeError if the signature is invalid.
| Parameter | Type | Required | Description |
|---|---|---|---|
body |
string|object |
✅ | Raw webhook payload string or parsed object |
signature |
string |
✅ | Signature from X-Webhook-Signature header |
Returns: WebhookPayload<T> — typed event payload
Throws: ParselyzeError with code INVALID_SIGNATURE (401) or INVALID_PAYLOAD (400)
Low-level signature verification. Returns true/false without throwing.
| Parameter | Type | Required | Description |
|---|---|---|---|
body |
string|object |
✅ | Webhook payload (parsed object or raw string) |
signature |
string |
✅ | Signature from X-Webhook-Signature header |
Returns: boolean
- Documents: PDF
- Images: JPG, PNG
- Archives: ZIP
- Node.js 18.0.0 or higher
MIT License. See the LICENSE file for details.