Extract exact source text
Use x-runtime.quote when an extracted value must come directly from the input: a part code, a date as written, or a sentence from a document. Struct selects the relevant text and enforces that each returned string is an exact, contiguous excerpt of its specified source.
This is a Struct extension to JSON Schema. A description asking the model to “copy exactly” guides its choice; the quote annotation enforces source membership. No OPA policy is needed.
Example: extract details from a notice
Extract the replacement date, part code and restart instruction from a maintenance notice. Save these files beside your client:
{
"text": "Maintenance notice: replace filter FX-200 on 14 November 2026. Keep the ventilation grille clear. Restart only after the status light turns green."
}
{
"type": "object",
"description": "Extract the maintenance details exactly as written in the notice.",
"properties": {
"service_date": {
"type": "string",
"description": "Copy the complete scheduled replacement date.",
"maxLength": 64,
"x-runtime": {
"quote": {
"ref": "/input/text",
"unit": "date"
}
}
},
"part_code": {
"type": "string",
"description": "Copy the filter part code.",
"maxLength": 32,
"x-runtime": {
"quote": {
"ref": "/input/text",
"unit": "identifier"
}
}
},
"restart_instruction": {
"type": "string",
"description": "Copy the complete sentence that states when restarting is allowed, including its final punctuation.",
"maxLength": 256,
"x-runtime": {
"quote": {
"ref": "/input/text",
"unit": "passage"
}
}
}
},
"required": [
"service_date",
"part_code",
"restart_instruction"
],
"additionalProperties": false
}
Send the input and schema to the usual resolve endpoint:
Before you run this example
Call https://api.blatent.ai from your server. Set your API key in the same terminal where you run the example:
export BLATENT_API_KEY='YOUR_SERVICE_KEY'
Python requires Python 3.10+ and HTTPX:
python -m pip install "httpx>=0.28,<1"
TypeScript requires Node.js 24+ and uses its built-in fetch. The cURL examples require curl and jq.
Save the displayed files and the selected client in one directory. Run the client there with python example.py, node example.ts or bash example.sh. Downloads use the example's name in place of example.
- Python
- TypeScript
- cURL
import json
import os
from pathlib import Path
import httpx
request = {
"input": json.loads(Path("maintenance.input.json").read_text(encoding="utf-8")),
"schema": json.loads(Path("maintenance-quotes.schema.json").read_text(encoding="utf-8")),
}
with httpx.Client(
base_url="https://api.blatent.ai",
headers={"Authorization": f"Bearer {os.environ['BLATENT_API_KEY']}"},
timeout=195,
) as client:
response = client.post("/v1/resolve", json=request)
response.raise_for_status()
print(json.dumps(response.json()["output"]))
import { readFileSync } from "node:fs";
const request = {
"input": JSON.parse(readFileSync("maintenance.input.json", "utf8")),
"schema": JSON.parse(readFileSync("maintenance-quotes.schema.json", "utf8")),
};
const response = await fetch(
"https://api.blatent.ai" + "/v1/resolve",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BLATENT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
signal: AbortSignal.timeout(195_000),
},
);
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(JSON.stringify((await response.json()).output));
set -eu
body=$(jq -n --argjson body '{}' \
--slurpfile f0 'maintenance.input.json' \
--slurpfile f1 'maintenance-quotes.schema.json' \
'$body | setpath(["input"]; $f0[0]) | setpath(["schema"]; $f1[0])')
curl --fail-with-body --silent --show-error \
"https://api.blatent.ai/v1/resolve" \
-H "Authorization: Bearer $BLATENT_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary "$body"
The generated value returned by this example:
{
"service_date": "14 November 2026",
"part_code": "FX-200",
"restart_instruction": "Restart only after the status light turns green."
}
The date stays as written. For a normalized value such as 2026-11-14, use standard formats instead.
Point to the source
Put x-runtime.quote on each string field you want to constrain.
| Part | Role |
|---|---|
description | Tell Struct which information to extract |
quote.ref | Select the source string with a JSON Pointer |
quote.unit | Give a hint about the kind of excerpt |
maxLength | Bound the returned string's length |
Here /input/text selects the request's input.text. Use /input when the entire input is a string. The reference must resolve to a string under input; it does not select from state. Different fields can quote different input strings.
This ref belongs to the quote annotation. It is not a JSON Schema $ref or the state/... reference used by eligibility rules and loops. A standard JSON Schema validator alone does not enforce source membership.
Guide the selection
unit | What to select |
|---|---|
number | A number or amount as written, such as 001.50 |
date | A date expression, such as 14 November 2026 |
word | A word from the source |
identifier | A part code or other identifier |
passage | A longer excerpt, including a sentence or several lines |
span | Any contiguous excerpt; the default |
Units are semantic hints, not JSON types or format validators. A quoted number is still a string; a date hint does not convert text to ISO format. You can supply one unit or an array of distinct units. Optional locale provides a language or region hint.
Quoting preserves the source's spelling, accents, whitespace and punctuation. Descriptions still matter: an exact excerpt can be the wrong answer to the question. Say which subject, fact or instruction the field should capture.
Handle missing and multiple values
If a fact may be absent, allow type: ["string", "null"] on the quoted field and describe when to return null. A required string cannot use null as a fallback. If the result cannot satisfy the schema, the request fails.
For several matches, use an array with the quote annotation on items and a bounded maxItems. Allow [] when no matches is a valid answer. Use uniqueItems when repeated string values should be excluded. Struct still decides which excerpts are relevant and whether information is absent; quoting enforces the source of each string, not that decision. It does not guarantee exhaustive selection or ordering.
Keep the constraints compatible
Each quoted string needs maxLength between 1 and 4,096. Extraction arrays require maxItems no greater than 256. Input size, context and execution limits also apply.
Supported string constraints still apply to the original excerpt. A pattern or format can reject a quote; it cannot rewrite it. Each string must be contiguous, so combining separate passages into one string requires a different operation.
Keep quote requests separate from OPA policies; that combination is not supported. See JSON Schema support for the quote-specific support notes.