Docs · REST API reference

REST API reference.

For stacks that don't speak MCP. Same data, same auth, same tier gating, just plain HTTPS endpoints.

Eight endpoints, mapped 1:1 to the MCP tools. Every endpoint is POST with a JSON body. Auth is your API key as Authorization: Bearer header (preferred) or ?key= query param.

Base URL · mcp.feasibly.com.au/api/v1 · JSON

Auth & base URL

One key. Two ways to send it.

Every endpoint sits under https://mcp.feasibly.com.au/api/v1/. All tool endpoints use POST with a JSON body. Authenticate with your API key from the dashboard.

# Option 1 — Authorization header (preferred)
curl -X POST "https://mcp.feasibly.com.au/api/v1/lookup" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"12 Smith Street, Brunswick VIC 3056"}'

# Option 2 — ?key= query param
curl -X POST "https://mcp.feasibly.com.au/api/v1/lookup?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"address":"12 Smith Street, Brunswick VIC 3056"}'

All responses are JSON. Errors return { "error": "..." } with appropriate HTTP status: 401 for missing/invalid key, 403 for tier-gated endpoints, 422 for unrecognised addresses, 429 for rate limits, 400 for missing required parameters. The full machine-readable spec lives at https://mcp.feasibly.com.au/api/v1/openapi.json.

Endpoints

Eight endpoints, three tiers.

Every tool is available via REST. Tier gating matches MCP exactly: Free unlocks three endpoints, Pro adds three more, Scale adds one. /usage is auth-only. Stuck on a 401 or a 403? See connect & troubleshoot.

POST/api/v1/lookupFree

Primary site lookup. Body: { "address": "..." } (or { "lat": -37.8, "lng": 144.9 }). Optional: include_enhanced (boolean, fetches easements + adjacent parcels + neighbourhood density), user_persona (developer | planner | agent | first_timer). Returns zone, schedule, overlays, building envelope, source URL. One credit per call.

POST/api/v1/zone-rulesFree

Zone rules without the spatial lookup (VIC). Body: { "zone_code": "GRZ1", "council": "MARIBYRNONG" }. Council name uppercase. Returns council-specific min lot, height, garden area, coverage with confidence + schedule provenance. No credit cost.

POST/api/v1/overlayFree

Overlay explainer. Body: { "overlay_code": "HO" }}: pass the overlay class code (HO, SLO, DDO, BMO...), not a schedule number. Returns plain-English description, clause reference, typical permit triggers. No credit cost.

POST/api/v1/compare-overlaysPro

Side-by-side comparison of multiple overlays. Body: { "overlay_codes": ["HO","SLO","DDO"] }. Returns each with full name + reference info. No credit cost.

POST/api/v1/subdivisionPro

Subdivision yield indicator. Body: { "address": "..." }. Optional: user_persona. Runs the full site lookup then returns property dimensions, planning rules, ResCode envelope, and indicative yield in the planning block. No credit charged — only /lookup, /batch and /compare-sites spend credits.

POST/api/v1/compare-sitesPro

Up to 5 sites in one structured response. Body: { "addresses": ["...", "...", "..."] }}: minimum 2, maximum 5. Each site is processed in parallel; partial failures are reported per-site. Pipeline triage. One credit per site.

POST/api/v1/reportScale

Branded PDF screening report (MarkupGo). Body: { "address": "..." } (or lat/lng). Optional: site_conditions, user_persona. Returns a signed URL valid for 30 days. No credit charged (Agency-tier endpoint; reports are metered by plan, not by credits).

POST/api/v1/usageAuth

Current tier + user identity. Empty body ({}) is fine. No credit cost. Useful for in-app credit-balance displays. Detailed period usage is also exposed via the MCP get_usage tool.

Need an OpenAPI 3.1 spec for code generation? Fetch https://mcp.feasibly.com.au/api/v1/openapi.json: that's the source of truth and gets shipped to ChatGPT Custom GPT manifests too.

Response shape

Same envelope on every endpoint.

Every successful response includes the requested data plus a _meta block with provenance, confidence, and attribution. Code your client to read _meta defensively: it's stable across all endpoints.

{
  "address": "12 Smith Street, Brunswick VIC 3056",
  "council": "Moreland",
  "zone": "GRZ1",
  "rules": {
    "minLotSize": { "value": 300, "source": "vpp_default" },
    "maxHeight":  { "value": 11,  "source": "schedule" },
    "gardenArea": { "value": 0.35, "source": "schedule" }
  },
  "overlays": [
    { "code": "HO47", "title": "Heritage Overlay 47", "permit_triggers": [...] }
  ],
  "_meta": {
    "confidence": "verified_schedule",
    "source_url": "https://planning-schemes.app.planning.vic.gov.au/Moreland/ordinance/32.08-s1",
    "attribution": "Contains data © State of Victoria (DTP) — CC BY 4.0",
    "fetched_at": "2026-04-28T11:32:18Z"
  }
}

_meta.confidence is one of verified_schedule, verified_vpp_default, or unverified_vpp_default: the 3-tier resolution model. Compound responses (compare-sites, compare-overlays) wrap individual results in arrays; the same _meta shape sits on each child.

Ready to integrate?

Get a free key, POST to /api/v1/lookup, parse the JSON.

If we get the zone wrong, that lookup is free and we credit ten more.