Generate OPF decks with the Claude API
Use Claude structured outputs to make the model return OPF-shaped JSON that validates against the canonical schema.
How it works
Claude's structured outputs constrain the response to a JSON Schema passed in output_config.format, so the model returns a deck that matches the schema's shape. Save the result as *.opf.json, validate it, and hand it to any OPF renderer.
Claude's structured outputs require additionalProperties: false on every object. Unlike OpenAI strict mode, optional properties stay optional — no nullable workarounds needed, which keeps the schema closer to plain OPF.
Output schema
This is a compact starter schema, not the full OPF schema. Use the schema reference when you need more OPF fields such as narratives, design hints, or multi-audience metadata.
{
"type": "object",
"description": "An Open Presentation Format deck. Generate one valid OPF JSON presentation document.",
"properties": {
"$schema": {
"type": "string",
"enum": [
"https://openpresentation.org/schema/opf/v1"
],
"description": "The OPF schema URL. Always use this exact value."
},
"name": {
"type": "string",
"description": "Short title for the presentation."
},
"audience": {
"type": "string",
"description": "The intended audience for the deck, as a free-form description or audiences catalog id."
},
"tone": {
"type": "string",
"description": "The tone of the deck, such as formal, executive, technical, educational, or sales."
},
"slides": {
"type": "array",
"description": "Ordered slides in the deck.",
"items": {
"type": "object",
"properties": {
"layout": {
"type": "string",
"description": "Renderer layout hint.",
"enum": [
"title",
"title-subtitle",
"section",
"content",
"bullets",
"two-column",
"quote",
"closing"
]
},
"title": {
"type": "string",
"description": "Concise slide title."
},
"subtitle": {
"type": "string",
"description": "Optional slide subtitle."
},
"text": {
"type": "string",
"description": "Short body paragraph for the slide."
},
"items": {
"type": "array",
"description": "Bullet points or short takeaways.",
"items": {
"type": "string"
}
}
},
"required": [
"title"
],
"additionalProperties": false
}
}
},
"required": [
"$schema",
"name",
"slides"
],
"additionalProperties": false
}Generate a deck
A minimal TypeScript example using the official Anthropic SDK:
import Anthropic from "@anthropic-ai/sdk"
import opfDeckSchema from "./claude-opf.schema.json"
const anthropic = new Anthropic()
const response = await anthropic.messages.create({
model: "claude-opus-4-8",
max_tokens: 16000,
output_config: {
format: {
type: "json_schema",
schema: opfDeckSchema,
},
},
messages: [
{
role: "user",
content: `Create an Open Presentation Format (OPF) JSON deck for this brief:
Topic: A 10-minute board update on Q2 customer retention.
Audience: Board of Directors.
Slide count: 6.
Tone: Formal and concise.`,
},
],
})
const block = response.content.find((b) => b.type === "text")
const deck = JSON.parse(block.text)Validate
Structured outputs guarantee the response matches your starter schema, but OPF tooling should still validate the finished file against the canonical schema at https://openpresentation.org/schema/opf/v1 before rendering. The validation guide shows how with Ajv and ajv-cli.
Anthropic documents schema requirements and supported models in the structured outputs guide.