Mailjet is an email delivery service. In this post I will show how we can use this platform to deliver programatically generated PDFs via email. To achieve that we’re going to use Node.js together with following libraries:

  • node-mailjet – as a wrapper over the Mailjet API
  • pdfkit – to generate PDF files
  • base64-stream – to convert generated PDF into a Base64 string which is required by Mailjet

First let’s write a function to generate a Base64 encoded PDF file using PDFKit.

import PDFDocument from "pdfkit";
import { Base64Encode } from "base64-stream";

async function generatePdf(userName: string): Promise<string> {
  // we wrap everything with a Promise to make a nice interface 
  // to just await a PDF content
  return new Promise((resolve, reject) => { 
    console.time("pdf"); // we can track how long it took to generate a PDF
    const doc = new PDFDocument();
    const stream = doc.pipe(new Base64Encode());
    let finalString = ""; // we collect the actual stream data in this variable
      .fontSize(24) // we can configure different font size for the first line
      .text("Order confirmation")
      .text(`Hello ${userName}. We just received your order`)
      .end(); // this will trigger the "end" event on the stream

    stream.on("data", (chunk) => {
      finalString += chunk;

    stream.on("end", () => {
      console.timeEnd("pdf"); // on my machine it took 32ms

    stream.on("error", (err) => {

The result is going to look something like this:


Now that we have a function to generate a PDF we can use Mailjet API to send the email:

import Mailjet from "node-mailjet";

// ...

async function main(sendToEmail: string, sendToName: string) {
  const apiKey = process.env.MAILJET_API_KEY as string;
  const apiSecret = process.env.MAILJET_API_SECRET as string; 
  const mailjet = Mailjet.apiConnect(apiKey, apiSecret);

  const pdfContent = await generatePdf("John Doe");
  await"send", { version: "v3.1" }).request({
    Messages: [
        From: {
          Email: "",
          Name: "Delivery",
        To: [
            Email: sendToEmail,
            Name: sendToName,
        Subject: "Order confirmation",
          "Dear receiver. Here's a confirmation or your order",
        Attachments: [
            ContentType: "application/pdf",
            FileName: "confirmation.pdf",
            Base64Content: pdfContent,

And if we call the function and check our email we can see the email looks like on the screenshots below:

That’s how it looks in the email client
And that’s the actual PDF file


I'm a software engineer with 9 years of experience. I highly value team work and focus a lot on knowledge sharing aspects within teams. I also support companies with technical interview process. On top of that I read psychological books in my spare time and find other people fascinating.