Skip to main content

FMCSA QCMobile API

OpenInsure integrates with the FMCSA QCMobile API — a free, publicly available API operated by the Federal Motor Carrier Safety Administration — to retrieve carrier safety data for underwriting and monitoring. This page documents the specific endpoints used, authentication, response field mappings, and how the client handles rate limits and retries.

Authentication

The QCMobile API uses a webKey query parameter for authentication. Keys are issued at no cost through the FMCSA portal at mobile.fmcsa.dot.gov.

GET https://mobile.fmcsa.dot.gov/qc/services/carriers/1234567?webKey=<your_key>

The webKey is stored in Cloudflare Workers secrets as FMCSA_WEB_KEY and injected into every request by the API worker. It is never logged or exposed in error messages.

caution

The FMCSA QCMobile API has no SLA and is rate-limited. Do not use it for synchronous user-facing requests. All production calls go through the daily cron pipeline, which spaces requests at 200ms intervals.

Endpoints Used

GET /carriers/:dot — Carrier Authority & Insurance

Retrieves the carrier's operating authority, insurance on file, and contact information.

https://mobile.fmcsa.dot.gov/qc/services/carriers/:dotNumber?webKey=<key>

Key response fields:

FMCSA FieldInternal MappingDescription
dotNumberdotNumberUSDOT number
legalNamelegalNameLegal entity name
dbaNamedbaNameDBA name, if any
carrierOperationoperationTypeA (interstate), B (intrastate hazmat), C (intrastate non-hazmat)
authorityStatusauthorityStatusA (active), I (inactive), N (not authorized)
bipdInsuranceOnFileinsuranceOnFileY / N — BI/PD insurance currently on file
bipdInsuranceRequiredinsuranceRequiredRequired insurance amount (dollars)
phyCity, phyStateaddress.city/statePhysical location
totalDriverstotalDriversNumber of drivers on file
totalPowerUnitstotalPowerUnitsNumber of power units on file

GET /carriers/:dot/basics — CSA BASIC Scores

Retrieves the carrier's Compliance, Safety, Accountability (CSA) BASIC percentile scores and investigation history.

https://mobile.fmcsa.dot.gov/qc/services/carriers/:dotNumber/basics?webKey=<key>

Seven BASIC categories:

BASIC NameInternal KeyIntervention Threshold
Unsafe DrivingUNSAFE_DRIVING65th percentile
Hours-of-ServiceHOS_COMPLIANCE65th percentile
Driver FitnessDRIVER_FITNESS80th percentile
Controlled Substances/AlcoholCONTROLLED_SUBSTANCES80th percentile
Vehicle MaintenanceVEHICLE_MAINT80th percentile
Hazardous MaterialsHAZMAT60th percentile
Crash IndicatorCRASH_INDICATOR65th percentile

The fetchBasics() function (in apps/api/src/lib/fmcsa.ts) maps the raw FMCSA basics array — which is keyed by numeric BASIC category codes — to the named keys above, and attaches whether each score has crossed the intervention threshold.

// Simplified output of fetchBasics()
{
basics: [
{
basic: 'HOS_COMPLIANCE',
percentile: 78,
interventionThreshold: 65,
aboveThreshold: true,
measureValue: '4.12',
inspections: 24,
violations: 9
},
// ...
],
investigations: [
{
type: 'COMPLIANCE_REVIEW',
date: '2024-11-15',
rating: 'CONDITIONAL'
}
]
}

GET /carriers/:dot/oos — Out-of-Service Rates

Retrieves the carrier's out-of-service rates for vehicles, drivers, and hazmat, compared to national averages.

https://mobile.fmcsa.dot.gov/qc/services/carriers/:dotNumber/oos?webKey=<key>

The fetchOosRates() function extracts and normalizes the three OOS rate categories:

// Simplified output of fetchOosRates()
{
vehicle: {
inspections: 48,
outOfService: 9,
rate: 18.75, // percentage
nationalAverage: 21.4
},
driver: {
inspections: 48,
outOfService: 3,
rate: 6.25,
nationalAverage: 5.5
},
hazmat: {
inspections: 12,
outOfService: 0,
rate: 0.0,
nationalAverage: 4.2
}
}

Client Implementation

The FMCSA client lives in apps/api/src/lib/fmcsa.ts and exports three functions:

fetchCarrier(dotNumber: string, webKey: string): Promise<FmcsaCarrier>
fetchBasics(dotNumber: string, webKey: string): Promise<FmcsaBasics>
fetchOosRates(dotNumber: string, webKey: string): Promise<FmcsaOosRates>

All three functions follow the same pattern:

  1. Build the QCMobile URL with the DOT number and webKey.
  2. Fetch with a 10-second timeout.
  3. On HTTP 404, return null (carrier not found in FMCSA — may be a new or deactivated carrier).
  4. On HTTP 429 or 503, throw FmcsaRateLimitError (see Retry Strategy below).
  5. On any other non-2xx status, throw FmcsaFetchError with the status code and URL.
  6. Parse and validate the response with Zod before returning.

Rate Limits and Retry Strategy

The QCMobile API does not publish a formal rate limit, but sustained traffic above approximately 5 requests per second triggers HTTP 429 responses. The cron pipeline enforces a 200ms delay between requests — meaning a portfolio of 150 carriers takes roughly 90 seconds to fully scan (150 carriers × 3 endpoints × 200ms).

The retry strategy for transient errors:

ErrorAction
HTTP 429Exponential backoff: 1s → 2s → 4s, then skip carrier and log warning
HTTP 503Same as 429
Network timeoutRetry once immediately, then skip carrier
HTTP 404No retry — carrier not in FMCSA, mark as not_found
HTTP 400No retry — invalid DOT number, log error

Carriers that could not be fetched are excluded from the alert diff for that run. They are not marked as having no alerts — they are simply not evaluated. The staleCarriers field in the /v1/fmcsa-history/stats response surfaces carriers with gaps in their snapshot history.

note

The FMCSA QCMobile API returns data as of the previous business day. FMCSA updates their database nightly, so a Monday morning cron run reflects Friday's data. This lag is expected and is noted in the carrier alert UI.