DocPeeldocs

SDK Examples

End-to-end snippets for the most common workflows, in JavaScript and Python.

Process a single PDF (Node)

import { DocPeel } from '@doc-peel/sdk';
import fs from 'node:fs';

const client = new DocPeel({ apiKey: process.env.DOCPEEL_API_KEY });

// DocPeel takes documents as base64 in a JSON body.
const fileB64 = fs.readFileSync('./invoice.pdf').toString('base64');

const result = await client.extractions.create({
  file:     fileB64,
  fileName: 'invoice.pdf',
});

console.log(`Total: ${result.fields.find(f => f.field === 'Total')?.value}`);

Browser — upload from a form

// app/upload/page.tsx
'use client';

export default function Upload() {
  async function onFile(e) {
    const file = e.target.files[0];
    if (!file) return;

    // Read & base64-encode in the browser, then POST as JSON to your backend.
    const buf  = await file.arrayBuffer();
    const b64  = btoa(String.fromCharCode(...new Uint8Array(buf)));

    const res = await fetch('/api/extract', {
      method:  'POST',
      headers: { 'content-type': 'application/json' },
      body:    JSON.stringify({
        file:         b64,
        file_name:    file.name,
        content_type: file.type,
      }),
    });
    const data = await res.json();
    console.log(data);
  }
  return <input type="file" onChange={onFile} />;
}

Process every file in a folder (batch)

import { DocPeel } from '@doc-peel/sdk';
import fs from 'node:fs/promises';
import path from 'node:path';
import pLimit from 'p-limit';

const client = new DocPeel({ apiKey: process.env.DOCPEEL_API_KEY });
const limit  = pLimit(5);  // 5 concurrent extractions

const files = await fs.readdir('./inbox');
const results = await Promise.all(files.map(name => limit(async () => {
  try {
    const buf = await fs.readFile(path.join('./inbox', name));
    return await client.extractions.create({
      file:     buf.toString('base64'),
      fileName: name,
    });
  } catch (err) {
    console.error(`${name} failed:`, err.message);
    return null;
  }
})));

Retry on rate limit

import { DocPeel, DocPeelError } from '@doc-peel/sdk';

async function withRetry(fn, max = 5) {
  let delay = 1000;
  for (let i = 0; i < max; i++) {
    try { return await fn(); }
    catch (e) {
      if (!(e instanceof DocPeelError) || ![429, 500, 503].includes(e.status) || i === max - 1) throw e;
      await new Promise(r => setTimeout(r, delay + Math.random() * 250));
      delay *= 2;
    }
  }
}

Python — process a single PDF

import base64
from docpeel import DocPeel

client = DocPeel()  # reads DOCPEEL_API_KEY

with open("invoice.pdf", "rb") as f:
    file_b64 = base64.b64encode(f.read()).decode("ascii")

result = client.extractions.create(
    file_b64=file_b64,
    file_name="invoice.pdf",
    template_id="tpl_invoice",
)

total = next((f.value for f in result.fields if f.field == "Total"), None)
print(f"Total: {total}")

Python — batch a folder with a thread pool

import base64
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from docpeel import DocPeel, DocPeelError

client = DocPeel()
inbox  = Path("./inbox")

def process(path: Path):
    try:
        b64 = base64.b64encode(path.read_bytes()).decode("ascii")
        return client.extractions.create(file_b64=b64, file_name=path.name)
    except DocPeelError as e:
        print(f"{path.name} failed: {e.code} {e.message}")
        return None

with ThreadPoolExecutor(max_workers=5) as pool:
    results = list(pool.map(process, inbox.glob("*.pdf")))

Python — exponential-backoff retry

import random, time
from docpeel import DocPeelError

def with_retry(fn, *args, max_attempts=5, **kwargs):
    delay = 1.0
    for attempt in range(max_attempts):
        try:
            return fn(*args, **kwargs)
        except DocPeelError as e:
            transient = e.status in (429, 500, 503)
            if not transient or attempt == max_attempts - 1:
                raise
            time.sleep(delay + random.random() * 0.25)
            delay *= 2