How to Create an API Mock Server for Development
Build mock API servers for development and testing without dependencies.
Jay Banlasan
The AI Systems Guy
An API mock server for development and testing lets you build and test without depending on live APIs. I use mock servers when working with rate-limited APIs, third-party services that charge per call, or APIs that are simply down. Your development never stops because of someone else's infrastructure.
What You Need Before Starting
- Python 3.8+ with FastAPI and uvicorn installed
- The API documentation or sample responses from the real API
- A folder for mock response data
Step 1: Install Dependencies
pip install fastapi uvicorn
Step 2: Define Mock Response Data
Create a folder structure for your mock data:
mkdir -p mock_data/anthropic mock_data/meta mock_data/stripe
Create mock_data/anthropic/messages.json:
{
"id": "msg_mock_001",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "This is a mock response from the Claude API."
}
],
"model": "claude-sonnet-4-20250514",
"usage": {
"input_tokens": 25,
"output_tokens": 15
}
}
Step 3: Build the Mock Server
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import json
import os
import time
app = FastAPI(title="API Mock Server")
MOCK_DIR = "mock_data"
def load_mock(provider, endpoint):
path = os.path.join(MOCK_DIR, provider, f"{endpoint}.json")
if os.path.exists(path):
with open(path) as f:
return json.load(f)
return {"error": f"No mock data for {provider}/{endpoint}"}
@app.post("/v1/messages")
async def mock_claude_messages(request: Request):
body = await request.json()
response = load_mock("anthropic", "messages")
time.sleep(0.3) # Simulate network latency
return JSONResponse(content=response)
@app.get("/v19.0/{ad_account_id}/insights")
async def mock_meta_insights(ad_account_id: str):
response = load_mock("meta", "insights")
return JSONResponse(content=response)
@app.post("/v1/charges")
async def mock_stripe_charge(request: Request):
response = load_mock("stripe", "charges")
return JSONResponse(content=response)
Step 4: Add Request Logging
Track every request so you can verify your code sends the right data:
import sqlite3
from datetime import datetime
def init_log_db():
conn = sqlite3.connect("mock_requests.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS requests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
method TEXT,
path TEXT,
body TEXT,
headers TEXT,
timestamp TEXT
)
""")
conn.commit()
conn.close()
@app.middleware("http")
async def log_requests(request: Request, call_next):
body = await request.body()
conn = sqlite3.connect("mock_requests.db")
conn.execute(
"INSERT INTO requests (method, path, body, headers, timestamp) VALUES (?,?,?,?,?)",
(request.method, str(request.url.path), body.decode()[:5000],
json.dumps(dict(request.headers)), datetime.utcnow().isoformat())
)
conn.commit()
conn.close()
return await call_next(request)
init_log_db()
Step 5: Run the Mock Server
uvicorn mock_server:app --port 8999 --reload
Point your application at the mock server by changing base URLs:
# In your .env for development
ANTHROPIC_BASE_URL=http://localhost:8999
META_API_BASE_URL=http://localhost:8999
Step 6: Add Dynamic Responses
Make responses change based on input:
@app.post("/v1/messages")
async def mock_claude_messages(request: Request):
body = await request.json()
user_message = body.get("messages", [{}])[-1].get("content", "")
response = load_mock("anthropic", "messages")
response["content"][0]["text"] = f"Mock response to: {user_message[:100]}"
response["usage"]["input_tokens"] = len(user_message.split())
return JSONResponse(content=response)
What to Build Next
Add scenario switching. Let your tests specify which scenario to return (success, error, timeout, rate-limited) by setting a header like X-Mock-Scenario: rate_limited. That lets you test every edge case without touching real APIs.
Related Reading
- Connecting Two Systems with APIs: A Practical Guide - API integration fundamentals
- The Testing Pyramid for AI Operations - testing strategies
- Designing for Failure - handling API failures gracefully
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment