Skip to main content

Node.js SDK

Official Node.js/TypeScript client for the qomplement API.

npm install qomplement

Source: github.com/Qomplement/qomplement-node Requires: Node.js 18+ · TypeScript types included

Quick Start

import { Qomplement } from "qomplement";

const client = new Qomplement("sd_your_api_key");

const result = await client.extract("invoice.pdf");
console.log(result.fields); // { invoice_number: '12345', total: '1500.50' }
console.log(result.documentType); // 'invoice'
console.log(result.confidence); // 94

Authentication

Pass your API key directly or set the QOMPLEMENT_API_KEY environment variable:

// Option 1: Direct
const client = new Qomplement("sd_your_api_key");

// Option 2: Environment variable
// QOMPLEMENT_API_KEY=sd_your_api_key
const client = new Qomplement();

Get your API key at developers.qomplement.com/keys.

Extract

Extract structured data from any document (PDF, DOCX, XLSX, images, and 30+ formats).

const result = await client.extract("invoice.pdf");

console.log(result.fields); // Extracted key-value pairs
console.log(result.tables); // Tables found
console.log(result.documentType); // Detected document type
console.log(result.language); // Detected language
console.log(result.confidence); // 0-100 confidence score
console.log(result.pagesProcessed); // Number of pages
console.log(result.processingTimeMs);

Options

// Use High Precision model
const result = await client.extract("complex_doc.pdf", {
model: "qomplement-OCR-XL-v1",
});

// Guided extraction with schema
const result = await client.extract("invoice.pdf", {
schema: [
{ name: "invoice_number", type: "string" },
{ name: "total_amount", type: "number" },
{ name: "date", type: "date" },
],
});

// Full AI detail (entities, summary)
const result = await client.extract("report.pdf", { detail: true });
console.log(result.detail.entities);
console.log(result.detail.summary);

// Text chunking
const result = await client.extract("long_doc.pdf", {
chunkSize: 1000,
chunkOverlap: 200,
});
result.chunks?.forEach((c) => console.log(c.text));

// CSV or XML output
const result = await client.extract("invoice.pdf", { outputFormat: "csv" });

Extract from Buffer

import * as fs from "fs";

const buffer = fs.readFileSync("document.pdf");
const result = await client.extract(buffer);

Fill PDF

Fill PDF forms using source documents, natural language instructions, or explicit mappings.

From a source document

import * as fs from "fs";

const result = await client.fillPDF("form.pdf", {
source: "invoice.pdf",
});

fs.writeFileSync("filled_form.pdf", result.fileBuffer);
console.log(`Filled ${result.fieldsFilled}/${result.fieldsTotal} fields`);

With natural language instructions

const result = await client.fillPDF("contract.pdf", {
instructions: "Fill client name as 'Acme Corporation' and date as January 15, 2026",
});
fs.writeFileSync("filled_contract.pdf", result.fileBuffer);

With explicit field mappings

const result = await client.fillPDF("form.pdf", {
fieldMappings: {
client_name: "Acme Corp",
invoice_date: "2026-01-15",
total: "1500.50",
},
});
fs.writeFileSync("filled_form.pdf", result.fileBuffer);

Field details

result.fieldDetails.forEach((f) => {
console.log(`${f.fieldName}: ${f.value} (confidence: ${f.confidence})`);
});

Fill Excel

Fill Excel templates using source documents or instructions.

// From source document
const result = await client.fillExcel("template.xlsx", {
source: "invoice.pdf",
});
fs.writeFileSync("filled_template.xlsx", result.fileBuffer);
console.log(`Wrote ${result.cellsWritten} cells in ${result.sheetsModified}`);

// With instructions
const result = await client.fillExcel("template.xlsx", {
instructions: "Add company name as Acme Corp in the header, total as $1500",
});
fs.writeFileSync("filled.xlsx", result.fileBuffer);

Fill modes

ModeDescription
smartAI decides the best strategy (default)
appendAdd new rows without modifying existing data
overwriteReplace existing cell values
const result = await client.fillExcel("template.xlsx", {
source: "invoice.pdf",
fillMode: "append",
});

Async Jobs

Large documents (>5 pages) are processed asynchronously. By default, the SDK waits for completion. Set wait: false to return immediately:

// Non-blocking
const job = await client.extract("large_document.pdf", { wait: false });
console.log(job.id); // Job ID
console.log(job.status); // 'processing'

// Check later
const status = await client.getJob(job.id);
if (status.status === "completed") {
console.log(status.result);
}

// List your jobs
const jobs = await client.listJobs({ status: "completed", type: "extract", limit: 10 });
jobs.forEach((j) => console.log(`${j.id}: ${j.type}${j.status}`));

// Download filled files
const buffer = await client.download(job.id);
fs.writeFileSync("output.pdf", buffer);

Usage & Info

// Current month usage
const usage = await client.usage();
console.log(`Requests: ${usage.requests}`);
console.log(`Pages: ${usage.pagesProcessed}`);
console.log(`PDFs filled: ${usage.pdfsFilled}`);

// Specific month
const usage = await client.usage("2026-02");

// Available models
const models = await client.models();
models.forEach((m) => console.log(`${m.id}: ${m.description}`));

// Supported formats (33+)
const formats = await client.formats();
console.log(formats.total_formats);

Error Handling

import {
Qomplement,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
TimeoutError,
QomplementError,
} from "qomplement";

const client = new Qomplement("sd_your_api_key");

try {
const result = await client.extract("document.pdf");
} catch (err) {
if (err instanceof AuthenticationError) {
console.log("Invalid API key");
} else if (err instanceof RateLimitError) {
console.log(`Rate limited — retry after ${err.retryAfter}s`);
} else if (err instanceof ValidationError) {
console.log(`Bad request: ${err.message}`);
} else if (err instanceof NotFoundError) {
console.log("Resource not found");
} else if (err instanceof TimeoutError) {
console.log("Job took too long");
} else if (err instanceof QomplementError) {
console.log(`API error ${err.statusCode}: ${err.message}`);
}
}
Error ClassTrigger
AuthenticationErrorInvalid or missing API key (401/403)
RateLimitErrorToo many requests (429)
ValidationErrorInvalid parameters (422)
NotFoundErrorJob or resource not found (404)
TimeoutErrorJob exceeds maxWait
QomplementErrorAny other API error

Configuration

const client = new Qomplement("sd_your_api_key", {
timeout: 120_000, // Request timeout in ms (default: 300,000)
maxWait: 300_000, // Max async job wait in ms (default: 600,000)
});

Environment variables

VariableDescription
QOMPLEMENT_API_KEYAPI key (alternative to passing directly)
QOMPLEMENT_BASE_URLOverride API base URL

TypeScript Types

All types are exported from the package:

import type {
ExtractResult,
FillPDFResult,
FillExcelResult,
FieldDetail,
Job,
UsageInfo,
QomplementOptions,
ExtractOptions,
FillPDFOptions,
FillExcelOptions,
} from "qomplement";