Document Stack
Document Stack
Docs

Node.js SDK — Advanced

Advanced patterns for the Document Stack Node.js SDK: streaming, retries, batch generation, and TypeScript types.

Client Configuration

The client accepts several options beyond the API key:

Full Configuration
import { DocumentStack } from "@document-stack/sdk-node";

const client = new DocumentStack({
    apiKey: process.env.DS_API_KEY!,
    baseUrl: "https://api.documentstack.dev",  // custom base URL
    timeout: 30_000,        // request timeout in ms (default: 30s)
    maxRetries: 3,          // retry transient errors (default: 2)
    retryDelay: 1000,       // initial retry delay in ms
});

Streaming PDF Response

For large documents, stream the PDF directly instead of waiting for the full response:

Stream to File
import { createWriteStream } from "fs";

const stream = await client.generate({
    templateId: "tmpl_abc123",
    data: { items: largeItemList },
    stream: true,
});

const writer = createWriteStream("output.pdf");
stream.pipe(writer);

await new Promise((resolve, reject) => {
    writer.on("finish", resolve);
    writer.on("error", reject);
});

console.log("PDF saved to output.pdf");

Batch Generation

Generate multiple PDFs in parallel with controlled concurrency:

Batch Generate
const customers = [
    { name: "Alice", invoiceId: "INV-001" },
    { name: "Bob", invoiceId: "INV-002" },
    { name: "Charlie", invoiceId: "INV-003" },
];

// Process 5 at a time to respect rate limits
const concurrency = 5;
const results = [];

for (let i = 0; i < customers.length; i += concurrency) {
    const batch = customers.slice(i, i + concurrency);
    const batchResults = await Promise.all(
        batch.map((customer) =>
            client.generate({
                templateId: "tmpl_invoice",
                data: customer,
            })
        )
    );
    results.push(...batchResults);
}

console.log(`Generated ${results.length} PDFs`);

Rate Limits

When batch-generating, monitor the X-RateLimit-Remaining header and throttle accordingly. See Rate Limits for plan-specific quotas.

Error Handling

The SDK throws typed errors that you can catch and inspect:

Typed Error Handling
import { DocumentStack, DocumentStackError } from "@document-stack/sdk-node";

try {
    const pdf = await client.generate({
        templateId: "tmpl_invalid",
        data: {},
    });
} catch (error) {
    if (error instanceof DocumentStackError) {
        console.error("Status:", error.status);     // 404
        console.error("Message:", error.message);    // "Template not found"
        console.error("Request ID:", error.requestId);
    } else {
        console.error("Unexpected error:", error);
    }
}

TypeScript Types

The SDK exports full TypeScript types for all request and response objects:

Using Types
import type {
    GenerateParams,
    GenerateResult,
    Template,
    TemplateListParams,
    PaginatedResult,
} from "@document-stack/sdk-node";

const params: GenerateParams = {
    templateId: "tmpl_abc123",
    data: { name: "Alice" },
};

const result: GenerateResult = await client.generate(params);

Custom HTTP Client

You can pass a custom Axios instance for advanced networking needs like proxies or custom certificates:

Custom Axios Instance
import axios from "axios";
import { DocumentStack } from "@document-stack/sdk-node";

const httpClient = axios.create({
    proxy: { host: "proxy.company.com", port: 8080 },
});

const client = new DocumentStack({
    apiKey: process.env.DS_API_KEY!,
    httpClient,
});

Next Steps