11 min read
Master OpenAPI Specification to create machine-readable API contracts that enable parallel development, automatic documentation, and client code generation. Learn from the complete AI Prompt Enhancer API specification with real examples and production-ready patterns.
You've planned your API's design and identified your resources, endpoints, and data structures.
Now you need to transform this design into a formal definition that developers and machines can understand and work with.
This is exactly what the OpenAPI Specification solves.
OpenAPI Specification (OAS) provides a standardized format for describing RESTful APIs. It creates a machine-readable definition that makes your API understandable to humans and computers alike.
Think of OpenAPI as the architectural blueprint for your house.
It doesn't build the house itself, but it communicates the design precisely, ensuring everyone involved in construction shares the same understanding of what needs to be built.
We could have jumped into coding when building our AI Prompt Enhancer API. But that approach often leads to:
By defining our API contract first with OpenAPI, we achieved:
This contract-first approach forms the foundation of successful API companies' "API First" methodology.
Let's examine the main sections using our complete AI Prompt Enhancer API specification as a real-world example.
The top level of your OpenAPI document contains essential information about your API:
openapi: 3.0.3
info:
title: AI Prompt Enhancer API
description: |
An API that transforms basic prompts into optimized, context-rich instructions for AI language models.
Works with both Mistral and OpenAI to enhance prompts and generate better AI responses.
version: 1.0.0
contact:
name: AI Prompt Enhancer Team
email: rahul@treblle.com
url: https://prompt-enhancer.ai
license:
name: MIT License
url: https://opensource.org/licenses/MIT
This metadata helps developers understand what your API does and how to get support when needed.
The servers section defines where users can access your API:
servers:
- url: https://prompt-enhancer.ai/v1
description: Production server
- url: https://api.prompt-enhancer.cloudflare.dev/v1
description: Cloudflare CDN
- url: https://cdn.prompt-enhancer.ai/v1
description: CDN-backed production server
- url: http://localhost:5000/v1
description: Local development server
Multiple server definitions help developers understand different environments and choose the appropriate endpoint for their use case.
Tags help organize your API endpoints into logical groups:
tags:
- name: Authentication
description: Authentication endpoints for token management
- name: Prompts
description: Prompt enhancement and management operations
These tags appear in generated documentation, making it easier for developers to find relevant endpoints.
This is where you define your actual API endpoints. Here's our main prompt enhancement endpoint:
paths:
/prompts:
post:
summary: Create an enhanced prompt
description: Takes a basic prompt and returns an optimized, context-rich version
operationId: createEnhancedPrompt
tags:
- Prompts
security:
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PromptRequest"
examples:
basicPrompt:
value:
text: "Write about quantum computing"
format: "structured"
responses:
"200":
description: Successfully enhanced prompt
headers:
Content-Type:
schema:
type: string
description: Content type of the response
example: "application/json"
Content-Encoding:
schema:
type: string
description: Compression method used for the response
example: "gzip"
X-RateLimit-Limit:
$ref: "#/components/headers/X-RateLimit-Limit"
X-RateLimit-Remaining:
$ref: "#/components/headers/X-RateLimit-Remaining"
X-RateLimit-Reset:
$ref: "#/components/headers/X-RateLimit-Reset"
X-Frame-Options:
schema:
type: string
description: Prevents clickjacking attacks
example: "DENY"
content:
application/json:
schema:
$ref: "#/components/schemas/PromptResponse"
examples:
successResponse:
value:
id: "prompt_abc123"
originalText: "Write about quantum computing"
enhancedText: "You are an expert physicist with deep knowledge in quantum mechanics and quantum computing..."
format: "structured"
createdAt: "2023-07-15T14:30:00Z"
Notice how we use $ref
to reference schemas defined elsewhere. This keeps your OpenAPI file DRY (Don't Repeat Yourself) and maintainable.
The components section contains reusable objects referenced throughout your API specification.
Schemas define the structure of your data objects, templates for the JSON data sent to or returned from your API:
components:
schemas:
TokenRequest:
type: object
description: Request to generate an authentication token
required:
- clientSecret
properties:
clientId:
type: string
description: Client identifier
example: "frontend-client"
clientSecret:
type: string
description: Client secret (API key)
example: "your-api-key-here"
TokenResponse:
type: object
description: Authentication token response
properties:
access_token:
type: string
description: JWT access token
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
token_type:
type: string
description: Token type
example: "Bearer"
expires_in:
type: integer
description: Token expiration time in seconds
example: 86400
scope:
type: string
description: Token scope
example: "api:access"
PromptRequest:
type: object
description: Request body for creating or updating a prompt enhancement
required:
- text
properties:
text:
type: string
description: The original prompt text to be enhanced
minLength: 1
maxLength: 8000
example: "Write about quantum computing"
format:
type: string
description: The desired format for the enhanced prompt
enum:
- structured
- paragraph
- bullet
- conversational
default: structured
example: "structured"
PromptResponse:
type: object
description: Response containing the enhanced prompt information
properties:
id:
type: string
description: Unique identifier for the enhanced prompt
example: "prompt_abc123"
originalText:
type: string
description: The original prompt text provided by the user
example: "Write about quantum computing"
enhancedText:
type: string
description: The enhanced, more detailed prompt text
example: "As a professional expert in quantum computing, provide a comprehensive overview..."
format:
type: string
description: The format used for enhancing the prompt
enum:
- structured
- paragraph
- bullet
- conversational
example: "structured"
createdAt:
type: string
format: date-time
description: Timestamp of prompt creation
example: "2023-07-15T14:30:00Z"
updatedAt:
type: string
format: date-time
description: Timestamp of the last prompt update (if applicable)
example: "2023-07-15T15:45:00Z"
Each property can include:
A standardized error response format ensures consistency and makes it easier for clients to handle failures:
Error:
type: object
description: Standard error response format
properties:
error:
type: object
description: Error details
properties:
code:
type: string
description: Machine-readable error code
example: "validation_error"
message:
type: string
description: Human-readable error message
example: "The 'text' field is required"
details:
type: object
description: Additional error details (when available)
example: { "param": "text", "reason": "missing_required_field" }
Define reusable response headers for consistent API behavior:
headers:
X-RateLimit-Limit:
description: Request limit per minute
schema:
type: integer
example: 100
X-RateLimit-Remaining:
description: Remaining requests allowed in the current period
schema:
type: integer
example: 95
X-RateLimit-Reset:
description: The time at which the current rate limit window resets (Unix timestamp)
schema:
type: integer
example: 1626369250
These headers provide crucial information about rate limiting that clients need to implement proper request throttling.
Security defines how your API is protected:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT token obtained from the /auth/tokens endpoint
security:
- BearerAuth: []
Our AI Prompt Enhancer API uses JWT-based Bearer tokens, obtained through the authentication endpoint and used in the Authorization header for subsequent requests.
Here's how we defined our complete authentication flow in OpenAPI:
/auth/tokens:
post:
summary: Generate authentication token
description: Generates a JWT token for API authentication
operationId: generateToken
tags:
- Authentication
security: [] # No auth required for token generation
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TokenRequest"
examples:
basicAuth:
value:
clientId: "frontend-client"
clientSecret: "your-api-key-here"
responses:
"200":
description: Successfully generated token
content:
application/json:
schema:
$ref: "#/components/schemas/TokenResponse"
"400":
description: Bad request - Invalid input
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"401":
description: Unauthorized - Invalid credentials
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
This specification clearly documents how clients should authenticate with your API.
Use $ref
pointers to reuse components rather than duplicating them:
responses:
'400':
description: Bad request - Invalid input
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
'401':
description: Unauthorized - Authentication failed
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
Include realistic examples for requests and responses to help developers understand your API:
examples:
basicPrompt:
value:
text: "Write about quantum computing"
format: "structured"
successResponse:
value:
id: "prompt_abc123"
originalText: "Write about quantum computing"
enhancedText: "You are an expert physicist with deep knowledge in quantum mechanics..."
format: "structured"
createdAt: "2023-07-15T14:30:00Z"
Include important response headers like rate limits and security headers:
headers:
X-RateLimit-Limit:
$ref: "#/components/headers/X-RateLimit-Limit"
X-RateLimit-Remaining:
$ref: "#/components/headers/X-RateLimit-Remaining"
X-Frame-Options:
schema:
type: string
description: Prevents clickjacking attacks
example: "DENY"
Use specific data types and validation rules to make your API predictable:
text:
type: string
description: The original prompt text to be enhanced
minLength: 1
maxLength: 8000
example: "Write about quantum computing"
format:
type: string
description: The desired format for the enhanced prompt
enum:
- structured
- paragraph
- bullet
- conversational
default: structured
Once you have an OpenAPI specification, you can generate interactive documentation. Here's how we implemented this in our AI Prompt Enhancer API:
// Setup Swagger UI in Express
const swaggerUi = require('swagger-ui-express');
const fs = require('fs');
const path = require('path');
function loadOpenApiSpec() {
try {
const publicOpenApiPath = path.join(__dirname, 'public', 'openapi.json');
const rootOpenApiPath = path.join(__dirname, 'openapi.json');
if (fs.existsSync(publicOpenApiPath)) {
return JSON.parse(fs.readFileSync(publicOpenApiPath, 'utf8'));
} else if (fs.existsSync(rootOpenApiPath)) {
return JSON.parse(fs.readFileSync(rootOpenApiPath, 'utf8'));
}
} catch (error) {
console.error('Error loading OpenAPI specification:', error.message);
return {
openapi: "3.0.3",
info: {
title: "AI Prompt Enhancer API",
version: "1.0.0",
description: "Error loading API documentation."
},
paths: {}
};
}
}
const openApiSpec = loadOpenApiSpec();
const swaggerUiOptions = {
explorer: true,
customCss: '.swagger-ui .topbar { display: none }',
swaggerOptions: {
docExpansion: 'list',
filter: true,
tagsSorter: 'alpha',
operationsSorter: 'alpha',
}
};
app.use('/docs', swaggerUi.serve, swaggerUi.setup(openApiSpec, swaggerUiOptions));
This creates interactive documentation available at /docs
that allows developers to test API endpoints directly.
Generate client libraries in various programming languages:
# Generate a TypeScript client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g typescript-fetch \
-o ./typescript-client
# Generate a Python client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g python \
-o ./python-client
# Generate a JavaScript client
npx openapi-generator-cli generate \
-i openapi.yaml \
-g javascript \
-o ./javascript-client
One of the biggest advantages of OpenAPI is enabling mock servers for parallel development:
# Create a mock server using Prism
npx @stoplight/prism-cli mock -p 4010 openapi.yaml
# Your mock server is now running at http://localhost:4010
Frontend developers can build against this mock API while backend developers implement the endpoints.
Before sharing your OpenAPI specification, validate it to catch issues:
# Use Spectral for comprehensive linting
npx @stoplight/spectral-cli lint openapi.yaml
# Use Swagger CLI for basic validation
npx swagger-cli validate openapi.yaml
Here's how we integrated OpenAPI into our AI Prompt Enhancer development process:
// Generate JSON from YAML during build
const fs = require('fs');
const YAML = require('yaml');
const yamlContent = fs.readFileSync('openapi.yaml', 'utf8');
const jsonContent = YAML.parse(yamlContent);
fs.writeFileSync('public/openapi.json', JSON.stringify(jsonContent, null, 2));
console.log('OpenAPI JSON generated successfully');
This ensures our documentation stays current with each deployment.
For our AI Prompt Enhancer API, we manage the OpenAPI specification as part of our codebase:
openapi.yaml
file in the repository root./docs
endpointThis approach ensures documentation never becomes outdated.
For the AI Prompt Enhancer API, we followed a documentation-first approach:
This process helped us catch inconsistencies early and provided a clear implementation guide for all team members.
❌ Inconsistent naming: Don't mix camelCase and snake_case in the same API
❌ Missing examples: Examples make your API much easier to understand and test
❌ Vague descriptions: Each field should have a clear, specific description
❌ No validation rules: Use minLength, maxLength, enum, and pattern where appropriate
❌ Incomplete error documentation: Document all possible error responses
❌ Missing security definitions: Clearly document authentication requirements
❌ Outdated specifications: Keep your OpenAPI file synchronized with the implementation
The OpenAPI specification is the single truth source guiding your entire API development process. By defining contracts first, you enable:
Try this contract-first approach on your next API project. Once you experience the benefits of OpenAPI-driven development, you'll wonder how you built APIs without it.