Back to skills
SkillHub ClubRun DevOpsFull StackBackendSecurity

openapi

OpenAPI Specification (OAS 3.x): document structure, paths, operations, schemas, parameters, security schemes, and validation.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
10
Hot score
84
Updated
March 20, 2026
Overall rating
C1.4
Composite score
1.4
Best-practice grade
C64.8

Install command

npx @skill-hub/cli install itechmeat-llm-code-openapi
apidocumentationspecificationvalidation

Repository

itechmeat/llm-code

Skill path: skills/openapi

OpenAPI Specification (OAS 3.x): document structure, paths, operations, schemas, parameters, security schemes, and validation.

Open repository

Best for

Primary workflow: Run DevOps.

Technical facets: Full Stack, Backend, Security.

Target audience: everyone.

License: name: Apache 2.0.

Original source

Catalog source: SkillHub Club.

Repository owner: itechmeat.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install openapi into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/itechmeat/llm-code before adding openapi to shared team environments
  • Use openapi for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: openapi
description: "OpenAPI Specification (OAS 3.x): document structure, paths, operations, schemas, parameters, security schemes, and validation."
version: "3.2.0"
release_date: "2025-09-19"
---

# OpenAPI Specification

This skill provides guidance for working with OpenAPI Specification (OAS) documents.

**Current version:** OpenAPI 3.2.0 (September 2025)

## Quick Navigation

- Document structure: `references/document-structure.md`
- Operations & paths: `references/operations.md`
- Schemas & data types: `references/schemas.md`
- Parameters & serialization: `references/parameters.md`
- Security: `references/security.md`

## When to Use

- Creating a new OpenAPI specification document
- Describing HTTP API endpoints
- Defining request/response schemas
- Configuring API security (OAuth2, API keys, JWT)
- Validating an existing OpenAPI document
- Generating client/server code from specs

## Document Structure Overview

An OpenAPI document MUST have either an OpenAPI Object or Schema Object at the root.

### Required Fields

```yaml
openapi: 3.2.0 # REQUIRED: OAS version
info: # REQUIRED: API metadata
  title: My API
  version: 1.0.0
```

### Complete Structure

```yaml
openapi: 3.2.0
info:
  title: Example API
  version: 1.0.0
  description: API description (supports CommonMark)
servers:
  - url: https://api.example.com/v1
paths:
  /resources:
    get:
      summary: List resources
      responses:
        "200":
          description: Success
components:
  schemas: {}
  parameters: {}
  responses: {}
  securitySchemes: {}
security:
  - apiKey: []
tags:
  - name: resources
    description: Resource operations
```

## Core Objects Reference

### Info Object

```yaml
info:
  title: Example API # REQUIRED
  version: 1.0.0 # REQUIRED (API version, NOT OAS version)
  summary: Short summary
  description: Full description (CommonMark)
  termsOfService: https://example.com/terms
  contact:
    name: API Support
    url: https://example.com/support
    email: [email protected]
  license:
    name: Apache 2.0
    identifier: Apache-2.0 # OR url (mutually exclusive)
```

### Server Object

```yaml
servers:
  - url: https://api.example.com/v1
    description: Production
  - url: https://{environment}.example.com:{port}/v1
    description: Configurable
    variables:
      environment:
        default: api
        enum: [api, staging, dev]
      port:
        default: "443"
```

### Path Item Object

```yaml
/users/{id}:
  summary: User operations
  parameters:
    - $ref: "#/components/parameters/userId"
  get:
    operationId: getUser
    responses:
      "200":
        description: User found
  put:
    operationId: updateUser
    requestBody:
      $ref: "#/components/requestBodies/UserUpdate"
    responses:
      "200":
        description: User updated
```

### Operation Object

```yaml
get:
  tags: [users]
  summary: Get user by ID
  description: Returns a single user
  operationId: getUserById # MUST be unique across all operations
  parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
  responses:
    "200":
      description: Success
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/User"
    "404":
      description: Not found
  security:
    - bearerAuth: []
  deprecated: false
```

## Schema Recipes

### Basic Object

```yaml
components:
  schemas:
    User:
      type: object
      required: [id, email]
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        age:
          type: integer
          minimum: 0
```

### Composition with allOf

```yaml
ExtendedUser:
  allOf:
    - $ref: "#/components/schemas/User"
    - type: object
      properties:
        role:
          type: string
          enum: [admin, user, guest]
```

### Polymorphism with oneOf

```yaml
Pet:
  oneOf:
    - $ref: "#/components/schemas/Cat"
    - $ref: "#/components/schemas/Dog"
  discriminator:
    propertyName: petType
    mapping:
      cat: "#/components/schemas/Cat"
      dog: "#/components/schemas/Dog"
```

### Nullable and Optional

```yaml
# OAS 3.1+ uses JSON Schema type arrays
properties:
  nickname:
    type: [string, "null"] # nullable
```

## Parameter Locations

| Location     | `in` value    | Notes                               |
| ------------ | ------------- | ----------------------------------- |
| Path         | `path`        | MUST be required: true              |
| Query        | `query`       | Standard query parameters           |
| Query string | `querystring` | Entire query string as single param |
| Header       | `header`      | Case-insensitive names              |
| Cookie       | `cookie`      | Cookie values                       |

### Parameter Styles

| Style      | `in`  | Type                   | Example (color=blue,black) |
| ---------- | ----- | ---------------------- | -------------------------- |
| simple     | path  | array                  | blue,black                 |
| form       | query | primitive/array/object | color=blue,black           |
| matrix     | path  | primitive/array/object | ;color=blue,black          |
| label      | path  | primitive/array/object | .blue.black                |
| deepObject | query | object                 | color[R]=100&color[G]=200  |

