Low Clearance Map Logo for Trucking and Logistics
Menu
User Avatar
Unknown
API Reference
Low Clearance Map

API Reference

A REST API for querying our curated database of 27,500+ low-clearance structures across the United States, United Kingdom and Canada. Filter by vehicle clearance, search by route, radius, state, country or structure ID, and receive results as JSON or map-ready GeoJSON.

Introduction

The Low Clearance Map API exposes the same clearance data that powers our routing products. It’s designed to drop into routing engines, transportation-management systems (TMS), and fleet-safety tools so you can flag height-restricted structures before a vehicle ever reaches them.

Every endpoint is read-only and returns JSON by default. Pass geojson=true on any bridge endpoint to get a GeoJSON FeatureCollection you can render directly on a map.

Getting a key takes about a minute. Start a free trial, no sales call required. Bulk database access is licensed annually and is still arranged with us directly — see Plans & access.

Plans & access

Routing endpoints are self-serve and metered by call. Bulk database access is licensed annually, because a single call to /api/all_bridges returns the entire dataset.

PlanPriceIncluded callsBeyond that
Starter
14-day free trial
$75 / month 5,000 / month $0.015 per call
Growth $250 / month 20,000 / month $0.015 per call
Data Portal
annual
$3,000 / year No API Browse, search and export the full database
Scale
annual
$900 / month, billed annually 100,000 / month Plus the full database, portal and bulk export

Starter and Growth are self-serve: start a trial with a card and your key is issued immediately. Data Portal and Scale are annual agreements, so talk to us.

Which endpoints your plan includes

Every plan carries one or both of two scopes. Calling an endpoint outside your scope returns 403 with "code": "scope_required".

EndpointScopeStarter / GrowthScale
Safe RouteroutingYesYes
Check RouteroutingYesYes
All bridgesdatabaseNoYes
Bridges by statedatabaseNoYes
Bridges by countrydatabaseNoYes
Bridges by IDdatabaseNoYes
Within radiusdatabaseNoYes
Along a routedatabaseNoYes

Spend cap

Every metered account has a spend cap, defaulting to three times the monthly fee. Overage accrues normally below it. At the cap, further calls return 429 until you raise it in Account settings or the billing period rolls over. It exists so a runaway loop cannot turn into an invoice you did not expect.

Fair use

Plans also carry an annual ceiling on the number of distinct structures revealed to your account: 2,500 on Starter, 7,500 on Growth, unlimited on Scale. Ordinary routing never approaches this, because vehicles repeat corridors. It exists to stop the API being used to reconstruct the database, which section 2.3 of the terms prohibits.

Authentication

Authenticate every request by sending your key in the X-Api-Secret HTTP header. Keys are issued per account and scoped to your plan. Keep them secret and never expose them in client-side code.

Requests without a valid key receive 403 Forbidden. A valid key calling an endpoint outside your plan also receives 403, with "code": "scope_required" in the body naming the scope you need. See Plans & access.

Lost a key? Rotate it from Account settings → API access. Keys are stored hashed, so we cannot show you an existing key again.

Authorization header
X-Api-Secret: YOUR_API_KEY

Base URL & requests

All endpoints are served from a single base URL over HTTPS:

https://lowclearancemap.com

Bridge lookups use GET with query-string parameters. The Safe Route endpoint uses POST with a JSON body. When a parameter value contains JSON (for example a clearance range), URL-encode it before adding it to the query string.

Minimal request
curl "https://lowclearancemap.com/api/all_bridges?vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"

Clearance filtering

Every bridge endpoint accepts a required vehicle_clearance parameter that filters results to the structures relevant to your vehicle. It accepts two forms:

Single value

A number (in feet) representing your maximum vehicle clearance. Returns every structure at or below that height.

Min / max range

A JSON object with min and/or max keys, URL-encoded. Useful for narrowing to a band of clearances.

Add the parameter to the request URL's query string. When the value is JSON (a clearance range), URL-encode it first. Most HTTP clients and language libraries do this for you.

Single value
# add to the request URL:
?vehicle_clearance=13.5
Range (URL-encoded JSON)
# readable JSON value:
?vehicle_clearance={"min":10,"max":15}

# URL-encoded (what you send):
?vehicle_clearance=%7B%22min%22%3A10%2C%22max%22%3A15%7D

Structure annotations

