# Carrier Vetting API — FMCSA Authority, Insurance History & Risk (`xprod_primera/carrier-vetting-api`) Actor

Vet US motor carriers by USDOT or MC number: operating authority with reinstatement/suspension history, insurance filings with pending cancellations, BOC-3, safety & OOS, dated change events and audience-specific risk signals. FMCSA QCMobile + Motus open data.

- **URL**: https://apify.com/xprod\_primera/carrier-vetting-api.md
- **Developed by:** [Bory Abdurakhmonov](https://apify.com/xprod_primera) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 carrier vetteds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Carrier Vetting API — FMCSA Authority, Insurance History, Changes & Risk (USDOT/MC)

Vet US motor carriers the way an experienced compliance analyst would — not just *"is the authority active right now?"*, but **what happened to this carrier lately and what is about to happen**. One call takes a list of USDOT or MC numbers and returns, per carrier: operating authority by type with status dates and reinstatements, insurance filings with **pending cancellations and replacement detection**, served **suspension notices with their effective dates**, BOC-3, safety rating and out-of-service data, a dated event timeline, audience-specific risk signals, and a plain-English summary with a LOW / MEDIUM / HIGH risk level.

Everything is built from official FMCSA data: the QCMobile API and the FMCSA **Motus** Licensing & Insurance open datasets (the successor to the L\&I website), refreshed daily.

### What you get

One dataset item per carrier (also available as JSON over HTTP in Standby mode):

- **Profile** — legal name, DBA, entity type, MC/docket numbers, address, phone, fleet size, drivers, MCS-150 date.
- **Authority** — per type (common carrier / broker) with status (`granted`, `reinstated`, `suspended`, `revoked`, `pending`, `none`), the date and FMCSA reason of the last change, the original grant date, and — uniquely — `suspension_effective` when FMCSA has **served a suspension notice that has not taken effect yet**.
- **Insurance** — BIPD required vs on file, every active filing (insurer, policy, coverage, effective date) **plus recently terminated policies**, and a derived `pending_cancellation` object: which policy is being cancelled, when it takes effect, and whether a **replacement policy is already on file** (a cancellation with a replacement is routine; one without is a red flag).
- **Events** — dated changes from the last 90 days (`authority_reinstated`, `insurance_cancellation_filed`, `authority_suspension_pending`, `insurance_replaced`, …), each with FMCSA row-level evidence references. `includeTimeline: true` adds the full history window (default 365 days).
- **Signals** — rule-driven, tuned per audience (`broker`, `insurance`, `factoring`, `vendor`, `generic`): e.g. `AUTHORITY_SUSPENSION_PENDING` (HIGH for brokers, with days-until-effective), `INSURANCE_CANCELLATION_PENDING` vs `INSURANCE_REPLACED_PENDING_CANCEL` (lead lost, for insurance sellers), `NEW_CARRIER` (opportunity for vendors).
- **Risk + summary** — `LOW`/`MEDIUM`/`HIGH` with explicit reasons, and a four-line human summary (CURRENT / RECENT / IMPORTANT) you can drop into Slack, a TMS note, or an underwriting file.

### Why history matters

Real carrier, real data — USDOT **3224925** (H TWO TRUCKING INC, Fresno CA), as vetted on Aug 30 2026:

- Jul 13 — BIPD policy replaced
- Aug 1 — operating authority **involuntarily suspended** (insurance cancellation, no active coverage)
- Aug 3 — FMCSA served a suspension notice, **effective Sep 2**
- Aug 15 — new BIPD policy filed (Motor Transport Mutual RRG)
- Aug 29 — authority **reinstated**
- A cancellation of the prior policy is still pending, effective Sep 2 — **replacement is on file**

A snapshot-only lookup — which is what typical carrier APIs return — says: *authority active, insurance active*. This Actor says: **risk MEDIUM — reinstated 1 day ago after an insurance lapse, a suspension notice is dated to take effect in 3 days (likely superseded by the reinstatement), prior policy cancellation effective Sep 2 with replacement on file**. That is the difference between booking a load blind and booking it with your eyes open. Carriers that lapse once tend to lapse again; factoring companies and insurers price exactly this pattern.

### Example output

```json
{
  "dot": "3224925",
  "profile": { "legal_name": "H TWO TRUCKING INC", "status": "active", "mc": ["MC-1009988"], "power_units": 2 },
  "authority": { "overall": "granted", "common": { "status": "reinstated", "status_date": "2026-08-29", "reason": "Reinstated", "suspension_effective": "2026-09-02" } },
  "insurance": {
    "bipd_required": 750000, "bipd_on_file": 750000, "boc3_on_file": true,
    "filings": [
      { "type": "bipd", "insurer": "Motor Transport Mutual Risk Retention Group, Inc.", "policy": "SLHMI396500", "effective": "2026-08-15", "status": "active" },
      { "type": "bipd", "insurer": "Universal Casualty Risk Retention Group, Inc", "policy": "URG02555", "cancellation_effective": "2026-09-02", "status": "cancellation_pending" }
    ],
    "pending_cancellation": { "policy": "URG02555", "effective": "2026-09-02", "replacement_on_file": true }
  },
  "events": [
    { "occurred_at": "2026-08-29", "type": "authority_reinstated" },
    { "occurred_at": "2026-08-15", "type": "insurance_filed" },
    { "occurred_at": "2026-08-03", "type": "authority_suspension_pending" },
    { "occurred_at": "2026-08-01", "type": "authority_suspended" }
  ],
  "signals": [
    { "severity": "HIGH", "signal": "AUTHORITY_SUSPENSION_PENDING", "daysUntilEffective": 3 },
    { "severity": "MEDIUM", "signal": "INSURANCE_REPLACED_PENDING_CANCEL" }
  ],
  "riskLevel": "MEDIUM",
  "summary": "DOT 3224925 — H TWO TRUCKING INC\nCURRENT: authority active (reinstated Aug 29) · insurance active · no OOS · risk MEDIUM\nRECENT: … \nIMPORTANT: authority suspension notice effective in 3 days …; prior policy cancellation effective Sep 2 — replacement policy is on file.",
  "sources": ["qcmobile", "motus"]
}
```

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `usdotNumbers` | string\[] | — | Up to 500 per run. |
| `mcNumbers` | string\[] | — | `MC1009988` / `MC-133655`; resolved via FMCSA QCMobile. Unresolvable dockets become per-item error records; the run continues. |
| `includeTimeline` | boolean | `false` | Full dated history per carrier (billed as `full-report`). |
| `audience` | enum | `generic` | `broker` · `insurance` · `factoring` · `vendor` · `generic`. |
| `maxHistoryDays` | integer | `365` | History window for the timeline and derived events. |

Standby mode (API-style): `GET https://<actor-standby-url>/vet/3224925?audience=broker&includeTimeline=true` returns the same item as JSON.

### Pricing

Pay-per-event — you pay for what the run actually does, and the run stops cleanly at your **Maximum total charge**:

| Event | Price | When |
|---|---|---|
| `run-start` | $0.005 | Once per run. |
| `carrier-vet` | $0.02 | Per carrier vetted (current state + 90-day events + signals). |
| `full-report` | $0.15 | Per carrier when `includeTimeline` is on (full dated history). |

Free Apify plans are capped at 5 carriers per run. 500 carriers ≈ $10.00 (or $75.00 with timelines).

### For freight brokers / factoring / insurance

- **Brokers**: onboarding + pre-tender checks. `AUTHORITY_SUSPENSION_PENDING` and `INSURANCE_CANCELLATION_PENDING` (no replacement filed) are the two signals that prevent hauling a load for a carrier who legally cannot run next week.
- **Factoring**: `CARRIER_RISK_INCREASED`, recent reinstatements and shrinking fleets flag invoices that may be at risk; the timeline shows whether a carrier's lapse is a one-off or a habit.
- **Insurance agents**: `INSURANCE_SALES_LEAD` fires when a cancellation is filed **without** a replacement — a shoppable carrier; `INSURANCE_REPLACED_PENDING_CANCEL` (lead lost) keeps your outreach list clean. `NEW_CARRIER` catches fresh authorities that must file coverage now.

### Data sources & freshness

- **FMCSA QCMobile API** (official): carrier census, fleet, safety rating, OOS rates, docket→USDOT resolution.
- **FMCSA Motus open datasets** on data.transportation.gov (official, the L\&I system of record): operating-authority status and history, insurance filings and cancellation history, BOC-3, suspension/revocation notices. FMCSA targets refreshing these **daily by 09:30 ET**.
- SAFER is used only as a fallback when both primaries are unavailable.

Each event carries evidence references (source, dataset id, row key, retrieval time). When the operator's state database is enabled, results are diffed against stored history, so events are *changes actually observed over time*, not inferences from a single snapshot.

### Not a consumer report (FCRA)

This Actor republishes and analyzes **public FMCSA safety and licensing records about businesses**. It is **not a consumer reporting agency** and its output is **not a consumer report** under the Fair Credit Reporting Act. Do not use it to determine a natural person's eligibility for credit, insurance, employment, housing, or any other FCRA-governed purpose. Data is provided as-is from FMCSA sources, which are themselves snapshots; always verify time-critical facts (e.g. today's insurance status) with FMCSA before acting.

