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

# Extract Structured Data with AI

> Use the Vercel AI SDK with Zod schemas to extract contacts, invoices, and product info from unstructured text. Reliable JSON output with type safety.

export const RuncrateStyles = () => {
  if (typeof document !== 'undefined' && !document.getElementById('runcrate-overrides')) {
    const s = document.createElement('style');
    s.id = 'runcrate-overrides';
    s.textContent = `
      /* Match Runcrate's rounding scale (--radius: 0.75rem) */
      .rounded-sm { border-radius: 0.5rem !important; }   /* 8px */
      .rounded-md { border-radius: 0.625rem !important; } /* 10px */
      .rounded-lg { border-radius: 0.75rem !important; }  /* 12px */
      .rounded-l-sm { border-top-left-radius: 0.5rem !important; border-bottom-left-radius: 0.5rem !important; }
      .rounded-r-sm { border-top-right-radius: 0.5rem !important; border-bottom-right-radius: 0.5rem !important; }
      .rounded-l-md { border-top-left-radius: 0.625rem !important; border-bottom-left-radius: 0.625rem !important; }
      .rounded-r-md { border-top-right-radius: 0.625rem !important; border-bottom-right-radius: 0.625rem !important; }
      .rounded-l-lg { border-top-left-radius: 0.75rem !important; border-bottom-left-radius: 0.75rem !important; }
      .rounded-r-lg { border-top-right-radius: 0.75rem !important; border-bottom-right-radius: 0.75rem !important; }

      /* Cards: never pure white in light mode */
      .card { background-color: #fcfcfc !important; border-radius: 0.75rem !important; }
      html.dark .card { background-color: #141414 !important; }

      /* Docs hero box */
      .rc-hero { background-color: #fcfcfc; border: 1px solid #e0e0e0; }
      html.dark .rc-hero { background-color: #141414; border-color: #242424; }
      html.dark .rc-hero h1 { color: #f5f5f5; }

      /* Runcrate scrollbar — thin, transparent track, hide-until-hover thumb */
      ::-webkit-scrollbar { width: 6px; height: 6px; background-color: transparent; }
      ::-webkit-scrollbar-track { background-color: transparent; }
      ::-webkit-scrollbar-thumb { background-color: rgba(155, 155, 155, 0.5); border-radius: 10px; transition: opacity 0.3s ease; opacity: 0; }
      ::-webkit-scrollbar-thumb:hover { background-color: rgba(155, 155, 155, 0.7); }
      *:hover::-webkit-scrollbar-thumb,
      *:focus::-webkit-scrollbar-thumb,
      *:active::-webkit-scrollbar-thumb { opacity: 1; }
      * { scrollbar-width: thin; scrollbar-color: rgba(155, 155, 155, 0.5) transparent; }
    `;
    document.head.appendChild(s);
  }
  return null;
};

<RuncrateStyles />

Turn unstructured text into typed JSON objects using the Vercel AI SDK's `generateObject` function. Define a Zod schema, pass the text, and get back validated, type-safe data — no regex, no prompt engineering for JSON formatting.

## How it works

```
Unstructured text → AI model + Zod schema → Typed JSON object
```

The Vercel AI SDK handles JSON mode, schema enforcement, and validation automatically. You define the shape, the model fills it in.

***

## Extract contact information

```typescript theme={"theme":"github-dark"}
import { runcrate } from '@runcrate/ai';
import { generateObject } from 'ai';
import { z } from 'zod';

const contactSchema = z.object({
  name: z.string().describe('Full name'),
  email: z.string().email().optional().describe('Email address'),
  phone: z.string().optional().describe('Phone number'),
  company: z.string().optional().describe('Company name'),
  role: z.string().optional().describe('Job title or role'),
});

const { object: contact } = await generateObject({
  model: runcrate('deepseek-ai/DeepSeek-V3'),
  schema: contactSchema,
  prompt: `Extract contact info from this email signature:

    Best regards,
    Sarah Chen
    Senior Product Manager, Acme Corp
    sarah.chen@acme.com | (415) 555-0192`,
});

console.log(contact.name);    // "Sarah Chen"
console.log(contact.company); // "Acme Corp"
console.log(contact.email);   // "sarah.chen@acme.com"
```

***

## Parse invoices

```typescript theme={"theme":"github-dark"}
import { runcrate } from '@runcrate/ai';
import { generateObject } from 'ai';
import { z } from 'zod';

const invoiceSchema = z.object({
  invoiceNumber: z.string().describe('Invoice or receipt number'),
  date: z.string().describe('Invoice date in ISO 8601 format'),
  vendor: z.string().describe('Vendor or merchant name'),
  items: z.array(z.object({
    description: z.string(),
    quantity: z.number(),
    unitPrice: z.number(),
    total: z.number(),
  })),
  subtotal: z.number(),
  tax: z.number(),
  total: z.number(),
  currency: z.string().default('USD'),
});

const invoiceText = `
INVOICE #INV-2024-0847
Date: March 15, 2025
From: Cloud Hardware Co.

2x NVIDIA A100 80GB rental (30 days) — $4,800.00 each
1x 10TB NVMe storage — $120.00

Subtotal: $9,720.00
Tax (8.5%): $826.20
Total: $10,546.20
`;

const { object: invoice } = await generateObject({
  model: runcrate('deepseek-ai/DeepSeek-V3'),
  schema: invoiceSchema,
  prompt: `Extract all invoice data from this text:\n\n${invoiceText}`,
});

console.log(`Invoice ${invoice.invoiceNumber}: $${invoice.total}`);
for (const item of invoice.items) {
  console.log(`  ${item.quantity}x ${item.description}: $${item.total}`);
}
```

The same pattern works for any structured data: product catalogs, support tickets, medical records, job postings. Define a Zod schema, call `generateObject`, and get typed results.

***

## Next steps

* [AI code generation](/examples/ai-code-generation) — use structured output for automated code review pipelines.
* [AI OCR and document extraction](/examples/ocr-document-extraction) — combine vision models with structured extraction for receipts and invoices.
* [Vercel AI SDK guide](/sdks/vercel-ai) — full setup and advanced patterns.
