Detect API response schema drift before it breaks your app.
diffapi is a lightweight CLI tool that monitors API endpoints for schema changes. It records response schemas, compares them over time, and alerts you to breaking changes like removed fields, type changes, or new required fields.
Perfect for:
- CI/CD pipelines testing third-party APIs
- Monitoring APIs you depend on but don't control
- Catching undocumented API changes early
- Tracking API evolution over time
Zero dependencies. Pure Python stdlib only.
pip install diffapiOr run directly:
curl -O https://raw.githubusercontent.com/kriskimmerle/diffapi/main/diffapi.py
chmod +x diffapi.py
./diffapi.py --help# Record a baseline schema
diffapi record https://api.example.com/users
# Later, check for changes
diffapi diff https://api.example.com/usersdiffapi record https://api.example.com/usersThis fetches the API response and stores the schema in .diffapi/schemas/.
diffapi diff https://api.example.com/usersOutput:
β
Response received (HTTP 200)
π Comparing against snapshot from 2025-02-01T10:30:00
π¨ BREAKING CHANGES (2):
- Field removed: $.user.email
~ Type changed at $.user.age: string β integer
β οΈ WARNINGS (1):
~ Nullable changed at $.user.phone: False β True
βΉοΈ INFO (1):
+ Field added: $.user.avatar_url
diffapi record -H "Authorization: Bearer your-token" https://api.example.com/users
diffapi diff -H "Authorization: Bearer your-token" https://api.example.com/usersExit with code 1 if breaking changes are detected:
diffapi diff --check https://api.example.com/usersPerfect for CI pipelines:
# .github/workflows/api-check.yml
name: API Schema Check
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check API schema
run: |
pip install diffapi
diffapi diff --check https://api.partner.com/v1/dataCreate a config file:
{
"endpoints": [
{
"url": "https://api.example.com/users",
"headers": {
"Authorization": "Bearer token123"
}
},
{
"url": "https://api.example.com/posts"
}
]
}Run:
diffapi watch config.jsondiffapi history https://api.example.com/usersOutput:
π Snapshot history for https://api.example.com/users:
2025-02-01T14-30-00.123456
2025-02-01T10-15-00.123456
2025-01-31T22-00-00.123456
Total: 3 snapshots
| Change Type | Severity | Description |
|---|---|---|
| Field removed | π¨ BREAKING | A field that existed before is now missing |
| Type changed | π¨ BREAKING | Field type changed (e.g., string β number) |
| Nullable changed (now required) | π¨ BREAKING | Field that was nullable is now required |
| Nullable changed (now optional) | Field that was required is now nullable | |
| Field added | βΉοΈ INFO | A new field appeared in the response |
-
Schema Extraction: Recursively walks JSON responses and extracts:
- Field names and paths
- Data types (string, number, boolean, array, object, null)
- Nullability
- Array item types
- Nested object structures
-
Storage: Schemas are stored as JSON in
.diffapi/schemas/with timestamps. By default, keeps the 10 most recent snapshots per endpoint. -
Diffing: Compares new schemas against the latest snapshot, detecting:
- Missing fields
- New fields
- Type mismatches
- Nullability changes
-
Reporting: Color-coded output with severity levels (BREAKING, WARNING, INFO)
diffapi diff --save https://api.example.com/usersdiffapi diff --format json https://api.example.com/usersdiffapi --base-dir ./api-snapshots record https://api.example.com/usersdiffapi record --max-snapshots 5 https://api.example.com/users# Daily cron job
0 9 * * * cd /your/project && diffapi diff --check https://api.partner.com/data# In your CI pipeline
diffapi diff --check https://staging-api.yourapp.com/endpoint || exit 1diffapi record https://api.example.com/v1/users
diffapi record https://api.example.com/v2/users
# Compare the snapshots to see what changed between versionsSee the examples/ directory for:
- CI/CD integration examples
- GitHub Actions workflows
- Docker usage
- Config file templates
- Zero dependencies: Uses only Python stdlib (urllib, json, pathlib)
- Simple: One command to record, one to compare
- CI-friendly: Exit codes and JSON output for automation
- Lightweight: Single Python file, ~500 lines
- Fast: Snapshots are local, no external services required
- Only supports JSON responses (not XML, HTML, etc.)
- Assumes GET requests (POST/PUT support coming soon)
- Schema inference is based on first array element
- No support for OAuth flows (use headers for Bearer tokens)
Issues and PRs welcome at https://github.com/kriskimmerle/diffapi
MIT License - see LICENSE
Created by Kris Kimmerle (@kriskimmerle)
Built with β€οΈ for developers who hate API surprises.