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

# Output Schemas

> Define the exact JSON structure for extraction results

# Output Schemas

An **output schema** defines the exact JSON structure you want Meter to return from extractions. Instead of getting whatever field names the AI chooses, you specify the fields, types, and nesting — and Meter maps the extracted data to match.

## When to use output schemas

* You need consistent field names across different strategies (e.g., all product scrapers return `price`, not `cost` or `product_price`)
* You want type coercion (prices as numbers, not strings like `"$19.99"`)
* Your downstream system expects a specific JSON shape
* You're using [strategy groups](/concepts/strategy-groups) and want uniform output across all members

## Defining a schema

A schema is a JSON object where keys are field names and values are type strings:

```json theme={null}
{
  "title": "string",
  "price": "number",
  "in_stock": "boolean",
  "tags": "array",
  "image_url": "string"
}
```

### Supported types

| Type      | Description       | Coercion behavior                                                             |
| --------- | ----------------- | ----------------------------------------------------------------------------- |
| `string`  | Text value        | Converts to string, `None` if empty                                           |
| `number`  | Decimal number    | Strips `$`, `€`, `£`, commas; parses float (e.g., `"$19.99"` → `19.99`)       |
| `float`   | Same as `number`  | Alias for `number`                                                            |
| `integer` | Whole number      | Same stripping as `number`, then rounds to int (e.g., `"225 points"` → `225`) |
| `int`     | Same as `integer` | Alias for `integer`                                                           |
| `boolean` | True/false        | `"true"`, `"yes"`, `"1"` → `True`; `"false"`, `"no"`, `"0"` → `False`         |
| `array`   | List of values    | If string, splits on commas; if single value, wraps in list                   |

### Nested schemas

You can define nested structures:

```json theme={null}
{
  "product": {
    "name": "string",
    "pricing": {
      "amount": "number",
      "currency": "string"
    }
  },
  "seller": {
    "name": "string",
    "rating": "float"
  }
}
```

Meter flattens extracted data internally using underscore-separated keys (e.g., `product_name`, `product_pricing_amount`) and then re-nests it to match your schema structure.

### Wrapper array pattern

For schemas with a single top-level key containing an array, Meter automatically wraps results:

```json theme={null}
{
  "listings": [
    {
      "title": "string",
      "price": "number"
    }
  ]
}
```

This produces output like:

```json theme={null}
{
  "listings": [
    {"title": "MacBook Pro", "price": 1999},
    {"title": "iPad Air", "price": 599}
  ]
}
```

## Where schemas apply

### Strategy generation

Pass an `output_schema` when generating a strategy to guide extraction and get consistent output from the start:

```python theme={null}
result = client.generate_strategy(
    url="https://shop.com/products",
    description="Extract product listings",
    name="Product Scraper",
    output_schema={
        "product_name": "string",
        "price": "number",
        "rating": "float",
        "in_stock": "boolean"
    }
)

# Preview data matches the schema structure
for item in result["preview_data"]:
    print(f"{item['product_name']}: ${item['price']}")
```

### Strategy groups

Apply a schema to all strategies in a group at once:

```python theme={null}
client.apply_group_schema(
    group_id="group-uuid",
    output_schema={
        "title": "string",
        "price": "number",
        "url": "string"
    }
)
```

See [Strategy Groups](/concepts/strategy-groups#group-output-schemas) for details.

### Bulk upload

When using [Bulk Upload](/guides/bulk-upload), you can define an output schema that applies to all generated strategies in the batch.

## URL field handling

Meter automatically detects URL fields in your schema (keys containing `url`, `link`, or `href`) and optimizes extraction to capture the `href` attribute rather than link text. You don't need to configure this — it happens automatically.

## Examples

### E-commerce product schema

```json theme={null}
{
  "product_name": "string",
  "price": "number",
  "original_price": "number",
  "discount_percentage": "integer",
  "rating": "float",
  "review_count": "integer",
  "in_stock": "boolean",
  "image_url": "string",
  "product_url": "string"
}
```

### Job listing schema

```json theme={null}
{
  "title": "string",
  "company": "string",
  "location": "string",
  "salary_min": "integer",
  "salary_max": "integer",
  "job_type": "string",
  "posted_date": "string",
  "apply_url": "string",
  "tags": "array"
}
```

## Next steps

<CardGroup cols={2}>
  <Card title="Strategy Groups" icon="layer-group" href="/concepts/strategy-groups">
    Apply schemas to many strategies at once
  </Card>

  <Card title="Filtering" icon="filter" href="/concepts/filtering">
    Filter extraction results post-processing
  </Card>

  <Card title="Strategies" icon="brain" href="/concepts/strategies">
    Learn how strategies use output schemas
  </Card>

  <Card title="Bulk Upload" icon="upload" href="/guides/bulk-upload">
    Create many strategies with a shared schema
  </Card>
</CardGroup>

## Need help?

Email me at [mckinnon@meter.sh](mailto:mckinnon@meter.sh)