### FAQ

**How current is the data?** Motus datasets refresh daily by ~09:30 ET; QCMobile is near-real-time. Each item carries `observedAt` and per-source retrieval times.

**What happens with a DOT that does not exist?** A per-item error record (`{ "input": "999", "error": "not found …" }`); the run continues and you are not charged for it.

**Can I call it like a REST API?** Yes — enable Standby and `GET /vet/:dot`. Runs are better for batches (500 per run).

**Why do some carriers show no insurance filings?** Intrastate carriers and carriers without for-hire interstate authority are not in the FMCSA L\&I system; you still get census/safety data via QCMobile.

**Do you store my input?** Inputs are USDOT/MC numbers only. The operator's database stores carrier snapshots and events (public data), which is what makes change detection possible.

**What is `pending_confirmation`?** Negative insurance events derived from a single non-authoritative source are held back until corroborated (two observations or Motus evidence), so you do not act on a false lapse.

# Actor input Schema

## `usdotNumbers` (type: `array`):

Carriers to vet by USDOT number (max 500 per run). Digits only; leading zeros are ignored.

## `mcNumbers` (type: `array`):

Carriers to vet by docket number (e.g. MC1009988 or MC-133655). Resolved to USDOT via FMCSA QCMobile; unresolvable dockets produce a per-item error record instead of failing the run.