Structures carry eight annotation fields that describe the physical form of the obstruction and how its clearance was verified against imagery. Fields that do not apply to a particular structure are returned as null, e.g. posted_raw when no height sign is posted, or clearance_max_in when the opening is uniform.

Annotations are off by default so existing integrations are unaffected. Add verbose=true to any JSON bridge endpoint (All bridges, by state, by country, by ID, within radius) to receive them.

Fields

FieldDescription
structure_typestring
The kind of overhead structure. One of BR bridge / overpass, TRU truss, TUN tunnel, CVB covered bridge, OBS other overhead obstruction (sign gantry, pipe rack, low cable), OTH other / unclassifiable.
carriesstring
What sits on top of the structure. One of ROAD, RAIL, PED pedestrian or bike only, MIX multiple or other, N/A nothing carried (tunnels, covered bridges, trusses).
clearance_varstring
How clearance varies across the opening, which tells a router where the opening is lowest. One of UNI uniform, ARC arched with a higher center and lower edges, SLP sloped with one side lower than the other, STEP stepped or physically separate spans with different heights.
postedstring
Y if a height sign is visible on the structure, otherwise N.
posted_rawstring
The sign value exactly as posted, e.g. 12'-6" or 3.8m. Null when posted is N.
clearance_min_ininteger
The controlling (lowest) clearance across the opening, in inches. This is the number a router should use.
clearance_max_ininteger
The highest clearance across the opening, in inches. Only populated when clearance_var is not UNI.
confidencestring
Curation confidence for the annotation. One of OK, REVISIT (queued for re-check), CANT_DETERMINE (imagery insufficient).
Example request
curl "https://lowclearancemap.com/api/bridges_by_id?structure_ids=5&verbose=true" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response (annotated bridge)
{
  "bridges": [{
    "Structure_ID": 5,
    "Name": "WV61 CR72 US60 KAN R CSX",
    "Latitude": 38.3007621,
    "Longitude": -81.5564591,
    "Country": "United States",
    "State": "WV",
    "Clearance": 13.5,
    "structure_type": "BR",
    "carries": "ROAD",
    "clearance_var": "UNI",
    "posted": "Y",
    "posted_raw": "13 6",
    "clearance_min_in": 162,
    "clearance_max_in": null,
    "confidence": "OK"
  }]
}

Response format

By default, responses are JSON objects containing metadata plus a bridges array. Each bridge includes its identifier, name, coordinates, country, state and clearance. Add verbose=true to any JSON bridge endpoint to also receive the structure annotation fields.

Add geojson=true to receive a GeoJSON FeatureCollection instead. Each hazard heading becomes a LineString feature, ready to drop onto a Mapbox or Leaflet map.

GeoJSON feature
{
  "type": "Feature",
  "properties": {
    "Name": "CR 1 SLS",
    "State": "WV",
    "Clearance": 13.5,
    "Feature_Type": "all_bridges"
  },
  "geometry": {
    "type": "LineString",
    "coordinates": [[-77.89, 39.38], [-77.89, 39.40]]
  }
}

Errors

The API uses conventional HTTP status codes. Error responses include a JSON error message.

200Success
400Missing or invalid parameters
403Invalid or missing API key
404No matching bridges found
500Internal server error

Safe Route POST

POST/api/saferoute

Safe Route is our flagship endpoint: the routing engine behind the Low Clearance Map web app and Headroom Turn-by-Turn navigation. It runs the exact same clearance-aware routing our own products rely on.

Given a start, an end, and your vehicle’s height, plus optional weight, length and width, it returns a complete, turn-by-turn route that routes around every structure your vehicle can’t safely clear, so a driver is never sent under a too-low bridge. Start, end and stops accept either coordinates ({"lat","lng"}) or a street address ({"address": "…"}).

Send a JSON body with a Content-Type: application/json header. The response always carries two routes: fastest_route, the unconstrained route with any hazards it crosses listed, and safe_route, the route that avoids them. safe_route_found tells you whether a hazard-free route exists; when it is false the safe route is the fastest route and still carries hazards. Set geojson: true to get both routes back as a map-ready GeoJSON FeatureCollection.

Body parameters

