Reuse schema definitions
Use $defs and $ref when several fields need the same schema. Define the allowed values, descriptions and constraints once, then reference that definition from each field. An edit to the definition applies wherever it is used.
Define once, reference where needed
$defs holds named schemas. A field's $ref points to one of them: #/$defs/decision means the decision definition in this schema document. The definitions organize your schema; they do not add fields to the generated output.
This example uses the same decision schema for primary and secondary:
{
"$defs": {
"decision": {
"enum": [
"accept",
"review"
],
"description": "Choose review when the input does not justify acceptance."
}
},
"type": "object",
"properties": {
"primary": {
"$ref": "#/$defs/decision"
},
"secondary": {
"$ref": "#/$defs/decision"
}
},
"required": [
"primary",
"secondary"
],
"additionalProperties": false
}
Each field independently allows accept or review. Sharing a definition does not require the two answers to be equal.
Send the schema
Save composition-refs.schema.json beside your client. The input describes two applications with different evidence:
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": "The primary application meets all acceptance criteria. The secondary application lacks the evidence required for acceptance.",
"schema": json.loads(Path("composition-refs.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": "The primary application meets all acceptance criteria. The secondary application lacks the evidence required for acceptance.",
"schema": JSON.parse(readFileSync("composition-refs.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 '{"input":"The primary application meets all acceptance criteria. The secondary application lacks the evidence required for acceptance."}' \
--slurpfile f0 'composition-refs.schema.json' \
'$body | setpath(["schema"]; $f0[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"
Illustrative output: {"primary":"accept","secondary":"review"}.
Both fields use the shared description to interpret the evidence for their application. The API receives the whole schema, including $defs, in one request.
Keep references local
Struct supports local, nonrecursive JSON Pointer references, such as #/$defs/decision. External, recursive and dynamic references are outside the current generation profile.
To store a complete schema and use its ID across requests, see Register and reuse schemas.