API Management
API Documentation

API Documentation

Comprehensive API documentation is crucial for developer experience and API adoption. Well-structured documentation reduces integration time, minimizes support requests, and enables self-service API consumption.

Documentation Standards

OpenAPI Specification

OpenAPI (formerly Swagger) is the industry standard for API documentation.

# Complete OpenAPI specification example
openapi: 3.0.3
info:
  title: Data Analytics API
  description: |
    The Data Analytics API provides access to data processing and analytics services.
    
    ## Authentication
    All API endpoints require authentication using API keys or JWT tokens.
    
    ## Rate Limits
    - Standard tier: 1000 requests per hour
    - Premium tier: 10000 requests per hour
    
    ## Support
    For support, contact api-support@example.com
  version: 2.1.0
  contact:
    name: API Support Team
    email: api-support@example.com
    url: https://docs.example.com/support
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
 
servers:
  - url: https://api.example.com/v2
    description: Production server
  - url: https://staging-api.example.com/v2
    description: Staging server
  - url: https://dev-api.example.com/v2
    description: Development server
 
security:
  - ApiKeyAuth: []
  - BearerAuth: []
 
paths:
  /datasets:
    get:
      summary: List datasets
      description: |
        Retrieve a paginated list of available datasets.
        
        You can filter datasets by:
        - Category
        - Creation date range
        - Size range
        
        Results are sorted by creation date (newest first) by default.
      tags:
        - Datasets
      parameters:
        - name: category
          in: query
          description: Filter by dataset category
          required: false
          schema:
            type: string
            enum: [sales, marketing, finance, operations]
          example: sales
        - name: limit
          in: query
          description: Maximum number of results per page
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of results to skip for pagination
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
        - name: created_after
          in: query
          description: Filter datasets created after this date
          required: false
          schema:
            type: string
            format: date
          example: "2024-01-01"
      responses:
        '200':
          description: Successfully retrieved datasets
          headers:
            X-Total-Count:
              description: Total number of datasets matching the criteria
              schema:
                type: integer
            X-Rate-Limit-Remaining:
              description: Number of requests remaining in current window
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      ref: '#/components/schemas/Dataset'
                  meta:
                    ref: '#/components/schemas/PaginationMeta'
              examples:
                successful_response:
                  summary: Successful response with datasets
                  value:
                    data:
                      - id: "dataset-123"
                        name: "Sales Q1 2024"
                        category: "sales"
                        size_mb: 1024
                        created_at: "2024-01-15T10:30:00Z"
                    meta:
                      total: 156
                      limit: 20
                      offset: 0
        '400':
          ref: '#/components/responses/BadRequest'
        '401':
          ref: '#/components/responses/Unauthorized'
        '403':
          ref: '#/components/responses/Forbidden'
        '429':
          ref: '#/components/responses/TooManyRequests'
    
    post:
      summary: Create dataset
      description: |
        Upload and create a new dataset in the system.
        
        ### Supported formats:
        - CSV (.csv)
        - JSON (.json)
        - Parquet (.parquet)
        
        ### File size limits:
        - Standard tier: 100MB max
        - Premium tier: 1GB max
      tags:
        - Datasets
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
                - name
                - category
              properties:
                file:
                  type: string
                  format: binary
                  description: Dataset file to upload
                name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: Human-readable name for the dataset
                category:
                  type: string
                  enum: [sales, marketing, finance, operations]
                  description: Dataset category
                description:
                  type: string
                  maxLength: 500
                  description: Optional description of the dataset
                tags:
                  type: array
                  items:
                    type: string
                  maxItems: 10
                  description: Tags for organizing datasets
            encoding:
              file:
                contentType: text/csv, application/json, application/octet-stream
      responses:
        '201':
          description: Dataset created successfully
          content:
            application/json:
              schema:
                ref: '#/components/schemas/Dataset'
        '400':
          ref: '#/components/responses/BadRequest'
        '413':
          description: File too large
          content:
            application/json:
              schema:
                ref: '#/components/schemas/Error'
 
  /datasets/{datasetId}/analytics:
    post:
      summary: Run analytics on dataset
      description: |
        Execute analytical operations on a specific dataset.
        
        ### Available operations:
        - Statistical summaries
        - Correlation analysis
        - Data profiling
        - Custom queries
      tags:
        - Analytics
      parameters:
        - name: datasetId
          in: path
          required: true
          description: Unique identifier of the dataset
          schema:
            type: string
            pattern: '^[a-zA-Z0-9-]+'
          example: "dataset-123"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              ref: '#/components/schemas/AnalyticsRequest'
            examples:
              statistical_summary:
                summary: Generate statistical summary
                value:
                  operation: "statistical_summary"
                  parameters:
                    columns: ["sales", "profit", "quantity"]
                    include_percentiles: true
              correlation_analysis:
                summary: Perform correlation analysis
                value:
                  operation: "correlation"
                  parameters:
                    method: "pearson"
                    columns: ["sales", "marketing_spend"]
      responses:
        '200':
          description: Analytics completed successfully
          content:
            application/json:
              schema:
                ref: '#/components/schemas/AnalyticsResult'
 
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        API key authentication. Include your API key in the X-API-Key header.
        
        Example: `X-API-Key: sk_live_abc123def456`
    
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT token authentication. Include your JWT token in the Authorization header.
        
        Example: `Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`
 
  schemas:
    Dataset:
      type: object
      required:
        - id
        - name
        - category
        - size_mb
        - created_at
      properties:
        id:
          type: string
          description: Unique dataset identifier
          example: "dataset-123"
        name:
          type: string
          description: Human-readable dataset name
          example: "Sales Q1 2024"
        category:
          type: string
          enum: [sales, marketing, finance, operations]
          description: Dataset category
        description:
          type: string
          description: Dataset description
          nullable: true
        size_mb:
          type: number
          format: float
          description: Dataset size in megabytes
          example: 1024.5
        row_count:
          type: integer
          description: Number of rows in the dataset
          example: 150000
        column_count:
          type: integer
          description: Number of columns in the dataset
          example: 25
        created_at:
          type: string
          format: date-time
          description: Dataset creation timestamp
          example: "2024-01-15T10:30:00Z"
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
          example: "2024-01-16T14:22:00Z"
        tags:
          type: array
          items:
            type: string
          description: Dataset tags
          example: ["quarterly", "revenue", "regional"]
        status:
          type: string
          enum: [processing, ready, error]
          description: Current dataset status
          example: "ready"
 
    AnalyticsRequest:
      type: object
      required:
        - operation
      properties:
        operation:
          type: string
          enum: [statistical_summary, correlation, data_profile, custom_query]
          description: Type of analytics operation to perform
        parameters:
          type: object
          description: Operation-specific parameters
          additionalProperties: true
        output_format:
          type: string
          enum: [json, csv, parquet]
          default: json
          description: Desired output format
 
    AnalyticsResult:
      type: object
      properties:
        operation:
          type: string
          description: The operation that was performed
        execution_time_ms:
          type: integer
          description: Execution time in milliseconds
        result:
          type: object
          description: Operation results
          additionalProperties: true
        download_url:
          type: string
          format: uri
          description: URL to download detailed results
          nullable: true
 
    PaginationMeta:
      type: object
      properties:
        total:
          type: integer
          description: Total number of items
        limit:
          type: integer
          description: Maximum items per page
        offset:
          type: integer
          description: Number of items skipped
        has_more:
          type: boolean
          description: Whether there are more items available
 
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Error code for programmatic handling
              example: "INVALID_REQUEST"
            message:
              type: string
              description: Human-readable error message
              example: "The request is invalid"
            details:
              type: object
              description: Additional error details
              additionalProperties: true
            trace_id:
              type: string
              description: Unique identifier for tracking this error
              example: "req_abc123def456"
 
  responses:
    BadRequest:
      description: Bad Request - Invalid input parameters
      content:
        application/json:
          schema:
            ref: '#/components/schemas/Error'
          examples:
            validation_error:
              summary: Validation error
              value:
                error:
                  code: "VALIDATION_ERROR"
                  message: "Request validation failed"
                  details:
                    field_errors:
                      category: "Value must be one of: sales, marketing, finance, operations"
    
    Unauthorized:
      description: Unauthorized - Authentication required
      content:
        application/json:
          schema:
            ref: '#/components/schemas/Error'
    
    Forbidden:
      description: Forbidden - Insufficient permissions
      content:
        application/json:
          schema:
            ref: '#/components/schemas/Error'
    
    TooManyRequests:
      description: Too Many Requests - Rate limit exceeded
      headers:
        Retry-After:
          description: Seconds to wait before making another request
          schema:
            type: integer
      content:
        application/json:
          schema:
            ref: '#/components/schemas/Error'
 