FieldDescription
start
required
object
{"lat","lng"} or {"address": "…"}.
end
required
object
{"lat","lng"} or {"address": "…"}.
stops
optional
array
Intermediate waypoints, visited in order. Each is {"lat","lng"} or {"address": "…"}.
clearance_feet
required
number
Vehicle height, feet component.
clearance_inches
optional
number
Vehicle height, inches component.
use_truck_routes
optional
boolean
Route on a commercial-truck profile that also honours weight, length and width restrictions. Defaults to false (car profile with a height constraint).
vehicle_weight_lbs
optional
number
Gross weight. Defaults to 80000. Used in truck mode.
vehicle_length_ft
optional
number
Defaults to 53. Used in truck mode.
vehicle_width_ft
optional
number
Passed to routing if provided. Used in truck mode.
avoid_tolls
optional
boolean
Avoid toll roads. Defaults to false.
avoid_highways
optional
boolean
Avoid controlled-access highways. Defaults to false.
geojson
optional
boolean
Return the routes as a GeoJSON FeatureCollection (one fastest feature, one safe feature). Defaults to false.
multiple_routes
optional
boolean
Also return a routes array with every candidate route considered, each hazard-annotated and flagged is_fastest_route / is_safe_route, ordered hazard-free first. Defaults to false.
speed_limits
optional
boolean
Also return posted speed limits along every returned route as a speed_limits array of spans (see Speed limits). Defaults to false.

geojson, multiple_routes and speed_limits may also be passed as query-string parameters (?speed_limits=true). Response keys are only added when the matching flag is on; the default response shape never changes.

Speed limits

With speed_limits: true, fastest_route, safe_route and every routes[] entry carry a speed_limits array: run-length spans of the posted limit along the route. A span applies from its start up to the next span’s start; the last span runs to the end of the route. Each span is addressed two ways so you can use whichever fits your client: start_index is the index into geometry.coordinates, and start_m is the distance from the start of the route in metres, which keeps working if you resample or densify the geometry.

speed_mps is always metres per second so you can display mph or km/h as you like; unit reports the unit the limit is posted in when the routing engine knows it and is null otherwise. A span with speed_mps: null means the limit is unknown for that stretch (or unlimited: true where no limit applies). Routes served by the exclusion-routing fallback have no limit data and return an empty array.

Example request
curl -X POST "https://lowclearancemap.com/api/saferoute" \
  -H "X-Api-Secret: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "start": {"lat": 40.7128, "lng": -74.0060},
    "end": {"address": "Boston, MA"},
    "clearance_feet": 13,
    "clearance_inches": 6,
    "use_truck_routes": true,
    "vehicle_weight_lbs": 80000,
    "vehicle_length_ft": 53,
    "speed_limits": true
  }'
200 Response
{
  "status": "ok",
  "message": "Alternative safe route found",
  "safe_route_found": true,
  "routes_are_same": false,
  "metadata": {
    "vehicle_clearance_ft": 13.5,
    "use_truck_routes": true,
    "vehicle_weight_lbs": 80000,
    "vehicle_length_ft": 53,
    "avoid_tolls": false,
    "avoid_highways": false,
    "route_distance_miles": 190.4,
    "is_long_route": false,
    "closure_aware": false,
    "speed_limits": true
  },
  "fastest_route": {
    "geometry": {
      "type": "LineString",
      "coordinates": [[-74.006, 40.7128],]
    },
    "distance_m": 346210,
    "distance_miles": 215.13,
    "distance_km": 346.21,
    "duration_s": 13980,
    "hazards": [ {
      "lat": 41.2034, "lng": -73.1187,
      "name": "Elm St Underpass",
      "clearance": 11.5,
      "distance_m": 52340, "distance_km": 52.3
    } ],
    "hazards_count": 1,
    "turns": [ {
      "instruction": "Turn right onto Main St",
      "direction": "right",
      "name": "Main St",
      "distance": 812.4, "duration": 95,
      "location": [-74.001, 40.72],
      "bearing": 87,
      "intersection_type": "traffic_signal"
    },],
    "speed_limits": [
      { "start_index": 0, "start_m": 0.0,
        "speed_mps": 11.176, "unit": null,
        "unlimited": false },
      { "start_index": 58, "start_m": 2054.0,
        "speed_mps": 24.587, "unit": null,
        "unlimited": false },]
  },
  "safe_route": {
    /* same fields as fastest_route, plus: */
    "hazards_count": 0,
    "is_same_as_fastest": false
  }
}

Distances are in metres with mile and kilometre conversions alongside; duration_s is seconds. turns[].location and every coordinate are [lng, lat]. hazards lists the low-clearance structures the route passes under, nearest first, with the distance along the route to each. With multiple_routes: true the response also includes routes and routes_count.

