# FMCSA Carrier Check: Authority & Insurance Monitor (`humble-echidna/fmcsa-carrier-check`) Actor

Check US motor carriers and brokers by USDOT or MC number: live SAFER authority and out-of-service status, insurance policies and cancellations, suspensions, revocations, safety rating, fleet and registered contact details. Monitor mode returns only carriers that changed since the last run.

- **URL**: https://apify.com/humble-echidna/fmcsa-carrier-check.md
- **Developed by:** [Michael Costa](https://apify.com/humble-echidna) (community)
- **Categories:** Business, Automation, Developer tools
- **Stats:** 4 total users, 2 monthly users, 98.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 carriers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does FMCSA Carrier Check do?

**FMCSA Carrier Check** is an **FMCSA carrier lookup** for freight brokers and their software. Give it **USDOT or
MC numbers**; it returns each carrier's **live operating authority status** from FMCSA's SAFER site, **insurance on
file** (policies, amounts, pending cancellations), **out-of-service orders**, **suspensions and revocations**,
**safety rating**, fleet, cargo, company officers and registered contact details, merged with FMCSA's daily open
data.

Run it before a load, or on a schedule in **monitor mode** to get **only the carriers whose authority, insurance,
out-of-service status, rating or contact details changed**, with what changed.

[Input fields](https://apify.com/humble-echidna/fmcsa-carrier-check/input-schema) ·
[API](https://apify.com/humble-echidna/fmcsa-carrier-check/api) ·
[Use it from Claude, ChatGPT or Cursor (MCP)](#can-i-use-fmcsa-carrier-check-from-an-ai-agent-mcp)

**Jump to:** [Monitor it](#monitor-your-carriers-for-authority-and-insurance-changes) ·
[Fields](#what-data-does-fmcsa-carrier-check-return) · [Flags](#vetting-flags) ·
[Price](#how-much-does-it-cost-to-check-a-carrier) · [How to use](#how-to-check-a-carrier-by-usdot-or-mc-number) ·
[Input](#input) · [Output](#output) · [AI agents (MCP)](#can-i-use-fmcsa-carrier-check-from-an-ai-agent-mcp) ·
[Data freshness](#how-fresh-is-the-data) · [Limits](#limits) · [FAQ](#faq)

**Try it in one click:** the input comes pre-filled with J.B. Hunt (USDOT 80806) and Werner Enterprises (MC138328).
That's 2 carriers, or about $0.006 (2 × $0.003, plus $0.00005 for the run start). **Then replace them with the carriers
you actually want to check.**

### Monitor your carriers for authority and insurance changes

1. Put your carriers in **USDOT numbers** and/or **MC / MX / FF docket numbers**, switch on **Only changed carriers
   (monitor)**, and click **Start**. The first run returns every carrier as `new`: it's the baseline.
2. Click **Save as a new task** (top right). A task keeps its own memory, so it always compares with its own last run.
   To keep several lists apart in one task or from the API, give each a **Monitor name**.
3. In Apify Console, open **Schedules**, click **Create new**, pick how often (FMCSA refreshes its data once a day,
   by about 9:30 US Eastern, so daily at 10:00 ET is a good default), then **Add** your task.
4. On the task, open the **Integrations** tab and send the changes where you work:
   - **Slack**: pick the channel and the "run succeeded" event; `{{resource.statusMessage}}` reads like
     "2 new, 3 changed, 995 unchanged".
   - **Gmail**: connect Google and attach the dataset as CSV.
   - **HTTP webhook**: event `ACTOR.RUN.SUCCEEDED`; then
     `GET https://api.apify.com/v2/datasets/<resource.defaultDatasetId>/items?format=json` (with your API token)
     returns only the changed carriers.

Each changed carrier has `changeType` (`new` or `changed`) and a `changes` list, one entry per field that moved, with
`before` and `after`. What counts as a change: USDOT status, operating authority status (live, from SAFER), docket
status, insurance on file, policies, pending cancellations, suspension and revocation orders, out-of-service status and
orders, safety rating and its date, and the registered phone, street or mailing address, email or officers (a carrier
whose contact details suddenly change is a classic sign of an identity takeover). Fleet size, mileage and name edits are in the
record but don't count on their own.

**A failure is never reported as "no change".** If one of FMCSA's datasets can't be read, the carriers in that
batch are reported as failed in the log and `RUN_STATS`, aren't charged, and are compared again next run. The same goes
for a carrier whose live SAFER check failed: in monitor mode it isn't compared (dataset values next to live ones would
look like changes) and isn't charged.

### What data does FMCSA Carrier Check return?

One row per carrier (per USDOT number):

| Field | Example | Notes |
|---|---|---|
| `dotNumber` | `53467` | Stable across runs; use it to deduplicate |
| `docketNumbers` | `["MC138328"]` | MC/MX/FF numbers, from SAFER, the census and Motus |
| `legalName`, `dbaName` | `WERNER ENTERPRISES INC` | The registered names; `dbaName` is `null` when none |
| `street`, `city`, `state`, `zip`, `country` | `14507 FRONTIER ROAD`, `OMAHA`, `NE` | Physical business address |
| `phone`, `mailingAddress`, `dunsNumber` | `(402) 895-6640` | Registered phone, mailing address and DUNS number |
| `companyOfficers` | `["ERIC DOWNING", "JAIME HAMM"]` | Officers named on the MCS-150 (up to two) |
| `email` | `jaime.hamm@werner.com` | The email the carrier gave FMCSA: self-reported, can be stale or empty |
| `usdotStatus` | `active` | `active`, `inactive`, `out-of-service` (live) or `pending` |
| `operatingAuthorityStatus`, `authorizedFor` | `authorized`, `["Motor Carrier of Property ..."]` | Live from SAFER: `authorized`, `not authorized` or `out-of-service` |
| `authority` | `{"motorCarrier": "active", "broker": "active", ...}` | Per kind of authority, from the live status |
| `authorities` | type, status, `statusSince`, `grantedOn` | Every authority on every docket, with its history (Motus or the 2026-05-14 files) |
| `insurance` | `{"bipdRequired": 1000000, "bipdOnFile": 5000000, ...}` | Required vs on file: BI\&PD (dollars), cargo, bond |
| `insurancePolicies` | insurer, policy number, coverage, amounts, dates | Active and pending policies (BI\&PD, cargo, bond, trust fund) |
| `insuranceCancellations` | policy, `cancelEffectiveDate`, `reason` | Pending, or ended in the last 30 days |
| `outOfService`, `outOfServiceDate`, `outOfServiceOrders` | `false`, `null`, `[]` | Live status and date, plus every order with its reason and rescind date |
| `suspensionsRevocations` | action, served and effective dates | Suspension and revocation orders |
| `safetyRating`, `safetyRatingDate`, `safetyReviewDate` | `satisfactory`, `1995-08-08` | Or `conditional`, `unsatisfactory`, `not rated` |
| `powerUnits`, `drivers`, `cargoCarried`, `hazmat` | `9863`, `9107` | Fleet and operation from the MCS-150 |
| `mcs150Date`, `mcs150Mileage` | `2024-07-23` | Last MCS-150 update and the miles it reported |
| `flags` | `["mcs150-older-than-24-months"]` | Vetting flags, below |
| `liveCheck`, `sources` | `ok`, `{"authority": {"source": "safer", "asOf": "2026-10-02"}, ...}` | How the live check went, and where each part came from and how current it is |

The phone, addresses, DUNS number, officers and email are the carrier's registration details as FMCSA publishes them,
for verifying that you're dealing with the carrier on file. The email comes from the carrier's own MCS-150 filing:
FMCSA doesn't check it, so it can be out of date or missing (about 1 in 4 carriers had none in a 2026-10-04 sample).
Cell phone and fax aren't returned: under 13% of carriers file them. Every row has the same fields; the full list is under [Output](#output). Amounts are dollars and
dates are `YYYY-MM-DD`, whatever format the source used.

#### Vetting flags

Each flag is a plain fact from the record (the live values when there are), for screening rules in your own system:

| Flag | When |
|---|---|
| `usdot-not-active` | The USDOT number is inactive, out of service or pending |
| `out-of-service` | SAFER shows the carrier out of service, or an out-of-service order newer than SAFER's page isn't rescinded |
| `no-active-authority` | A for-hire carrier (it has dockets or authority records) with no authority active now |
| `authority-pending`, `revocation-pending` | An authority is still pending, or in revocation (2026-05-14 records) |
| `suspension-or-revocation-pending` | A suspension or revocation order takes effect today or later |
| `bipd-below-required` | An active carrier's BI\&PD on file and its policies in force are both below the requirement |
| `cargo-insurance-missing`, `broker-bond-missing` | Required but not on file, while the authority is active |
| `insurance-cancellation-pending` | A policy is cancelled with a future effective date |
| `safety-rating-conditional`, `safety-rating-unsatisfactory` | That safety rating |
| `authority-granted-within-90-days` | An active authority was first granted in the last 90 days |
| `mcs150-older-than-24-months` | FMCSA asks for an MCS-150 update every 24 months |
| `insurance-from-2026-05-14-snapshot` | The carrier isn't in Motus yet: its insurance is from FMCSA's frozen 2026-05-14 files (see [freshness](#how-fresh-is-the-data)) |
| `authority-from-2026-05-14-snapshot` | Same for authority, when there was no live check |
| `live-check-failed`, `not-on-safer` | The SAFER page couldn't be read, or SAFER has no active record: the dataset values stand |

### How much does it cost to check a carrier?

You pay per carrier returned: **$3.00 per 1,000 carriers** on the Free plan, **$2.70** on Starter, **$2.40** on
Scale and **$2.10** on Business, plus **$0.00005** each time a run starts. In monitor mode, a carrier that didn't change
isn't returned and costs **$0.20 per 1,000** (the reads still have to happen). Never charged: numbers that aren't
valid or that FMCSA doesn't know, and carriers whose data couldn't be read.

- **The example below:** 2 carriers × $0.003 + $0.00005 = $0.00605 (Free plan).
- **One carrier per load, from your TMS:** about $0.003 a check (Free) or $0.0028 (Starter); 100 loads a day ≈ $8.25 a month on Starter.
- **Monitoring 1,000 carriers daily, ~10 changing a day:** 30 × ($0.00005 + 10 × $0.0027 + 990 × $0.0002) ≈ **$6.75 a
  month** on Starter.
- **Caps:** **Max results per run** in the input, and **Maximum cost per run** in the run options. The run stops
  cleanly at whichever comes first, before reading carriers it couldn't charge for.

### How to check a carrier by USDOT or MC number

1. Open FMCSA Carrier Check and click **Try for free** (or **Start** if you're signed in).
2. Paste USDOT numbers into **USDOT numbers** and/or MC numbers into **MC / MX / FF docket numbers**, one per line.
3. Optional: switch on **Only changed carriers (monitor)** for scheduled checks, and set **Max results per run**.
4. Click **Start**, then open the **Output** tab and export as JSON, CSV or Excel.

### Example: J.B. Hunt and Werner

The pre-filled input:

```json
{"dotNumbers": ["80806"], "docketNumbers": ["MC138328"]}
```

It returned 2 carriers. Werner's (real output from a local run on 2026-10-04; `cargoCarried` and two of the four
policies shortened, `sources` trimmed to four of its eleven groups):

```json
{
  "dotNumber": "53467",
  "docketNumbers": ["MC138328"],
  "legalName": "WERNER ENTERPRISES INC",
  "dbaName": null,
  "street": "14507 FRONTIER ROAD", "city": "OMAHA", "state": "NE", "zip": "68138", "country": "US",
  "phone": "(402) 895-6640",
  "mailingAddress": {"street": "PO BOX 45308", "city": "OMAHA", "state": "NE", "zip": "68145-0308", "country": "US"},
  "dunsNumber": "022086565",
  "companyOfficers": ["ERIC DOWNING", "JAIME HAMM"],
  "email": "jaime.hamm@werner.com",
  "usdotStatus": "active",
  "entityTypes": ["carrier", "broker"],
  "operatingClasses": ["AUTHORIZED FOR HIRE", "PRIVATE PROPERTY"],
  "carrierOperation": "interstate",
  "hazmat": true,
  "cargoCarried": ["General Freight", "Metal: Sheets, Coils, Rolls", "Building Materials", "..."],
  "powerUnits": 9863, "trucks": 9821, "buses": 42, "drivers": 9107,
  "mcs150Date": "2024-07-23", "mcs150Mileage": 796071597, "mcs150MileageYear": 2023,
  "addedOn": "1974-06-01",
  "safetyRating": "satisfactory", "safetyRatingDate": "1995-08-08",
  "safetyReviewDate": "2024-11-15", "safetyReviewType": "Non-Ratable",
  "dockets": [{"docketNumber": "MC138328", "status": "active"}],
  "operatingAuthorityStatus": "authorized",
  "authorizedFor": ["Motor Carrier of Property (Except Household Goods)", "Broker of Property (Except Household Goods)"],
  "authority": {"motorCarrier": "active", "broker": "active", "freightForwarder": "none"},
  "authorities": [
    {"docketNumber": "MC138328", "type": "Broker of Property (Except Household Goods)", "status": "active",
     "statusSince": "1989-08-25", "statusReason": "GRANTED", "grantedOn": "1989-08-25"},
    {"docketNumber": "MC138328", "type": "Motor Carrier of Property (Except Household Goods)", "status": "active",
     "statusSince": "2026-06-16", "statusReason": "Granted", "grantedOn": "1992-04-24"}
  ],
  "authoritySource": "motus",
  "insurance": {"bipdRequired": 1000000, "bipdOnFile": 5000000, "cargoRequired": false, "cargoOnFile": false,
                "bondRequired": true, "bondOnFile": true},
  "insurancePolicies": [
    {"docketNumber": "MC138328", "coverage": "BI&PD", "form": "BMC-91X", "layer": "excess",
     "insurer": "Ace American Insurance Company", "policyNumber": "XSAH11428927", "coverageAmount": 4000000,
     "underlyingLimit": 1000000, "effectiveDate": "2025-08-01", "postedDate": "2025-07-28",
     "cancelEffectiveDate": null},
    {"docketNumber": "MC138328", "coverage": "bond", "form": "BMC-84", "layer": null,
     "insurer": "Travelers Casualty and Surety Company of America", "policyNumber": "106001707",
     "coverageAmount": 75000, "underlyingLimit": 0, "effectiveDate": "2013-10-01", "postedDate": "2013-10-01",
     "cancelEffectiveDate": null}
  ],
  "insuranceCancellations": [],
  "suspensionsRevocations": [],
  "outOfService": false,
  "outOfServiceDate": null,
  "outOfServiceOrders": [],
  "liveCheck": "ok",
  "sources": {
    "authority": {"source": "safer", "asOf": "2026-10-02"},
    "authorityHistory": {"source": "motus", "asOf": "2026-10-03"},
    "insurance": {"source": "motus", "asOf": "2026-10-03"},
    "outOfServiceOrders": {"source": "oos-orders", "asOf": "2026-10-03"}
  },
  "saferUrl": "https://safer.fmcsa.dot.gov/query.asp?searchtype=ANY&query_type=queryCarrierSnapshot&query_param=USDOT&query_string=53467",
  "flags": ["mcs150-older-than-24-months"],
  "matchedInputs": ["MC138328"],
  "checkedAt": "2026-10-04T08:11:30Z"
}
```

The run cost $0.00605 at the Free-plan price (2 carriers and the start), and took 9.5 seconds locally (two SAFER pages
and eight dataset requests).

### Input

| Field | What it does |
|---|---|
| **USDOT numbers** | One per line, e.g. `80806`; leading zeros and a `USDOT` prefix are fine. |
| **MC / MX / FF docket numbers** | One per line, e.g. `MC138328`, `MC-138328`, `FF51075`; a bare number is read as MC. An MC/MX number FMCSA's datasets don't have is looked up on SAFER. |
| **Live check on FMCSA's SAFER site** | On (default): each carrier's SAFER page, one a second, for current status. Off: datasets only, about 20 times faster for big batches. |
| **Only changed carriers (monitor)** | Return only carriers that changed since this monitor's last run (first run: all, as `new`). |
| **Monitor name** | Keeps separate memories, e.g. `approved-carriers` vs `prospects`. Default: the task's own, else `default`. |
| **Max results per run** | Caps the carriers returned. |
| **Socrata app token (optional)** | Your own free token from data.transportation.gov; avoids throttling on busy shared addresses. Stored encrypted, never logged. |

A carrier named more than once (by USDOT and by MC number, say) is checked and charged once, with every input line in
`matchedInputs`. Up to 10,000 carriers per run. A monitor keeps separate memories with the live check on and off, so
switching starts a fresh baseline instead of a burst of false changes.

```json
{
  "dotNumbers": ["80806", "3496484"],
  "docketNumbers": ["MC138328"],
  "onlyChanges": true,
  "monitorName": "approved-carriers"
}
```

### Output

Every row has the same fields; a field FMCSA doesn't publish for that carrier is `null` (or an empty list).

- `dotNumber`, `docketNumbers`, `dockets` (each docket with the census `active`/`inactive` flag), `legalName`,
  `dbaName`, `street`, `city`, `state`, `zip`, `country`, `phone`, `mailingAddress` (`street`, `city`, `state`,
  `zip`, `country`), `dunsNumber`, `companyOfficers`, `email`.
- `usdotStatus`, `entityTypes` (carrier, broker, freight forwarder, shipper, ...), `operatingClasses` (e.g. AUTHORIZED
  FOR HIRE), `carrierOperation` (interstate, intrastate hazmat, intrastate non-hazmat), `hazmat`, `cargoCarried`.
- `powerUnits`, `trucks`, `buses`, `drivers`, `mcs150Date`, `mcs150Mileage`, `mcs150MileageYear`, `addedOn`.
- `safetyRating`, `safetyRatingDate`, `safetyReviewDate`, `safetyReviewType`.
- `operatingAuthorityStatus`, `authorizedFor`, `authority`, `authorities` (`docketNumber`, `type`, `status`,
  `statusSince`, `statusReason`, `grantedOn`), `authoritySource` (where `authorities` and insurance came from:
  `motus`, `snapshot-2026-05-14` or `none`).
- `insurance` (`bipdRequired`, `bipdOnFile`, `cargoRequired`, `cargoOnFile`, `bondRequired`, `bondOnFile`),
  `insurancePolicies` (`coverage`, `form`, `layer`, `insurer`, `policyNumber`, `coverageAmount`, `underlyingLimit`,
  `effectiveDate`, `postedDate`, `cancelEffectiveDate`), `insuranceCancellations` (`coverage`, `insurer`,
  `policyNumber`, `cancelEffectiveDate`, `reason`: `cancelled`, `replaced` or `name change`).
- `suspensionsRevocations` (`docketNumber`, `authorityType`, `action`, `servedDate`, `effectiveDate`),
  `outOfService`, `outOfServiceDate`, `outOfServiceOrders` (`date`, `reason`, `rescindedDate`, `active`).
- `liveCheck` (`ok`, `off`, `not on SAFER`, `record inactive on SAFER`, `failed: <why>`, `skipped: <why>`) and
  `sources`: for each group (`identity`, `officersAndEmail`, `usdotStatus`, `authority`, `authorityHistory`,
  `insurance`, `outOfService`,
  `outOfServiceOrders`, `safetyRating`, `fleet`, `operation`), `{"source": ..., "asOf": "YYYY-MM-DD"}`, where source
  is `safer`, `motus`, `census`, `oos-orders`, `snapshot-2026-05-14` or `none`. `trucks`, `buses` and `hazmat` always
  come from the census.
- `flags`, `saferUrl` (the carrier's SAFER page, for a person to look at), `matchedInputs`, `checkedAt`.
- Monitor mode only: `changeType` and `changes` (`field`, `before`, `after`).

The run's `RUN_STATS` record lists every input line with its outcome (`returned`, `unchanged`) or the reason it
failed, the date of each source read, the number of requests, and the live check's tally (`safer`: requests, failures,
the last errors, and whether the run stopped asking SAFER).

### Run it on a schedule, or from your own code

1. Save your input as a [task](https://docs.apify.com/platform/actors/running/tasks) and add it to a
   [schedule](https://docs.apify.com/platform/schedules); the steps are under
   [Monitor it](#monitor-your-carriers-for-authority-and-insurance-changes).
2. Collect results: download the dataset as JSON, CSV or Excel; call the
   [API](https://apify.com/humble-echidna/fmcsa-carrier-check/api)
   (`GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=json`, with
   your API token); let a [webhook](https://docs.apify.com/platform/integrations/webhooks) tell your TMS when a run
   succeeds; or connect Make, Zapier or n8n through [Apify's integrations](https://docs.apify.com/platform/integrations).

For a check per load, call the actor synchronously with one number
(`POST https://api.apify.com/v2/acts/humble-echidna~fmcsa-carrier-check/run-sync-get-dataset-items` with
`{"dotNumbers": ["80806"]}`). A one-carrier check with the live check took about 9 seconds in local runs, plus Apify's start-up time.

#### Can I use FMCSA Carrier Check from an AI agent (MCP)?

Yes, through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp), from Claude, ChatGPT, Cursor or
any other MCP client. Add this to your client's MCP configuration; your client signs you in to Apify:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=humble-echidna/fmcsa-carrier-check"
    }
  }
}
```

To use an [Apify API token](https://console.apify.com/settings/integrations) instead of signing in, add
`"headers": {"Authorization": "Bearer <APIFY_TOKEN>"}` next to `url`.

The agent passes the numbers, e.g. `{"dotNumbers": ["80806"]}` or `{"docketNumbers": ["MC138328"]}`, and reads
`flags`, `operatingAuthorityStatus`, `insurance` and `outOfService` for a yes/no answer, with `sources` for how
current each part is.

### Who it's for

Freight brokers and 3PLs who vet a carrier before tendering a load and keep watching the carriers they've approved,
and the TMS, load-board and compliance software that does it for them. The recurring job: the same few hundred or
thousand carriers, checked before every load or every morning, with an alert only when authority, insurance or
out-of-service status changes.

### Why this one?

- **Live where it matters.** USDOT status, operating authority and out-of-service come from each carrier's SAFER page
  at run time, so a carrier FMCSA hasn't moved to its new system yet still gets its current authority. In a sample of
  52 such carriers on 2026-10-04, 4 had a different authority status on SAFER than in the frozen May files (3 now out
  of service, 1 newly authorized).
- **Honest about freshness.** Every part of the record names its source and date in `sources`; insurance that only
  exists in FMCSA's frozen 2026-05-14 files is flagged.
- **Monitor mode with the change itself.** Only changed carriers come back, each with `before` and `after` per field;
  an unchanged carrier costs $0.20 per 1,000.
- **Screening-ready.** Policies are de-duplicated (Motus repeats each one per authority), amounts are dollars,
  dates are ISO, and the `flags` list covers the usual broker checks.
- **One price per carrier.** No compute, proxy or storage charges on top, apart from the $0.00005 run-start fee.
- **Polite and safe.** It identifies itself honestly (User-Agent `HumbleEchidnaApify`), follows the portal's
  robots.txt and its Crawl-delay of one request a second, reads SAFER one page at a time with a second between pages,
  and only contacts data.transportation.gov and safer.fmcsa.dot.gov.
- **Reliable.** A bad number never affects the others, and a dataset that fails fails its batch rather than returning
  a record with a hole in it. The log and `RUN_STATS` say which input had a problem and why.

### Limits

- **Insurance for carriers not yet in Motus is from 2026-05-14.** FMCSA stopped updating its old Licensing &
  Insurance files on that date, and its Licensing & Insurance website (li-public.fmcsa.dot.gov) is retired for filings
  and behind a reCAPTCHA, so it isn't read. Carriers that haven't moved to Motus (most of them in October 2026) get
  the snapshot's insurance and authority history, flagged; their authority status, USDOT status and out-of-service
  status are live from SAFER. Confirm such a carrier's insurance on `saferUrl` before relying on it.
- **The live check is one SAFER page a second:** about 1,000 carriers in 18 minutes. For big batch jobs where the
  daily datasets are enough, switch **Live check** off (about 1,000 carriers a minute).
- SAFER's page is a day or two behind FMCSA's systems (it states its own date, in `sources`), and it leaves the safety
  rating off an out-of-service carrier's page; the census' rating is used then.
- No name search: look carriers up by USDOT or docket number. Many carriers are one-person businesses registered under
  the owner's name, and a name search would make this a people search.
- No cell phone or fax: too few carriers file them to be useful (2.4% and 12% in a 2026-10-04 sample).
- No CSA/SMS BASIC scores, inspections or crash records.

### FAQ

#### Is it legal to use FMCSA carrier data?

The data is FMCSA's own: open data on the US DOT portal (each dataset's metadata says "Public Access Level: public"),
read through the portal's documented Socrata API, and each carrier's public SAFER Company Snapshot, which FMCSA offers
"to industry and the public over the Internet". No login is used. As a US government publication it isn't under
copyright, and DOT's own site policy treats information on its sites as public information that "may be distributed
or copied". FMCSA's disclaimer says the data is a snapshot "for informational purposes only", so treat it as a
screening input, not a legal determination. The registered name, phone, addresses, officers and email are the public
registration details of a licensed carrier, as FMCSA publishes them, returned for verification.

#### How fresh is the data?

`sources` gives each part's source and date. What's live and what isn't:

| Part | Source | How current |
|---|---|---|
| USDOT status, operating authority status, out-of-service status and date | SAFER, at run time | SAFER's stated date, a day or two behind (2026-10-02 on a 2026-10-04 run) |
| Names, addresses, phone, DUNS, fleet, MCS-150, classification, operation, cargo, safety rating | SAFER (the census when SAFER has no record) | Same |
| Company officers, email | Census | Daily (but self-reported on the MCS-150, so only as fresh as the carrier's last filing) |
| Out-of-service order history, docket active flags, trucks, buses, hazmat | FMCSA's daily datasets | Refreshed daily by about 9:30 US Eastern |
| Authority history and insurance, carriers in Motus | Motus datasets | Daily |
| Authority history and insurance, carriers not in Motus yet | Legacy files | Frozen on 2026-05-14 |

With **Live check** off, everything comes from the datasets, and authority status for carriers not in Motus is the
2026-05-14 snapshot.

#### Why did a USDOT or MC number return nothing?

The log and `RUN_STATS` say why, per line: not a valid number, a USDOT number the census doesn't have, a docket
number FMCSA's authority records don't have, or a dataset that couldn't be read (retried next run). None of these
are charged.

#### Can I get only the carriers that changed since my last run?

Yes: switch on **Only changed carriers (monitor)** (`onlyChanges`). The memory lives in a key-value store named
`fmcsa-carrier-check-memory` in your own Apify account, one per monitor name or task, and moves on only for carriers
you actually received, so a run cut by your maximum cost reports the change next time.

#### How is this different from FMCSA's SAFER website or QCMobile API?

SAFER shows one carrier at a time to a person, without insurance policies; QCMobile needs a key you register for.
FMCSA Carrier Check reads SAFER's current status for each carrier and joins it with the insurance policies,
cancellations, orders and authority history from FMCSA's open datasets into one record, for thousands of carriers per
run, with a change monitor on top. The gap is insurance for carriers not in Motus yet (above).

#### Do I need a Socrata app token?

No. Without one, the portal may throttle a busy shared address; the actor waits and retries. If you check thousands of
carriers often, a free token from your own data.transportation.gov account (Developer settings) avoids that.

### Related actors

| Actor | Use it when |
|---|---|
| [Join Datasets](https://apify.com/humble-echidna/dataset-join) | You want the results joined back onto your own carrier list (CSV or dataset) by USDOT number. |
| [Dataset Transformer](https://apify.com/humble-echidna/dataset-transform) | You want a flat CSV or Excel of just a few fields, or only the carriers with flags. |
| [Dataset Diff](https://apify.com/humble-echidna/dataset-diff) | You keep your own snapshots and want new, changed and removed rows between any two. |

### Feedback and support

Found a bug, or need a field FMCSA publishes that isn't here? Open an issue on the **Issues** tab with the input you
used.

### Versions

Current version: **0.1**. See the Changelog tab for what changed in each version.

# Changelog

This Actor's version history is a separate document: https://apify.com/humble-echidna/fmcsa-carrier-check/changelog.md

# Actor input Schema

## `dotNumbers` (type: `array`):

Carriers to check by USDOT number, one per line, e.g. 80806 (leading zeros and a 'USDOT' prefix are fine). Combine freely with docket numbers; a carrier named twice is checked and charged once. Up to 10,000 carriers per run.

## `docketNumbers` (type: `array`):

Carriers, brokers or freight forwarders to check by docket number, one per line, e.g. MC138328, MC-138328 or FF51075. A bare number is read as an MC number. Each is matched to its USDOT number first; one that FMCSA's authority records don't have is reported in the log, not charged.

## `liveCheck` (type: `boolean`):

Read each carrier's SAFER Company Snapshot (one page a second) for its current USDOT status, operating authority status, out-of-service date, fleet, MCS-150 and safety rating, over FMCSA's daily datasets. On by default. Off: datasets only, about 20 times faster for big batches, but authority and insurance for carriers not yet in Motus are from 2026-05-14.

## `onlyChanges` (type: `boolean`):

Return only carriers whose authority, insurance, out-of-service orders, suspensions or revocations, USDOT status or safety rating changed since this monitor's last run, each with a `changes` list (field, before, after). The first run returns every carrier as new. Unchanged carriers aren't returned and cost a small 'unchanged carrier' fee. Off (the default): every carrier is returned.

## `monitorName` (type: `string`):

Names this monitor's memory, e.g. 'approved-carriers'. Leave empty: a saved task keeps its own memory, and runs outside a task share one called 'default'. Use different names for carrier lists you check separately. Only used with onlyChanges.

## `maxResults` (type: `integer`):

Stop after this many carriers returned, e.g. 100. Minimum 1; leave empty (the default) for no limit. The run also stops cleanly at the maximum cost per run you set in the run options, whichever comes first. In monitor mode, carriers past the limit are compared again on the next run.

## `socrataAppToken` (type: `string`):

Your own free app token from data.transportation.gov (Developer settings), sent as the X-App-Token header. Optional: the data is public without it, but Socrata may throttle busy shared addresses, and with a token it doesn't. Stored encrypted, never logged.

## Actor input object example

```json
{
  "dotNumbers": [
    "80806"
  ],
  "docketNumbers": [
    "MC138328"
  ],
  "liveCheck": true,
  "onlyChanges": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runStats` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "dotNumbers": [
        "80806"
    ],
    "docketNumbers": [
        "MC138328"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("humble-echidna/fmcsa-carrier-check").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "dotNumbers": ["80806"],
    "docketNumbers": ["MC138328"],
}

# Run the Actor and wait for it to finish
run = client.actor("humble-echidna/fmcsa-carrier-check").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "dotNumbers": [
    "80806"
  ],
  "docketNumbers": [
    "MC138328"
  ]
}' |
apify call humble-echidna/fmcsa-carrier-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,humble-echidna/fmcsa-carrier-check"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Vw27qrNaBe49oE1Zt/builds/zT5rFdllTEQf3Kbkp/openapi.json
