Authentication
Every /v1 request is authenticated with an API key sent in the X-API-Key header.
Sending your key
All /v1 endpoints require an API key. Send it in the X-API-Key header:
Example request
curl "https://graywinston.modavi.me/v1/counties" \
-H "X-API-Key: gw_standard_4f9a…"Keys look like gw_<tier>_<secret>. Treat them like passwords: they are shown once at creation and stored only as a hash.
Tiers
| Tier | Per minute | Per day | Intended for |
|---|---|---|---|
admin | 500 | 50,000 | Full access, including key management |
internal | 240 | 20,000 | Firm staff tools |
standard | 60 | 10,000 | Production client integrations |
free | 10 | 1,000 | Evaluation / light use |
Details in Rate limiting.
Admin: creating and revoking keys
Keys are managed with the admin endpoints (admin tier required). The raw key is returned exactly once, at creation — it cannot be retrieved afterwards.
Create a key
POST /v1/admin/keys
X-API-Key: gw_admin_…
{ "name": "Firm staff tool", "tier": "internal" }
→ 201
{
"id": "…",
"name": "Firm staff tool",
"tier": "internal",
"key_prefix": "gw_internal_4f9a",
"api_key": "gw_internal_4f9a_…full secret, shown once…",
"rate_limit_per_minute": 240,
"rate_limit_per_day": 20000,
"created_at": "2026-10-09T12:00:00Z"
}List keys (prefixes only) / revoke
GET /v1/admin/keys?include_revoked=false
DELETE /v1/admin/keys/{key_id}Revocation is a soft delete: the audit trail is preserved, and the key immediately returns 403.
Auth errors
| Status | Code | Meaning |
|---|---|---|
| 401 | MISSING_API_KEY | No X-API-Key header was sent |
| 401 | INVALID_API_KEY | Unknown key |
| 403 | API_KEY_REVOKED | Key was revoked |
| 403 | ADMIN_REQUIRED | Endpoint needs the admin tier |
| 429 | RATE_LIMIT_EXCEEDED | Over the tier limit — see Retry-After |
Full error envelope shape: Errors.
Bootstrap admin key
The very first admin key can authenticate with the bootstrap key from the backend's
ADMIN_API_KEY setting — no manual SQL needed.