Speed limit span
{
  "start_index": 58,    /* into geometry.coordinates */
  "start_m": 2054.0,    /* metres from route start */
  "speed_mps": 24.587,  /* m/s; null = unknown */
  "unit": "mph",        /* "mph" | "km/h" | null */
  "unlimited": false    /* true = no limit applies */
}

Check Route POST

POST/api/check_route

Already have a route? Check Route audits a route you already have (for example the geometry returned by Google Maps, HERE, or Mapbox Directions) against your vehicle’s clearance, and tells you whether it is safe. If it isn’t, every low-clearance structure that lies on the route is listed.

Unlike Safe Route, this endpoint does not build a route or suggest an alternative; it only validates the geometry you supply. Use Safe Route to generate a clearance-aware route; use Check Route to verify a route that came from somewhere else.

Send a JSON body with a Content-Type: application/json header. The route geometry goes in route and may be an encoded polyline (Google / Mapbox, precision 5 or 6), a HERE flexible polyline, a GeoJSON LineString, a list of [lng, lat] pairs, or a list of {"lat","lng"} objects. A bridge is only flagged when the route actually travels through it in a hazardous direction.

Body parameters

FieldDescription
route
required
string | array | object
The route geometry to audit. Aliases geometry, polyline, linestring, coordinates are also accepted.
geometry_format
optional
string
auto (default), polyline, polyline6, flexible, geojson, or coordinates. auto tries standard polyline, then precision 6, then HERE flexible.
coordinate_order
optional
string
Order of raw numeric pairs: lnglat (default, GeoJSON) or latlng.
clearance_feet
required
number
Vehicle height, feet component (combine with clearance_inches).
clearance_inches
optional
number
Vehicle height, inches component.
vehicle_clearance
optional
number
Vehicle height in decimal feet, an alternative to clearance_feet/clearance_inches.
on_route_m
optional
number
How close (meters) a structure must be to count as on-route. Defaults to 25.
heading_tol
optional
number
Travel-heading match tolerance in degrees. Defaults to 20.
Example request
curl -X POST "https://lowclearancemap.com/api/check_route" \
  -H "X-Api-Secret: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "route": "izpdFn~xtMhA}A",
    "geometry_format": "polyline",
    "clearance_feet": 11,
    "clearance_inches": 6
  }'
200 Response
{
  "status": "ok",
  "safe": false,
  "vehicle_clearance_ft": 11.5,
  "route_points": 182,
  "hazard_count": 1,
  "hazards": [ {
    "structure_id": "15999",
    "name": "Main St Underpass",
    "lat": 34.052235, "lng": -118.243683,
    "clearance": 10.5,
    "state": "CA", "country": "USA",
    "distance_m": 1200, "distance_km": 1.2
  } ],
  "message": "Route is NOT safe: 1 low-clearance hazard(s) detected for a 11.5 ft vehicle."
}

When the route is clear, safe is true, hazards is an empty array, and hazard_count is 0.

All bridges GET

GET/api/all_bridges

Returns every structure in the database that matches the supplied clearance filter.

Query parameters

ParameterDescription
vehicle_clearance
required
number | json
Maximum vehicle clearance, or a URL-encoded {"min","max"} range. See Clearance filtering.
geojson
optional
boolean
Set to true for GeoJSON output. Defaults to false.
verbose
optional
boolean
Set to true to include the eight structure annotation fields on each bridge. Works with both JSON and GeoJSON output. Defaults to false.
Example request
curl "https://lowclearancemap.com/api/all_bridges?vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "number_of_bridges": 2,
  "vehicle_clearance": { "max_clearance": 13.5 },
  "bridges": [
    { "Name": "Bridge 1", "Latitude": 34.0522,
      "Longitude": -118.2437, "Clearance": 13.5 }
  ]
}

Bridges by state GET

GET/api/bridges_by_state

Returns low-clearance structures in one or more U.S. states (or U.K./Canadian regions), filtered by clearance.

Query parameters

ParameterDescription
states
required
string
Comma-separated state/region codes, e.g. CA,NY.
vehicle_clearance
required
number | json
See Clearance filtering.
geojson
optional
boolean
Set to true for GeoJSON output.
verbose
optional
boolean
Set to true to include the eight structure annotation fields on each bridge. Works with both JSON and GeoJSON output. Defaults to false.
Example request
curl "https://lowclearancemap.com/api/bridges_by_state?states=CA,NY&vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "states_given": ["CA", "NY"],
  "number_of_bridges": 2,
  "bridges": [
    { "Name": "Bridge 1", "Clearance": 13.5 },
    { "Name": "Bridge 2", "Clearance": 13.0 }
  ]
}