tags:
  - name: Datasets
    description: Dataset management operations
  - name: Analytics
    description: Data analytics and processing operations

Interactive Documentation

Swagger UI Integration

from flask import Flask, render_template_string
from flask_restx import Api, Resource, fields
from flask_restx import Namespace
 
app = Flask(__name__)
api = Api(
    app,
    doc='/docs/',  # Swagger UI endpoint
    title='Data Analytics API',
    version='2.1.0',
    description='Comprehensive data analytics and processing API',
    contact='api-support@example.com',
    license='MIT',
    authorizations={
        'apikey': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'X-API-Key'
        },
        'bearer': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'Authorization',
            'description': 'JWT token with Bearer prefix'
        }
    },
    security=['apikey', 'bearer']
)
 
# Define namespaces
datasets_ns = Namespace('datasets', description='Dataset operations')
analytics_ns = Namespace('analytics', description='Analytics operations')
 
api.add_namespace(datasets_ns)
api.add_namespace(analytics_ns)
 
# Define models for Swagger UI
dataset_model = api.model('Dataset', {
    'id': fields.String(required=True, description='Dataset ID'),
    'name': fields.String(required=True, description='Dataset name'),
    'category': fields.String(required=True, enum=['sales', 'marketing', 'finance']),
    'size_mb': fields.Float(description='Size in MB'),
    'created_at': fields.DateTime(description='Creation timestamp')
})
 
