Installation
Copy
npm install parsefy zod
- parsefy: Parsefy SDK for document extraction
- zod: TypeScript-first schema validation library
Environment setup
Add your API key to.env.local:
Copy
PARSEFY_API_KEY=pk_your_api_key
Server Action
Create a server action to handle document extraction:Copy
// app/actions/extract.ts
'use server';
import { Parsefy } from 'parsefy';
import * as z from 'zod';
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'),
line_items: z.array(z.object({
description: z.string(),
quantity: z.number(),
amount: z.number(),
})).describe('Line items'),
});
export async function extractInvoice(formData: FormData) {
const file = formData.get('file') as File;
const { object, error } = await client.extract({
file,
schema: invoiceSchema,
});
if (error) {
return { error: error.message };
}
return { data: object };
}
React component
Create a form component to upload documents:Copy
// app/components/InvoiceUploader.tsx
'use client';
import { useState } from 'react';
import { extractInvoice } from '../actions/extract';
export function InvoiceUploader() {
const [result, setResult] = useState<any>(null);
const [loading, setLoading] = useState(false);
async function handleSubmit(formData: FormData) {
setLoading(true);
const response = await extractInvoice(formData);
setResult(response);
setLoading(false);
}
return (
<div>
<form action={handleSubmit}>
<input type="file" name="file" accept=".pdf,.docx" />
<button type="submit" disabled={loading}>
{loading ? 'Extracting...' : 'Extract'}
</button>
</form>
{result?.data && (
<pre>{JSON.stringify(result.data, null, 2)}</pre>
)}
{result?.error && (
<p className="error">{result.error}</p>
)}
</div>
);
}
API Route (alternative)
If you prefer API routes over server actions:Copy
// app/api/extract/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Parsefy } from 'parsefy';
import * as z from 'zod';
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'),
});
export async function POST(request: NextRequest) {
const formData = await request.formData();
const file = formData.get('file') as File;
const { object, error, metadata } = await client.extract({
file,
schema: invoiceSchema,
});
if (error) {
return NextResponse.json({ error: error.message }, { status: 422 });
}
return NextResponse.json({
data: object,
credits: metadata.credits,
});
}
