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.
Install command
npx @skill-hub/cli install itechmeat-llm-code-openapi
Repository
Skill path: skills/openapi
OpenAPI Specification (OAS 3.x): document structure, paths, operations, schemas, parameters, security schemes, and validation.
Open repositoryBest 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
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
```