## Security Schemes

### API Key

```yaml
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header # header, query, or cookie
      name: X-API-Key
```

### Bearer Token (JWT)

```yaml
bearerAuth:
  type: http
  scheme: bearer
  bearerFormat: JWT
```

### OAuth2

```yaml
oauth2:
  type: oauth2
  flows:
    authorizationCode:
      authorizationUrl: https://auth.example.com/authorize
      tokenUrl: https://auth.example.com/token
      scopes:
        read:users: Read user data
        write:users: Modify user data
```

### Apply Security

```yaml
# Global (all operations)
security:
  - bearerAuth: []

# Per-operation
paths:
  /public:
    get:
      security: [] # Override: no auth required
  /protected:
    get:
      security:
        - oauth2: [read:users]
```

## Reference Object

Use `$ref` to avoid duplication:

```yaml
# Reference within same document
$ref: '#/components/schemas/User'

# Reference to external file
$ref: './schemas/user.yaml'
$ref: './common.yaml#/components/schemas/Error'
```

## Components Object

Reusable building blocks:

```yaml
components:
  schemas: # Data models
  responses: # Reusable responses
  parameters: # Reusable parameters
  examples: # Reusable examples
  requestBodies: # Reusable request bodies
  headers: # Reusable headers
  securitySchemes: # Security definitions
  links: # Links between operations
  callbacks: # Webhook definitions
  pathItems: # Reusable path items
```

## Best Practices Checklist

- [ ] Include `operationId` for all operations (unique, programming-friendly)
- [ ] Use `$ref` for reusable components
- [ ] Add meaningful `description` fields (supports CommonMark)
- [ ] Define all possible response codes
- [ ] Include `examples` for complex schemas
- [ ] Use `tags` to group related operations
- [ ] Mark deprecated operations with `deprecated: true`
- [ ] Use semantic versioning for `info.version`

## Critical Prohibitions

- Do NOT omit `openapi` and `info` fields (they are REQUIRED)
- Do NOT use duplicate `operationId` values
- Do NOT mix `$ref` with sibling properties in Reference Objects
- Do NOT use path parameters without `required: true`
- Do NOT use implicit OAuth2 flow in new APIs (deprecated)
- Do NOT forget security for protected endpoints

## Validation

### File Naming

- Entry document: `openapi.json` or `openapi.yaml` (recommended)
- Format: JSON or YAML (equivalent)
- All field names are case-sensitive

### Common Validation Errors

| Error                      | Fix                                                   |
| -------------------------- | ----------------------------------------------------- |
| Missing required field     | Add `openapi`, `info.title`, `info.version`           |
| Invalid operationId        | Use unique, valid identifier                          |
| Path parameter not in path | Ensure `{param}` matches parameter name               |
| Duplicate path template    | Remove conflicting `/users/{id}` vs `/users/{userId}` |
| Invalid $ref               | Check URI syntax and target existence                 |

## Links

- Official spec: https://spec.openapis.org/oas/latest.html
- Learning resources: https://learn.openapis.org/
- JSON Schema (for schemas): https://json-schema.org/


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/document-structure.md

```markdown
# OpenAPI Document Structure

Detailed anatomy of an OpenAPI Description (OAD) document.

## Root Object (OpenAPI Object)

The root of every OpenAPI document.

### Required Fields

| Field   | Type   | Description                            |
| ------- | ------ | -------------------------------------- |
| openapi | string | OAS version (e.g., `3.2.0`). REQUIRED. |
| info    | Info   | API metadata. REQUIRED.                |

### At Least One Required

At least one of these MUST be present:

- `paths` - Available API endpoints
- `webhooks` - Incoming webhook definitions
- `components` - Reusable components

### Optional Fields

| Field             | Type                   | Description                          |
| ----------------- | ---------------------- | ------------------------------------ |
| $self             | string                 | Self-assigned URI of this document   |
| jsonSchemaDialect | string                 | Default `$schema` for Schema Objects |
| servers           | [Server]               | Server connectivity info             |
| security          | [Security Requirement] | Global security requirements         |
| tags              | [Tag]                  | Metadata for operation grouping      |
| externalDocs      | External Documentation | Additional documentation             |

## Info Object

API metadata.

```yaml
info:
  title: Pet Store API # REQUIRED
  version: 1.0.0 # REQUIRED (API version)
  summary: A sample pet store API
  description: |
    Full API description.
    Supports **CommonMark** markdown.
  termsOfService: https://example.com/terms/
  contact:
    name: API Support
    url: https://www.example.com/support
    email: [email protected]
  license:
    name: Apache 2.0
    identifier: Apache-2.0 # SPDX identifier
    # OR use url (mutually exclusive with identifier)
    # url: https://www.apache.org/licenses/LICENSE-2.0.html
```

### Important Notes

- `info.version` is the API version, NOT the OAS version
- `license.identifier` and `license.url` are mutually exclusive
- All `description` fields support CommonMark 0.27+

## Server Object

Defines API server(s).

```yaml
servers:
  - url: https://api.example.com/v1
    description: Production server
    name: prod # Optional unique name

  - url: https://{username}.example.com:{port}/{basePath}
    description: Development server
    variables:
      username:
        default: demo
        description: User-specific subdomain
      port:
        enum: ["443", "8443"]
        default: "8443"
      basePath:
        default: v2
