Give the API a US address or a lat/lon and it returns the FEMA flood zone, whether the point is in a Special Flood Hazard Area (SFHA), the FIRM panel and its effective date when available, and a plain-English explanation for a homeowner. Every response is queried live from FEMA at request time and cites its source. Unmapped locations return an explicit unknown — never a silent "safe."
Base URL
https://flood-zone-lookup-fema.netlify.app
No API key, no sign-up, no rate-limit tier — call it directly. A metered plan with support is planned; until it exists, this is the only base URL.
GET /flood-zone
Provide address, OR both lat and lon.
| Param | Type | Required | Notes |
|---|---|---|---|
| address | string | one of | US street address. Geocoded via keyless US Census. |
| lat | number | one of | Latitude −90..90. Requires lon. |
| lon | number | one of | Longitude −180..180. Requires lat. |
Example
GET /flood-zone?address=1 Lincoln Rd, Miami Beach, FL 33139
{
"query": { "address": "1 Lincoln Rd, Miami Beach, FL 33139" },
"location": {
"matchedAddress": "1 LINCOLN RD, MIAMI BEACH, FL, 33139",
"lat": 25.79, "lon": -80.13,
"county": "Miami-Dade County", "zip": "33139"
},
"result": {
"coverage": "mapped",
"isMapped": true,
"floodZone": "AE",
"inSpecialFloodHazardArea": true,
"riskLevel": "high",
"staticBaseFloodElevationFt": 9,
"meaning": "High-risk (Special Flood Hazard Area). 1%+ annual chance of flooding...",
"firmPanel": { "panel": "12086C0317L", "panelNumber": "0317", "suffix": "L", "effectiveDate": "2009-09-11" }
},
"source": {
"floodData": "FEMA National Flood Hazard Layer (NFHL), public ArcGIS MapServer",
"floodService": "https://hazards.fema.gov/arcgis/rest/services/public/NFHL/MapServer",
"geocoder": "US Census Geocoder (geographies/onelineaddress, Public_AR_Current)"
},
"retrievedAt": "2026-07-21T00:00:00.000Z",
"disclaimer": "Flood zone determined live from FEMA's National Flood Hazard Layer..."
}
The coverage field (read this)
| Value | Meaning |
|---|---|
mapped | A flood-hazard polygon covers the point. floodZone / inSpecialFloodHazardArea are definitive. |
mapped_no_zone | Inside FEMA coverage but no polygon at this exact point (open water, "area not included," map seam). Not a "safe" result — nudge the point. |
unmapped | Outside the NFHL entirely. inSpecialFloodHazardArea is null (unknown). Guidance provided. HTTP is still 200. |
inSpecialFloodHazardArea is true, false, or null. It is only false when FEMA has actually mapped the point outside the SFHA. When FEMA has no data, it is null — the API never converts "no data" into "not in a flood zone."FEMA flood zones you'll see
| Zone | SFHA? | Meaning |
|---|---|---|
| A, AE, AH, AO | Yes | High-risk (1% annual chance). AE has a Base Flood Elevation. |
| V, VE | Yes | Highest-risk coastal, with wave action. |
| X (shaded) | No | Moderate — 0.2% annual chance ("500-year"). |
| X (unshaded) | No | Minimal risk. |
| D | No | Undetermined — not studied. |
GET /health
Discovery + uptime document. Returns { "status": "ok", ... } and the endpoint catalog.
Errors
| Status | When |
|---|---|
| 400 | Missing/invalid params (no address and not both lat+lon). |
| 404 | Address could not be geocoded. |
| 422 | lat/lon out of valid range. |
| 405 | Non-GET method. |
| 502 | FEMA service unreachable/errored. Retry shortly. |
Notes
- Keyless and stateless — safe to cache, and safe behind a proxy or gateway.
- CORS is open (
*) so you can call it directly from a browser app. - Data is live FEMA NFHL; treat results as informational, not an official determination.
Machine-readable spec
The full API is described in OpenAPI 3.1 — import it into Postman, Insomnia, or a client generator, or hand it to an agent. The response schemas in it were generated from real responses this API actually returned, not written by hand, so they describe what you will receive rather than what someone intended you to receive.
https://flood-zone-lookup-fema.netlify.app/openapi.json