DocuParse API Next.js Integration
Use DocuParse API in your Next.js application with Route Handlers or Server Actions. Keep your API key server-side and proxy requests through your own API routes.
Prerequisites
Add to .env.local:
# .env.local (not committed to version control) DOCUPARSE_API_KEY=dex_your_api_key_here
Important: Never expose your API key to the browser. Always proxy requests through a Route Handler or Server Action so the key stays on the server.
Option 1: Route Handler
Recommended for most use cases
Create a Route Handler that accepts file uploads from your client components and proxies them to DocuParse API server-side.
// app/api/extract/route.ts
import { NextRequest, NextResponse } from 'next/server';
const API_KEY = process.env.DOCUPARSE_API_KEY; // in .env.local, not .env
const API_URL = 'https://docuparseapi.com/api/v1/extract';
export async function POST(request: NextRequest) {
const formData = await request.formData();
const file = formData.get('file') as File | null;
if (!file) {
return NextResponse.json({ error: 'No file provided' }, { status: 400 });
}
const upstreamForm = new FormData();
upstreamForm.append('file', file);
const res = await fetch(API_URL, {
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}` },
body: upstreamForm,
});
if (!res.ok) {
return NextResponse.json(
{ error: 'Extraction failed' },
{ status: res.status }
);
}
const data = await res.json();
return NextResponse.json(data);
}Client component
Upload UI that calls your route handler
// components/ReceiptUpload.tsx
'use client';
import { useState } from 'react';
export function ReceiptUpload() {
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
async function handleUpload(e: React.ChangeEvent<HTMLInputElement>) {
const file = e.target.files?.[0];
if (!file) return;
setLoading(true);
const form = new FormData();
form.append('file', file);
const res = await fetch('/api/extract', {
method: 'POST',
body: form,
});
const data = await res.json();
setResult(data);
setLoading(false);
}
return (
<div>
<input type="file" accept=".pdf,.jpg,.jpeg,.png,.csv,application/pdf,image/jpeg,image/png,text/csv" onChange={handleUpload} />
{loading && <p>Extracting...</p>}
{result && (
<div>
<p>Merchant: {result.merchant}</p>
<p>Total: {result.total} {result.currency}</p>
<p>Date: {result.date}</p>
</div>
)}
</div>
);
}Option 2: Server Action
Alternative for form-based uploads
Use a Server Action to handle file uploads in form submissions:
// app/actions/extract.ts
'use server';
export async function extractDocument(formData: FormData) {
const file = formData.get('file') as File | null;
if (!file) throw new Error('No file provided');
const upstreamForm = new FormData();
upstreamForm.append('file', file);
const res = await fetch('https://docuparseapi.com/api/v1/extract', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.DOCUPARSE_API_KEY}` },
body: upstreamForm,
});
if (!res.ok) throw new Error(`Extraction failed: ${res.status}`);
return res.json();
}Response
Structured JSON returned from both approaches:
{
"success": true,
"document_type": "receipt",
"merchant": "Office Depot",
"total": "45.50",
"tax": "3.50",
"date": "2026-04-26",
"currency": "USD",
"receipt_id": "R-10492",
"line_items": [...]
}Tip: Check the extraction_source field to see which extraction method was used for each document.
Start with Next.js today
Start with 20 documents/month and full API access. No credit card required.