Product
Enterprise
Solutions
DocumentationPricing
Resources
Book a DemoSign InGet Started
Product
Solutions
Solutions
Design Phase | Contract Definition using OpenAPI Specification

Contract Definition using OpenAPI Specification

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.

Cover image

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.

What is the OpenAPI Specification?

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.

Why Define API Contracts First?

We could have jumped into coding when building our AI Prompt Enhancer API. But that approach often leads to:

  • Misaligned expectations between frontend and backend teams
  • Documentation that diverges from the actual implementation
  • Frequent breaking changes that frustrate API consumers
  • Poor developer experience with inconsistent interfaces

By defining our API contract first with OpenAPI, we achieved:

  • Parallel development: Frontend and backend teams worked simultaneously
  • Early testing: QA could begin testing before implementation was complete
  • Automatic client generation: SDKs generated directly from the specification
  • Living documentation: Documentation stayed accurate and current with zero maintenance

This contract-first approach forms the foundation of successful API companies' "API First" methodology.

Components of an OpenAPI Specification

Let's examine the main sections using our complete AI Prompt Enhancer API specification as a real-world example.

Metadata Section

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.

Server Configuration

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.

Organization with Tags

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.

Paths and Operations

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.

Components: Reusable Building Blocks

The components section contains reusable objects referenced throughout your API specification.

Schema Definitions

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:

  • Data type (string, number, boolean, array, object)
  • A description explaining its purpose and usage
  • Example values for documentation and testing
  • Validation constraints (min/max values, regex patterns, length limits)
  • Enumerations of allowed values for controlled inputs

Error Response Standards

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" }

Response Headers

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 Schemes

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.

Authentication Flow Definition

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.

Best Practices for OpenAPI Specifications

Keep It DRY ((Don't Repeat Yourself)) with References

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"

Provide Realistic Examples

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"

Document All Response Headers

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"

Be Specific with Validation

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

Tools for Working with OpenAPI

Generating Interactive Documentation

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.

Client Code Generation

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

API Mocking for Parallel Development

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.

Validation and Quality Assurance

Validating Your OpenAPI Document

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

Integration with Development Workflow

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.

Managing OpenAPI in Your Project

For our AI Prompt Enhancer API, we manage the OpenAPI specification as part of our codebase:

  • Source of truth: openapi.yaml file in the repository root.
  • Generated documentation: JSON version created during the build process
  • Live documentation: Served through Swagger UI at /docs endpoint
  • Automatic updates: Documentation regenerates with each deployment

This approach ensures documentation never becomes outdated.

Documentation-First Development Process

For the AI Prompt Enhancer API, we followed a documentation-first approach:

  1. Define all endpoints in the OpenAPI specification with request/response models
  2. Generate and validate the documentation using automated tools
  3. Create mock servers for frontend development and testing
  4. Implement actual endpoints following the specification exactly
  5. Validate implementation against the original specification

This process helped us catch inconsistencies early and provided a clear implementation guide for all team members.

Common OpenAPI Mistakes to Avoid

❌ 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

Key Takeaways

The OpenAPI specification is the single truth source guiding your entire API development process. By defining contracts first, you enable:

  • Parallel development between the frontend and backend teams
  • Automatic documentation that stays current with implementation
  • Client code generation in multiple programming languages
  • API testing before implementation is complete
  • Clear communication between all stakeholders

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.

© 2025 Treblle. All Rights Reserved.
GDPR BadgeSOC2 BadgeISO BadgeHIPAA Badge