> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parsefy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Hono

> Build edge-ready financial document extraction APIs with Hono

## Installation

```bash theme={null}
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

```bash theme={null}
export PARSEFY_API_KEY=pk_your_api_key
```

## Basic setup

```typescript theme={null}
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({
  // REQUIRED - triggers fallback if below confidence threshold
  invoice_number: z.string().describe('The invoice number'),
  total: z.number().describe('Total amount including tax'),
  
  // OPTIONAL - won't trigger fallback if missing
  date: z.string().optional().describe('Invoice date'),
  vendor: z.string().optional().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, verification } = await client.extract({
    file,
    schema: invoiceSchema,
    confidenceThreshold: 0.85,
    enableVerification: true,
  });

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

  return c.json({
    data: object,
    confidence: object?._meta.confidence_score,
    fieldConfidence: object?._meta.field_confidence,
    credits: metadata.credits,
    verification: verification,
  });
});

export default app;
```

## Cloudflare Workers

Deploy to Cloudflare Workers:

```typescript theme={null}
// 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({
  // REQUIRED
  invoice_number: z.string().describe('The invoice number'),
  total: z.number().describe('Total amount including tax'),
  
  // OPTIONAL
  date: z.string().optional().describe('Invoice date'),
  vendor: z.string().optional().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, verification } = await client.extract({
    file,
    schema: invoiceSchema,
    confidenceThreshold: 0.85,
    enableVerification: true,
  });

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

  return c.json({
    data: object,
    confidence: object?._meta.confidence_score,
    fieldConfidence: object?._meta.field_confidence,
    issues: object?._meta.issues,
    credits: metadata.credits,
    verification: verification,
  });
});

export default app;
```

Add your API key to `wrangler.toml`:

```toml theme={null}
name = "parsefy-worker"
main = "src/index.ts"

[vars]
PARSEFY_API_KEY = "pk_your_api_key"
```

## Vercel Edge Functions

```typescript theme={null}
// 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({
  // REQUIRED
  invoice_number: z.string().describe('The invoice number'),
  total: z.number().describe('Total amount'),
  
  // OPTIONAL
  date: z.string().optional().describe('Invoice date'),
});

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

  const { object, error, metadata, verification } = await client.extract({
    file,
    schema,
    confidenceThreshold: 0.85,
    enableVerification: true,
  });

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

  return c.json({
    data: object,
    confidence: object?._meta.confidence_score,
    fieldConfidence: object?._meta.field_confidence,
    verification: verification,
  });
});

export default handle(app);
```

## Testing

```bash theme={null}
curl -X POST http://localhost:3000/extract \
  -F "file=@invoice.pdf"
```
