Quick Start
HTTP — from an OpenAPI spec
Generate a complete mock config from any OpenAPI 3 spec and start serving immediately:
apitwin generate --spec openapi.yaml --out ./mocks
apitwin --config ./mocksYour mock server is now running at http://localhost:4000 with routes for every operation in the spec.
Tip: Open
http://localhost:4000/__ui/in your browser to see all routes, test requests, and watch config changes in real time. The devtool UI is always available — no extra flags needed.
HTTP — manual scaffold
Create a starter config and point your frontend at apitwin:
apitwin --init
apitwin --target https://api.example.comYour frontend points at http://localhost:4000:
- Matched routes return mock responses
- Everything else proxies to
--target
Edit apitwin.toml to add routes, change responses, or switch between cases — changes apply instantly with no restart.
Tip: Visit
http://localhost:4000/__ui/for a visual dashboard of all your mocked routes.
Minimal config example
[[routes]]
method = "GET"
match = "/api/countries"
enabled = true
fallback = "success"
[routes.cases.success]
status = 200
file = "stubs/countries.json"
[routes.cases.empty]
status = 200
json = '{"countries": []}'
[routes.cases.error]
status = 500
json = '{"message": "Internal Server Error"}'
delay = 2Change fallback from "success" to "empty" or "error" to switch responses. The next request picks up the change automatically.
Add geographic data
Create stub files for your mock data:
stubs/countries.json:
[
{"code": "morocco", "name": "Morocco", "continent": "africa", "capital": "Rabat"},
{"code": "germany", "name": "Germany", "continent": "europe", "capital": "Berlin"},
{"code": "japan", "name": "Japan", "continent": "asia", "capital": "Tokyo"},
{"code": "canada", "name": "Canada", "continent": "north-america", "capital": "Ottawa"}
]Or use directory-based stubs for full CRUD:
[[routes]]
method = "GET"
match = "/api/countries"
fallback = "list"
[routes.cases.list]
file = "stubs/countries/" # Aggregates all .json files in the directorystubs/countries/
├── morocco.json
├── germany.json
├── japan.json
└── canada.jsongRPC — from a .proto file
Generate config and stubs from a proto file, then start both HTTP and gRPC servers:
# Generate config + stubs
apitwin generate --proto service.proto --out ./mocks
# Start servers (HTTP on :4000, gRPC on :50051)
apitwin --config ./mocks --grpc-proto service.protoInspect with grpcurl:
# List all services (via server reflection)
grpcurl -plaintext localhost:50051 list
# Describe a service
grpcurl -plaintext localhost:50051 describe geo.CountryService
# Call a method
grpcurl -plaintext -d '{"country_code":"morocco"}' localhost:50051 geo.CountryService/GetCountryWhat's next?
- Devtool UI — visual dashboard for routes and request testing
- CLI Reference — all flags and subcommands
- Configuration — config file format and options
- Features — conditions, persistence, transitions, and more
- gRPC — gRPC-specific documentation
- Examples — runnable examples for every feature