Docs/Registry
External authoring

OPF registry guide

Publish reusable OPF design choices over plain HTTPS and validate them through the same API that validates decks.

What is a registry?

A registry is a pair of JSON shapes: an index that lists items and their registry_urls, and a per-item descriptor that carries the full details for one item. Both use the same schema.

Each item declares a type from the registered OPF type namespace. As of OPF v1.0, the supported types are:

  • registry:background
  • registry:chart
  • registry:color-scheme
  • registry:font-scheme
  • registry:layout
  • registry:narrative
  • registry:theme

Index shape

The index identifies the registry and lists its items. Each entry points at a per-item descriptor via registry_url.

{
  "$schema": "https://pptx.dev/schema/registry.schema.json",
  "name": "string",
  "registry_url": "https://your-host/registry.json",
  "opf_version": "1.0",
  "items": [
    {
      "name": "string",
      "type": "registry:layout",
      "registry_url": "https://your-host/registry/layouts/your-layout.json",
      "dependencies": [],
      "opf_version": "1.0"
    }
  ]
}

Required at the index level: name, registry_url, opf_version, and items. Each entry in items requires name, type, registry_url, and opf_version; dependencies is optional.

Per-item descriptor shape

Fetching an item's registry_url returns a descriptor that carries the OPF payload, copy targets, and metadata needed to render or embed the item.

{
  "$schema": "https://pptx.dev/schema/registry.schema.json",
  "name": "string",
  "type": "registry:layout",
  "registry_url": "https://your-host/registry/layouts/your-layout.json",
  "dependencies": [],
  "opf_version": "1.0",
  "slug": "your-layout",
  "category": "layouts",
  "description": "string",
  "web_url": "https://your-host/layouts/your-layout",
  "opf": [
    { "name": "default", "label": "Default OPF snippet", "language": "json", "source": "...", "value": { } }
  ],
  "copy_targets": [
    { "name": "registry_url", "label": "Registry URL", "content_type": "text/plain", "value": "https://your-host/registry/layouts/your-layout.json" }
  ],
  "metadata": { }
}

Required on a descriptor: name, type, registry_url, and opf_version. Common additional fields are slug, category, description, web_url, dependencies, opf[] (snippet records), copy_targets[], and metadata.

Field reference

$schema
Must equal https://pptx.dev/schema/registry.schema.json. Optional but recommended; enables tooling to locate the schema automatically.
name
Display name of the registry or item.
registry_url
Canonical HTTPS URL of this JSON file. Must be fetchable without authentication.
opf_version
OPF contract version the payload targets. Currently "1.0".
type
Registry item type. One of the 7 registry:* values listed above. Required on per-item descriptors and on each entry in items.
dependencies
Array of registry_url strings this item depends on, for example a theme that references color and font schemes.
items
Index-only. Array of entries that point at per-item descriptors.
slug / category / description / web_url
Per-item display metadata. slug is the URL-safe id; category groups items (for example layouts, themes); web_url points at a human-viewable page.
opf[]
Array of snippet records — each has name, label, language, source (string form), and value (parsed form).
copy_targets[]
Array of copyable strings surfaced to users — each has name, label, content_type, and value.
metadata
Informational object. Extensible by publishers; validators ignore unknown keys.

Example: index

Example descriptor for https://www.pptx.gallery/registry.json:

{
  "$schema": "https://pptx.dev/schema/registry.schema.json",
  "name": "PPTX.gallery OPF Registry",
  "registry_url": "https://www.pptx.gallery/registry.json",
  "opf_version": "1.0",
  "items": [
    {
      "name": "Cover",
      "type": "registry:layout",
      "registry_url": "https://www.pptx.gallery/registry/layouts/cover.json",
      "dependencies": [],
      "opf_version": "1.0"
    },
    {
      "name": "Cool Horizon",
      "type": "registry:color-scheme",
      "registry_url": "https://www.pptx.gallery/registry/color-schemes/cool-horizon.json",
      "dependencies": [],
      "opf_version": "1.0"
    },
    {
      "name": "Minimal",
      "type": "registry:theme",
      "registry_url": "https://www.pptx.gallery/registry/themes/minimal.json",
      "dependencies": [
        "https://www.pptx.gallery/registry/color-schemes/cool-horizon.json",
        "https://www.pptx.gallery/registry/font-schemes/aptos.json"
      ],
      "opf_version": "1.0"
    }
  ]
}

Example: per-item descriptor

Example descriptor for https://www.pptx.gallery/registry/layouts/cover.json:

{
  "$schema": "https://pptx.dev/schema/registry.schema.json",
  "name": "Cover",
  "type": "registry:layout",
  "registry_url": "https://www.pptx.gallery/registry/layouts/cover.json",
  "dependencies": [],
  "opf_version": "1.0",
  "slug": "cover",
  "category": "layouts",
  "description": "A presentation cover with a title, optional subtitle, and logo.",
  "web_url": "https://www.pptx.gallery/layouts/cover",
  "opf": [
    {
      "name": "default",
      "label": "Default OPF snippet",
      "language": "json",
      "source": "{\n  \"name\": \"Cover example\",\n  \"slides\": [\n    {\n      \"layout\": \"cover\",\n      \"title\": \"Presentation title\"\n    }\n  ],\n  \"catalogs\": {\n    \"default\": {\n      \"source\": \"https://www.pptx.gallery\",\n      \"layouts\": {\n        \"cover\": {\n          \"name\": \"Cover\",\n          \"summary\": \"The opening slide: title, subtitle and an optional picture.\",\n          \"tags\": [\n            \"Openers and closers\"\n          ],\n          \"design\": {\n            \"titleAlignment\": \"center\",\n            \"contentAlignment\": \"center\"\n          },\n          \"direction\": \"row\",\n          \"regions\": [\n            {\n              \"name\": \"title\"\n            },\n            {\n              \"name\": \"media\",\n              \"accepts\": [\n                \"image\",\n                \"video\"\n              ],\n              \"role\": \"media\",\n              \"flow\": \"none\",\n              \"bleed\": true\n            }\n          ],\n          \"description\": \"Open a presentation with its subject and a short introduction. Add a picture when it helps establish the context.\",\n          \"preview\": {\n            \"vectorSrc\": \"https://www.pptx.gallery/layout-previews/cover.svg\"\n          }\n        }\n      }\n    }\n  }\n}",
      "value": {
        "name": "Cover example",
        "slides": [
          {
            "layout": "cover",
            "title": "Presentation title"
          }
        ],
        "catalogs": {
          "default": {
            "source": "https://www.pptx.gallery",
            "layouts": {
              "cover": {
                "name": "Cover",
                "summary": "The opening slide: title, subtitle and an optional picture.",
                "tags": [
                  "Openers and closers"
                ],
                "design": {
                  "titleAlignment": "center",
                  "contentAlignment": "center"
                },
                "direction": "row",
                "regions": [
                  {
                    "name": "title"
                  },
                  {
                    "name": "media",
                    "accepts": [
                      "image",
                      "video"
                    ],
                    "role": "media",
                    "flow": "none",
                    "bleed": true
                  }
                ],
                "description": "Open a presentation with its subject and a short introduction. Add a picture when it helps establish the context.",
                "preview": {
                  "vectorSrc": "https://www.pptx.gallery/layout-previews/cover.svg"
                }
              }
            }
          }
        }
      }
    }
  ],
  "copy_targets": [
    {
      "name": "registry_url",
      "label": "Registry URL",
      "content_type": "text/plain",
      "value": "https://www.pptx.gallery/registry/layouts/cover.json"
    },
    {
      "name": "web_url",
      "label": "Gallery URL",
      "content_type": "text/plain",
      "value": "https://www.pptx.gallery/layouts/cover"
    },
    {
      "name": "opf:default",
      "label": "Default OPF snippet",
      "content_type": "application/json",
      "value": "{\n  \"name\": \"Cover example\",\n  \"slides\": [\n    {\n      \"layout\": \"cover\",\n      \"title\": \"Presentation title\"\n    }\n  ],\n  \"catalogs\": {\n    \"default\": {\n      \"source\": \"https://www.pptx.gallery\",\n      \"layouts\": {\n        \"cover\": {\n          \"name\": \"Cover\",\n          \"summary\": \"The opening slide: title, subtitle and an optional picture.\",\n          \"tags\": [\n            \"Openers and closers\"\n          ],\n          \"design\": {\n            \"titleAlignment\": \"center\",\n            \"contentAlignment\": \"center\"\n          },\n          \"direction\": \"row\",\n          \"regions\": [\n            {\n              \"name\": \"title\"\n            },\n            {\n              \"name\": \"media\",\n              \"accepts\": [\n                \"image\",\n                \"video\"\n              ],\n              \"role\": \"media\",\n              \"flow\": \"none\",\n              \"bleed\": true\n            }\n          ],\n          \"description\": \"Open a presentation with its subject and a short introduction. Add a picture when it helps establish the context.\",\n          \"preview\": {\n            \"vectorSrc\": \"https://www.pptx.gallery/layout-previews/cover.svg\"\n          }\n        }\n      }\n    }\n  }\n}"
    }
  ],
  "metadata": {
    "category": "layouts",
    "slug": "cover",
    "page_url": "https://www.pptx.gallery/layouts/cover",
    "inspector_url": "https://pptx.dev/inspector?config=layouts:cover"
  }
}

Pointing at an external registry

Tools consume a registry by fetching its registry_url, reading the items array, and fetching each item's registry_url on demand. That is the entire discovery protocol — no index file, manifest, or authentication is required beyond serving the JSON publicly.

Validating your registry

Send the public registry URL to /api/v1/validate:

curl -X POST https://pptx.dev/api/v1/validate \
  -H "Authorization: Bearer $PPTX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"registryUrl":"https://www.pptx.gallery/registry.json"}'

The response includes top-level valid, errors, and warnings, plus one result per registry item. A top-level valid: false means the registry file could not be used as a valid registry; a per-item valid: false means that item failed its own OPF validation.

If you validate locally with AJV, enable Draft 2020-12 and ajv-formats. The registry schema uses format: "uri" for HTTPS fields.

pnpm --package=ajv-cli@5.0.0 --package=ajv-formats@3.0.1 dlx ajv validate \
  --spec=draft2020 \
  -c ajv-formats \
  -s schema.json \
  -d registry.json

Publishing

Host the JSON anywhere HTTPS is available, such as GitHub Pages, Vercel, S3, or Cloudflare R2. Each file must be publicly fetchable, no larger than 1 MiB, and should be served with an application/json Content-Type.

Stability guarantees

Registries built against OPF v1.0 validate for the life of v1.0. See the OPF v1.0 stability contract for the versioning rules that keep third-party registries compatible.