Last updated
Valid OpenAPI 3.0 Specification
A minimal valid OpenAPI 3.0 spec that passes validation:
openapi: "3.0.3"
info:
title: User API
version: "1.0.0"
description: API for managing users
paths:
/users:
get:
summary: List all users
operationId: listUsers
parameters:
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: string
name:
type: string
email:
type: string
format: email
Common Validation Error — Missing Path Parameter
Every path parameter in the URL template must have a definition:
# INVALID — {userId} in path but no parameter definition
paths:
/users/{userId}:
get:
summary: Get user by ID
responses:
"200":
description: User found
# Validator error:
# Path parameter 'userId' defined in path '/users/{userId}'
# but not declared in operation parameters
# VALID — parameter is defined
paths:
/users/{userId}:
get:
summary: Get user by ID
parameters:
- name: userId
in: path
required: true # Path parameters must be required: true
schema:
type: string
responses:
"200":
description: User found
Common Validation Error — Broken $ref
All $ref references must point to existing definitions:
# INVALID — $ref points to non-existent schema
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/UserResponse" # Does not exist!
# Validator error:
# Could not resolve reference: #/components/schemas/UserResponse
# VALID — schema exists in components
components:
schemas:
UserResponse:
type: object
properties:
id:
type: string
name:
type: string
Request Body Validation
Correct structure for a POST endpoint with a request body:
paths:
/users:
post:
summary: Create a user
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
- email
properties:
name:
type: string
minLength: 1
maxLength: 100
email:
type: string
format: email
responses:
"201":
description: User created
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"400":
description: Invalid request body
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
Security Scheme Validation
Security schemes must be defined before they can be referenced:
# INVALID — security references undefined scheme
paths:
/users:
get:
security:
- BearerAuth: [] # Not defined in components!
# VALID — scheme defined in components
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.example.com/oauth/authorize
tokenUrl: https://auth.example.com/oauth/token
scopes:
read:users: Read user data
write:users: Create and update users
Schema Validation — Correct JSON Schema Usage
Common schema mistakes caught by the validator:
# INVALID — mixing inclusion and exclusion in properties
schema:
type: object
properties:
name:
type: string
additionalProperties: false
required: name # Wrong! required must be an array
# VALID
schema:
type: object
required:
- name
- email
properties:
name:
type: string
email:
type: string
additionalProperties: false
# INVALID — enum with wrong type
schema:
type: integer
enum:
- "active" # String in integer enum!
- "inactive"
# VALID
schema:
type: string
enum:
- active
- inactive
- pending
Validator Warnings — Best Practice Violations
Warnings that don't break the spec but indicate poor design:
# Warning: Duplicate operationId
paths:
/users:
get:
operationId: getUsers # Used twice!
/admin/users:
get:
operationId: getUsers # Duplicate!
# Warning: Missing response for common status codes
paths:
/users/{userId}:
get:
responses:
"200":
description: User found
# Missing 404 — what happens when user doesn't exist?
# Warning: Operation missing operationId
paths:
/users:
get:
summary: List users
# No operationId — code generators will create unpredictable names
OpenAPI 2.0 (Swagger) vs 3.0 Differences
The validator handles both versions — key structural differences:
# OpenAPI 2.0 (Swagger)
swagger: "2.0"
info:
title: My API
version: "1.0"
basePath: /api/v1
consumes:
- application/json
produces:
- application/json
# OpenAPI 3.0
openapi: "3.0.3"
info:
title: My API
version: "1.0.0"
servers:
- url: https://api.example.com/v1
# No global consumes/produces — defined per operation
Circular Reference Detection
Circular $ref references cause infinite loops in code generators:
# PROBLEMATIC — circular reference
components:
schemas:
Category:
type: object
properties:
name:
type: string
subcategories:
type: array
items:
$ref: "#/components/schemas/Category" # Circular!
# Validator warning:
# Circular reference detected: Category → Category
# This may cause issues with some code generators
# Fix — use a separate schema for nested items
components:
schemas:
Category:
type: object
properties:
name:
type: string
subcategories:
type: array
items:
$ref: "#/components/schemas/CategorySummary"
CategorySummary:
type: object
properties:
id:
type: string
name:
type: string