KeysIQ Public API
v1 — REST + GraphQL
Programmatic access to the same scoring engine that powers keysiq.xyz. Built for insurance carriers, mortgage underwriters, and anyone running portfolios across the Florida Keys.
Get an API key
Sign up at app.keysiq.xyz, open the Embed → API Keys tab, and create a key with the public-api scope. Free tier is 1,000 requests/month — no credit card.
Pricing
| Tier | Price | Monthly requests | Rate limit |
|---|---|---|---|
| Free dev | $0 | 1,000 | 60 / min |
| Starter | $99/mo | 10,000 | 300 / min |
| Growth | $499/mo | 100,000 | 600 / min |
| Enterprise | contact | custom | custom |
Rate-limit headers (`X-RateLimit-Limit`, `X-Quota-Limit`, `X-Quota-Remaining`) appear on every response. A 429 means either the per-minute bucket is empty (retry in 60s) or the monthly quota is exhausted (resets at the timestamp in `X-RateLimit-Reset`).
Authentication
curl -H "Authorization: Bearer kpa_..." \ https://api.keysiq.xyz/api/v1/parcels/00046800-000000
REST endpoints
/api/v1/parcels/:parcelIdFull property report — all six scores plus raw inputs and source attribution.
/api/v1/parcels?address=<addr>Geocode + lookup. Returns the same shape as a parcel-id lookup.
/api/v1/parcels/:parcelId/scoresJust the six scores — lighter payload for portfolio-wide ETLs.
/api/v1/parcels/:parcelId/comparables?radius_mi=1&limit=5Nearby parcels, ranked by composite score.
/api/v1/batch/lookupBody: { "parcelIds": ["a","b",...] }. Up to 100 ids per call. Per-row ok/error envelope.
/api/v1/layers/flood-zones?bbox=...GeoJSON layers — flood zones, ROGO tiers, SLR scenarios, recent permits.
Response envelope
{
"data": { ... },
"meta": {
"request_id": "01HFG...",
"version": "1.0",
"rate_limit": { "capacity": 600, "remaining": 600, "reset_at": "2026-05-01T00:00:00Z" },
"quota": { "monthly_limit": 10000, "used": 274, "remaining": 9726 }
}
}GraphQL
Same data via POST /api/v1/graphql. Schema includes parcel(id), parcelByAddress(address), comparables, and batchLookup. GraphiQL is enabled on staging.
query ($id: ID!) {
parcel(id: $id) {
parcel_id
address
scores {
composite
flood_risk
insurance_cost_usd_per_year
rogo_buildability
vr_income
climate_resilience
}
}
}Code examples
Node (fetch)
const res = await fetch(
"https://api.keysiq.xyz/api/v1/parcels/00046800-000000",
{ headers: { authorization: `Bearer ${process.env.KEYSIQ_API_KEY}` } }
);
const { data, meta } = await res.json();Python
import os, requests
r = requests.get(
f"https://api.keysiq.xyz/api/v1/parcels/00046800-000000",
headers={"Authorization": f"Bearer {os.environ['KEYSIQ_API_KEY']}"})
print(r.json()["data"]["scores"])Insurance figures are estimates only — not binding quotes. Always verify with a licensed Florida agent before relying on them.
See the changelog for version history.