Documentation
Browse the UI at almanac.wihlarkop.com ↗ or use the API directly. Everything below covers the backend.
Public API available
You can hit the hosted API directly without self-hosting anything:
https://almanac-api.wihlarkop.com Cold start notice: The API sleeps after inactivity. The first request after idle can take up to 50 seconds to respond. Subsequent requests are fast.
Get Started
Run the API locally in under a minute.
1. Clone the repo
git clone https://github.com/wihlarkop/almanac
cd almanac 2. Configure environment
Copy the example env file and edit as needed — all values have sensible defaults.
cp .env.example .env 3. Run
Requires Rust 1.96+.
cargo run API starts at http://localhost:8080.
Interactive docs at /swagger-ui ↗ and /scalar ↗.
Deploy / Self-host
The catalog is baked into the image — no database and no config required to run.
Option A — Pre-built image (fastest)
Pull and run the published image — nothing to clone or build.
docker run -p 8080:8080 ghcr.io/wihlarkop/almanac:latest Pin a release with a version tag, e.g. ghcr.io/wihlarkop/almanac:v0.27.0.
Option B — Build your own image
Clone and build from source — use this to customise the catalog or code.
git clone https://github.com/wihlarkop/almanac
cd almanac
docker build -t almanac .
docker run -p 8080:8080 almanac Deploying to a platform? The deployment guide ↗ covers Render, Fly.io, Railway, Google Cloud Run, and Docker Compose.
Configuration
All environment variables are optional — the defaults work out of the box.
| Variable | Default | Description |
|---|---|---|
| PORT | 8080 | Port the API server listens on. |
| DATA_DIR | . | Directory containing the model catalog data files. |
| REDIS_URL | — | Redis connection string (rediss://...). Required for redis-backed rate limiting and caching. |
| RATE_LIMIT_RPS | — | Max requests per second per IP. Omit to disable rate limiting. |
| RATE_LIMIT_BACKEND | memory | memory or redis. Falls back to memory if REDIS_URL is absent. |
| TRUST_PROXY_HEADERS | false | Set to true only behind a trusted proxy or load balancer so rate limiting uses forwarded client IPs. |
| CACHE_BACKEND | none | none, memory, or redis. Caches all GET /api/v1/* responses. |
| CACHE_TTL_SECS | 300 | Cache time-to-live in seconds. |
| LOG_FORMAT | pretty | pretty for dev, json for production. |
| RUST_LOG | info | Log level: trace, debug, info, warn, error. |
API Reference
Full interactive docs at almanac-api.wihlarkop.com/swagger-ui ↗
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/models | List models with filtering, sorting, and pagination |
| GET | /api/v1/models/:provider/:id | Get a single model by provider and ID |
| GET | /api/v1/providers | List all providers |
| GET | /api/v1/search | Fuzzy search across all models |
| GET | /api/v1/compare | Compare two or more models side by side |
| GET | /api/v1/validate | Validate model IDs and parameter usage |
| GET | /metrics | Prometheus metrics endpoint |
Query parameters — GET /api/v1/models
| Param | Type | Description |
|---|---|---|
| query | string | Search by model name or ID |
| provider | string | Filter by provider ID. Comma-separated for multiple (e.g. openai,anthropic) |
| status | string | active, deprecating, deprecated, or retired |
| capability | string | Filter by capability e.g. vision, tools, json_mode |
| min_context | integer | Minimum context window in tokens |
| max_input_price | float | Maximum input price in $/1M tokens |
| sort | string | provider, id, status, context_window, input_price, or output_price |
| order | string | asc or desc |
| limit | integer | Results per page (default 20, capped by the API) |
| offset | integer | Pagination offset (default 0) |
Response Headers
Every API response includes these headers when the relevant feature is enabled.
| Header | Value | Description |
|---|---|---|
| x-cache | HIT / MISS | Whether the response was served from cache. Only present when CACHE_BACKEND is enabled. |
| x-ratelimit-remaining | e.g. 7 | Requests remaining in the current rate limit window. Only present when RATE_LIMIT_RPS is set. |
| retry-after | e.g. 1 | Seconds to wait before retrying. Only present on 429 Too Many Requests responses. |
| x-request-id | UUID | Unique ID for every request. Useful for debugging. |