# Resource with detailed documentation
@datasets_ns.route('/')
class DatasetList(Resource):
    @datasets_ns.doc('list_datasets')
    @datasets_ns.param('category', 'Filter by category', type='string')
    @datasets_ns.param('limit', 'Results per page', type='integer', default=20)
    @datasets_ns.param('offset', 'Results offset', type='integer', default=0)
    @datasets_ns.marshal_list_with(dataset_model)
    @datasets_ns.response(200, 'Success')
    @datasets_ns.response(400, 'Bad Request')
    @datasets_ns.response(401, 'Unauthorized')
    def get(self):
        """List all datasets with filtering and pagination"""
        # Implementation here
        pass
    
    @datasets_ns.doc('create_dataset')
    @datasets_ns.expect(dataset_model)
    @datasets_ns.marshal_with(dataset_model, code=201)
    @datasets_ns.response(201, 'Dataset created')
    @datasets_ns.response(400, 'Invalid input')
    def post(self):
        """Create a new dataset"""
        # Implementation here
        pass

Code Examples and SDKs

Multi-Language Examples

Python SDK

# Python SDK example
from dataclasses import dataclass
from typing import List, Optional
import requests
import json
 
@dataclass
class Dataset:
    id: str
    name: str
    category: str
    size_mb: float
    created_at: str
 