```

### URL Resolution

- Server URLs MAY be relative (resolved against document location)
- Path from `paths` is appended to server URL (no relative resolution)
- Default server if not specified: `url: /`

## Paths Object

Container for all API endpoints.

```yaml
paths:
  /pets:
    get:
      summary: List all pets
      responses:
        "200":
          description: A list of pets

  /pets/{petId}:
    parameters:
      - name: petId
        in: path
        required: true
        schema:
          type: string
    get:
      summary: Get a pet by ID
      responses:
        "200":
          description: A single pet
```

### Path Templating

- Path MUST begin with `/`
- Template variables: `{variableName}`
- Concrete paths match before templated
- Templates with same hierarchy but different names are invalid
  - ❌ `/pets/{petId}` and `/pets/{id}` cannot coexist

## Components Object

Holds reusable definitions.

```yaml
components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

  parameters:
    petId:
      name: petId
      in: path
      required: true
      schema:
        type: string

  responses:
    NotFound:
      description: Resource not found

  requestBodies:
    Pet:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Pet"

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
```

### Component Name Restrictions

All component keys MUST match: `^[a-zA-Z0-9\.\-_]+$`

Valid: `User`, `User_1`, `User-Name`, `my.org.User`

## Multi-Document Structure

An OAD MAY span multiple documents connected by `$ref`.

### Entry Document

- Document where parsing begins
- Recommended naming: `openapi.json` or `openapi.yaml`
- Contains root OpenAPI Object

### Referenced Documents

- MUST have OpenAPI Object or Schema Object at root
- Connected via `$ref` fields

### Base URI Resolution

1. `$self` field (highest priority)
2. Encapsulating entity
3. Retrieval URI
4. Configured/default base

## Tags

Organize operations with tags.

```yaml
tags:
  - name: pets
    summary: Pet operations
    description: Everything about pets
    externalDocs:
      url: https://docs.example.com/pets

  - name: users
    summary: User operations
    parent: account # Hierarchical nesting (OAS 3.2+)

paths:
  /pets:
    get:
      tags: [pets] # Reference tags by name
```

### Tag Behavior

- Tags in operations don't need declaration in root `tags`
- Undeclared tags: tool-specific ordering
- Declared tags: ordered as listed
- Each tag name MUST be unique

## External Documentation

```yaml
externalDocs:
  description: Find more info here
  url: https://example.com/docs # REQUIRED, must be URI
```

## Specification Extensions

Extend the specification with custom fields.

```yaml
paths:
  /pets:
    x-rate-limit: 100 # Custom extension
    x-internal-only: true
    get:
      summary: List pets
```

### Rules

- Extension fields MUST begin with `x-`
- Reserved prefixes: `x-oai-`, `x-oas-`
- Value can be any valid JSON value
- Support is OPTIONAL per implementation

```

### references/operations.md

```markdown
# Operations and Paths

Defining API endpoints in OpenAPI.

## Path Item Object

Describes operations available on a single path.

```yaml
/users/{id}:
  $ref: "./paths/users.yaml" # Can reference external file
  summary: User operations
  description: Operations on user resource

  # Common parameters for all operations on this path
  parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string

  # HTTP method operations
  get: {}
  put: {}
  post: {}
  delete: {}
  options: {}
  head: {}
  patch: {}
  trace: {}
  query: {} # IETF draft method

  # Additional/custom methods (OAS 3.2+)
  additionalOperations:
    COPY:
      summary: Copy resource
      responses:
        "200":
          description: Copied

  # Server override
  servers:
    - url: https://special.example.com
```

## Operation Object

Describes a single API operation.

```yaml
get:
  tags: [users]
  summary: Get user by ID # Short summary
  description: | # Long description (CommonMark)
    Returns a single user by their unique identifier.

    ## Usage Notes
    - Rate limited to 100 req/min

  externalDocs:
    url: https://docs.example.com/users

  operationId: getUserById # MUST be unique across API

  parameters:
    - name: include
      in: query
      description: Related resources to include
      schema:
        type: array
        items:
          type: string
          enum: [profile, settings]

  requestBody: # For methods with body
    $ref: "#/components/requestBodies/User"

  responses: # REQUIRED, at least one response
    "200":
      description: Success
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/User"
    "404":
      description: Not found
    default:
      description: Unexpected error

  callbacks:
    onUserUpdate:
      "{$request.body#/callbackUrl}":
        post:
          requestBody:
            content:
              application/json:
                schema:
                  $ref: "#/components/schemas/UserEvent"
          responses:
            "200":
              description: Callback received

  deprecated: false # Mark as deprecated

  security: # Override global security
    - bearerAuth: []
    - {} # Allow anonymous

  servers: # Override servers
    - url: https://special.example.com
```

### operationId Best Practices

```yaml
# Good - programming-friendly, unique, descriptive
operationId: getUserById
operationId: createUser
operationId: listUserOrders

# Bad - not unique, not descriptive
operationId: get
operationId: user
```

## Request Body Object

Describes the request payload.

```yaml
requestBody:
  description: User data to create
  required: true # Defaults to false
  content:
    application/json:
      schema:
        $ref: "#/components/schemas/UserCreate"
      examples:
        basic:
          summary: Basic user
          value:
            name: John Doe
            email: [email protected]

    application/xml:
      schema:
        $ref: "#/components/schemas/UserCreate"

    multipart/form-data: # For file uploads
      schema:
        type: object
        properties:
          file:
            type: string
            format: binary
          metadata:
            type: object
