US Bridge Condition & Scour Risk Monitor — FHWA NBI
Pricing
from $4.40 / 1,000 results
US Bridge Condition & Scour Risk Monitor — FHWA NBI
Screen 620,000+ US bridges from the FHWA National Bridge Inventory by state, condition (Poor/Fair/Good) and scour-critical status. Composite 0-100 risk score from condition, scour, overdue inspections, and traffic. For engineers, insurers, infrastructure investors, and journalists.
Pricing
from $4.40 / 1,000 results
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Screen the FHWA National Bridge Inventory (NBI) — 624,193 US highway bridges as of the June 20 2025 extract — by state, overall condition (Poor / Fair / Good), and scour-critical status, and get back a normalized record per bridge with a composite 0–100 risk score, decoded NBI vocabularies, load ratings, inspection regimes and programmed-improvement costs.
Data comes straight from the official NTAD (National Transportation Atlas Database) ArcGIS service published by the US DOT — no API key, no scraping fragile HTML. 41,685 US bridges are currently rated in Poor condition; this actor finds them, ranks them, and flags why.
What changed in 1.1 (2026-08)
posted_or_closedwas wrong on 352 bridges. 1.0 computed it as "NBI item 41 is anything other than A". Code G means "new structure not yet open to traffic" — a brand-new bridge, not a load restriction. Those 352 bridges (live count 2026-08-01) were published as load-restricted.posted_or_closedis now true only for codes B, D, E, K, P, R,nullwhen no code was published, and code G gets its ownnot_yet_open_to_trafficflag.- A mid-run page failure no longer sells you a partial inventory. 1.0 broke out of the paging loop on an upstream error and emitted whatever it had already collected — an arbitrary subset presented as the complete answer to your filter, billed, run SUCCEEDED. Rows are now buffered and the run fails loudly, billing nothing.
- Truncation is visible.
matching_bridge_countis the service's own count of everything that matched your filter, next tobridges_scannedandresult_truncated. - A live drift probe runs before any billable row: the layer resolves (a
retired ArcGIS service answers HTTP 200 with an embedded error, not a 404),
every column this actor reads still exists (an unknown field name returns
zero features, not an error), the national count sits in a band, a
positive canary returns bridges, a negative control returns exactly zero, and
DATE_OF_INSPECT_090still parses as MMYY — the encoding every overdue verdict depends on. - Closed vocabularies are enforced. Every NBI condition, scour, posting and 0–9 rating code was enumerated live against the whole layer. An unrecognised code fails the run rather than being scored as though it were benign.
- The data vintage is reported (
nbi_data_vintage) — the NBI is a periodically republished snapshot, not a live feed. - 70 new fields from columns the layer has always published. The layer carries 128; 1.0 emitted 33.
What the risk score adds (the transform)
Raw NBI dumps give you 128 cryptic coded columns. This actor turns each bridge into a decision-ready row:
risk_score(0–100) = condition weight (Poor ≫ Fair ≫ Good) × scour-critical factor (item 113 codes 0–3 boost) × inspection-overdue factor (months since last inspection vs. the designated interval) × log-scaled traffic exposure (ADT). Higher = riskier. The worst possible combination (Poor + scour failure + 2× past inspection + 100k ADT) scores 100.risk_flags[]— machine-readable:poor_condition,condition_unknown,scour_critical,scour_action_required,scour_unknown,inspection_overdue,no_inspection_on_record,posted_or_closed,closed,not_yet_open_to_traffic,fracture_critical,high_traffic_poor.- Decoded vocabularies — condition letters, the full 0–9/N/T/U scour
vocabulary, the 0–9 condition ratings, the 8 posting codes, owner and
maintaining-agency codes, MMYY inspection dates → ISO
YYYY-MM, state FIPS → postal code.
Who uses this
- Bridge engineering & inspection firms — build target lists of Poor / scour-critical / overdue / fracture-critical bridges by state for business development, with the inspection interval and last-inspection date attached.
- Infrastructure investors & muni-bond analysts — screen the bridge stock behind an issuer or geography, with programmed improvement costs and deck area.
- P&C and infrastructure insurers — exposure screening around portfolios, with load ratings, truck share, waterway adequacy and detour length.
- DOT contractors — find rehab candidates before RFPs drop.
- Journalists & researchers — "how many Poor, load-posted, high-traffic bridges are in my state?" answered in one run.
Example input
{"states": ["CO"],"conditions": ["P"],"scourCriticalOnly": true,"minADT": 1000,"minRiskScore": 40,"maxResults": 500}
States accept postal codes ("CO"), full names ("Colorado"), or FIPS
("08"). Leave states and conditions empty to scan the national inventory
(bounded by maxResults). Empty input never fails — it runs a bounded default.
Output fields (one row per bridge)
Identity & location
| Field | Meaning |
|---|---|
structure_number | NBI item 8 structure number |
state | 2-letter postal code |
state_fips | 2-digit state FIPS (the NBI's own key) |
county_code | 3-digit county code |
facility_carried | What the bridge carries (item 7) |
features_desc | What it crosses (item 6A) |
location | Free-text location description (item 9) |
lat / lon | Decimal-degree coordinates |
source_url | A live query returning this exact record |
Condition
| Field | Meaning |
|---|---|
condition / condition_code | Overall NBI condition, Good/Fair/Poor |
deck_cond / deck_cond_desc | Deck rating (item 58) + decode |
superstructure_cond / superstructure_cond_desc | Superstructure rating (59) + decode |
substructure_cond / substructure_cond_desc | Substructure rating (60) + decode |
culvert_cond / culvert_cond_desc | Culvert rating (62) + decode |
channel_cond / channel_cond_desc | Channel & channel-protection rating (61) + decode — the leading scour indicator |
lowest_rating | Lowest of the component ratings |
Scour
| Field | Meaning |
|---|---|
scour_critical | Raw NBI item 113 code |
scour_critical_desc | Full decode of the 0–9 / N / T / U vocabulary |
scour_critical_flag | True for codes 0–3, FHWA's scour-critical definition |
scour_action_required | True for code 4 — foundations stable, but action required to protect exposed foundations (24,218 bridges nationally) |
Posting, restriction & load rating
| Field | Meaning |
|---|---|
open_closed_posted_code | Raw NBI item 41 code |
open_closed_posted | Plain-English decode |
posted_or_closed | True for B/D/E/K/P/R. False for G ("new structure not yet open to traffic"). Null when no code was published |
posting_evaluation | Item 70 appraisal of operating rating vs legal load |
operating_rating_metric_tons / operating_rating_method_code | Items 64 / 63 |
inventory_rating_metric_tons / inventory_rating_method_code | Items 66 / 65 |
Inspection regime
| Field | Meaning |
|---|---|
last_inspection_date | ISO YYYY-MM, parsed from the MMYY item 90 |
months_since_inspection | Whole months elapsed |
inspection_frequency_months | Designated interval (item 91) |
inspection_overdue | True when past the interval; null when unknown |
fracture_critical | True when item 92A flags fracture-critical details |
fracture_critical_code | Raw item 92A value (e.g. Y24) |
fracture_inspection_freq_months | The interval embedded in item 92A |
fracture_last_inspection_date | Item 93A, ISO YYYY-MM |
underwater_inspection_code / underwater_inspection_required / underwater_last_inspection_date | Items 92B / 93B |
special_inspection_code / special_inspection_required / special_last_inspection_date | Items 92C / 93C |
NBI appraisal ratings
| Field | Meaning |
|---|---|
structural_evaluation | Item 67 |
deck_geometry_evaluation | Item 68 |
underclearance_evaluation | Item 69 |
waterway_evaluation | Item 71 — waterway adequacy, the overtopping signal |
approach_road_evaluation | Item 72 |
Size, traffic & network role
| Field | Meaning |
|---|---|
structure_length_m, max_span_length_m, main_unit_spans | Items 49 / 48 / 45 |
deck_area_sq_m | Deck area — the denominator for cost-per-sq-m estimates |
roadway_width_m, deck_width_m, traffic_lanes_on | Items 51 / 52 / 28A |
min_vertical_clearance_m | Item 10. Null when NBI records the 99.99 "no restriction" sentinel |
adt, adt_year | Average daily traffic and its year |
percent_adt_truck | Item 109 truck share — the fatigue driver |
future_adt, future_adt_year | Items 114 / 115 forecast |
detour_length_km | Item 19 — network criticality if the bridge closes |
functional_class_code, highway_system_code | Items 26 / 104 |
on_strahnet | Item 100 — Strategic Highway Network / defence route |
federal_lands_code | Item 105 |
navigation_control_code, pier_protection_code | Items 38 / 111 — vessel-collision signals |
toll_code | Item 20 |
Ownership, age & programmed work
| Field | Meaning |
|---|---|
owner_code / owner | Item 22 + decode |
maintenance_responsibility_code / maintenance_responsibility | Item 21 + decode (can differ from the owner) |
year_built | Item 27 |
year_reconstructed | Item 106. Null when NBI records the 0000 "never reconstructed" sentinel |
is_temporary_structure | Item 103 |
structure_kind_code, structure_type_code | Items 43A / 43B |
deck_structure_type_code, wearing_surface_type_code | Items 107 / 108A |
work_proposed_code | Item 75A type of work proposed |
bridge_improvement_cost_usd_thousands | Item 94 |
total_improvement_cost_usd_thousands | Item 96 |
improvement_estimate_year | Item 97. Null when NBI records the 0000 sentinel |
federal_agency_code, submitted_by_code | Submitting agency |
Scoring & provenance
| Field | Meaning |
|---|---|
risk_score | Composite 0–100 |
risk_flags | Machine-readable screening flags (see above) |
nbi_source_status | ok. A row only exists when the FeatureServer answered and the full result set was retrieved |
nbi_data_vintage | The FHWA extract date from the layer description (e.g. June 20 2025) |
nbi_layer_name | The FeatureServer layer that answered |
nbi_layer_feature_count | Total bridges in the layer at run time |
matching_bridge_count | The service's own count of everything matching your filter |
bridges_scanned | How many were actually retrieved and scored |
result_truncated | True when matching_bridge_count exceeded what maxResults allowed |
where_clause | The exact server-side filter this run applied |
checked_at | ISO timestamp of the run |
Inputs that populate the sparser columns
- Everything above is populated somewhere in
{"states": ["CO"], "conditions": ["P"]}— the actor's own prefill, 417 rows, zero null-on-every-row columns. result_truncated: true,matching_bridge_count:{"conditions": ["P"], "maxResults": 50}(41,685 bridges match nationally).scour_action_required: true: any run touching NBI scour code 4 — 24,218 bridges nationally.not_yet_open_to_traffic: 352 bridges nationally carry NBI item 41 code G.pier_protection_code: 97,639 bridges nationally publish item 111.special_inspection_required/special_last_inspection_date: bridges on a special-inspection regime (item 92C begins withY).
Use as an MCP tool
This actor is discoverable to AI agents via mcp.apify.com. Field-level output
descriptions make it a clean, chainable tool: pass a state and a condition and
get back structured, decoded bridge records an agent can reason over. Agents
should read result_truncated and matching_bridge_count before treating a
result set as complete, and must not read a null boolean as a negative.
Pricing
$8 per 1,000 results (single automatic Result/dataset-item event — one billed record per bridge). Rows are buffered and the billing gate runs before anything is pushed: if a page of the query fails part-way, the run fails and nothing is billed rather than selling you an arbitrary partial inventory.
FAQ
Does this need an API key? No — the NTAD ArcGIS service is a keyless public US DOT endpoint.
How current is the data? The NBI is a periodically republished snapshot, not
a live feed. Every row carries nbi_data_vintage — the extract date FHWA stamps
in the layer description (currently June 20 2025), so a new publication can
never change your numbers silently.
Why did my run fail instead of returning some bridges? Because a partial inventory presented as the complete answer to your filter is worse than a failure. If a page of the query errors, or the layer fails its live drift check, or FHWA publishes a code this actor cannot score, the run fails loudly and bills nothing.
Is risk_score an official FHWA rating? No. It is an editorial composite of
condition, scour, inspection overdue-ness and traffic exposure. FHWA does not
publish a single 0–100 bridge risk number. Use it to rank and triage, not to
make an engineering determination.
Why is posted_or_closed false on a bridge with a non-A posting code? NBI
item 41 code G means "new structure not yet open to traffic" — that is not a
load restriction. open_closed_posted gives you the plain-English code, and the
not_yet_open_to_traffic flag tells you why.
Related actors
- National Tunnel Inventory Risk Monitor — the tunnel counterpart on the same NTAD platform.
- NFIP Flood Loss Risk Screener and FEMA NRI County Risk Profile — flood and multi-hazard context for the waterways these bridges cross.
- USACE Levee Flood Risk Screener, EPA Contaminated Site Screener — the rest of an infrastructure-diligence stack.
Each is a screening tool, not an engineering determination.