Document Stack
Document Stack
Docs

Express Integration

Generate PDFs from Express.js applications with the Document Stack Node.js SDK.

Setup

Bash
npm install express @document-stack/sdk-node
src/client.ts
import { DocumentStack } from "@document-stack/sdk-node";

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

Generate Endpoint

src/routes/pdf.ts
import { Router } from "express";
import { dsClient } from "../client";

const router = Router();

router.post("/generate", async (req, res) => {
    try {
        const { templateId, data } = req.body;

        if (!templateId) {
            return res.status(400).json({
                success: false,
                error: "templateId is required",
            });
        }

        const pdf = await dsClient.generate({ templateId, data });

        res.json({
            success: true,
            data: { url: pdf.url },
        });
    } catch (error) {
        console.error("PDF generation failed:", error);
        res.status(500).json({
            success: false,
            error: "Failed to generate PDF",
        });
    }
});

export default router;

Direct PDF Download

Stream the generated PDF directly as a download response:

Download Route
router.get("/download/:templateId", async (req, res) => {
    try {
        const pdf = await dsClient.generate({
            templateId: req.params.templateId,
            data: req.query,
        });

        const pdfResponse = await fetch(pdf.url);
        const buffer = Buffer.from(await pdfResponse.arrayBuffer());

        res.set({
            "Content-Type": "application/pdf",
            "Content-Disposition": 'attachment; filename="document.pdf"',
            "Content-Length": buffer.length,
        });

        res.send(buffer);
    } catch (error) {
        res.status(500).json({
            success: false,
            error: "Download failed",
        });
    }
});

Validation Middleware

Zod Validation
import { z } from "zod";

const generateSchema = z.object({
    templateId: z.string().min(1),
    data: z.record(z.unknown()).optional().default({}),
});

function validate(schema: z.ZodSchema) {
    return (req, res, next) => {
        const result = schema.safeParse(req.body);
        if (!result.success) {
            return res.status(400).json({
                success: false,
                error: result.error.issues[0].message,
            });
        }
        req.body = result.data;
        next();
    };
}

router.post("/generate", validate(generateSchema), async (req, res) => {
    const pdf = await dsClient.generate(req.body);
    res.json({ success: true, data: { url: pdf.url } });
});

Complete Example

src/index.ts
import express from "express";
import pdfRoutes from "./routes/pdf";

const app = express();
app.use(express.json());
app.use("/api/pdf", pdfRoutes);

app.listen(3001, () => {
    console.log("Server running on http://localhost:3001");
});

Production Checklist

Add authentication middleware, rate limiting, and CORS configuration before deploying to production.

Next Steps