```

### Request Body Location Rules

| HTTP Method       | Request Body Support             |
| ----------------- | -------------------------------- |
| POST, PUT, PATCH  | Fully supported                  |
| GET, DELETE, HEAD | Discouraged (SHOULD avoid)       |
| OPTIONS, TRACE    | Not recommended                  |
| QUERY             | Explicitly supported (RFC draft) |

## Responses Object

Container for possible responses.

```yaml
responses:
  "200": # HTTP status code as string
    description: Success # REQUIRED

  "201":
    description: Created
    headers:
      Location:
        description: URL of created resource
        schema:
          type: string
          format: uri

  "4XX": # Range (400-499)
    description: Client error

  "5XX": # Range (500-599)
    description: Server error

  default: # Catch-all
    description: Unexpected error
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/Error"
```

### Response Status Codes

- Use specific codes when possible
- Ranges (`4XX`, `5XX`) for generic handling
- `default` for undeclared responses
- At least one response code REQUIRED
- Should include successful operation response

## Response Object

Single response definition.

```yaml
"200":
  summary: Successful response # Short summary
  description: Returns the user # REQUIRED

  headers:
    X-Rate-Limit-Remaining:
      description: Remaining requests
      schema:
        type: integer
    X-Rate-Limit-Reset:
      schema:
        type: integer
        format: unix-timestamp

  content:
    application/json:
      schema:
        $ref: "#/components/schemas/User"
      examples:
        admin:
          $ref: "#/components/examples/AdminUser"
        regular:
          value:
            id: "123"
            name: Regular User
            role: user

    text/plain:
      schema:
        type: string

  links:
    GetUserOrders:
      operationId: getUserOrders
      parameters:
        userId: $response.body#/id
      description: Get orders for this user
```

### Content Negotiation

- Key is media type or range (`text/*`, `*/*`)
- More specific types take precedence
- Empty content indicates no body

## Callback Object

Describes out-of-band callbacks.

```yaml
callbacks:
  paymentCallback:
    "{$request.body#/callbackUrl}":
      post:
        summary: Payment status callback
        requestBody:
          content:
            application/json:
              schema:
                type: object
                properties:
                  paymentId:
                    type: string
                  status:
                    type: string
                    enum: [completed, failed]
        responses:
          "200":
            description: Callback acknowledged
```

### Runtime Expressions

Used in callback URLs and link parameters:

| Expression                | Description                    |
| ------------------------- | ------------------------------ |
| `$url`                    | Full request URL               |
| `$method`                 | HTTP method                    |
| `$request.path.name`      | Path parameter value           |
| `$request.query.name`     | Query parameter value          |
| `$request.header.name`    | Request header value           |
| `$request.body#/pointer`  | Request body via JSON Pointer  |
| `$response.header.name`   | Response header value          |
| `$response.body#/pointer` | Response body via JSON Pointer |

## Link Object

Describes relationship between operations.

```yaml
responses:
  "200":
    description: User created
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/User"
    links:
      GetUserById:
        operationId: getUser # Reference by operationId
        parameters:
          userId: $response.body#/id # Map response to param
        description: Get the created user

      GetUserOrders:
        operationRef: "#/paths/~1users~1{userId}~1orders/get"
        parameters:
          userId: $response.body#/id
```

### Link Fields

| Field        | Description                               |
| ------------ | ----------------------------------------- |
| operationId  | Target operation by ID (recommended)      |
| operationRef | Target operation by URI reference         |
| parameters   | Map of parameter name to value/expression |
| requestBody  | Value/expression for request body         |
| description  | Description of the link                   |
| server       | Server object override                    |

## Deprecated Operations

```yaml
get:
  summary: Get user (deprecated)
  deprecated: true # Mark as deprecated
  description: |
    **Deprecated:** Use GET /v2/users/{id} instead.

    This endpoint will be removed in API v3.
  x-deprecated-since: "2024-01-01" # Custom extension
```

```

### references/schemas.md

```markdown
# Schemas and Data Types

OpenAPI uses JSON Schema (Draft 2020-12) for data modeling.

## JSON Schema Types

| Type    | Description                  | Example            |
| ------- | ---------------------------- | ------------------ |
| null    | Null value                   | `null`             |
| boolean | True or false                | `true`, `false`    |
| object  | Key-value pairs              | `{"key": "value"}` |
| array   | Ordered list                 | `[1, 2, 3]`        |
| number  | Any numeric value            | `3.14`, `-42`      |
| string  | Text                         | `"hello"`          |
| integer | Whole numbers (OAS-specific) | `42`, `-1`         |

## Basic Schema Definitions

### String

```yaml
type: string
minLength: 1
maxLength: 255
pattern: "^[a-zA-Z]+$" # Regex pattern
```

### Numeric

```yaml
type: number
minimum: 0
maximum: 100
exclusiveMinimum: 0              # > 0, not >= 0
multipleOf: 0.01                 # Precision constraint

type: integer
format: int32                    # 32-bit signed
format: int64                    # 64-bit signed
```

### Boolean

```yaml
type: boolean
default: false
```

### Array

```yaml
type: array
items:
  type: string
minItems: 1
maxItems: 100
uniqueItems: true # No duplicates
```

### Object

```yaml
type: object
required: # Required properties
  - id
  - name
properties:
  id:
    type: string
  name:
    type: string
  age:
    type: integer
additionalProperties: false # No extra properties
```

## Format Keyword

Common formats for semantic meaning:

