Miami-Dade Property Records API: Address, Flood Zone, Permits
Pricing
from $4.00 / 1,000 property records
Miami-Dade Property Records API: Address, Flood Zone, Permits
Miami-Dade property data API. Look up any address or folio, or search by ZIP, sale date and owner type: beds, baths, value, last sale, FEMA flood zone, permits, violations and a 0-100 lead score. Clean JSON in seconds, no login or proxy.
Pricing
from $4.00 / 1,000 property records
Rating
0.0
(0)
Developer
Nathan Madrishin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 hours ago
Last modified
Categories
Share
Miami-Dade Property Records API: Address Lookup, Flood Zone, Permits & Owner Signals
Turn any Miami-Dade address, folio number or ZIP code into a property dossier in seconds. This Actor reads the Miami-Dade County Property Appraiser roll, FEMA's flood maps and the county's building-permit and code-violation feeds, and returns clean JSON, CSV or Excel: beds, baths, square feet, lot, year built, assessed value, last sale date and price, owner type, absentee-owner flag, FEMA flood zone, recent permits, open violations and a 0-100 prospecting score. No API keys, no logins, no proxies, no scraping of private data.
Use it to look up one address from an agent, to enrich a spreadsheet of addresses, or to build a list ("single-family homes sold in the last 60 days in ZIP 33133, absentee owners only") without touching a website.
At a glance (for people, scripts and AI agents): two modes. Lookup: pass
addressesand/orfolios, get one record per parcel. Search: pass filters (zipCodes,cities,propertyTypes,soldWithinDays, price / age / size filters, owner filters) and get matching parcels, newest sale first. Addenrich: truefor FEMA flood zone, permits, violations, signals and a score. Output is flat, typed JSON. Defaults return the 25 most recent sales countywide in seconds. From $4 per 1,000 records. Snippets for MCP, curl, Python and JavaScript are under "Use it from AI agents, code and no-code tools".
Who it is for
| You are... | Try this |
|---|---|
| A real-estate investor or wholesaler | soldWithinDays, absenteeOwnersOnly, yearBuiltMax, maxAssessedValue |
| A roofer, window, solar, pool or HVAC contractor | Older single-family homes by ZIP, enrich for recent roof permits and open violations |
| An insurance agent or flood-mitigation firm | specialFloodHazardOnly (FEMA zones A, AE, V ...) plus older buildings and high value |
| A mortgage, title or moving company | Homes sold in the last 30 days (soldWithinDays) by ZIP with sale price and date |
| A property manager or landlord service | Entity- or absentee-owned properties near you (entityOwnersOnly, absenteeOwnersOnly) |
| An appraiser, analyst or proptech developer | Address or folio lookup with facts, coordinates and flood zone in one call |
| An AI agent answering "what do we know about 500 Alton Rd #901?" | addresses, enrich |
What you get
| Source | Data |
|---|---|
| Miami-Dade County Property Appraiser | Parcel roll for the whole county: site address and unit, land-use code, beds, baths, heated and total building area, lot size, year built, floors, units, current assessed value, latest recorded sale (date and price), owner type (company, trust or individual) and mailing state, legal description, coordinates |
| FEMA National Flood Hazard Layer | Effective flood zone at the property (AE, X, VE ...), whether it is a Special Flood Hazard Area, base flood elevation where FEMA publishes one |
| Miami-Dade permit feed | Recent building permits (roof, electrical, plumbing, mechanical, pool, demolition ...) by folio: count, latest date, latest roof permit, the most recent permits with work type, contractor company and value |
| Miami-Dade code compliance and building violation cases | Open and closed cases by folio; code cases without a folio are matched by street address (not for condo units) |
Lookup or search
Lookup mode (addresses and/or folios): one record per matching parcel. Addresses can be written any way people write them: 1111 Brickell Ave, Miami, FL 33131, 14332 Southwest 48th Lane, 500 Alton Rd #901. Ordinal and street-type spellings are normalised. For a condo, include the unit; without one you get up to maxUnitsPerAddress units. Addresses or folios that match nothing are not billed and are listed in the SUMMARY record under notFound.
Search mode (everything else): filters run on the county's servers, so a run stays fast. Results come back newest sale first (or best score first with enrich).
Quick start - copy one of these inputs
One address, full dossier
{ "addresses": ["1111 Brickell Ave, Miami, FL 33131"], "enrich": true }
Enrich a list of addresses or folios
{"addresses": ["14332 SW 48 Ln", "500 Alton Rd #901", "1111 Brickell Ave"],"folios": ["01-4115-023-0110"],"enrich": true}
Homes sold in the last 60 days in Coconut Grove and Coral Gables, priced sales only
{"zipCodes": ["33133", "33134"],"propertyTypes": ["single-family"],"soldWithinDays": 60,"excludeNominalSales": true,"maxResults": 300}
Absentee-owned older houses (roofing, insurance and investor leads), ranked
{"cities": ["Hialeah", "Miami Gardens"],"propertyTypes": ["single-family"],"yearBuiltMax": 1985,"absenteeOwnersOnly": true,"enrich": true,"maxResults": 200}
Flood-zone properties for an insurance or mitigation campaign
{"cities": ["Miami Beach"],"propertyTypes": ["single-family", "condo"],"minAssessedValue": 500000,"specialFloodHazardOnly": true,"maxResults": 200}
Run with no input at all to get the 25 most recent sales countywide.
Input
| Field | Default | Notes |
|---|---|---|
addresses | - | free-text Miami-Dade addresses; unit accepted (#901, Apt 4) |
folios | - | 13-digit folio numbers, with or without dashes |
zipCodes, cities | - | search filters; cities are the county's city names (any capitalisation) |
propertyTypes | all | single-family, condo, multifamily, mobile-home, vacant-land, commercial, industrial, agricultural, institutional-government (Florida DOR land-use groups) |
soldWithinDays | - | latest recorded sale within N days (1-3,650); with no other search filter, 30 is used |
minSalePrice, maxSalePrice, excludeNominalSales | - | sale-price filters; excludeNominalSales drops $100-or-less transfers |
yearBuiltMin, yearBuiltMax | - | building age filters |
minAssessedValue, maxAssessedValue | - | county assessed value |
minBedrooms, minLivingArea, minLotSize | - | size filters (sq ft) |
absenteeOwnersOnly, entityOwnersOnly (companies and government), outOfStateOwnersOnly | false | owner filters (the search pool is widened automatically) |
specialFloodHazardOnly, minScore | - | need flood / score data, so they switch enrich on |
enrich | false | flood zone, permits, violations, signals, score; billed at the enriched rate |
requireAddress | true | search mode: skip parcels with no site address |
maxUnitsPerAddress | 10 | lookup mode: units returned when a condo address has no unit |
maxResults | 25 | hard cap on returned and billed records (max 5,000); your run's maximum-charge setting is honoured too |
In lookup mode the search filters are ignored: you asked for those specific properties.
Output example (abridged, enrich: true)
{"recordType": "property","folio": "3000000000000", "folioFormatted": "30-0000-000-0000","address": "1234 EXAMPLE AVE", "unit": null, "city": "Miami", "state": "FL", "zip": "33133", "county": "Miami-Dade","useCode": "0101", "useDescription": "SINGLE FAMILY : 1 UNIT", "propertyType": "single-family","bedrooms": 4, "bathrooms": 3.5, "livingAreaSqft": 2800, "lotSizeSqft": 9000, "yearBuilt": 1958, "buildingAgeYears": 68, "stories": 2,"assessedValue": 1450000, "lastSaleDate": "2026-08-07", "lastSalePrice": 100, "isNominalSale": true, "daysSinceSale": 43,"ownerName": null, "ownerType": "individual", "isAbsenteeOwner": true, "isOutOfStateOwner": true, "isForeignOwner": false, "ownerMailingState": "GA","latitude": 25.74, "longitude": -80.23,"floodZone": "AE", "floodRisk": "high", "isSpecialFloodHazardArea": true, "baseFloodElevationFt": 9,"permits": { "count": 2, "lastIssuedDate": "2026-09-17", "lastRoofPermitDate": "2026-09-17", "recent": [ { "permitNumber": "2026072280", "permitType": "Building", "workType": "RE-ROOF/REPAIR", "issuedDate": "2026-09-17", "contractorCompany": "S&S ROOFING CORPORATION" } ] },"violations": { "openCount": 1, "totalCount": 2, "latestOpenedDate": "2026-09-17", "recent": [ { "caseNumber": "20260250634", "source": "building", "caseType": "Unsafe Structure", "isOpen": true, "openedDate": "2026-09-17", "matchedBy": "folio" } ] },"signals": ["recent-sale", "nominal-transfer", "absentee-owner", "out-of-state-owner", "older-building", "high-value", "special-flood-hazard-area", "open-violation", "recent-permit-activity"],"score": 94,"scoreReasons": ["sold in the last 90 days", "nominal-price transfer (gift, estate, quitclaim or entity change)", "owner mailing address differs from the property", "..."]}
The example values are made up for illustration and do not describe a real property. The run's key-value store also holds a SUMMARY record: mode, filters applied, counts, notFound lookups, warnings and data notes.
Use it from AI agents, code and no-code tools
The Actor is built to be called by machines: a run with the defaults finishes in seconds, every input has a safe default, and the output is flat, typed JSON with a stable schema. There is no login, proxy or browser to configure.
AI agents (MCP). Add the Apify MCP server and expose just this Actor as a tool:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=open-records-data/miami-dade-property-records"}}}
Works with Claude, Cursor, VS Code and any MCP client. Sign in with OAuth, or send an Authorization: Bearer <APIFY_TOKEN> header. Then ask, for example: "Is 500 Alton Rd #901 in a flood zone, and when was it last sold?" or "List single-family homes sold in ZIP 33133 in the last 30 days."
HTTP API (one call, JSON back):
curl -X POST "https://api.apify.com/v2/acts/open-records-data~miami-dade-property-records/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"addresses":["1111 Brickell Ave, Miami, FL 33131"],"enrich":true}'
Python:
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("open-records-data/miami-dade-property-records").call(run_input={"zipCodes": ["33133"], "propertyTypes": ["single-family"], "soldWithinDays": 45, "enrich": True, "maxResults": 100})for p in client.dataset(run["defaultDatasetId"]).iterate_items():print(p["score"], p["address"], p["lastSaleDate"], p["floodZone"], p["signals"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('open-records-data/miami-dade-property-records').call({ folios: ['01-4115-023-0110'], enrich: true });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Schedules and integrations. Put a search on a weekly schedule (for example soldWithinDays: 7) and send the results to Google Sheets, Airtable, Slack or e-mail via Apify integrations, Zapier, Make or n8n, or a webhook into your CRM.
Tips for agents.
- To answer a question about one property, use lookup mode with a small
maxResults; checksummary.notFoundif nothing comes back. - For condos, pass the unit (
#901). A building address without a unit returns the building's own parcel(s) when the county has them, otherwise up tomaxUnitsPerAddressunits. - Use filters instead of downloading everything and filtering yourself; they run server-side.
enrichcosts more per record but adds flood, permits, violations and a ranked score with reasons.lastSalePriceof $100 or less is a nominal transfer (gift, estate, quitclaim, entity change), flagged asisNominalSale; it is not a market price.- Records are public-record data with private owners' names removed. Do not use them for tenant screening, credit, insurance underwriting or employment decisions.
Output fields
| Field | Type | Meaning |
|---|---|---|
folio, folioFormatted, parentFolio | string | 13-digit parcel number, dashed form, and the condo's parent folio |
address, unit, city, state, zip, county | string | Site address (street only), unit, city, state, 5-digit ZIP |
useCode, useDescription, propertyType | string | County land-use code and text; propertyType is the DOR group (single-family, condo, commercial ...) |
isCondoUnit, subdivision, legalDescription | boolean, string | Condo flag, subdivision code, legal description |
bedrooms, bathrooms, livingAreaSqft, buildingAreaSqft, lotSizeSqft, stories, units | number or null | Building facts (half baths count as 0.5) |
yearBuilt, buildingAgeYears | number or null | Year built and age today |
assessmentYear, assessedValue | number | Assessment year and assessed value on the county roll |
lastSaleDate, lastSalePrice, daysSinceSale, pricePerSqft | date, number | The parcel's latest recorded sale (the roll keeps one) |
isNominalSale | boolean | Latest sale was $100 or less |
ownerName, ownerType | string or null, entity | trust | individual | unknown | Name only when the owner is a company or government body; trusts, estates and individuals are withheld |
isAbsenteeOwner | boolean or null | Owner's mailing address differs from the property |
isOutOfStateOwner, isForeignOwner, ownerMailingState, ownerMailingCountry | Where the owner mails from (state and country only; the street address is dropped) | |
latitude, longitude | number | Parcel point, WGS84 |
matchedInput | string | Lookup mode: the address you asked for |
signals | string[] | Plain flags: recent-sale, nominal-transfer, absentee-owner, out-of-state-owner, entity-owned, older-building, high-value, special-flood-hazard-area, open-violation, recent-permit-activity |
floodZone, floodZoneSubtype, floodRisk, isSpecialFloodHazardArea, baseFloodElevationFt | With enrich: FEMA zone; floodRisk is high, moderate, minimal, undetermined or null | |
permits | object | With enrich: count, lastIssuedDate, lastRoofPermitDate, recent[] |
violations | object | With enrich: openCount, totalCount, latestOpenedDate, recent[] |
score, scoreReasons | 0-100, string[] | With enrich: prospecting score and the reasons behind it |
sourceUrl | string | Where to verify the parcel on the county's public property search |
Pricing
Pay per event - you only pay for records you actually receive:
- $4.00 per 1,000 records (
enrichoff) - $20.00 per 1,000 enriched records (
enrichon: flood zone, permits, violations, signals, score) - $0.005 per run start
Lookups that match nothing are not billed. Set a maximum charge on the run and it stops there. Enriching a 300-property list costs about $6.
Privacy by design
- This Actor is not a people finder. Private individuals' names are not returned: owners appear only when the name is a company or government body (trusts and estates are labelled
trustand their names withheld, since they often contain a person's name). Owner mailing street addresses are dropped; only the mailing state and country are kept, to flag absentee and out-of-state owners. - Permit text has phone numbers and e-mails removed. Contractor entries are the licensed company names shown on the permit.
- Not an appraisal, title report or consumer report. Not for FCRA-regulated uses (tenant screening, credit, insurance underwriting, employment).
FAQ
Is this legal? It reads public records that Miami-Dade County and FEMA publish for reuse through their official open-data services. It is not affiliated with or endorsed by either.
How fresh is the data? The property roll is the county's current assessment year (2026 when this was written) and is republished by the county on a regular schedule; the Actor reads the live layers on every run. Sales appear once the county records them.
Why does a home show a $100 sale? Many transfers are recorded for a nominal amount (family gifts, estate transfers, moves into an LLC). They are flagged with isNominalSale. Use excludeNominalSales to skip them.
How far back do permits go? The county's public permit feed is a rolling window of about two years, so "no permits" means none in that window, not none ever. Violation cases go back decades.
Why is a code case missing for a condo unit? Many code cases have no folio and are matched by street address, which is only safe for standalone parcels. Cases with a folio are matched to the unit.
Does it cover Broward or Palm Beach? Not yet. Miami-Dade is first; requests for more counties are welcome on the Issues tab.
Is the score a prediction? No. It is a transparent triage heuristic: scoreReasons says exactly why a record ranks where it does.
More Florida public-record Actors
- Florida New Business Leads - newly licensed businesses in Miami-Dade, Broward and the City of Miami from official business tax receipt feeds.
- Florida Building Permits & Code Violation Leads - fresh permits and open code-violation cases across South and Central Florida, with lead scores.
Limitations
- Coverage is Miami-Dade County. Property facts are only as accurate as the Property Appraiser publishes them.
- The roll holds one sale per parcel (the latest); earlier sales are not available.
- Flood zones are FEMA's effective maps at the parcel point; they are not a flood-insurance determination or elevation certificate.
- Absentee, out-of-state and score fields are heuristics built from public mailing data.