This guide compares the strengths and weaknesses of each tool for this specific task. Choose the tool that best matches your workflow, budget, and technical requirements.
Understanding the Task
When you have an existing API codebase—whether Express, FastAPI, Django, or another framework—creating an OpenAPI specification manually is time-consuming. The AI must analyze your route handlers, function signatures, and data models to generate accurate OpenAPI JSON or YAML.
The quality of the output depends heavily on how well you prompt the AI and how much context you provide about your codebase.
ChatGPT Approach
ChatGPT excels at generating straightforward OpenAPI specifications when given clear code examples. Its strength lies in pattern recognition for common frameworks.
Example Prompt for ChatGPT
Generate an OpenAPI 3.0 spec for this Express route:
// Provide your route code
app.get('/users/:id', async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
});
ChatGPT typically produces a basic OpenAPI spec:
paths:
/users/{id}:
get:
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: User found
content:
application/json:
schema:
type: object
Where ChatGPT Excels
ChatGPT handles single-endpoint generation efficiently. If you need a quick spec for one or two routes, ChatGPT provides usable output with minimal iteration. Its training data includes extensive examples of popular frameworks, so Express, Flask, and FastAPI routes are well-recognized.
ChatGPT Limitations
The main challenge with ChatGPT is context window limitations. For larger codebases with many routes, you must feed endpoints one at a time or in small batches. This fragmentation sometimes leads to inconsistent formatting across endpoints. Additionally, ChatGPT occasionally invents response schemas when your code lacks explicit return types.
Claude Approach
Claude takes a more thorough approach, often asking clarifying questions before generating specifications. Its extended context window allows processing larger code sections simultaneously.
Example Prompt for Claude
Analyze these Express routes and generate a complete OpenAPI 3.0 specification:
const express = require('express');
const router = express.Router();
router.get('/users', async (req, res) => {
const { limit = 10, offset = 0 } = req.query;
const users = await User.find().limit(limit).skip(offset);
res.json({ data: users, total: users.length });
});
router.post('/users', async (req, res) => {
const { email, name } = req.body;
const user = await User.create({ email, name });
res.status(201).json(user);
});
Claude produces more output, including proper query parameter handling and request body schemas:
openapi: 3.0.3
info:
title: Users API
version: 1.0.0
paths:
/users:
get:
operationId: getUsers
parameters:
- name: limit
in: query
schema:
type: integer
default: 10
- name: offset
in: query
schema:
type: integer
default: 0
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/User'
total:
type: integer
post:
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- name
properties:
email:
type: string
format: email
name:
type: string
responses:
'201':
description: User created
Where Claude Excels
Claude handles complex request body schemas with validation rules more accurately. It better understands TypeScript interfaces and can map them to OpenAPI schemas. When you provide multiple related files—controllers, models, and middleware—Claude maintains consistency across the entire specification.
For large codebases, Claude’s ability to process more code at once reduces the iteration cycles needed to complete a full specification.
Claude Limitations
Claude’s thoroughness can be a drawback when you need quick, simple specs. Its responses tend to be longer, which means more tokens consumed. Some users find its formatting less predictable than ChatGPT’s for simple, repetitive tasks.
Side-by-Side Comparison
| Aspect | ChatGPT | Claude |
|---|---|---|
| Context handling | Process in small batches | Handle larger code sections |
| Schema accuracy | Good for simple cases | Better for complex types |
| Speed | Faster for single endpoints | Slightly slower but more complete |
| Consistency | May vary across batches | More consistent within sessions |
TypeScript and Zod Schema Extraction
TypeScript codebases with explicit types give both tools significantly more to work with. The key is providing the type definitions alongside the routes.
ChatGPT with TypeScript types:
// Provide both the type and the handler
interface CreateUserRequest {
email: string;
name: string;
role: 'admin' | 'user' | 'viewer';
organizationId?: string;
}
interface UserResponse {
id: string;
email: string;
name: string;
role: string;
createdAt: string;
}
app.post('/users', async (req: Request<{}, UserResponse, CreateUserRequest>, res) => {
const user = await createUser(req.body);
res.status(201).json(user);
});
With the types provided, ChatGPT maps 'admin' | 'user' | 'viewer' to enum: ['admin', 'user', 'viewer'] in the spec and marks organizationId as optional. Without the types, it guesses based on the handler body.
Claude with Zod schemas:
Claude is particularly effective at converting Zod schemas to OpenAPI:
import { z } from 'zod';
const CreateOrderSchema = z.object({
customerId: z.string().uuid(),
items: z.array(z.object({
productId: z.string().uuid(),
quantity: z.number().int().positive().max(99),
unitPrice: z.number().positive(),
})).min(1).max(50),
shippingAddress: z.object({
street: z.string().max(200),
city: z.string().max(100),
countryCode: z.string().length(2),
postalCode: z.string().regex(/^\d{5}(-\d{4})?$/),
}),
notes: z.string().max(500).optional(),
});
Claude converts this to a complete OpenAPI schema with minItems, maxItems, minimum, maximum, maxLength, pattern, and optional flags all correctly mapped. ChatGPT handles the same input adequately but sometimes flattens nested validation rules.
Handling Authentication and Security Schemes
OpenAPI specs need securitySchemes definitions. Neither tool adds authentication without prompting — but the prompt structure differs.
For ChatGPT, be explicit:
Generate an OpenAPI spec for these routes. Include:
- JWT Bearer token authentication in securitySchemes
- Apply the security scheme to all endpoints except GET /health
- Include 401 and 403 responses on authenticated endpoints
For Claude, provide the middleware:
// Share your auth middleware — Claude infers the security scheme from it
const requireAuth = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
// ...validate token
};
router.get('/orders', requireAuth, async (req, res) => { ... });
router.get('/health', async (req, res) => { ... }); // no auth
Claude reads the middleware application pattern and correctly marks /health as unauthenticated while adding the Bearer security requirement to the other routes.
Validating Generated Specs
Neither tool produces error-free specs on the first pass for complex codebases. Build validation into your workflow:
# Install Redocly CLI
npm install -g @redocly/cli
# Validate the generated spec
redocly lint openapi.yaml
# Common errors to watch for:
# - Missing $ref targets
# - Undeclared path parameters
# - Response schemas referencing undefined components
# - operationId duplicates
ChatGPT tends to produce $ref targets that point to schemas it described in text but never defined in components/schemas. Claude tends to produce over-specified schemas that are technically valid but verbose.
After validation, use redocly bundle to resolve all $ref references into a single self-contained file — useful for sharing with external consumers who may not have access to your internal schema definitions.
Practical Recommendations
For small projects with a handful of endpoints, either tool works well. Feed the code, review the output, and make minor adjustments.
For larger codebases, consider this workflow:
- Use Claude for the initial spec generation—its context handling reduces fragmentation
- Use ChatGPT for targeted fixes and refinements on specific endpoints
- Always validate the output using tools like
swagger-cliorredoclybefore integrating
If your codebase uses TypeScript with explicit type definitions, Claude generally produces more accurate schema mappings. For plain JavaScript with JSDoc comments, ChatGPT’s pattern recognition works well.
The most efficient approach for most teams: write a prompt template specific to your framework and response patterns, store it as a team artifact, and use whichever tool gives you the best acceptance rate on the first pass. Refine the template as you encounter edge cases.
Related Articles
- Generate Openapi Specs from Existing Codebase AI Tools
- ChatGPT vs Claude for Creating Database Migration Scripts
- Claude vs ChatGPT for Creating AWS CDK Infrastructure Stacks
- How to Use AI to Help Designers Write Micro Interaction Spec
- AI Tools for Generating dbt Project Structure from Existing
Built by theluckystrike — More at zovo.one