| Format        | Type    | Description               |
| ------------- | ------- | ------------------------- |
| int32         | integer | 32-bit signed integer     |
| int64         | integer | 64-bit signed integer     |
| float         | number  | Single precision          |
| double        | number  | Double precision          |
| byte          | string  | Base64 encoded            |
| binary        | string  | Binary data               |
| date          | string  | Full-date (RFC 3339)      |
| date-time     | string  | Date-time (RFC 3339)      |
| duration      | string  | Duration (RFC 3339)       |
| password      | string  | Hint for UI masking       |
| email         | string  | Email address             |
| uri           | string  | URI (RFC 3986)            |
| uri-reference | string  | URI or relative reference |
| uuid          | string  | UUID                      |
| hostname      | string  | Internet hostname         |
| ipv4          | string  | IPv4 address              |
| ipv6          | string  | IPv6 address              |

## Nullable Values (OAS 3.1+)

```yaml
# Use type array for nullable
type: [string, "null"]

# Or with oneOf
oneOf:
  - type: string
  - type: "null"
```

## Composition Keywords

### allOf (AND)

All schemas must be satisfied:

```yaml
allOf:
  - $ref: "#/components/schemas/BaseModel"
  - type: object
    properties:
      extraField:
        type: string
```

**Use case:** Inheritance, extending base schemas.

### oneOf (XOR)

Exactly one schema must match:

```yaml
oneOf:
  - $ref: "#/components/schemas/Cat"
  - $ref: "#/components/schemas/Dog"
```

**Use case:** Polymorphism, mutually exclusive options.

### anyOf (OR)

At least one schema must match:

```yaml
anyOf:
  - type: string
  - type: number
```

**Use case:** Flexible types, multiple valid formats.

### not

Schema must NOT match:

```yaml
not:
  type: string
  pattern: "^admin" # Cannot start with "admin"
```

## Discriminator Object

Helps parsers identify the correct schema in polymorphic types.

```yaml
Pet:
  oneOf:
    - $ref: "#/components/schemas/Cat"
    - $ref: "#/components/schemas/Dog"
    - $ref: "#/components/schemas/Fish"
  discriminator:
    propertyName: petType # Property that identifies type
    mapping:
      cat: "#/components/schemas/Cat"
      dog: "#/components/schemas/Dog"
      fish: "#/components/schemas/Fish"
    defaultMapping: Fish # Default if no match (OAS 3.2+)

Cat:
  type: object
  required: [petType]
  properties:
    petType:
      const: "cat" # Fixed value
    name:
      type: string
    huntingSkill:
      type: string
```

### Discriminator Mapping

- **Implicit:** Uses schema name (e.g., `Cat` → `#/components/schemas/Cat`)
- **Explicit:** Define custom mappings
- Property value determines which schema applies

## Enum and Const

### Enum (multiple allowed values)

```yaml
status:
  type: string
  enum:
    - pending
    - active
    - completed
    - cancelled
```

### Const (single value)

```yaml
type:
  const: "user" # Must be exactly "user"
```

## Default Values

```yaml
properties:
  status:
    type: string
    default: pending # Default if not provided
  count:
    type: integer
    default: 0
```

**Note:** `default` documents receiver behavior, doesn't insert values.

## Read-Only and Write-Only

```yaml
properties:
  id:
    type: string
    readOnly: true # Sent in responses only
  password:
    type: string
    writeOnly: true # Sent in requests only
```

## Deprecated Properties

```yaml
properties:
  oldField:
    type: string
    deprecated: true
    description: Use newField instead
```

## External Documentation

```yaml
User:
  type: object
  externalDocs:
    description: User model documentation
    url: https://docs.example.com/models/user
```

## Binary Data

### Raw Binary (multipart, octet-stream)

```yaml
# No type, indicate binary with contentMediaType
contentMediaType: image/png
```

### Encoded Binary (JSON context)

```yaml
type: string
contentMediaType: image/png
contentEncoding: base64 # or base64url
```

## Examples in Schemas

```yaml
User:
  type: object
  properties:
    id:
      type: string
      example: "usr_123" # Deprecated, use examples
    name:
      type: string
  examples: # Preferred (JSON Schema)
    - id: "usr_123"
      name: "John Doe"
    - id: "usr_456"
      name: "Jane Smith"
```

## Additional Properties

Control extra properties in objects:

```yaml
# Strict - no extra properties
type: object
additionalProperties: false

# Allow any extra properties
additionalProperties: true

# Type extra properties
additionalProperties:
  type: string

# Dictionary/map pattern
type: object
additionalProperties:
  $ref: '#/components/schemas/Value'
```

## Pattern Properties

Properties matching a regex pattern:

```yaml
type: object
patternProperties:
  "^x-": # Extension properties
    type: string
  "^[a-z]{2}$": # Language codes
    type: string
```

## Property Names

Constrain property name format:

```yaml
type: object
propertyNames:
  pattern: "^[a-z][a-zA-Z0-9]*$" # camelCase only
  maxLength: 50
```

## Conditional Schemas

```yaml
if:
  properties:
    type:
      const: admin
then:
  required: [adminLevel]
  properties:
    adminLevel:
      type: integer
      minimum: 1
      maximum: 5
else:
  properties:
    adminLevel: false # Disallow for non-admins
```

## XML Modeling

For XML serialization hints:

```yaml
Pet:
  type: object
  xml:
    name: pet # XML element name
    namespace: http://example.com/schema
    prefix: ex
  properties:
    id:
      type: integer
      xml:
        nodeType: attribute # As XML attribute
    tags:
      type: array
      xml:
        wrapped: true # Wrap in container element
        name: tags
      items:
        type: string
        xml:
          name: tag
```

## Schema References

```yaml
# Internal reference
$ref: '#/components/schemas/User'

# External file
$ref: './schemas/user.yaml'

# External with JSON pointer
$ref: './common.yaml#/components/schemas/Error'
```

