Developer docs
Published zoning content as structured data: municipalities, districts, rules, and reviewed Q&A, every rule with its ordinance citation and source link, plus address-to-district resolution where a public GIS path exists.
ZoningVerdict summarizes public zoning regulations for information purposes. It is not legal advice, professional architectural or engineering services, or a substitute for confirmation with the municipality. Regulations change; verify before acting.
Every response carries that disclaimer and the content pack's last-reviewed date and version, so agents can cite and cache coherently. Draft content never appears through any path.
Authentication
The municipalities and districts endpoints are free and keyless. Rules, questions, and parcel resolve need a key from /api-access (self-serve, shown once), sent as a Bearer token or an X-Api-Key header. Each key includes 100 free calls per month; after that, $0.10 per rules or questions call and $0.25 per parcel resolve, billed through Stripe.
OpenAPI
The schema is served at https://zoningverdict.com/api/v1/openapi.json.
Endpoints
GET /api/v1/municipalities
Published coverage with pack version and last-reviewed date. Free.
curl https://zoningverdict.com/api/v1/municipalities
GET /api/v1/districts?municipality=
District codes, names, and summaries for one municipality. Free.
curl "https://zoningverdict.com/api/v1/districts?municipality=rochester-hills"
GET /api/v1/rules?municipality=&district=&topic=
Structured rules with citations and source URLs. Metered.
curl -H "Authorization: Bearer zvk_..." \ "https://zoningverdict.com/api/v1/rules?municipality=rochester-hills&district=R-2&topic=fences"
GET /api/v1/questions?municipality=&topic=
Reviewed question-and-answer pairs with citations. Metered.
curl -H "Authorization: Bearer zvk_..." \ "https://zoningverdict.com/api/v1/questions?municipality=rochester-hills&topic=adu"
POST /api/v1/parcel/resolve
Address to municipality and district, lookup method disclosed. Metered.
curl -X POST https://zoningverdict.com/api/v1/parcel/resolve \
-H "Authorization: Bearer zvk_..." -H "content-type: application/json" \
-d '{"address": "1000 Rochester Hills Dr, Rochester Hills, MI"}'Recommended flow for agents
Never guess district codes: the discovery calls are free, and an address resolves straight to its district. Every empty result carries a note naming the valid district codes or covered topics, so the next call can succeed.
# Address-first (the usual case)
1. POST /api/v1/parcel/resolve {"address": "..."} -> municipality + district_code
2. GET /api/v1/rules?municipality=...&district=... -> rules with citations
3. GET /api/v1/questions?municipality=... -> reviewed Q&A
# No address? Discover, then fetch (discovery is free and keyless)
1. GET /api/v1/municipalities -> covered slugs
2. GET /api/v1/districts?municipality=... -> valid district codes
3. GET /api/v1/rules?municipality=...&district=...
Same flow over MCP: resolve_parcel_district -> get_district_rules,
or list_municipalities -> list_districts -> get_district_rules.MCP server
The same content is exposed as MCP tools — list_municipalities, list_districts, get_district_rules, ask_zoning_question, and resolve_parcel_district — over the streamable HTTP transport. The two listing tools are free and keyless. Every response carries the disclaimer, pack version, last-reviewed date, and ordinance source link. The paid property brief is deliberately not an MCP tool: the brief stays a human-purchase surface.
Endpoint: https://zoningverdict.com/api/mcp Auth: Authorization: Bearer zvk_... (same keys as the REST API) Trial: no key needed for 3 calls per day per address Free: list_municipalities and list_districts never count
Agent payments (x402)
Agents can also pay per call, no key or account needed. A keyless call to a metered endpoint gets 3 free calls per day per address; past that it returns HTTP 402 with a PAYMENT-REQUIRED header carrying x402 protocol version 2 payment requirements: $0.01 in USDC on Base, exact scheme. Retry with a PAYMENT-SIGNATURE header from any x402 v2 client; the settlement transaction comes back in the PAYMENT-RESPONSE header. Keys remain the better rate at volume.
# One paid call with the x402 fetch wrapper (@x402/fetch):
Price: $0.01 per call, USDC on Base
Endpoints: /api/v1/rules, /api/v1/questions, /api/v1/parcel/resolve
Flow: request -> 402 + PAYMENT-REQUIRED -> sign -> retry with
PAYMENT-SIGNATURE -> 200 + PAYMENT-RESPONSE (settlement)Limits
- Per-key daily limit (default 1,000 calls), reset at midnight UTC.
- Published content only. Topics: permitted_uses, special_land_uses, setbacks, height, lot_coverage, lot_size, parking, adu, accessory_structures, fences, signs, home_occupation, variance_process.
- HTTP errors return {error, message} with conventional status codes.
- Empty results are teaching results: an unknown district returns the valid district codes, and a query with no reviewed answer returns the topics that do have one.