1. Home
  2. Guides
  3. PDF summary API with JavaScript

Summarize PDFs with JavaScript & Node.js — API Tutorial

Call the PDF Summarizer API from Node.js (or any server-side JavaScript runtime) with nothing more than fetch and FormData. This tutorial covers a first request, streaming, a small Express endpoint for your own app, and error handling.

Key facts
  • Works with Node.js 18+ (built-in fetch, FormData, Blob) — no SDK needed.
  • POST https://pdf-summarize.com/api/summarize.php, multipart/form-data, field file, header Authorization: Bearer sk_....
  • Options: length, format, outputLang, includeKeywords.
  • Add ?stream=1 and read the response body as Server-Sent Events.
  • Never expose your key in browser code — proxy requests through your server.
Updated 2 min read By the PDF Summarizer team

Your first request in Node.js

  1. Get a free API keySign up and copy it from your dashboard.
  2. Store it in an environment variablePDF_SUMMARIZE_KEY.
  3. Build a FormDataAppend the PDF as a Blob under the field file.
  4. POST it and read the JSON.
// summarize.mjs — node summarize.mjs report.pdf
import { readFile } from 'node:fs/promises';
import { basename } from 'node:path';

const API_URL = 'https://pdf-summarize.com/api/summarize.php';
const KEY = process.env.PDF_SUMMARIZE_KEY;

export async function summarizePdf(path, { length = 'medium', format = 'bullets', outputLang = 'auto' } = {}) {
  const form = new FormData();
  form.append('file', new Blob([await readFile(path)], { type: 'application/pdf' }), basename(path));
  form.append('length', length);
  form.append('format', format);
  form.append('outputLang', outputLang);

  const res = await fetch(API_URL, {
    method: 'POST',
    headers: { Authorization: `Bearer ${KEY}` },
    body: form,
    signal: AbortSignal.timeout(180_000),
  });
  const data = await res.json();
  if (!res.ok || !data.success) throw new Error(`${res.status}: ${data.error ?? JSON.stringify(data)}`);
  return data;
}

const result = await summarizePdf(process.argv[2]);
console.log(result.summary);
console.log(`${result.page_count} pages, ${result.processing_time}s, ${result.requests_remaining} requests left`);

Streaming the summary

export async function streamSummary(path, onText) {
  const form = new FormData();
  form.append('file', new Blob([await readFile(path)], { type: 'application/pdf' }), basename(path));
  form.append('length', 'long');

  const res = await fetch(API_URL + '?stream=1', { method: 'POST', headers: { Authorization: `Bearer ${KEY}` }, body: form });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);

  const decoder = new TextDecoder();
  let buffer = '';
  for await (const chunk of res.body) {
    buffer += decoder.decode(chunk, { stream: true });
    const lines = buffer.split('\n');
    buffer = lines.pop();
    for (const line of lines) {
      if (!line.startsWith('data: ')) continue;
      const payload = line.slice(6);
      if (payload === '[DONE]') return;
      const event = JSON.parse(payload);
      if (event.error) throw new Error(event.error);
      if (event.type === 'summary') onText(event.content);
    }
  }
}

await streamSummary('paper.pdf', (t) => process.stdout.write(t));

An Express endpoint for your own app

Your front-end uploads to your server, which adds the key and forwards the file:

import express from 'express';
import multer from 'multer';

const app = express();
const upload = multer({ limits: { fileSize: 20 * 1024 * 1024 } });

app.post('/summarize', upload.single('file'), async (req, res) => {
  if (!req.file) return res.status(400).json({ error: 'No file' });
  const form = new FormData();
  form.append('file', new Blob([req.file.buffer], { type: 'application/pdf' }), req.file.originalname);
  form.append('length', req.body.length ?? 'medium');
  const r = await fetch('https://pdf-summarize.com/api/summarize.php', {
    method: 'POST', headers: { Authorization: `Bearer ${process.env.PDF_SUMMARIZE_KEY}` }, body: form,
  });
  res.status(r.status).json(await r.json());
});

app.listen(3000);

Error handling

Status Meaning
400 Missing file, not a PDF, or page limit exceeded
401 Missing or invalid key
413 File too large
422 No readable text in the PDF
429 Rate limit or quota reached — retry later with backoff
500 Temporary summarization error — retry
See the engine in action firstTry the free web tool with one of your PDFs.
Try the tool →

Frequently asked questions

Can I call the API directly from the browser?

Technically yes, but your key would be visible to anyone. Proxy requests through your backend as in the Express example.

Does it work with Deno, Bun or Cloudflare Workers?

Yes — any runtime with standard fetch and FormData works the same way.

Is there a TypeScript SDK?

Not yet. The API is a single multipart endpoint, so a small typed wrapper around fetch is enough.

Where is the full reference?

In the API documentation, with all parameters and examples in several languages.

Written by the PDF Summarizer team, who build and run the extraction and summarization pipeline behind this site. We test every method described here on real documents. Last reviewed October 19, 2026. Found an error? Tell us.