API for vendors.
If your software serves a fire department, it can read that department's pre-plans from FirePreplans and stay current. The department makes a key and gives it to you. A key reads only that department's cards.
Get a key
A chief or officer signs in to the department's FirePreplans setup, opens Vendor keys and makes a key with your name on it. They copy it to you once; we keep only a hash, so we cannot read it back or send it again. The department can cancel a key at any time, and it stops at once.
Send the key on every request, as Authorization: Bearer fpp_... or X-Api-Key: fpp_.... Call the API from your server only. A key in a browser or an app can be copied.
Always current
Every card has a link, the url field. The link never changes and always opens the newest card, so the simplest use is to show that link next to the address. To keep your own copy, read every card once, then ask for changes. The cards change when the department changes its setup and when we rebuild them with newer public records. Once an hour is plenty.
Requests
| Request | Returns |
|---|---|
GET /api/v1/cards | Every card of the department: slug, address, box, town, building type, the time it last changed and its link. Add ?box=46-11 for one fire box. |
GET /api/v1/cards/{slug} | One card: every field below, its link and the time it last changed. Add ?raw=1 for the full card data (outline, map and every measurement) the card page draws from. |
GET /api/v1/changes?since={time} | The cards that changed after a time, and the cards taken off. Keep the until value and send it as since next time. |
curl https://firepreplans.com/api/v1/cards \ -H "Authorization: Bearer fpp_..."
One card:
{
"department": { "fdid": "PA-00000", "name": "Example Fire Company" },
"slug": "100-example-rd",
"url": "https://firepreplans.com/plans/46/100-example-rd",
"updated_at": "2026-10-24T21:23:06Z",
"fields": {
"box": "46-11",
"address": "100 Example Rd",
"building_type": "Home",
"water_need_gpm": 550,
"water_plan": "Hydrant",
"hydrant_ft_by_road": 288,
"alert_line": "100 EXAMPLE RD | BOX 46-11 | ...",
...
}
}Changes:
curl "https://firepreplans.com/api/v1/changes?since=2026-10-24T00:00:00Z" \
-H "Authorization: Bearer fpp_..."
{
"since": "2026-10-24T00:00:00Z",
"until": "2026-10-25T06:00:00Z",
"changed": [{ "slug": "100-example-rd", "updated_at": "2026-10-24T21:23:06Z", "what": ["card"] }],
"removed": []
}Every time is UTC, written like 2026-10-24T21:23:06Z.
Fields
An empty field is null. Values marked estimated or unverified stay that way until the department's crew checks the card.
| Field | What it holds |
|---|---|
box | Fire box |
address | Street address |
town | Town or township |
building_type | Home, Apartments or condos, Business, Industry, Church or public, School, Care home, Farm, or Other or vacant |
county_use | The county's land use for the lot |
parcel | County parcel number |
lot_acres | Lot size, acres |
footprint_sqft | Building footprint, square feet (estimated) |
outline_from | How the building outline was found |
roof_peak_ft | Roof peak height, feet (measured, unverified) |
eave_ft | Eave height, feet (measured, unverified) |
life_risk | A care home, school or child care site on the state lists, when there is one |
water_need_gpm | Water the building needs, gallons per minute (estimated) |
need_method | How the water need was worked out |
water_plan | Hydrant, Tanker shuttle, Draft, or No plan fits yet (the department's own words where it set them) |
hydrant | Nearest hydrant |
hydrant_ft_by_road | Feet to that hydrant by road |
hydrant_tested_gpm | The hydrant's tested flow, gallons per minute; empty when not tested |
fill_site | Tanker fill site |
fill_site_estimated | "yes" when the fill site was found on public maps and is not checked yet |
fill_miles | Road miles to the fill site |
tankers | Tankers the shuttle needs |
loop_min | Minutes for one tanker loop |
one_fill_keeps_up | Whether one fill site keeps up with the need |
tank_site_supply_ft | Supply line from the tank site, feet |
draft | Draft site at open water |
draft_ft | Feet to the draft site by road |
ask_on_dispatch | What to ask for on dispatch |
flood_zone | Flood zone |
drive_ft | Drive length, feet |
drive_from | How the drive was measured |
road_mi_from_station | Road miles from the first due station |
station | First due station |
nearest_exposure | The nearest exposure building |
checks_open | Automated checks the crew still has to look at |
crew_question | A question only someone local can answer |
alert_line | The dispatch alert line, as the department set it up |
lat | Latitude of the address point |
lon | Longitude of the address point |
Owner answers
Building owners can tell the department about their building through the code on each card. An officer checks every answer before it goes on a card. When the department ticks owner answers for your key, each card also has owner: the answers the officer approved and when. A changed owner answer shows in changes with "owner" in what. Show owner answers only to the department's members.
Errors
An error comes back as JSON with error and message.
| Status | Meaning |
|---|---|
401 key_missing | No key was sent. |
401 key_invalid | The key is not right, or the department canceled it. Ask the department for a new one. |
404 not_found | No card has this slug. |
410 gone | The card was taken off. removed_at says when. |
400 bad_since | since is not a date and time. |
503 unavailable | Try again in a few minutes. |
Questions about the API: send us a note with the note box on this page.