## `includeTimeline` (type: `boolean`):

Adds the carrier's dated event history (authority actions, insurance filings/cancellations) to each item. Charged as the higher-priced full-report event.

## `audience` (type: `string`):

Tailors the signal set and severities.

## `maxHistoryDays` (type: `integer`):

How far back events are derived from FMCSA history rows.

## Actor input object example

```json
{
  "usdotNumbers": [
    "3224925"
  ],
  "includeTimeline": false,
  "audience": "generic",
  "maxHistoryDays": 365
}
```

# Actor output Schema

## `vettedCarriers` (type: `string`):

One item per requested carrier: profile, authority with history, insurance filings incl. pending cancellations, safety/OOS, dated change events, audience-specific risk signals, riskLevel and a plain-English summary.

## `overviewTable` (type: `string`):

Console table view of the vetted carriers (USDOT, carrier, risk level, summary).

# 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 = {
    "usdotNumbers": [
        "3224925"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("xprod_primera/carrier-vetting-api").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 = { "usdotNumbers": ["3224925"] }

# Run the Actor and wait for it to finish
run = client.actor("xprod_primera/carrier-vetting-api").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 '{
  "usdotNumbers": [
    "3224925"
  ]
}' |
apify call xprod_primera/carrier-vetting-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xprod_primera/carrier-vetting-api"
        }
    }
}

```

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/O2CoIyZarZ8N4uz6t/builds/9n7Tu4rv88HXMmhYd/openapi.json
