> ## 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.

# Math Verification

> Ensure extracted numeric data is mathematically consistent

## Overview

Math Verification transforms Parsefy from a probabilistic extraction tool into a **deterministic verification platform**. When enabled, Parsefy automatically verifies that extracted numeric data is mathematically consistent.

<Info>
  **Validated output or fail loudly.** Math verification ensures totals match subtotals + tax, line items sum correctly, and cross-field calculations are accurate.
</Info>

## How It Works

<Steps>
  <Step title="Schema Analysis">
    Parsefy scans your schema for verifiable numeric fields (totals, subtotals, taxes, line items). Only fields with `type: "number"` or `type: "integer"` are considered for verification.
  </Step>

  <Step title="Rule Synthesis">
    Mathematical rules are automatically generated based on detected field roles
  </Step>

  <Step title="Secure Evaluation">
    Extracted numeric values are verified against the synthesized rules
  </Step>

  <Step title="Result Reporting">
    Verification results are included in the API response
  </Step>
</Steps>

## Enabling Verification

<CodeGroup>
  ```typescript TypeScript theme={null}
  const { object, metadata, verification } = await client.extract({
    file: './invoice.pdf',
    schema,
    enableVerification: true, // Enable math verification
  });

  if (verification) {
    console.log(`Status: ${verification.status}`);
    console.log(`Checks passed: ${verification.checks_passed}`);
    console.log(`Checks failed: ${verification.checks_failed}`);
  }
  ```

  ```python Python theme={null}
  result = client.extract(
      file="invoice.pdf",
      schema=Invoice,
      enable_verification=True  # Enable math verification
  )

  if result.verification:
      print(f"Status: {result.verification.status}")
      print(f"Checks passed: {result.verification.checks_passed}")
      print(f"Checks failed: {result.verification.checks_failed}")
  ```
</CodeGroup>

## Verification Response

When `enable_verification` is set to `true`, the response includes a `verification` object:

```json theme={null}
{
  "verification": {
    "status": "PASSED",
    "checks_passed": 2,
    "checks_failed": 0,
    "cannot_verify_count": 0,
    "checks_run": [
      {
        "type": "HORIZONTAL_SUM",
        "status": "PASSED",
        "fields": ["total", "subtotal", "tax"],
        "passed": true,
        "delta": 0.0,
        "expected": 1250.00,
        "actual": 1250.00
      },
      {
        "type": "VERTICAL_SUM",
        "status": "PASSED",
        "fields": ["subtotal", "line_items"],
        "passed": true,
        "delta": 0.0,
        "expected": 1150.00,
        "actual": 1150.00
      }
    ]
  }
}
```

## Verification Status Values

| Status          | Description                                             |
| --------------- | ------------------------------------------------------- |
| `PASSED`        | All math checks passed                                  |
| `FAILED`        | One or more math checks failed                          |
| `PARTIAL`       | Some checks passed, some failed or couldn't be verified |
| `CANNOT_VERIFY` | Required fields are missing (not a math error)          |
| `NO_RULES`      | No verifiable fields detected in schema                 |

## Supported Verification Rules

| Rule Type           | Formula                  | Example                    |
| ------------------- | ------------------------ | -------------------------- |
| **HORIZONTAL\_SUM** | `total = subtotal + tax` | Invoice total verification |
| **VERTICAL\_SUM**   | `subtotal = sum(items)`  | Line item sum verification |

## Field Requirements

<Warning>
  **Only numeric fields can be verified.** Fields with `type: "number"` (or `type: "integer"`) in your schema are eligible for math verification. String fields will not be verified, even if they contain numeric values.
</Warning>

For a field to be included in verification:

* **Must be numeric**: The field must have `type: "number"` or `type: "integer"` in your JSON Schema
* **Must be part of a verifiable relationship**: The field must be part of a mathematical relationship (e.g., `total`, `subtotal`, `tax`, or line item amounts)

**Examples:**

```json theme={null}
{
  "properties": {
    "total": { "type": "number" },        // ✅ Will be verified
    "subtotal": { "type": "number" },     // ✅ Will be verified
    "tax": { "type": "number" },          // ✅ Will be verified
    "invoice_number": { "type": "string" }, // ❌ Will NOT be verified
    "date": { "type": "string" }          // ❌ Will NOT be verified
  }
}
```

## Check Result Fields

Each check in `checks_run` contains:

| Field      | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `type`     | string  | Type of check: `HORIZONTAL_SUM` or `VERTICAL_SUM`    |
| `status`   | string  | Check status: `PASSED`, `FAILED`, or `CANNOT_VERIFY` |
| `fields`   | array   | Fields involved in this check                        |
| `passed`   | boolean | Whether the check passed                             |
| `delta`    | number  | Difference between expected and actual values        |
| `expected` | number  | Expected value from the verification rule            |
| `actual`   | number  | Actual value extracted from the document             |

## Shadow Extraction

When verification is enabled and only a single verifiable field is requested (e.g., just `total`), Parsefy automatically extracts supporting fields in the background:

1. User requests: `{ "total": { "type": "number" } }` with `enable_verification=true`
2. Parsefy internally expands to include shadow fields: `subtotal`, `tax`, `line_items`
3. LLM extracts all fields
4. Math verification runs
5. Shadow fields are removed before response

This ensures verification even when users only need the final total.

## Best Practices

<CardGroup cols={2}>
  <Card title="Include Verification Fields" icon="calculator">
    For best verification, include `subtotal`, `tax`, and `total` in your schema
  </Card>

  <Card title="Use for Financial Data" icon="file-invoice-dollar">
    Enable verification for invoices, receipts, and bills where math accuracy is critical
  </Card>

  <Card title="Handle Failures Gracefully" icon="triangle-exclamation">
    When verification fails, flag for manual review rather than rejecting outright
  </Card>

  <Card title="Check Individual Results" icon="list-check">
    Review `checks_run` to identify which specific calculations failed
  </Card>
</CardGroup>

## Example: Full Invoice Extraction with Verification

<CodeGroup>
  ```typescript TypeScript theme={null}
  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'),
    subtotal: z.number().describe('Subtotal before tax'),
    tax: z.number().describe('Tax amount'),
    total: z.number().describe('Total amount including tax'),
    line_items: z.array(z.object({
      description: z.string(),
      quantity: z.number(),
      unit_price: z.number(),
      amount: z.number(),
    })).optional().describe('Line items'),
  });

  const { object, verification, error } = await client.extract({
    file: './invoice.pdf',
    schema: invoiceSchema,
    enableVerification: true,
  });

  if (!error && object) {
    console.log(`Invoice #${object.invoice_number}`);
    console.log(`Total: $${object.total}`);
    
    if (verification) {
      if (verification.status === 'PASSED') {
        console.log('Math verification passed!');
      } else {
        console.log(`Verification: ${verification.status}`);
        verification.checks_run.forEach(check => {
          if (!check.passed) {
            console.log(`  Failed: ${check.type}`);
            console.log(`    Expected: ${check.expected}, Actual: ${check.actual}`);
            console.log(`    Delta: ${check.delta}`);
          }
        });
      }
    }
  }
  ```

  ```python Python theme={null}
  from parsefy import Parsefy
  from pydantic import BaseModel, Field

  client = Parsefy()

  class LineItem(BaseModel):
      description: str = Field(description="Item description")
      quantity: int = Field(description="Quantity")
      unit_price: float = Field(description="Price per unit")
      amount: float = Field(description="Line total")

  class Invoice(BaseModel):
      invoice_number: str = Field(description="The invoice number")
      subtotal: float = Field(description="Subtotal before tax")
      tax: float = Field(description="Tax amount")
      total: float = Field(description="Total amount including tax")
      line_items: list[LineItem] | None = Field(default=None, description="Line items")

  result = client.extract(
      file="invoice.pdf",
      schema=Invoice,
      enable_verification=True
  )

  if result.error is None:
      print(f"Invoice #{result.data.invoice_number}")
      print(f"Total: ${result.data.total}")
      
      if result.verification:
          if result.verification.status == "PASSED":
              print("Math verification passed!")
          else:
              print(f"Verification: {result.verification.status}")
              for check in result.verification.checks_run:
                  if not check.passed:
                      print(f"  Failed: {check.type}")
                      print(f"    Expected: {check.expected}, Actual: {check.actual}")
                      print(f"    Delta: {check.delta}")
  ```
</CodeGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Confidence Scores" icon="chart-line" href="/learn/confidence-scores">
    Understand field-level confidence and evidence
  </Card>

  <Card title="Schema Basics" icon="brackets-curly" href="/learn/schema-basics">
    Learn how to define effective extraction schemas
  </Card>
</CardGroup>
