# How to Structure the OpenAPI Specification for Complex Plugins: A Complete Guide

> Master structuring complex OpenAPI specifications for OpenAI plugins. Learn to modularize, version, paginate, and secure your API definitions for seamless integration and maintenance.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-07-12

---

**Structure complex OpenAPI specifications for plugins by splitting them into modular files (paths, components, security schemes) referenced via `$ref`, and include explicit versioning, pagination parameters, and security definitions to ensure maintainability and compatibility with the OpenAI plugin host.**

Creating a well-structured OpenAPI specification is critical when building complex plugins that expose multiple endpoints, handle authentication, and require long-term maintainability. This guide examines proven patterns from the [OpenAI Plugins repository](https://github.com/openai/plugins), specifically analyzing how the Zoom and Cloudflare implementations organize their specifications. You will learn to architect modular specs that scale from simple endpoints to enterprise-grade APIs.

## Why Modular Architecture Matters for Complex Plugins

Monolithic OpenAPI files become unmanageable as your plugin grows. The **modular definition** principle keeps specifications readable and allows different teams to own distinct API domains simultaneously.

According to the repository's reference implementations, splitting specs into multiple files and referencing them via `$ref` prevents merge conflicts and enables parallel development. This approach also supports **versioning and backwards compatibility**, ensuring that changes to one domain (like meetings) do not accidentally break another (like user management).

## Recommended File Layout for Scalable OpenAPI Specs

Organize your specification using a directory structure that separates concerns by functional domain. The following layout is derived from best practices observed across the OpenAI plugins ecosystem:

```

openapi/
├── openapi.yaml                # Root document (info, servers, security)

├── paths/
│   ├── users.yaml              # /users/* endpoints

│   └── meetings.yaml           # /meetings/* endpoints

├── components/
│   ├── schemas/
│   │   ├── User.yaml
│   │   └── Meeting.yaml
│   ├── parameters/
│   │   └── Pagination.yaml
│   └── securitySchemes/
│       └── OAuth2.yaml
└── external/
    └── examples/               # Sample request/response payloads

```

### Root Document Structure

The root [`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml) acts as the entry point, pulling together all sub-resources using `$ref` statements. Define global **security schemes** here to apply authentication consistently across operations.

```yaml
openapi: 3.0.0
info:
  title: Complex Plugin API
  version: 1.2.0
  description: |
    A full-featured OpenAPI spec for a multi-service plugin.
servers:
  - url: https://api.example.com/v1
    description: Production server
security:
  - OAuth2: []                     # Applied globally; override per-operation if needed

paths:
  /users:
    $ref: './paths/users.yaml#/paths/~1users'
  /meetings:
    $ref: './paths/meetings.yaml#/paths/~1meetings'
components:
  schemas:
    $ref: './components/schemas/User.yaml#/User'
  securitySchemes:
    $ref: './components/securitySchemes/OAuth2.yaml'

```

### Domain-Specific Path Files

Isolate each logical domain (users, meetings, files) into separate files under `paths/`. This separation allows independent versioning and ownership. Use **kebab-case** for path segments (`/users/{user-id}`), **camelCase** for query parameters, and **snake_case** for payload fields to maintain consistency across the specification.

## Essential Components for Production-Ready Specs

### Reusable Security Schemes

Explicitly define authentication methods in `components/securitySchemes/` to simplify token handling for the plugin host. The specification supports OAuth2, API keys, and Bearer tokens.

In [`components/securitySchemes/OAuth2.yaml`](https://github.com/openai/plugins/blob/main/components/securitySchemes/OAuth2.yaml):

```yaml
type: oauth2
flows:
  authorizationCode:
    authorizationUrl: https://auth.example.com/oauth/authorize
    tokenUrl: https://auth.example.com/oauth/token
    scopes:
      read: Grant read access
      write: Grant write access

```

### Standardized Pagination

Implement pagination as a reusable parameter component to ensure consistent behavior across list endpoints.

In [`components/parameters/Pagination.yaml`](https://github.com/openai/plugins/blob/main/components/parameters/Pagination.yaml):

```yaml
name: page
in: query
description: Page number for paginated results
required: false
schema:
  type: integer
  default: 1
  minimum: 1

```

Reference this in your path files:

```yaml
get:
  summary: List users
  parameters:
    - $ref: '../components/parameters/Pagination.yaml'
  responses:
    200:
      description: A paginated list of users

```

### Rich Documentation and Examples

Add `description`, `example`, and `summary` fields for every operation and schema. This enables auto-generated client SDKs and improves the plugin's discoverability in API explorers.

## Real-World Implementations in OpenAI Plugins

### Zoom Plugin: Legacy Swagger 2.0 and SDK Generation

The Zoom skill in [`plugins/zoom/skills/rest-api/references/openapi.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/rest-api/references/openapi.md) demonstrates how to handle legacy specifications. It ships with **deprecated Swagger 2.0** specs ([`openapi.v2.json`](https://github.com/openai/plugins/blob/main/openapi.v2.json)) and uses **OpenAPI Generator** to create TypeScript and Python clients.

The reference file documents known issues such as enum mismatches and missing required fields, providing workarounds for generating functional SDKs from imperfect specs.

Generate a TypeScript client using the Zoom pattern:

```bash

# Download the spec

curl -o zoom-api-v2.json \
  https://raw.githubusercontent.com/zoom/api/442998230a148f403c3d1de1fe7aa54937354fa9/openapi.v2.json

# Generate client via OpenAPI Generator

npm install @openapitools/openapi-generator-cli -g
openapi-generator-cli generate \
  -i zoom-api-v2.json \
  -g typescript-fetch \
  -o ./zoom-client

```

### Cloudflare Workers: Hono and Zod Integration

For modern implementations, the Cloudflare skill in [`plugins/cloudflare/skills/cloudflare/references/workers/frameworks.md`](https://github.com/openai/plugins/blob/main/plugins/cloudflare/skills/cloudflare/references/workers/frameworks.md) embeds OpenAPI definitions directly in code using the **Hono** framework with `@hono/zod-openapi`.

This approach provides **type-safe validation** and automatic OpenAPI generation from Zod schemas:

```typescript
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';

const app = new OpenAPIHono();

const route = createRoute({
  method: 'get',
  path: '/users/{id}',
  request: { 
    params: z.object({ id: z.string() }) 
  },
  responses: {
    200: {
      description: 'User found',
      content: {
        'application/json': {
          schema: z.object({ 
            id: z.string(),
            name: z.string(),
            email: z.string().email()
          })
        }
      }
    }
  },
});

app.openapi(route, (c) => {
  const { id } = c.req.valid('param');
  return c.json({ id, name: 'Jane Doe', email: 'jane@example.com' });
});

// Expose the generated spec
app.doc('/openapi.json', { 
  openapi: '3.0.0', 
  info: { version: '1.0.0', title: 'API' } 
});

```

## Step-by-Step Implementation Guide

Follow this workflow to structure your complex plugin specification:

1. **Analyze logical domains** (users, meetings, files) and create separate path files for each.
2. **Define reusable schemas** in `components/schemas/` with complete `example` values.
3. **Configure global security** in `components/securitySchemes/` and reference it in the root document.
4. **Standardize pagination** by creating shared parameter components.
5. **Validate the merged spec** using Swagger Editor or `openapi-validator` before deployment.
6. **Publish the specification** at a public URL (e.g., `https://api.example.com/openapi.json`) as demonstrated in [`plugins/replayio/skills/replay-qa-api/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/replayio/skills/replay-qa-api/SKILL.md).
7. **Generate client SDKs** using OpenAPI Generator to verify specification completeness.

## Summary

- **Modular file structure** separates paths, components, and security schemes into reusable files referenced via `$ref`.
- **Consistent naming conventions** (kebab-case paths, camelCase parameters, snake_case payloads) reduce integration errors.
- **Explicit security definitions** in `components.securitySchemes` enable proper authentication handling by the OpenAI plugin host.
- **Pagination parameters** should be defined as reusable components to ensure consistent list behavior.
- **Real-world examples** in `plugins/zoom/` and `plugins/cloudflare/` demonstrate both legacy (Swagger 2.0) and modern (Hono+Zod) approaches.

## Frequently Asked Questions

### How do I handle breaking changes in my OpenAPI specification?

Update the `info.version` field in your root [`openapi.yaml`](https://github.com/openai/plugins/blob/main/openapi.yaml) file following semantic versioning (semver) principles. Avoid removing or renaming existing paths, parameters, or response fields. Instead, deprecate old endpoints using the `deprecated: true` flag and introduce new versions alongside existing ones.

### Can I split my OpenAPI spec across multiple files in the OpenAI plugins repository?

Yes, the modular approach using `$ref` pointers is fully supported. The root document should reference external files for paths, schemas, and security schemes. This pattern is documented in [`plugins/zoom/skills/rest-api/references/full-guide.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/skills/rest-api/references/full-guide.md) and [`plugins/cloudflare/skills/cloudflare/references/c3/api.md`](https://github.com/openai/plugins/blob/main/plugins/cloudflare/skills/cloudflare/references/c3/api.md).

### What authentication schemes does the OpenAI plugin host support?

The host supports OAuth2 (authorization code flow), API keys, and Bearer tokens. Define these in `components/securitySchemes` and reference them globally or per-operation. The Zoom plugin example shows OAuth2 implementation, while the Cloudflare references demonstrate API key patterns.

### How do I validate my OpenAPI specification before deployment?

Use the Swagger Editor online tool or command-line validators like `swagger-codegen validate` or `@apidevtools/swagger-parser`. Validate both individual component files and the fully-resolved merged specification to catch `$ref` errors and schema mismatches before the plugin attempts to load your API definition.