Data schemas
The JSON Schema extensions data schemas support, beyond plain validation.
A data schema wraps a JSON Schema document as a named, storable resource used to validate extracted records (see Validating against a schema). The schema itself is plain JSON Schema (Draft 2020-12), but validation runs through an extended validator that adds a handful of x- keywords on top of standard validation: defaulting absent fields, computing fields from the rest of the document, pulling fields from external context, and transforming values before or after validation. This page documents that extended machinery.
$schema references are not supported; schemas are always validated against Draft 2020-12 directly.
How extended validation works
Each keyword below attaches to a single subschema (a property, array item schema, or the root) and is evaluated as part of a two-pass walk over the document:
- Before validation, for each node: if
x-contextis present, it supplies the value (overriding anything in the input). Otherwise the input value is used if present, falling back tox-default, falling back to a zero value for the schema'stype("",0,false,[],{}, ornull). Thenx-before-transformsrun on the result, in order. - The document is validated against the plain JSON Schema, with
x-*keywords ignored by the validator (they are not JSON Schema vocabulary). - After validation, for each node:
x-after-transformsrun on the value, in order, thenx-compute(if present) overwrites the value with a computed result that sees the whole validated document.
This means x-before-transforms and x-default/x-context can fix up data so it passes validation, while x-after-transforms and x-compute run on already-valid data and can themselves produce a value that no longer matches the schema. A failure at that point surfaces as json_schema_validation_failed, the same validation error used elsewhere, since the result is checked against the schema again.
x-default
Supplies a value for a field when it is missing from the input, before validation.
{
"type": "string",
"x-default": { "name": "literal", "params": { "value": "draft" } }
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | The registered default-value extension to use. |
params | object | no | Parameters passed to the extension. |
literal
The only built-in default extension. Returns params.value verbatim, regardless of type.
x-compute
Overwrites a field with a computed value after the document has validated. The computation sees the entire validated document, so it can derive a field from sibling or unrelated fields.
{
"type": "number",
"x-compute": {
"name": "expression",
"params": { "expression": "root.price * root.quantity" }
}
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | The registered computed-value extension to use. |
params | object | no | Parameters passed to the extension. |
expression
The only built-in computed-value extension. Evaluates a CEL expression with the root document bound to the variable root, and returns the result as the field's value.
x-context
Sources a field's value from an external runtime context supplied by the caller, rather than from the input document. When present, it takes priority over the input value, x-default, and zero-value fallback.
{
"type": "string",
"x-context": { "expression": "context.tenant_id" }
}| Field | Type | Required | Description |
|---|---|---|---|
expression | string | yes | A CEL expression with the supplied context bound to the variable context. |
There is no extension registry for x-context; it always evaluates as a CEL expression. The context value itself is supplied by the caller of validation, not by the document being validated; whether and what context is available depends on where validation is invoked. The available context when the schema is used within a parsing
pipeline is:
| Field | Type | Description |
|---|---|---|
url | string | The URL of the document being parsed. |
content_type | string | The content type of the document being parsed, if known. |
assets | object | The assets extracted alongside the document. |
run_id | string | A unique identifier for this parsing run, if applicable. |
The assets object has the asset types as keys and arrays of asset references as values. Each asset reference is an object with:
| Field | Type | Description |
|---|---|---|
type | string | The asset type. |
url | string | The asset URL. |
key | string | The blob storage key where this asset is stored. |
metadata | object | The asset reference metadata. |
Where the metadata object contains:
| Field | Type | Description |
|---|---|---|
content_type | string | The asset content type, if known. |
content_length | number | The asset content length in bytes, if known. |
filename | string | The asset filename, if known. |
extension | string | The asset file extension, if known. |
x-before-transforms / x-after-transforms
Arrays of transforms applied to a field's value, in order. x-before-transforms run after the value is sourced (input, x-context, x-default, or zero value) but before validation; x-after-transforms run after validation, on the validated value.
{
"type": "string",
"x-before-transforms": [
{ "name": "coerce", "params": { "target": "string" } },
{ "name": "trim" }
]
}Each entry is:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | The registered transform to use. |
params | object | no | Parameters passed to the transform. Omit for transforms that take none. |
coerce
Converts a string, number, or boolean value to another primitive type.
| Field | Type | Required | Description |
|---|---|---|---|
target | "string", "number", "float", or "boolean" | yes | The type to coerce the value to. |
Coercion is between primitives only; arrays, objects, and null are not supported and fail the transform.
trim
Trims leading and trailing whitespace from a string value. Takes no parameters. Non-string values pass through unchanged.
Errors
Extended validation failures use the same error shapes as the rest of the API:
| Code | When |
|---|---|
invalid_json_schema | The schema itself is not valid Draft 2020-12, or references $schema. |
json_schema_validation_failed | The data does not match the schema, whether on the first pass or after x-after-transforms/x-compute run. |
extension_error | A transform, default, or compute extension failed at runtime (for example, coerce on an unsupported value). |
extension_compile_error | An x-* keyword names an extension that is not registered, or a CEL expression fails to compile. |