Skip to main content

Installation

npm install parsefy zod hono
  • parsefy: Parsefy SDK for document extraction
  • zod: TypeScript-first schema validation library
  • hono: Lightweight web framework for the edge (Cloudflare, Vercel, Deno)

Environment setup

export PARSEFY_API_KEY=pk_your_api_key

Basic setup

import { Hono } from 'hono';
import { Parsefy } from 'parsefy';
import * as z from 'zod';

const app = new Hono();
const client = new Parsefy();

const invoiceSchema = z.object({
  invoice_number: z.string().describe('The invoice number'),
  date: z.string().describe('Invoice date'),
  total: z.number().describe('Total amount'),
  vendor: z.string().describe('Vendor name'),
});

app.post('/extract', async (c) => {
  const formData = await c.req.formData();
  const file = formData.get('file') as File;

  if (!file) {
    return c.json({ error: 'No file uploaded' }, 400);
  }

  const { object, error, metadata } = await client.extract({
    file,
    schema: invoiceSchema,
  });

  if (error) {
    return c.json({ error: error.message }, 422);
  }

  return c.json({
    data: object,
    credits: metadata.credits,
  });
});

export default app;

Cloudflare Workers

Deploy to Cloudflare Workers:
// src/index.ts
import { Hono } from 'hono';
import { Parsefy } from 'parsefy';
import * as z from 'zod';

type Bindings = {
  PARSEFY_API_KEY: string;
};

const app = new Hono<{ Bindings: Bindings }>();

const invoiceSchema = z.object({
  invoice_number: z.string().describe('The invoice number'),
  date: z.string().describe('Invoice date'),
  total: z.number().describe('Total amount'),
  vendor: z.string().describe('Vendor name'),
});

app.post('/extract', async (c) => {
  const client = new Parsefy(c.env.PARSEFY_API_KEY);
  
  const formData = await c.req.formData();
  const file = formData.get('file') as File;

  if (!file) {
    return c.json({ error: 'No file uploaded' }, 400);
  }

  const { object, error, metadata } = await client.extract({
    file,
    schema: invoiceSchema,
  });

  if (error) {
    return c.json({ error: error.message }, 422);
  }

  return c.json({
    data: object,
    credits: metadata.credits,
  });
});

export default app;
Add your API key to wrangler.toml:
name = "parsefy-worker"
main = "src/index.ts"

[vars]
PARSEFY_API_KEY = "pk_your_api_key"

Vercel Edge Functions

// api/extract.ts
import { Hono } from 'hono';
import { handle } from 'hono/vercel';
import { Parsefy } from 'parsefy';
import * as z from 'zod';

export const config = {
  runtime: 'edge',
};

const app = new Hono().basePath('/api');
const client = new Parsefy();

const schema = z.object({
  invoice_number: z.string().describe('The invoice number'),
  total: z.number().describe('Total amount'),
});

app.post('/extract', async (c) => {
  const formData = await c.req.formData();
  const file = formData.get('file') as File;

  const { object, error } = await client.extract({ file, schema });

  if (error) {
    return c.json({ error: error.message }, 422);
  }

  return c.json({ data: object });
});

export default handle(app);

Testing

curl -X POST http://localhost:3000/extract \
  -F "[email protected]"