> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runautomat.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runautomat.com/_mcp/server.

# Schemas

## Overview

Schemas define exactly what data to extract from your documents and in what format.
A well-defined schema is the key to accurate, consistent extractions.

Automat schemas follow [JSON Schema](https://json-schema.org/) conventions with
some AI-specific extensions for better extraction guidance.

## Basic Structure

```json
{
  "field_name": {
    "type": "string",
    "description": "What this field represents"
  }
}
```

Every field should include:

* **type** - The data type (string, number, boolean, array, object)
* **description** - A clear explanation that guides the AI

## Field Types

### String

For text values:

```json
{
  "customer_name": {
    "type": "string",
    "description": "Full name of the customer"
  }
}
```

### Number

For numeric values (integers and decimals):

```json
{
  "total_amount": {
    "type": "number",
    "description": "Total invoice amount in dollars"
  }
}
```

### Boolean

For true/false values:

```json
{
  "is_paid": {
    "type": "boolean",
    "description": "Whether the invoice has been paid"
  }
}
```

### Enum

For predefined set of values:

```json
{
  "status": {
    "type": "string",
    "enum": ["pending", "approved", "rejected"],
    "description": "Current approval status"
  }
}
```

### Array

For lists of values:

```json
{
  "line_items": {
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "description": { "type": "string" },
        "quantity": { "type": "number" },
        "amount": { "type": "number" }
      }
    },
    "description": "List of invoice line items"
  }
}
```

### Object

For nested structures:

```json
{
  "vendor": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Company name"
      },
      "address": {
        "type": "string",
        "description": "Full mailing address"
      },
      "tax_id": {
        "type": "string",
        "description": "Tax identification number"
      }
    },
    "description": "Vendor/seller information"
  }
}
```

## Complete Example

Here's a comprehensive invoice extraction schema:

```json
{
  "invoice_number": {
    "type": "string",
    "description": "Unique invoice identifier (e.g., INV-2024-001)"
  },
  "invoice_date": {
    "type": "string",
    "description": "Date the invoice was issued, in YYYY-MM-DD format"
  },
  "due_date": {
    "type": "string",
    "description": "Payment due date, in YYYY-MM-DD format"
  },
  "vendor": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Vendor company name"
      },
      "address": {
        "type": "string",
        "description": "Vendor street address, city, state, zip"
      },
      "phone": {
        "type": "string",
        "description": "Vendor phone number"
      },
      "email": {
        "type": "string",
        "description": "Vendor email address"
      }
    },
    "description": "Information about the vendor/seller"
  },
  "customer": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "description": "Customer/buyer name or company"
      },
      "address": {
        "type": "string",
        "description": "Billing address"
      }
    },
    "description": "Information about the customer/buyer"
  },
  "line_items": {
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string",
          "description": "Item or service description"
        },
        "quantity": {
          "type": "number",
          "description": "Number of units"
        },
        "unit_price": {
          "type": "number",
          "description": "Price per unit in dollars"
        },
        "total": {
          "type": "number",
          "description": "Line item total (quantity × unit_price)"
        }
      }
    },
    "description": "Itemized list of products or services"
  },
  "subtotal": {
    "type": "number",
    "description": "Sum of all line items before tax"
  },
  "tax_rate": {
    "type": "number",
    "description": "Tax percentage applied (e.g., 8.5 for 8.5%)"
  },
  "tax_amount": {
    "type": "number",
    "description": "Total tax amount in dollars"
  },
  "total_amount": {
    "type": "number",
    "description": "Final total including tax"
  },
  "payment_terms": {
    "type": "string",
    "enum": ["net_15", "net_30", "net_60", "due_on_receipt"],
    "description": "Payment terms"
  },
  "notes": {
    "type": "string",
    "description": "Any additional notes or comments on the invoice"
  }
}
```

## Writing Effective Descriptions

Descriptions are crucial for accurate extraction. They guide the AI on:

* **What** to look for
* **Where** it might be found
* **How** to format the value

#### Be Specific

❌ `"Date of the document"`

✅ `"Invoice issue date, typically at the top of the document, in YYYY-MM-DD format"`

#### Disambiguate Similar Fields

When a document has multiple similar values:

```json
{
  "ship_date": {
    "description": "Date items were shipped, not the order date or delivery date"
  },
  "delivery_date": {
    "description": "Expected or actual delivery date, not the ship date"
  }
}
```

#### Specify Format

```json
{
  "phone": {
    "description": "Phone number in format (XXX) XXX-XXXX"
  },
  "amount": {
    "description": "Dollar amount as a number without currency symbol"
  }
}
```

#### Handle Missing Values

```json
{
  "po_number": {
    "description": "Purchase order number if present, otherwise null"
  }
}
```

## Optional vs Required Fields

By default, all fields are optional. Use the `required` property for mandatory fields:

```json
{
  "type": "object",
  "required": ["invoice_number", "total_amount"],
  "properties": {
    "invoice_number": { ... },
    "total_amount": { ... },
    "po_number": { ... }
  }
}
```

## Best Practices

#### Start Simple

Begin with 5-10 core fields, validate accuracy, then expand

#### Use Consistent Naming

Use snake_case and descriptive names: `total_amount` not `amt`

#### Group Related Fields

Use nested objects for related data (vendor info, customer info, etc.)

#### Test Edge Cases

Test with documents missing optional fields to ensure graceful handling