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

# Schema Keyword Support

> Which JSON Schema keywords Extract guarantees in the output, and which it treats as guidance

Extract accepts a JSON Schema and returns JSON that matches it. Not every keyword carries the same guarantee. Some keywords are enforced: the output always satisfies them. Others are best effort: Extract reads them as guidance and follows them in most cases, but you should validate them in your own code.

This page applies to the `v4` extract model. See [Model Versions](/reference/model-versions) for how to select it.

***

## How Extract uses your schema

Your schema does two jobs at once:

1. **Output shape.** Extract constrains the response so it always has the fields and types you declared.
2. **Guidance.** Field names, descriptions, and constraints tell Extract what to look for and how to format it.

Enforced keywords do both jobs. Best-effort keywords only do the second one. For example, `"pattern": "^[A-Z]{2}-\\d{4}$"` on a string guarantees the output matches. `"format": "email"` does not guarantee a valid address, but it does steer Extract toward one.

***

## Enforced keywords

The output satisfies these keywords, with the exceptions noted in each row.

| Keyword                                                      | Notes                                                                                                                                                                                          |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                                                       | Includes type lists such as `["string", "null"]`. Scalar fields can also be `null` when the value is not in the document.                                                                      |
| `enum`                                                       | The output value is always one of the listed values, or `null` when the value is not in the document.                                                                                          |
| `const`                                                      | The output value always equals the declared value. Declare `type` next to `const` so the field is never `null`.                                                                                |
| `properties`                                                 | Every declared field is always present.                                                                                                                                                        |
| `required`                                                   | Treated as all fields required. Every declared field is always in the output.                                                                                                                  |
| `additionalProperties`                                       | Objects are closed by default: Extract only returns declared fields.                                                                                                                           |
| `items`                                                      | Every array item matches the item schema.                                                                                                                                                      |
| `prefixItems`                                                | Positional item schemas are honored.                                                                                                                                                           |
| `minItems`, `maxItems`                                       | Array length stays inside the bounds during generation. Extract then drops empty items (`null`, `[]`, or objects with only `null` values), so a returned array can be shorter than `minItems`. |
| `minLength`, `maxLength`                                     | String length stays inside the bounds.                                                                                                                                                         |
| `pattern`                                                    | The whole string must match. Patterns are treated as anchored even without `^` and `$`.                                                                                                        |
| `minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum` | Exact for integers. For non-integer numbers, exclusive bounds can behave like inclusive bounds.                                                                                                |
| `anyOf`, `oneOf`                                             | The output matches at least one branch.                                                                                                                                                        |
| `patternProperties`, `propertyNames`, `minProperties`        | Object key constraints are honored.                                                                                                                                                            |
| `$ref` to `#/$defs/...`                                      | Local references are resolved before extraction.                                                                                                                                               |
| `nullable: true`                                             | Treated as adding `null` to `type`.                                                                                                                                                            |
| `uniqueItems`                                                | Checked after generation. A response with duplicate items fails validation and is never returned as a success. Arrays reached through `$ref` are not checked.                                  |

### Every field is always returned

Extract returns every declared field on every object, even if you list only some of them in `required`. Scalar fields (string, number, integer, boolean, enum) with no supporting value in the document come back as `null`. Object and array fields keep their declared shape: an array with no matches is `[]`, and an object has all of its own fields set to `null`. If a field must not be `null` in your system, check for it in your code.

```json theme={null}
{
  "type": "object",
  "properties": {
    "invoice_number": { "type": "string" },
    "po_number": { "type": "string" }
  },
  "required": ["invoice_number"]
}
```

Output for a document with no PO number:

```json theme={null}
{ "invoice_number": "INV-2041", "po_number": null }
```

***

## Best-effort keywords

Extract reads these keywords as guidance. Output usually follows them, but it is not guaranteed. Validate these in your code if they matter.

| Keyword                                                       | What to expect                                                                                                                                 |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `description`, `title`, `examples`                            | Guidance only. Descriptions are the strongest lever you have for extraction quality. See [Best Practices](/extraction/best-practices-extract). |
| `format`                                                      | Steers formatting for values such as `date`, `date-time`, `email`, and `uuid`. Use `pattern` when the exact shape must be guaranteed.          |
| `multipleOf`                                                  | Not guaranteed.                                                                                                                                |
| `allOf`                                                       | Not guaranteed. Merge the branches into a single schema when possible.                                                                         |
| `not`                                                         | Not guaranteed.                                                                                                                                |
| `if`, `then`, `else`, `dependentRequired`, `dependentSchemas` | Conditional rules are not guaranteed.                                                                                                          |
| `contains`, `minContains`, `maxContains`                      | Not guaranteed.                                                                                                                                |

### Prefer `pattern` over `format`

`format` improves how Extract writes a value, but only `pattern` guarantees the shape.

```json theme={null}
{
  "type": "string",
  "description": "Invoice date in ISO 8601 format",
  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
}
```

***

## Ignored keywords

These keywords are accepted but have no effect on extraction: `default`, `$comment`, `$schema`, `deprecated`, `readOnly`, `writeOnly`.

***

## Schema validation

Extract validates your schema before it runs. Invalid schemas fail with a `400` and a message that points at the problem. Common causes:

* The schema is not valid JSON Schema (draft 2020-12).
* An object declares no `properties`.
* An array declares no `items`.
* `$ref` points outside `#/$defs`, or forms a cycle.
* A `required` entry names a field that is not in `properties` on a closed object.
* An `enum` or `const` value does not match the declared `type` or violates a sibling constraint, such as `"enum": ["ab"]` with `"minLength": 3`.

***

## Troubleshooting

**A value comes back `null` even though it is in the document.**
Extract works from the Parse output, so your Parse configuration affects extraction accuracy. Use [Parse r-1](/parse/r-1) or [agentic modes](/configs/parse/agentic-modes) for the best results. If the value is still missing, tighten the field `description` to say where the value appears.

**A string does not match my `format`.**
`format` is best effort. Add a `pattern` for the exact shape.

**An extra field I did not declare is missing.**
Extract only returns declared fields. Declare the field in `properties`.

**My `allOf` constraint is not respected.**
`allOf` is best effort. Combine the branches into one object schema with the union of their properties and constraints.