class DataAnalyticsClient:
    def __init__(self, api_key: str, base_url: str = "https://api.example.com/v2"):
        self.api_key = api_key
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({
            'X-API-Key': api_key,
            'Content-Type': 'application/json'
        })
    
    def list_datasets(self, category: Optional[str] = None, 
                     limit: int = 20, offset: int = 0) -> List[Dataset]:
        """
        List datasets with optional filtering.
        
        Args:
            category: Filter by dataset category
            limit: Maximum number of results (1-100)
            offset: Number of results to skip
            
        Returns:
            List of Dataset objects
            
        Raises:
            APIError: If the request fails
            
        Example:
            >>> client = DataAnalyticsClient('your-api-key')
            >>> datasets = client.list_datasets(category='sales', limit=10)
            >>> print(f"Found {len(datasets)} datasets")
        """
        params = {
            'limit': limit,
            'offset': offset
        }
        if category:
            params['category'] = category
            
        response = self.session.get(f"{self.base_url}/datasets", params=params)
        response.raise_for_status()
        
        data = response.json()
        return [Dataset(**item) for item in data['data']]
    
    def create_dataset(self, name: str, category: str, 
                      file_path: str, description: Optional[str] = None) -> Dataset:
        """
        Upload and create a new dataset.
        
        Args:
            name: Human-readable dataset name
            category: Dataset category (sales, marketing, finance, operations)
            file_path: Path to the dataset file
            description: Optional dataset description
            
        Returns:
            Created Dataset object
            
        Example:
            >>> client = DataAnalyticsClient('your-api-key')
            >>> dataset = client.create_dataset(
            ...     name="Q1 Sales Data",
            ...     category="sales",
            ...     file_path="./sales_q1.csv",
            ...     description="First quarter sales figures"
            ... )
            >>> print(f"Created dataset: {dataset.id}")
        """
        with open(file_path, 'rb') as f:
            files = {'file': f}
            data = {
                'name': name,
                'category': category
            }
            if description:
                data['description'] = description
                
            response = self.session.post(
                f"{self.base_url}/datasets",
                files=files,
                data=data
            )
            response.raise_for_status()
            
        return Dataset(**response.json())
 
# Usage example
if __name__ == "__main__":
    client = DataAnalyticsClient('sk_live_your_api_key_here')
    
    try:
        # List datasets
        datasets = client.list_datasets(category='sales')
        print(f"Found {len(datasets)} sales datasets")
        
        # Create new dataset
        new_dataset = client.create_dataset(
            name="Monthly Revenue",
            category="finance",
            file_path="revenue_data.csv"
        )
        print(f"Created dataset: {new_dataset.name} ({new_dataset.id})")
        
    except requests.exceptions.HTTPError as e:
        print(f"API error: {e}")

JavaScript/Node.js SDK

// JavaScript SDK example
class DataAnalyticsClient {
    constructor(apiKey, baseUrl = 'https://api.example.com/v2') {
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
        this.headers = {
            'X-API-Key': apiKey,
            'Content-Type': 'application/json'
        };
    }
 
    /**
     * List datasets with optional filtering
     * @param {Object} options - Filter options
     * @param {string} options.category - Filter by category
     * @param {number} options.limit - Maximum results (default: 20)
     * @param {number} options.offset - Results offset (default: 0)
     * @returns {Promise<Array>} Array of dataset objects
     * 
     * @example
     * const client = new DataAnalyticsClient('your-api-key');
     * const datasets = await client.listDatasets({
     *     category: 'sales',
     *     limit: 10
     * });
     * console.log(`Found {datasets.length} datasets`);
     */
    async listDatasets({ category, limit = 20, offset = 0 } = {}) {
        const params = new URLSearchParams({
            limit: limit.toString(),
            offset: offset.toString()
        });
        
        if (category) {
            params.append('category', category);
        }
        
        const response = await fetch(`[mathematical expression]{params}`, {
            headers: this.headers
        });
        
        if (!response.ok) {
            throw new Error(`API error: [mathematical expression]{response.statusText}`);
        }
        
        const data = await response.json();
        return data.data;
    }
 
