Next.js Integration

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

Next.js 13+ with App Router
A DocuParse API key (sign up for a free account)
API key stored in .env.local (never exposed to the browser)

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.