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.
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 Field | Internal Mapping | Description |
|---|---|---|
dotNumber | dotNumber | USDOT number |
legalName | legalName | Legal entity name |
dbaName | dbaName | DBA name, if any |
carrierOperation | operationType | A (interstate), B (intrastate hazmat), C (intrastate non-hazmat) |
authorityStatus | authorityStatus | A (active), I (inactive), N (not authorized) |
bipdInsuranceOnFile | insuranceOnFile | Y / N — BI/PD insurance currently on file |
bipdInsuranceRequired | insuranceRequired | Required insurance amount (dollars) |
phyCity, phyState | address.city/state | Physical location |
totalDrivers | totalDrivers | Number of drivers on file |
totalPowerUnits | totalPowerUnits | Number 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 Name | Internal Key | Intervention Threshold |
|---|---|---|
| Unsafe Driving | UNSAFE_DRIVING | 65th percentile |
| Hours-of-Service | HOS_COMPLIANCE | 65th percentile |
| Driver Fitness | DRIVER_FITNESS | 80th percentile |
| Controlled Substances/Alcohol | CONTROLLED_SUBSTANCES | 80th percentile |
| Vehicle Maintenance | VEHICLE_MAINT | 80th percentile |
| Hazardous Materials | HAZMAT | 60th percentile |
| Crash Indicator | CRASH_INDICATOR | 65th 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:
- Build the QCMobile URL with the DOT number and webKey.
- Fetch with a 10-second timeout.
- On HTTP 404, return
null(carrier not found in FMCSA — may be a new or deactivated carrier). - On HTTP 429 or 503, throw
FmcsaRateLimitError(see Retry Strategy below). - On any other non-2xx status, throw
FmcsaFetchErrorwith the status code and URL. - 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:
| Error | Action |
|---|---|
| HTTP 429 | Exponential backoff: 1s → 2s → 4s, then skip carrier and log warning |
| HTTP 503 | Same as 429 |
| Network timeout | Retry once immediately, then skip carrier |
| HTTP 404 | No retry — carrier not in FMCSA, mark as not_found |
| HTTP 400 | No 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.
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.