OPF
DocsHow-to

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.

Generate a deck

To generate a presentation with the Claude API, pass an OPF starter schema in output_config.format. Claude returns a JSON deck; save it as deck.opf.json, validate it, and convert it to PowerPoint or PDF with the OPF CLI. This TypeScript example uses the official Anthropic SDK, reads ANTHROPIC_API_KEY from the environment and loads the output schema below from claude-opf.schema.json:

generate-deck.ts
import { writeFile } from "node:fs/promises"
import Anthropic from "@anthropic-ai/sdk"
import opfDeckSchema from "./claude-opf.schema.json" with { type: "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")
if (!block) throw new Error("Claude returned no text block")
await writeFile("deck.opf.json", JSON.stringify(JSON.parse(block.text), null, 2))

Validate and export

Structured outputs guarantee the response matches your starter schema. Check the finished deck against the full OPF schema, then export it. Run these in a project with the CLI and export packages installed (first local run):

shell
npx opf validate deck.opf.json --fail-on warning
npx opf convert deck.opf.json deck.pptx
npx opf convert deck.opf.json deck.pdf

The first command exits 1 while any error or warning is left. To validate in code instead, the validation guide shows Ajv and ajv-cli against https://openpresentation.org/schema/opf/v1.

Checked on October 29, 2026 with @anthropic-ai/sdk 1.3.0, TypeScript 7.0.2, Node 26.7.0 and OPF CLI 0.29.1. generate-deck.ts type-checks in strict mode and runs against a local stand-in for the Messages API that returns a sample deck; the saved deck passes the commands above and converts to PPTX and PDF. The live API call was not part of the check, so a real response can differ.

Schema rules

Pass the starter schema in output_config.format, save the returned JSON, then validate the canonical OPF.

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.

claude-opf.schema.json
{
  "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": "Registered layout id (starter subset).",
            "enum": [
              "cover",
              "section",
              "text",
              "list",
              "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
}

A deck in the shape this schema asks for (written by hand as a sample, not a recorded response):

deck.opf.json (sample)
{
  "$schema": "https://openpresentation.org/schema/opf/v1",
  "name": "Q2 customer retention",
  "audience": "Board of Directors",
  "tone": "formal",
  "slides": [
    {
      "layout": "cover",
      "title": "Q2 customer retention",
      "subtitle": "Board update"
    },
    {
      "layout": "list",
      "title": "What changed",
      "items": [
        "Renewals rose in the pilot",
        "Fewer support escalations"
      ]
    },
    {
      "layout": "text",
      "title": "Next quarter",
      "text": "Extend the pilot to two more regions."
    },
    {
      "layout": "closing",
      "title": "Questions"
    }
  ]
}

Anthropic documents schema requirements and supported models in the structured outputs guide.