    /**
     * Create a new dataset by uploading a file
     * @param {Object} options - Dataset creation options
     * @param {string} options.name - Dataset name
     * @param {string} options.category - Dataset category
     * @param {File|Buffer} options.file - File to upload
     * @param {string} [options.description] - Optional description
     * @returns {Promise<Object>} Created dataset object
     * 
     * @example
     * const client = new DataAnalyticsClient('your-api-key');
     * const fileInput = document.getElementById('file-input');
     * const dataset = await client.createDataset({
     *     name: 'Q1 Sales',
     *     category: 'sales',
     *     file: fileInput.files[0],
     *     description: 'First quarter sales data'
     * });
     * console.log(`Created dataset: {dataset.id}`);
     */
    async createDataset({ name, category, file, description }) {
        const formData = new FormData();
        formData.append('name', name);
        formData.append('category', category);
        formData.append('file', file);
        
        if (description) {
            formData.append('description', description);
        }
        
        const response = await fetch(`{this.baseUrl}/datasets`, {
            method: 'POST',
            headers: {
                'X-API-Key': this.apiKey
                // Don't set Content-Type for FormData
            },
            body: formData
        });
        
        if (!response.ok) {
            const error = await response.json();
            throw new Error(`API error: {error.error.message}`);
        }
        
        return await response.json();
    }
}
 
// Usage example
const client = new DataAnalyticsClient('sk_live_your_api_key_here');
 
// List datasets
try {
    const datasets = await client.listDatasets({ category: 'sales' });
    console.log('Sales datasets:', datasets);
} catch (error) {
    console.error('Error listing datasets:', error.message);
}

cURL Examples

# List datasets
curl -X GET "https://api.example.com/v2/datasets?category=sales&limit=10" \
  -H "X-API-Key: sk_live_your_api_key_here" \
  -H "Accept: application/json"
 
# Create dataset
curl -X POST "https://api.example.com/v2/datasets" \
  -H "X-API-Key: sk_live_your_api_key_here" \
  -F "name=Q1 Sales Data" \
  -F "category=sales" \
  -F "description=First quarter sales figures" \
  -F "file=@sales_data.csv"
 
# Run analytics
curl -X POST "https://api.example.com/v2/datasets/dataset-123/analytics" \
  -H "X-API-Key: sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "statistical_summary",
    "parameters": {
      "columns": ["sales", "profit", "quantity"],
      "include_percentiles": true
    }
  }'

Testing Documentation

Postman Collection

{
  "info": {
    "name": "Data Analytics API",
    "description": "Complete test collection for the Data Analytics API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-API-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.example.com/v2"
    },
    {
      "key": "api_key",
      "value": "sk_live_your_api_key_here"
    }
  ],
  "item": [
    {
      "name": "List Datasets",
      "request": {
        "method": "GET",
        "url": {
          "raw": "{{base_url}}/datasets?category=sales&limit=10",
          "host": ["{{base_url}}"],
          "path": ["datasets"],
          "query": [
            {"key": "category", "value": "sales"},
            {"key": "limit", "value": "10"}
          ]
        }
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "exec": [
              "pm.test('Status code is 200', function () {",
              "    pm.response.to.have.status(200);",
              "});",
              "",
              "pm.test('Response has data array', function () {",
              "    const jsonData = pm.response.json();",
              "    pm.expect(jsonData).to.have.property('data');",
              "    pm.expect(jsonData.data).to.be.an('array');",
              "});"
            ]
          }
        }
      ]
    }
  ]
}

Well-documented APIs accelerate adoption, reduce support burden, and improve developer experience. Comprehensive documentation should include detailed specifications, interactive examples, multi-language SDKs, and testing resources to enable successful API integration.