**Important:** In Reference Objects, `$ref` cannot have sibling properties except `summary` and `description` which override the referenced values.

## Generic/Template Schemas (Advanced)

Using `$dynamicRef` for generics:

```yaml
GenericList:
  $id: generic-list
  type: array
  items:
    $dynamicRef: "#item"
  $defs:
    defaultItem:
      $dynamicAnchor: item

StringList:
  $id: string-list
  $ref: generic-list
  $defs:
    stringItem:
      $dynamicAnchor: item
      type: string
```

```

### references/parameters.md

```markdown
# Parameters and Serialization

How to define and serialize API parameters.

## Parameter Locations

| `in` value  | Description                                       |
| ----------- | ------------------------------------------------- |
| path        | Part of the URL path (e.g., `/users/{id}`)        |
| query       | Query string parameters (e.g., `?page=1`)         |
| querystring | Entire query string as single parameter (OAS 3.2) |
| header      | HTTP request headers                              |
| cookie      | Cookie values                                     |

## Parameter Object

```yaml
parameters:
  - name: userId # REQUIRED
    in: path # REQUIRED
    required: true # REQUIRED for path params
    description: User identifier
    deprecated: false
    allowEmptyValue: false # Query only, deprecated
    schema:
      type: string
      format: uuid
    example: "123e4567-e89b-12d3-a456-426614174000"
```

## Path Parameters

MUST be `required: true` and match a `{template}` in the path.

```yaml
paths:
  /users/{userId}/orders/{orderId}:
    parameters:
      - name: userId
        in: path
        required: true # MUST be true
        schema:
          type: string
      - name: orderId
        in: path
        required: true
        schema:
          type: string
```

## Query Parameters

```yaml
parameters:
  - name: page
    in: query
    schema:
      type: integer
      minimum: 1
      default: 1

  - name: filter
    in: query
    style: deepObject # For nested objects
    explode: true
    schema:
      type: object
      properties:
        status:
          type: string
        createdAfter:
          type: string
          format: date
```

## Header Parameters

```yaml
parameters:
  - name: X-Request-ID
    in: header
    required: true
    schema:
      type: string
      format: uuid

  - name: Accept-Language
    in: header
    schema:
      type: string
      default: en
```

**Note:** Header names are case-insensitive per HTTP spec.

### Reserved Header Names

These parameter definitions are ignored (handled by OpenAPI):

- `Accept`
- `Content-Type`
- `Authorization`

## Cookie Parameters

```yaml
parameters:
  - name: sessionId
    in: cookie
    required: true
    schema:
      type: string

  - name: preferences
    in: cookie
    style: form
    explode: true
    schema:
      type: object
      properties:
        theme:
          type: string
        language:
          type: string
```

## Serialization Styles

### Style Options

| Style      | `in`          | Array Example (`[3,4,5]`)      | Object Example (`{a:1,b:2}`) |
| ---------- | ------------- | ------------------------------ | ---------------------------- |
| simple     | path, header  | `3,4,5`                        | `a,1,b,2`                    |
| label      | path          | `.3.4.5`                       | `.a.1.b.2`                   |
| matrix     | path          | `;id=3,4,5`                    | `;a=1;b=2` (explode)         |
| form       | query, cookie | `id=3,4,5` or `id=3&id=4&id=5` | `a=1&b=2` (explode)          |
| deepObject | query         | N/A                            | `id[a]=1&id[b]=2`            |

### Default Styles

| Location | Default Style | Default Explode |
| -------- | ------------- | --------------- |
| path     | simple        | false           |
| query    | form          | true            |
| header   | simple        | false           |
| cookie   | form          | true            |

### Explode Behavior

```yaml
# explode: false (default for simple)
# Array [1,2,3] → color=1,2,3
# Object {a:1,b:2} → color=a,1,b,2

# explode: true (default for form)
# Array [1,2,3] → color=1&color=2&color=3
# Object {a:1,b:2} → a=1&b=2
```

## Style Examples

### Simple Style (Path)

```yaml
/files/{path}:
  parameters:
    - name: path
      in: path
      required: true
      style: simple
      explode: false
      schema:
        type: array
        items:
          type: string
```

Input: `["docs", "readme.md"]` → `/files/docs,readme.md`

### Matrix Style (Path)

```yaml
/users{;id}:
  parameters:
    - name: id
      in: path
      required: true
      style: matrix
      schema:
        type: integer
```

Input: `5` → `/users;id=5`

### Label Style (Path)

```yaml
/calendar{.year,month}:
  parameters:
    - name: year
      in: path
      required: true
      style: label
      schema:
        type: integer
    - name: month
      in: path
      required: true
      style: label
      schema:
        type: integer
```

Input: `2024`, `3` → `/calendar.2024.3`

### Form Style (Query)

```yaml
/search:
  parameters:
    - name: tags
      in: query
      style: form
      explode: true # Default for form
      schema:
        type: array
        items:
          type: string
```

Input: `["red", "blue"]` → `?tags=red&tags=blue`

### Deep Object Style (Query)

```yaml
/filter:
  parameters:
    - name: filter
      in: query
      style: deepObject
      explode: true # Required for deepObject
      schema:
        type: object
        properties:
          status:
            type: string
          dateRange:
            type: object
            properties:
              start:
                type: string
              end:
                type: string
```

Input: `{status: "active", dateRange: {start: "2024-01"}}` →
`?filter[status]=active&filter[dateRange][start]=2024-01`

## Content-Based Serialization

For complex serialization, use `content` instead of `schema`:

