> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.twelvelabs.io/v1.3/agents/guides/create-a-response/structured-output/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.twelvelabs.io/_mcp/server. # Structured output Retrieve predictable, typed JSON responses by providing a JSON Schema with your request. This guide shows you how to define the schema and read the typed response. # Key concepts * **JSON Schema**: A standard for describing the structure of JSON data. You define the expected shape (properties, types, arrays), and the platform constrains its output to match. # Prerequisites * You've already uploaded your videos and images, and the assets have reached the `ready` status. See the [Upload content](/v1.3/agents/guides/upload-content) page for details. * You've already created a knowledge store. See the [Create a knowledge store](/v1.3/agents/guides/create-a-knowledge-store) page for details. * You've already added at least one asset to the knowledge store, and the item has reached the `ready` status. See the [Add assets to a knowledge store](/v1.3/agents/guides/add-assets) page for details. * You've already read the [Create a response](/v1.3/agents/guides/create-a-response) page and understand the basic request and response format. # Example Define a JSON Schema describing the output you want, then pass it in the `text` parameter. This example extracts themes and entities from your videos and images. Replace the placeholders surrounded by `<>` with your values. **`Python`** ```python Python maxlines=30 import json from twelvelabs import TwelveLabs, TextParam from twelvelabs.types.text_param_format import TextParamFormat_JsonSchema client = TwelveLabs(api_key="") response = client.responses.create( knowledge_store_id="", input=[{"type": "message", "role": "user", "content": "List the main themes and key entities in these videos and images"}], text=TextParam( format=TextParamFormat_JsonSchema( name="themes_and_entities", schema_={ "type": "object", "properties": { "themes": {"type": "array", "items": {"type": "string"}}, "entities": { "type": "array", "items": { "type": "object", "properties": { "name": {"type": "string"}, "type": {"type": "string"}, "frequency": {"type": "string"}, }, }, }, }, }, ) ), ) for output in response.output: if output.type == "message": for content in output.content: structured = json.loads(content.text) print(f"Themes: {structured['themes']}") for entity in structured["entities"]: print(f" {entity['name']} ({entity['type']})") ``` **`Node.js`** ```javascript Node.js maxlines=30 import { TwelveLabs } from "twelvelabs-js"; const client = new TwelveLabs({ apiKey: "" }); const response = await client.responses.create({ knowledgeStoreId: "", input: [{ type: "message", role: "user", content: "List the main themes and key entities in these videos and images" }], text: { format: { type: "json_schema", name: "themes_and_entities", schema: { type: "object", properties: { themes: { type: "array", items: { type: "string" } }, entities: { type: "array", items: { type: "object", properties: { name: { type: "string" }, type: { type: "string" }, frequency: { type: "string" }, }, }, }, }, }, }, }, }); for (const output of response.output ?? []) { if (output.type === "message") { for (const content of output.content ?? []) { const structured = JSON.parse(content.text); console.log(`Themes: ${structured.themes}`); for (const entity of structured.entities) { console.log(` ${entity.name} (${entity.type})`); } } } } ``` # Code explanation #### Python To receive typed JSON output, call the [`responses.create`](/v1.3/sdk-reference/python/responses#create-a-response) method with a `text` parameter that describes your JSON Schema. This example parses the returned JSON string and prints the extracted themes and entities to the standard output.\ **Parameters**: * `knowledge_store_id`: The unique identifier of the knowledge store to reason over. Every request requires exactly one. * `input`: An array of input items. Each item is a message you send to [Jockey](/v1.3/agents/concepts/jockey). * `text`: An object that specifies the response format. To return structured JSON, set the `format` field. Within it, the `schema_` field defines the structure the output must match, and the `name` field identifies the schema. See the [JSON schema requirements](#json-schema-requirements) section for the schema rules.\ **Return value**: An object of type `ResponseObject`. Iterate the `output` array and read the `text` field of each content part in a `message` item to obtain a JSON string that matches your schema. Parse it with the `json.loads()` method into a native object. #### Node.js To receive typed JSON output, call the [`responses.create`](/v1.3/sdk-reference/node-js/responses#create-a-response) method with a `text` parameter that describes your JSON Schema. You pass all parameters as properties of a single object. This example parses the returned JSON string and prints the extracted themes and entities to the standard output.\ **Parameters**: * `knowledgeStoreId`: The unique identifier of the knowledge store to reason over. Every request requires exactly one. * `input`: An array of input items. Each item is a message you send to Jockey. * `text`: An object that specifies the response format. To return structured JSON, set the `format` field. Within it, the `type` field must be `"json_schema"`, the `schema` field defines the structure the output must match, and the `name` field identifies the schema. See the [JSON schema requirements](#json-schema-requirements) section for the schema rules.\ **Return value**: An `HttpResponsePromise` that resolves to an object of type `ResponseObject`. Iterate the `output` array and read the `text` field of each content part in a `message` item to obtain a JSON string that matches your schema. Parse it with the `JSON.parse()` method into a native object. # Example response The response text is a JSON string that matches your schema: ```json { "themes": ["outdoor recreation", "team building", "nature conservation"], "entities": [ {"name": "John Rivera", "type": "person", "frequency": "3 items"}, {"name": "Yellowstone", "type": "location", "frequency": "2 items"} ] } ``` # Combine with instructions Use the `instructions` field to apply a domain-specific lens, and a schema to capture the results in a structured format. This example enriches videos and images through a brand strategy perspective. **`Python`** ```python Python maxlines=30 enrichment_schema = { "type": "object", "properties": { "enrichments": { "type": "array", "items": { "type": "object", "properties": { "item_reference": {"type": "string"}, "original_summary": {"type": "string"}, "enriched_analysis": {"type": "string"}, "new_insights": {"type": "array", "items": {"type": "string"}}, "tags": {"type": "array", "items": {"type": "string"}}, }, }, } }, } response = client.responses.create( knowledge_store_id="", instructions="You are a brand strategist. Analyze videos and images through the lens of brand perception and marketing effectiveness.", input=[{"type": "message", "role": "user", "content": "For each item, provide enriched analysis focusing on brand messaging effectiveness, audience engagement signals, and production quality."}], text=TextParam(format=TextParamFormat_JsonSchema(name="enrichment", schema_=enrichment_schema)), ) ``` **`Node.js`** ```javascript Node.js maxlines=30 const enrichmentSchema = { type: "object", properties: { enrichments: { type: "array", items: { type: "object", properties: { item_reference: { type: "string" }, original_summary: { type: "string" }, enriched_analysis: { type: "string" }, new_insights: { type: "array", items: { type: "string" } }, tags: { type: "array", items: { type: "string" } }, }, }, }, }, }; const response = await client.responses.create({ knowledgeStoreId: "", instructions: "You are a brand strategist. Analyze videos and images through the lens of brand perception and marketing effectiveness.", input: [{ type: "message", role: "user", content: "For each item, provide enriched analysis focusing on brand messaging effectiveness, audience engagement signals, and production quality." }], text: { format: { type: "json_schema", name: "enrichment", schema: enrichmentSchema } }, }); ``` Swap the `instructions` field to apply a different analysis lens. The schema stays the same: | Context | Instructions | | ------------- | --------------------------------------------------------------------------------------------------------------------------- | | Accessibility | "Analyze for accessibility: describe visual elements for screen readers, note caption quality, identify audio-only content" | | Compliance | "Review for regulatory compliance: identify claims, disclaimers, required disclosures" | | Education | "Analyze pedagogical effectiveness: identify learning objectives, teaching methods, assessment opportunities" | | SEO | "Extract SEO metadata: keywords, descriptions, suggested titles, topic clusters" | # JSON schema requirements > **Note** > > The constraints in this section apply to the Responses API. The schema the platform uses during [ingestion](/v1.3/agents/guides/create-a-knowledge-store/configure-ingestion#json-schema) supports different keywords and rejects unknown keywords with a `422` error. Your schema must adhere to the [JSON Schema Draft 2020-12 specification](https://json-schema.org/draft/2020-12) and must meet the requirements below: * **Supported data types**: `array`, `boolean`, `integer`, `null`, `number`, `object`, and `string`. * **Automatic schema changes**: The platform adds all object properties to `required` and sets `additionalProperties` to `false` on every object. You do not need to include `required` or `additionalProperties` in your schema. * **Unsupported keywords**: Do not use `oneOf`, `default`, `if`/`then`/`else`, `not`, `patternProperties`, `contains`, or `prefixItems`. They may produce incomplete or malformed output without returning an error. Use `anyOf` instead of `oneOf`, and `properties` instead of `patternProperties`. Omit the others. * **Subschema references**: You can reference subschemas using `$ref`. Define subschemas within `$defs` at the root of the schema. External URIs and relative-path references are not supported. For details, see the [JSON Schema documentation on \$defs](https://json-schema.org/understanding-json-schema/structuring#defs). For complete specifications, see the [`schema`](/v1.3/api-reference/responses/create#request.body.text.format.json_schema.schema) field in the API Reference section. # Common pitfalls * **Large schemas can reduce output quality.** Keep nesting to 5 levels of objects or fewer. Keep the total number of properties across all objects to 100 or fewer. These are best-practice guidelines, not enforced limits. * **Response text is a JSON string.** You still need to parse the text content with the `json.loads()` method (Python) or the `JSON.parse()` method (Node.js) into a native object. * **Structured responses contain no citations.** The generated JSON has no citation markers, and the annotations array is empty. To display cited answers, send the request without a response format. * **Truncated responses may fail to parse.** Even with a valid schema, the platform may truncate the response at the token limit. If the `status` field is `incomplete`, simplify your schema or break the request into smaller queries. # Next steps * [Recipes](/v1.3/agents/recipes) - complete examples that combine structured output with real tasks like entity extraction, content organization, and enrichment * [Streaming](/v1.3/agents/guides/create-a-response/streaming) - combine streaming with structured output for real-time typed responses * [Multi-turn sessions](/v1.3/agents/guides/create-a-response/multi-turn-sessions) - use structured output across a multi-turn conversation * [Create a response](/v1.3/agents/guides/create-a-response) - review the basic request and response format # Jupyter notebook [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/twelvelabs-io/twelvelabs-developer-experience/blob/main/quickstarts/jockey/guides/structured_output.ipynb)