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.