```yaml
parameters:
  - name: coordinates
    in: query
    content:
      application/json:
        schema:
          type: object
          required: [lat, long]
          properties:
            lat:
              type: number
            long:
              type: number
        examples:
          location:
            value:
              lat: 40.7128
              long: -74.0060
            serializedValue: '{"lat":40.7128,"long":-74.0060}'
```

Result: `?coordinates={"lat":40.7128,"long":-74.0060}` (URL-encoded)

## Allow Reserved Characters

```yaml
parameters:
  - name: callback
    in: query
    allowReserved: true # Don't percent-encode reserved chars
    schema:
      type: string
```

Use for URLs or values containing `:/?#[]@!$&'()*+,;=`

## Empty Values

```yaml
parameters:
  - name: refresh
    in: query
    allowEmptyValue: true # Deprecated, avoid
    schema:
      type: boolean
```

Allows `?refresh=` or `?refresh` (presence indicates true).

**Note:** `allowEmptyValue` is deprecated. Use nullable or boolean instead.

## Parameter Examples

### Single Example

```yaml
parameters:
  - name: userId
    in: path
    required: true
    schema:
      type: string
    example: "usr_abc123"
```

### Multiple Examples

```yaml
parameters:
  - name: format
    in: query
    schema:
      type: string
    examples:
      json:
        summary: JSON format
        value: json
      xml:
        summary: XML format
        value: xml
      csv:
        summary: CSV format
        value: csv
```

### Serialization Examples

```yaml
parameters:
  - name: ids
    in: query
    style: form
    explode: false
    schema:
      type: array
      items:
        type: integer
    examples:
      multiple:
        dataValue: [1, 2, 3]
        serializedValue: "ids=1,2,3"
```

## Header Object

Same as Parameter Object but without `name` and `in`:

```yaml
components:
  headers:
    X-Rate-Limit:
      description: Rate limit remaining
      schema:
        type: integer
    X-Request-ID:
      required: true
      schema:
        type: string
        format: uuid
```

Usage in responses:

```yaml
responses:
  "200":
    headers:
      X-Rate-Limit:
        $ref: "#/components/headers/X-Rate-Limit"
```

## Encoding Object

For multipart/form-data and application/x-www-form-urlencoded:

```yaml
requestBody:
  content:
    multipart/form-data:
      schema:
        type: object
        properties:
          file:
            type: string
            format: binary
          metadata:
            type: object
      encoding:
        file:
          contentType: image/png, image/jpeg
        metadata:
          contentType: application/json
          headers:
            X-Custom-Header:
              schema:
                type: string
```

### Encoding Fields

| Field         | Description                      |
| ------------- | -------------------------------- |
| contentType   | Media type(s) for the property   |
| headers       | Additional headers for multipart |
| style         | Serialization style              |
| explode       | Explode behavior                 |
| allowReserved | Allow reserved characters        |

## Common Patterns

### Pagination

```yaml
parameters:
  - name: page
    in: query
    schema:
      type: integer
      minimum: 1
      default: 1
  - name: limit
    in: query
    schema:
      type: integer
      minimum: 1
      maximum: 100
      default: 20
  - name: offset
    in: query
    schema:
      type: integer
      minimum: 0
```

### Filtering

```yaml
parameters:
  - name: filter
    in: query
    style: deepObject
    explode: true
    schema:
      type: object
      additionalProperties: true
  - name: sort
    in: query
    schema:
      type: string
      pattern: "^[+-]?[a-zA-Z_]+$"
      example: "-createdAt"
```

### ID Parameter (Reusable)

```yaml
components:
  parameters:
    resourceId:
      name: id
      in: path
      required: true
      schema:
        type: string
        pattern: "^[a-z]+_[a-zA-Z0-9]+$"
      example: "usr_abc123"
```

```

### references/security.md

```markdown
# Security Schemes

Defining API authentication and authorization in OpenAPI.

## Security Scheme Types

| Type          | Description                               |
| ------------- | ----------------------------------------- |
| apiKey        | API key in header, query, or cookie       |
| http          | HTTP authentication (Basic, Bearer, etc.) |
| oauth2        | OAuth 2.0 flows                           |
| openIdConnect | OpenID Connect Discovery                  |
| mutualTLS     | Mutual TLS (client certificate)           |

## API Key

```yaml
components:
  securitySchemes:
    # Header-based API key
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key passed in header

    # Query parameter API key
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key

    # Cookie-based API key
    ApiKeyCookie:
      type: apiKey
      in: cookie
      name: api_session
```

### Apply API Key

```yaml
security:
  - ApiKeyHeader: [] # Empty array (no scopes)
```

## HTTP Authentication

### Basic Authentication

```yaml
components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: Base64 encoded username:password
```

### Bearer Token

```yaml
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT # Hint only, not validated
      description: JWT access token
```

### Other HTTP Schemes

```yaml
components:
  securitySchemes:
    DigestAuth:
      type: http
      scheme: digest

    HobaAuth:
      type: http
      scheme: hoba
```

Valid schemes from IANA registry: basic, bearer, digest, hoba, mutual, negotiate, oauth, scram-sha-1, scram-sha-256, vapid.

## OAuth 2.0

### Authorization Code Flow (Recommended)

```yaml
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      description: OAuth 2.0 Authorization Code with PKCE
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          refreshUrl: https://auth.example.com/refresh # Optional
          scopes:
            read:users: Read user information
            write:users: Modify user information
            admin: Full administrative access
```

### Client Credentials Flow

For machine-to-machine authentication:

```yaml
components:
  securitySchemes:
    OAuth2ClientCreds:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.example.com/token
          scopes:
            api:read: Read API data
            api:write: Write API data
```

### Implicit Flow (Deprecated)

**Warning:** Implicit flow is deprecated for security reasons.

```yaml
components:
  securitySchemes:
    OAuth2Implicit:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://auth.example.com/authorize
          scopes:
            read: Read access
```

### Password Flow

```yaml
components:
  securitySchemes:
    OAuth2Password:
      type: oauth2
      flows:
        password:
          tokenUrl: https://auth.example.com/token
          scopes:
            read: Read access
            write: Write access
```

### Device Authorization Flow (OAS 3.2+)

```yaml
components:
  securitySchemes:
    OAuth2Device:
      type: oauth2
      flows:
        deviceAuthorization:
          deviceAuthorizationUrl: https://auth.example.com/device
          tokenUrl: https://auth.example.com/token
          scopes:
            read: Read access
```

### Multiple Flows

```yaml
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            read: Read access
            write: Write access
        clientCredentials:
          tokenUrl: https://auth.example.com/token
          scopes:
            api:admin: Administrative access
```

### OAuth2 Metadata URL (OAS 3.2+)

```yaml
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      oauth2MetadataUrl: https://auth.example.com/.well-known/oauth-authorization-server
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/authorize
          tokenUrl: https://auth.example.com/token
          scopes:
            read: Read access
```

## OpenID Connect

```yaml
components:
  securitySchemes:
    OpenIdConnect:
      type: openIdConnect
      openIdConnectUrl: https://auth.example.com/.well-known/openid-configuration
      description: OpenID Connect authentication
```

The discovery URL provides authorization, token URLs, and supported scopes.

## Mutual TLS

```yaml
components:
  securitySchemes:
    MutualTLS:
      type: mutualTLS
      description: Client certificate required
```

No additional configuration - relies on TLS handshake.

## Applying Security

### Global Security

Apply to all operations:

```yaml
security:
  - BearerAuth: []
```

### Per-Operation Security

```yaml
paths:
  /public/info:
    get:
      security: [] # No authentication required
      responses:
        "200":
          description: Public information

  /users/me:
    get:
      security:
        - BearerAuth: [] # Bearer token required
      responses:
        "200":
          description: Current user
```

### Multiple Options (OR)

Any one scheme satisfies the requirement:

```yaml
security:
  - ApiKeyHeader: []
  - BearerAuth: []
  - OAuth2: [read]
```

### Combined Requirements (AND)

All schemes must be satisfied:

```yaml
security:
  - ApiKeyHeader: []
    BearerAuth: [] # Both required
```

### OAuth2 Scopes

```yaml
security:
  - OAuth2:
      - read:users
      - write:users
```

### Optional Authentication

Include empty object for anonymous access:

```yaml
security:
  - {} # Anonymous allowed
  - BearerAuth: [] # Or authenticated
```

## Security Requirement Object

```yaml
# Format: {scheme_name}: [scope1, scope2, ...]

security:
  # No scopes (apiKey, http, mutualTLS)
  - ApiKey: []

  # With scopes (oauth2, openIdConnect)
  - OAuth2:
      - read
      - write

  # Combined requirements
  - ApiKey: []
    OAuth2:
      - admin
```

## Deprecated Security Schemes

```yaml
components:
  securitySchemes:
    LegacyApiKey:
      type: apiKey
      in: header
      name: X-Legacy-Key
      deprecated: true
      description: |
        **Deprecated:** Use BearerAuth instead.
        Will be removed in API v3.
```

## Common Patterns

### API Key + OAuth2 Fallback

```yaml
security:
  - ApiKey: []
  - OAuth2:
      - read

paths:
  /admin:
    get:
      security:
        - OAuth2:
            - admin # Override: only OAuth2 admin
```

### Webhook Authentication

```yaml
webhooks:
  orderStatus:
    post:
      security:
        - WebhookSignature: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrderStatus"

components:
  securitySchemes:
    WebhookSignature:
      type: apiKey
      in: header
      name: X-Webhook-Signature
      description: HMAC-SHA256 signature of request body
```

### Multi-Tenant API

```yaml
security:
  - BearerAuth: []
    TenantId: [] # Tenant + Auth both required

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
    TenantId:
      type: apiKey
      in: header
      name: X-Tenant-ID
```

## Security Best Practices

### DO

- Use Authorization Code + PKCE for web/mobile apps
- Use Client Credentials for machine-to-machine
- Define clear, granular scopes
- Mark deprecated schemes with `deprecated: true`
- Document security requirements clearly

### DON'T

- Use Implicit flow (deprecated, insecure)
- Use Password flow for third-party apps
- Send API keys in query strings (appears in logs)
- Use Basic auth without HTTPS
- Rely on client-side security alone

## Security Considerations

### Documenting Sensitive Endpoints

```yaml
paths:
  /admin/users:
    get:
      security:
        - OAuth2:
            - admin:users
      tags: [admin]
      x-internal: true # Custom extension for internal APIs
```

### Rate Limiting Documentation

```yaml
paths:
  /api/data:
    get:
      responses:
        "429":
          description: Rate limit exceeded
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
            X-RateLimit-Remaining:
              schema:
                type: integer
            X-RateLimit-Reset:
              schema:
                type: integer
                format: unix-timestamp
```

### Security Filtering

API providers may hide endpoints based on authentication:

- Paths Object MAY be empty (access denied to all)
- Path Item Object MAY be empty (path visible, no operations)
- Undocumented security may exist beyond what's in the spec

```