Bridges by country GET

GET/api/bridges_by_country

Returns low-clearance structures in one or more countries, filtered by clearance.

Query parameters

ParameterDescription
countries
required
string
Comma-separated country names, e.g. United States,Canada.
vehicle_clearance
required
number | json
See Clearance filtering.
geojson
optional
boolean
Set to true for GeoJSON output.
verbose
optional
boolean
Set to true to include the eight structure annotation fields on each bridge. Works with both JSON and GeoJSON output. Defaults to false.
Example request
curl "https://lowclearancemap.com/api/bridges_by_country?countries=United%20States,Canada&vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "countries_given": ["United States", "Canada"],
  "number_of_bridges": 2,
  "bridges": [ /* … */ ]
}

Bridges by ID GET

GET/api/bridges_by_id

Looks up specific structures by their Structure_ID. Pass IDs as a comma-separated list, or repeat the parameter. Unknown IDs are returned in an invalid_ids array.

Query parameters

ParameterDescription
structure_ids
required
string | array
e.g. 1799,15999 or repeated structure_ids=1799&structure_ids=15999.
geojson
optional
boolean
Set to true for GeoJSON output.
verbose
optional
boolean
Set to true to include the eight structure annotation fields on each bridge. Works with both JSON and GeoJSON output. Defaults to false.
Example request
curl "https://lowclearancemap.com/api/bridges_by_id?structure_ids=1799,15999,16002" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "number_of_bridges": 2,
  "bridges": [ /* … */ ],
  "invalid_ids": ["16002"]
}

Bridges within radius GET

GET/api/bridges_within_radius

Returns structures within a given radius of a point, filtered by clearance.

Query parameters

ParameterDescription
latitude
required
number
Latitude of the center point.
longitude
required
number
Longitude of the center point.
radius
required
number
Search radius in kilometers.
vehicle_clearance
required
number | json
See Clearance filtering.
geojson
optional
boolean
Set to true for GeoJSON output.
verbose
optional
boolean
Set to true to include the eight structure annotation fields on each bridge. Works with both JSON and GeoJSON output. Defaults to false.
Example request
curl "https://lowclearancemap.com/api/bridges_within_radius?latitude=34.0522&longitude=-118.2437&radius=10&vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "center": [34.0522, -118.2437],
  "radius": 10,
  "number_of_bridges": 1,
  "bridges": [ /* … */ ]
}

Bridges along a route GET

GET/api/bridges_along_route

Returns structures that fall on a route between two points, plus those within ~50 miles of the route corridor. The response separates the two sets.

Query parameters

ParameterDescription
start_latitude
required
number
Latitude of the route start.
start_longitude
required
number
Longitude of the route start.
end_latitude
required
number
Latitude of the route end.
end_longitude
required
number
Longitude of the route end.
vehicle_clearance
required
number | json
See Clearance filtering.
geojson
optional
boolean
Set to true for GeoJSON output.
Example request
curl "https://lowclearancemap.com/api/bridges_along_route?start_latitude=34.0522&start_longitude=-118.2437&end_latitude=36.1699&end_longitude=-115.1398&vehicle_clearance=13.5" \
  -H "X-Api-Secret: YOUR_API_KEY"
200 Response
{
  "number_of_bridges_on_route": 1,
  "number_of_bridges_50_miles_along_route": 1,
  "bridges_on_route": [ /* … */ ],
  "bridges_50miles_along_route": [ /* … */ ]
}

Rate limits & support

Requests are rate limited per key: 10 per second on Starter, 25 on Growth, 60 on Scale. Exceeding it returns 429 Too Many Requests with a Retry-After header. Back off and retry rather than hammering.

A 429 can mean one of three things, and the code field in the body says which: rate_limited (too fast, retry shortly), spend_cap_reached (raise the cap in settings), or allowance_exhausted (trial used up, add a plan).

A refused request is always refused outright. We never return a route with hazards omitted because a limit was hit, so a 200 is always a complete answer.

Need more than Scale, or bulk data access? Email info@lowclearancemap.com. Prefer the no-code route? The Database Portal gives you the same data as downloadable CSV, Excel and JSON.

Manage keys, usage and billing in Account settings → API access. Your use of the API is governed by the API Terms of Service.