Most legacy APIs lack OpenAPI specifications, making it impossible to generate SDKs, documentation, or proper contract testing. Manually writing OpenAPI specs is tedious and error-prone. Modern AI tools can analyze your existing API code and generate complete, accurate OpenAPI 3.0 specifications in minutes. This guide shows exactly how to use Claude, ChatGPT, and specialized tools to turn any API into a properly documented specification.
Why Generate OpenAPI from Code?
OpenAPI specs enable:
- Auto-generated client SDKs in 15+ languages
- API documentation that stays in sync with implementation
- Contract testing to catch breaking changes
- API gateway configuration and mock servers
- Team onboarding (developers see all endpoints immediately)
The challenge: documenting your actual behavior requires inspecting hundreds of lines of controller code. AI tools automate this extraction.
Tool Comparison for OpenAPI Generation
| Tool | Best For | Code Context | Accuracy | Price |
|---|---|---|---|---|
| Claude 3.5 Sonnet | Complete specs from entire codebase dumps | 200K tokens | 95%+ | $3/MTok |
| ChatGPT-4 | Quick specs from single files | 128K tokens | 85-90% | $0.03/1K |
| Swagger Editor + AI | Visual editing with AI suggestions | Limited | 80% | Free |
| OpenAPI Generator | Code-to-spec with templates | AST-based | 70% | Free |
| AWS API Gateway + Claude | Managed API documentation | AWS logs | 85% | $0.003/request |
Recommendation: Use Claude 3.5 Sonnet for initial generation (paste entire codebase), then use ChatGPT-4 for quick updates to individual endpoints.
Step 1: Extract Your API Code
Gather all controller/route code in one file for AI analysis.
Express.js Example
# Combine all route files
find ./src/routes -name "*.js" -o -name "*.ts" | xargs cat > api_code.txt
# Add middleware definitions too
find ./src/middleware -name "*.js" | xargs cat >> api_code.txt
Create a summary file with endpoint list:
# Quick reference of all routes
grep -r "app\.\(get\|post\|put\|delete\)" ./src/routes | \
sed "s/.*app\.\([a-z]*\)('\([^']*\)'.*/\1 \2/" > routes_summary.txt
Django Example
# Extract URLconf patterns
find ./myapp -name "urls.py" | xargs cat > api_urls.txt
# Get view signatures
grep -r "def\s\+\w\+.*Request\|class.*APIView\|class.*ViewSet" ./myapp > views_summary.txt
Spring Boot Example
# Extract all controller methods
find ./src -name "*Controller.java" | xargs grep -A 5 "@GetMapping\|@PostMapping\|@RequestMapping" > controller_methods.txt
Step 2: Generate with Claude
Paste your code to Claude with this prompt:
Below is my entire Express.js API codebase. Generate a complete
OpenAPI 3.0 specification in YAML format that documents all endpoints.
Include:
- All request/response schemas with examples
- Path parameters with descriptions
- Query parameters with types and defaults
- Request body schemas (content-type application/json)
- All HTTP status codes returned
- Authentication requirements (bearer tokens, API keys)
- Base URL: https://api.example.com/v1
[PASTE YOUR API CODE HERE]
Generate the full openapi.yaml specification:
Claude will output:
openapi: 3.0.0
info:
title: My API
version: "1.0.0"
description: Auto-generated from codebase
servers:
- url: https://api.example.com/v1
paths:
/customers:
get:
summary: List all customers
operationId: listCustomers
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
- name: offset
in: query
schema:
type: integer
default: 0
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Customer'
total:
type: integer
/customers/{id}:
get:
summary: Get customer by ID
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Customer found
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
'404':
description: Customer not found
components:
schemas:
Customer:
type: object
required:
- id
- email
- name
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
created_at:
type: string
format: date-time
Step 3: Generate Client SDKs
Once you have an OpenAPI spec, generate SDKs automatically:
# Install OpenAPI Generator
brew install openapi-generator
# Generate Python client
openapi-generator generate \
-i openapi.yaml \
-g python \
-o ./python-client
# Generate TypeScript client
openapi-generator generate \
-i openapi.yaml \
-g typescript-axios \
-o ./typescript-client
# Generate Go client
openapi-generator generate \
-i openapi.yaml \
-g go \
-o ./go-client
Your generated Python client works immediately:
from openapi_client import ApiClient, CustomerApi
client = ApiClient()
customer_api = CustomerApi(api_client=client)
# Get customer (generated from spec)
customer = customer_api.get_customer(id="123e4567-e89b-12d3-a456-426614174000")
print(customer.email)
Step 4: Advanced OpenAPI Features
Ask Claude to enhance your spec with advanced features:
Request Body Validation
/orders:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrder'
examples:
minimal:
value:
items:
- sku: "SKU123"
quantity: 2
complete:
value:
items:
- sku: "SKU123"
quantity: 2
shipping_address:
street: "123 Main St"
city: "Portland"
zip: "97201"
Authentication Schemes
components:
securitySchemes:
bearer_auth:
type: http
scheme: bearer
bearerFormat: JWT
api_key:
type: apiKey
in: header
name: X-API-Key
security:
- bearer_auth: []
- api_key: []
Rate Limiting Headers
responses:
'200':
description: Success
headers:
X-RateLimit-Limit:
schema:
type: integer
description: Requests allowed per minute
X-RateLimit-Remaining:
schema:
type: integer
description: Requests remaining
X-RateLimit-Reset:
schema:
type: integer
description: Unix timestamp when limit resets
Step 5: Keep OpenAPI In Sync
Set up automation to update your spec as code changes:
Express.js with Swagger JSDoc
npm install swagger-jsdoc swagger-ui-express
Add JSDoc comments to routes:
/**
* @swagger
* /customers:
* get:
* summary: List customers
* responses:
* 200:
* description: Customer list
*/
app.get('/customers', (req, res) => {
// Implementation
});
Generate spec automatically:
const swaggerJsdoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const spec = swaggerJsdoc({
definition: {
openapi: '3.0.0',
info: { title: 'API', version: '1.0.0' },
},
apis: ['./routes/*.js'],
});
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(spec));
Django with drf-spectacular
pip install drf-spectacular
Auto-generates from DRF serializers and viewsets:
# settings.py
INSTALLED_APPS = ['drf_spectacular']
SPECTACULAR_SETTINGS = {
'SCHEMA_PATH_PREFIX': '/api/v[0-9]',
}
# urls.py
from drf_spectacular.views import SpectacularAPIView
urlpatterns = [
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
]
Real-World Example: Convert Legacy REST API
Original undocumented endpoints:
@app.route('/api/products', methods=['GET'])
def get_products():
limit = request.args.get('limit', 20)
offset = request.args.get('offset', 0)
products = db.query(Product).limit(limit).offset(offset).all()
return jsonify([p.to_dict() for p in products])
@app.route('/api/products/<product_id>', methods=['GET'])
def get_product(product_id):
product = db.query(Product).filter_by(id=product_id).first()
if not product:
return jsonify({'error': 'Not found'}), 404
return jsonify(product.to_dict())
@app.route('/api/products', methods=['POST'])
def create_product():
data = request.json
product = Product(name=data['name'], price=data['price'])
db.session.add(product)
db.session.commit()
return jsonify(product.to_dict()), 201
Ask Claude: “Convert this Flask API to OpenAPI 3.0 spec with proper schemas”
Claude generates:
paths:
/api/products:
get:
operationId: listProducts
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
- name: offset
in: query
schema:
type: integer
default: 0
responses:
'200':
description: List of products
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Product'
post:
operationId: createProduct
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateProductRequest'
responses:
'201':
description: Product created
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
/api/products/{product_id}:
get:
operationId: getProduct
parameters:
- name: product_id
in: path
required: true
schema:
type: string
responses:
'200':
description: Product details
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'404':
description: Product not found
components:
schemas:
Product:
type: object
properties:
id:
type: string
name:
type: string
price:
type: number
CreateProductRequest:
type: object
required:
- name
- price
properties:
name:
type: string
price:
type: number
Validation Checklist
After Claude generates your spec, verify:
- All endpoints included (compare against routes file)
- All HTTP methods correct (GET vs POST vs PUT)
- Response schemas match actual JSON structure
- Status codes accurate (200 vs 201 vs 400 vs 404)
- Required fields properly marked
- Examples are realistic and valid
Related Articles
- AI Tools for Generating OpenAPI Specs from Code
- ChatGPT vs Claude for Creating OpenAPI Spec from Existing
- AI Tools for Generating dbt Project Structure from Existing
- Which AI Generates Better SwiftUI Views From Design Swift UI
- AI Tools for Writing OpenAPI Specifications in 2026
Built by theluckystrike — More at zovo.one