Get a Sandbox Key
Log in, issue a free key, and use it with any of the 50 fixture carriers.
Sandbox is free. API is $500/mo unlimited.
Download OpenAPILog in, issue a free key, and use it with any of the 50 fixture carriers.
curl "https://mds.motorcarrier.ai/v2/profile?dot=54283" \
-H "Authorization: Bearer YOUR_API_KEY"Authorization: Bearer. Sandbox key hits the 50 fixture carriers. Paid key is unlimited.
Full dossier lives on GET /v2/profile — open Profile for the field-by-field schema.
Sandbox is fixture data for those 50 DOTs on GET /v2/profile and GET /v2/profile-lite, same response shapes, 30 requests/min. Paid is live warehouse, $500/mo unlimited, 60 requests/min. Paid carrier-list, autocomplete, and monitoring access requires an mca_live_ key with the $500/mo API subscription.
Free
Build, prototype, and test before you spend a cent.
$500/mo
Unlimited pulls
When to call which route — always pick the smallest payload that finishes the job.
| Route | Returns | Use when | Prefer instead when | Auth | Sandbox |
|---|---|---|---|---|---|
GET /v2/profile | Fat dossier groups: identity, authority, iss, flags, inspection_units, contact_history, reliability_signals, risk_index (+ live groups as shipped) | Underwriting / deep review / one-carrier truth | You only need name+fleet → lite; browsing many → carriers/autocomplete | Bearer | Yes (50) |
GET /v2/profile-lite | carrier identity/address/fleet + lookups_remaining | After typeahead / fast enrichment | Need flags/ISS/inspections → profile | Bearer | Yes (50) |
GET /v2/carriers | Lean list + pagination; inferred renewal fields | Daily lead ingest by units + renewal window | Single DOT known → profile/lite | Paid mca_live_ | No |
GET /v2/autocomplete | Lean results[] hits | Typeahead DOT/MC/name/DBA | Exact DOT known → lite/profile | Paid mca_live_ | No |
GET /v2/monitoring | items[] watches from stored snapshot | Dashboard of watched DOTs | Need fresh dossier → profile | Paid mca_live_ | No |
POST /v2/monitoring | item + created | Start watching a DOT | DOT unknown to warehouse → will 404 | Paid mca_live_ | No |
DELETE /v2/monitoring/{dot} | removed | Stop watching | — | Paid mca_live_ | No |
GET /v2/monitoring/events | events[] + next_cursor | Poll for authority/insurance/safety changes on watched DOTs | Need the fresh dossier, not just the diff → profile | Paid mca_live_ | No |
POST /v2/monitoring/webhooks | id + url + secret (once) + created_at | Register a push endpoint instead of polling | Secret is shown once — store it immediately | Paid mca_live_ | No |
GET /v2/monitoring/webhooks | webhooks[] (no secrets) | Audit registered endpoints | Need the secret again → re-register | Paid mca_live_ | No |
DELETE /v2/monitoring/webhooks/{id} | revoked | Stop delivery to an endpoint | — | Paid mca_live_ | No |
POST /v2/exports | id + state | Queue a filtered CSV export over more rows than carriers/list pagination is worth | Need it right now / under ~500 rows → carriers | Paid mca_live_ | No |
GET /v2/exports/{id} | state + authenticated download url when ready | Poll a queued export | — | Paid mca_live_ | No |
| Item | Detail |
|---|---|
| Header | Authorization: Bearer YOUR_API_KEY |
| Sandbox key | Fixture carriers only (50 DOTs) on profile + profile-lite |
| Paid key | Live warehouse; $500/mo unlimited pulls |
| Paid-only routes | carriers, autocomplete, monitoring family, exports family — require mca_live_ + monthly API subscription |
| Owner binding | Monitoring and exports fail closed with 403 if paid key has no owner (cannot resolve watchlist / export ownership) |
| Quota fields | When a response includes lookups_remaining, it also includes unlimited. A zero balance is not exhausted when unlimited is true. |
| Tier | Limit |
|---|---|
| Sandbox | 30 requests/min |
| Paid | 60 requests/min |
| Over limit | 429 + Retry-After header (seconds) |
| Field | Detail |
|---|---|
limit | default 100, max 500 |
cursor | opaque continuation from pagination.next_cursor |
| Stop | pagination.next_cursor is null |
| Sort | estimated_expiration_date asc, then DOT asc |
| Param | Type | Default | Range / notes |
|---|---|---|---|
power_units_min | integer | 11 | Min census power_units |
renewal_days_min | integer | 85 | Inclusive days from current UTC; 0–365 |
renewal_days_max | integer | 95 | Inclusive; 0–365 |
renewal_date_min | ISO date | — | With renewal_date_max, instead of renewal_days_*; UTC today to today+365 |
renewal_date_max | ISO date | — | Inclusive; on or after renewal_date_min |
state | codes | — | Comma-separated, e.g. TX,OH; max 60; unknown codes are a 400 |
exclude_state | codes | — | e.g. NY,MA; also drops carriers with no state; not with state |
lower48 | boolean | false | 48 contiguous states + DC; combine with exclude_state, not with state |
operating_status | active | any | any | any (default) keeps every carrier; active = census status_code A |
authority | common | contract | broker | any_active | none | any | any | FMCSA authority status Active; broker counts as an authority; none includes carriers with no authority record |
has_mc | boolean | — | true = has an MC number, false = none; omit for both |
| Cap | Detail |
|---|---|
| Max rows per job | 10,000 — paginated from the carrier list warehouse view |
| Max concurrent jobs | 3 non-terminal (queued or building) exports per owner at a time — 409 past that |
| Artifact TTL | 24 hours from creation, then the job expires and the CSV is deleted |
| Signed download | Use the absolute signed URL returned by status within 5 minutes; poll status again for a fresh URL |
| email_when_ready | Best-effort only. Sent when Resend is configured; the export still reports ready if the email fails |
GET /v2/profile[-lite] needs exactly one of dot, mc, name, vin, phone, or email; export filters must be integers in range; include accepts only contacts (code invalid_include).
Missing or invalid Bearer.
A paid monthly API key is required for carrier-list, autocomplete, monitoring, and exports requests.
No warehouse hit for dot/mc/name/vin/phone/email, the DOT is not on your monitoring list, or the export id is not yours.
Monitoring list is at capacity, or mc/name/vin/phone/email on GET /v2/profile[-lite] matched more than one carrier — see candidates[], or you already have 3 exports in progress.
Too many requests. Sandbox 30/min. Paid 60/min. Retry-After is seconds.
Retry-After: <seconds>
Header value is seconds until retry.
Carrier list or monitoring temporarily unavailable. Retry later. Code contacts_unavailable: contact suppression could not be checked, or an export was invalidated by a newer suppression (no lookup consumed).
Sandbox keys resolve these fixture DOTs on GET /v2/profile and GET /v2/profile-lite — same response shapes as paid, 30 requests/min.
| DOT | Note |
|---|---|
54283 | Mega carrier — Swift Transportation. Soft-bound partial dossier: empty contact_history, no_data reliability signals, risk_index.state unavailable (see the Profile example above). |
86876 | Standard fixture carrier |
80806 | Standard fixture carrier |
21800 | Standard fixture carrier |
3706 | Standard fixture carrier |
63585 | Standard fixture carrier |
264184 | Standard fixture carrier |
511412 | Standard fixture carrier |
53467 | Standard fixture carrier |
354406 | Standard fixture carrier |
Full sandbox allowlist is 50 DOTs (MDS_SANDBOX_DOTS in source) — the first 10 are listed here.
Contact Data is phone, cell_phone, email, contact_name and officer names. Paid keys receive it by default. include=contacts remains accepted as a compatibility no-op.
| Route | Contact data returned by default |
|---|---|
GET /v2/profile | carrier.contacts, identity.officers, and the phone, cell_phone, email and officer rows of contact_history |
GET /v2/carriers | carriers[].contacts |
POST /v2/exports | phone, cell_phone, email and contact_name CSV columns (query parameter or body field include) |
| Field | Type | Notes |
|---|---|---|
contacts.phone | string | null | Primary business phone on file |
contacts.cell_phone | string | null | Returned independently even when it equals phone |
contacts.email | string | null | Primary email on file |
contacts.contact_name | string | null | Primary contact or officer name on file |
Opted-out values (contact opt-out) come back as null. When a carrier's Contact Data is suppressed as a whole, contacts are null, identity.officers and contact_history are empty, and physical/mailing street addresses are blanked. A failed suppression check returns 503 before charging the lookup.
/v2/profileFat warehouse dossier for one carrier — identity through as-of in a single GET.
ISS-CSA from warehouse SMS. Official flags from Otto. Inspection-unit VINs from vPIC. Contact history from Motus daily-diff, forward-only. Reliability signals from Otto. Not a 0–100 score. Risk index from Otto dossier facts with contributing factors. Not an opaque probability. Provide exactly one of dot, mc, name, vin, phone, or email — a mc/name/vin/phone/email match with more than one carrier returns 409 with a compact candidates[] list ({ dot, mc, name }) instead of guessing. Phone accepts 10 digits with common punctuation and an optional leading +1. Email is trimmed, lowercased, and matched exactly. Registration reverse lookup is deferred until an indexed warehouse column exists. Autocomplete does not search VIN, phone, or email.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dot | query | string | one of dot, mc, name, vin, phone, email | USDOT; examples use 54283 |
mc | query | string | one of dot, mc, name, vin, phone, email | MC/MX docket, e.g. MC136818 |
name | query | string | one of dot, mc, name, vin, phone, email | Legal or DBA name contains; 2+ characters. 409 if it matches more than one carrier |
vin | query | string | one of dot, mc, name, vin, phone, email | Stored MCMIS inspection-unit VIN; exactly 17 chars after trim/uppercase. 404 if unknown. 409 if ambiguous |
phone | query | string | one of dot, mc, name, vin, phone, email | Exact stored business or cell phone; 10 digits after common punctuation and optional +1 normalization. 404 if unknown. 409 if ambiguous |
email | query | string | one of dot, mc, name, vin, phone, email | Exact stored business email; trimmed and lowercased, up to 254 characters. 404 if unknown. 409 if ambiguous |
include | query | string | no | contacts — accepted as a compatibility no-op. See Contact data |
curl "https://mds.motorcarrier.ai/v2/profile?dot=54283" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile?mc=MC136818" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile?name=Swift%20Transportation" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile?vin=1M8GDM9AXKP042788" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile?phone=%2B1%20%28555%29%20123-4567" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile?email=dispatch%40carrier.example" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
identity | object | Core carrier identity |
identity.dot_number | string | |
identity.mc_number | string | |
identity.legal_name | string | |
identity.dba_name | string | null | |
identity.status_code | string | e.g. A |
identity.allowed_to_operate | boolean | |
identity.physical | object | street, city, state, zip, country |
identity.power_units | number | |
identity.total_drivers | number | |
identity.mcs150_date | string | date |
authority | object | |
authority.current.docket_number | string | |
iss | object | Warehouse SMS ISS-CSA |
iss.value | number | |
iss.recommendation | string | |
iss.algorithm | string | e.g. ISS-CSA |
flags | array | Official flags; items { id, on, state } |
inspection_units | array | Items may include vin, year, make, model |
identity.officers | string[] | Contact Data returned by default for paid keys unless contact suppression applies |
contacts | object | phone, cell_phone, email, contact_name. See Contact data |
contact_history | array | Backward-compatible legal, address, phone, cell_phone, email, and officer history |
insurance | array | Filings on file from all sources: docket_number, insurance_type, form_code, company_name, policy_number, effective_date, cancel_effective_date, source |
insurance[].estimated_expiration_date | string | null | ESTIMATE, never verified: FMCSA filings stay in force until cancelled and no source reports a policy term. Primary BIPD filings only; null for cargo, bond, excess and cancelled filings |
insurance[].expiration_basis | string | null | cancellation_filed | replacement_filed (cancellation on file) · future_policy_effective (later filing on file) · anniversary | anniversary_rolled (effective-date anniversary) |
insurance[].expiration_verified | boolean | Always false |
insurance[].renewal_confidence | string | null | event (a filing on record) | modeled (anniversary assumption) |
reliability_signals | object | state, as_of, signals[] { id, state } |
risk_index | object | state, score, baseline, excluded_count, as_of, factors[] — not an opaque probability |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"identity": {
"dot_number": "54283",
"mc_number": "136818",
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"dba_name": null,
"status_code": "A",
"allowed_to_operate": true,
"physical": {
"street": "2200 S 75TH AVE",
"city": "PHOENIX",
"state": "AZ",
"zip": "85043",
"country": "US"
},
"power_units": 12940,
"total_drivers": 12883,
"mcs150_date": "2025-08-05"
},
"authority": {
"current": {
"docket_number": "136818"
}
},
"iss": {
"value": 75,
"recommendation": "Inspect",
"algorithm": "ISS-CSA"
},
"flags": [
{ "id": "shared_phone", "on": false, "state": "clear" },
{ "id": "shared_address", "on": false, "state": "clear" },
{ "id": "revoke_in_36_months", "on": false, "state": "clear" },
{ "id": "authority_gap", "on": false, "state": "clear" },
{ "id": "insurance_not_on_file", "on": false, "state": "clear" },
{ "id": "oos", "on": false, "state": "clear" },
{ "id": "new_entrant", "on": false, "state": "clear" },
{ "id": "name_change_churn", "on": false, "state": "no_data" },
{ "id": "same_vin_multiple_dots", "on": false, "state": "clear" },
{ "id": "shared_email", "on": false, "state": "clear" },
{ "id": "shared_officer", "on": false, "state": "clear" },
{ "id": "prior_revoke", "on": false, "state": "clear" },
{ "id": "not_allowed_to_operate", "on": false, "state": "clear" },
{ "id": "hazmat", "on": false, "state": "clear" },
{ "id": "authority_pending", "on": false, "state": "clear" },
{ "id": "sms_basic_alert", "on": false, "state": "no_data" },
{ "id": "crash_in_12_months", "on": false, "state": "clear" },
{ "id": "inspection_oos", "on": false, "state": "clear" }
],
"inspection_units": [
{ "vin": "1M8GDM9AXKP042788", "year": "1998", "make": "MCI", "model": null }
],
"contact_history": [],
"reliability_signals": {
"state": "empty",
"as_of": null,
"signals": [
{ "id": "boc3_on_file", "state": "no_data" },
{ "id": "unbroken_coverage_12mo", "state": "no_data" },
{ "id": "authority_60mo", "state": "no_data" },
{ "id": "never_revoked", "state": "no_data" },
{ "id": "recent_mcs150", "state": "no_data" }
]
},
"risk_index": {
"state": "unavailable",
"score": null,
"baseline": 50,
"excluded_count": 24,
"as_of": null,
"factors": [
{ "id": "flag_oos", "label": "Out of service", "direction": "excluded", "weight": 14, "points": null, "source": "flags" }
]
},
"lookups_remaining": 0,
"unlimited": true
}/v2/profile-liteLean official identity, address, and fleet after typeahead — no full dossier, no scores added.
Provide exactly one of dot, mc, name, vin, phone, or email — a mc/name/vin/phone/email match with more than one carrier returns 409 with a compact candidates[] list ({ dot, mc, name }) instead of guessing. Phone accepts 10 digits with common punctuation and an optional leading +1. Email is trimmed, lowercased, and matched exactly. Registration reverse lookup is deferred until an indexed warehouse column exists.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dot | query | string | one of dot, mc, name, vin, phone, email | USDOT |
mc | query | string | one of dot, mc, name, vin, phone, email | MC/MX docket, e.g. MC136818 |
name | query | string | one of dot, mc, name, vin, phone, email | Legal or DBA name contains; 2+ characters. 409 if it matches more than one carrier |
vin | query | string | one of dot, mc, name, vin, phone, email | Stored MCMIS inspection-unit VIN; exactly 17 chars after trim/uppercase. 404 if unknown. 409 if ambiguous |
phone | query | string | one of dot, mc, name, vin, phone, email | Exact stored business or cell phone; 10 digits after common punctuation and optional +1 normalization. 404 if unknown. 409 if ambiguous |
email | query | string | one of dot, mc, name, vin, phone, email | Exact stored business email; trimmed and lowercased, up to 254 characters. 404 if unknown. 409 if ambiguous |
curl "https://mds.motorcarrier.ai/v2/profile-lite?dot=54283" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile-lite?mc=MC136818" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile-lite?name=Swift%20Transportation" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile-lite?vin=1M8GDM9AXKP042788" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile-lite?phone=5551234567" \
-H "Authorization: Bearer YOUR_API_KEY"
curl "https://mds.motorcarrier.ai/v2/profile-lite?email=dispatch%40carrier.example" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
carrier | object | Lean carrier |
carrier.dot_number | string | |
carrier.mc_number | string | |
carrier.legal_name | string | |
carrier.dba_name | string | null | |
carrier.status_code | string | |
carrier.allowed_to_operate | boolean | |
carrier.physical | object | street/city/state/zip/country |
carrier.mailing | object | street/city/state/zip/country |
carrier.power_units | number | |
carrier.total_drivers | number | |
carrier.mcs150_date | string | |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | true for unlimited paid keys; false for metered and sandbox keys |
{
"carrier": {
"dot_number": "54283",
"mc_number": "136818",
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"dba_name": null,
"status_code": "A",
"allowed_to_operate": true,
"physical": {
"street": "2200 S 75TH AVE",
"city": "PHOENIX",
"state": "AZ",
"zip": "85043",
"country": "US"
},
"mailing": {
"street": "PO BOX 29243",
"city": "PHOENIX",
"state": "AZ",
"zip": "85038",
"country": "US"
},
"power_units": 12940,
"total_drivers": 12883,
"mcs150_date": "2025-08-05"
},
"lookups_remaining": 0,
"unlimited": true
}/v2/carriersPaid lean hits for daily lead ingest — every carrier with a current BIPD filing from any insurance source, filtered by power units, estimated expiration window, state, operating status, authority and MC number.
Defaults target estimated expirations 85–95 days from current UTC. Stable order: estimated_expiration_date asc, DOT asc. Continue with next_cursor as cursor; it preserves the original filters while warehouse rows refresh. Estimates come from a nightly all-source index (meta.as_of_date); until its first refresh completes, the list is served from the earlier Motus observation set (meta.source), and a cursor from that set returns 400 cursor_expired once the index is live — restart without cursor. The authority filter needs that index: before its first refresh it returns 503 filter_unavailable. Invalid or conflicting filter values return 400.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
power_units_min | query | integer | no | 11 | Min power_units |
renewal_days_min | query | integer | no | 85 | Inclusive; 0–365 |
renewal_days_max | query | integer | no | 95 | Inclusive; 0–365 |
renewal_date_min | query | ISO date | no | — | Absolute window start (UTC today to today+365); send with renewal_date_max instead of renewal_days_* |
renewal_date_max | query | ISO date | no | — | Absolute window end, inclusive |
state | query | string | no | — | Include these physical states, e.g. TX,OH (max 60) |
exclude_state | query | string | no | — | Exclude these states, e.g. NY,MA; carriers with no state are excluded too |
lower48 | query | boolean | no | false | 48 contiguous states + DC; with exclude_state, minus those |
operating_status | query | string | no | any | any (default) keeps every carrier; active = census status_code A |
authority | query | string | no | any | common | contract | broker | any_active | none (Active FMCSA authority; broker counts as an authority; none includes carriers with no authority record) |
has_mc | query | boolean | no | — | true = has an MC number, false = none |
cursor | query | string | no | — | Opaque next_cursor from the prior response; it carries every filter, so send no filters with it (blank values count as omitted) |
limit | query | integer | no | 100 | Max 500 |
include | query | string | no | — | contacts — accepted as a compatibility no-op |
curl "https://mds.motorcarrier.ai/v2/carriers?power_units_min=11&renewal_days_min=85&renewal_days_max=95&limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
carriers | array | Lean hits |
carriers[].dot | string | |
carriers[].name | string | |
carriers[].power_units | number | |
carriers[].inferred_renewal_date | string | Deprecated alias of estimated_expiration_date |
carriers[].days_to_renewal | number | estimated_expiration_date minus today (UTC), computed per request |
carriers[].state | string | |
carriers[].mc_number | string | null | |
carriers[].status_code | string | null | Census operating status |
carriers[].estimated_expiration_date | string | Otto estimate — not a guarantee, never an FMCSA-filed expiration |
carriers[].expiration_basis | string | cancellation_filed | replacement_filed | future_policy_effective | anniversary | anniversary_rolled |
carriers[].renewal_confidence | string | event (filed cancellation or future filing) | modeled (anniversary) |
carriers[].expiration_verified | boolean | Always false — no source reports a policy term |
carriers[].bipd_sources | string[] | Insurance sources reporting the current BIPD filings |
carriers[].insurer | string | null | |
carriers[].latest_effective_date | string | null | Latest in-force BIPD effective date |
carriers[].contacts | object | phone, cell_phone, email, contact_name; returned by default |
pagination.limit | number | |
pagination.total | number | Fixed from the first page |
pagination.next_cursor | string | null | Pass as cursor; null is the stop condition |
meta.source | string | carrier_renewal_index | insurance_renewal_observations (fallback before the first index refresh) |
meta.as_of_date | string | null | Index refresh date; null on the fallback |
{
"carriers": [
{
"dot": "218563",
"name": "EXAMPLE FREIGHT LLC",
"power_units": 25,
"inferred_renewal_date": "2026-12-15",
"days_to_renewal": 90,
"state": "TX",
"mc_number": "MC123456",
"status_code": "A",
"estimated_expiration_date": "2026-12-15",
"expiration_basis": "anniversary",
"renewal_confidence": "modeled",
"expiration_verified": false,
"bipd_sources": ["dot_data_portal", "motus_insur_all_c5y8-a4uz"],
"insurer": "EXAMPLE MUTUAL INSURANCE CO",
"latest_effective_date": "2025-12-15"
}
],
"pagination": {
"limit": 100,
"total": 1,
"next_cursor": null
},
"meta": {
"source": "carrier_renewal_index",
"as_of_date": "2026-09-16"
}
}/v2/autocompletePaid typeahead over DOT, MC, legal name, or DBA — lean hits, no risk claim.
Default limit: 10 hits. Request profile separately for dossier.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
q | query | string | yes | Minimum 2 characters after trimming. Accepts DOT, MC, legal name, or DBA name. |
curl "https://mds.motorcarrier.ai/v2/autocomplete?q=Swift%20Transportation" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
query | string | Echo |
results | array | Lean hits |
results[].dot_number | string | |
results[].mc_number | string | |
results[].legal_name | string | |
results[].dba_name | string | null | |
results[].status_code | string | |
results[].allowed_to_operate | boolean | |
results[].physical_city | string | |
results[].physical_state | string | |
results[].power_units | number | |
results[].total_drivers | number | |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"query": "Swift Transportation",
"results": [
{
"dot_number": "54283",
"mc_number": "136818",
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"dba_name": null,
"status_code": "A",
"allowed_to_operate": true,
"physical_city": "PHOENIX",
"physical_state": "AZ",
"power_units": 12940,
"total_drivers": 12883
}
],
"lookups_remaining": 0,
"unlimited": true
}/v2/monitoringLists DOTs your paid key monitors — identity from the stored watch snapshot, not a fresh dossier pull.
None — lists every watch owned by the key's account.
curl "https://mds.motorcarrier.ai/v2/monitoring" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
items | array | |
items[].dot_number | string | |
items[].watched_at | string | ISO timestamp |
items[].legal_name | string | From snapshot |
items[].dba_name | string | null | |
items[].status_code | string | |
items[].allowed_to_operate | boolean | |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"items": [
{
"dot_number": "54283",
"watched_at": "2026-09-01T12:00:00.000Z",
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"dba_name": null,
"status_code": "A",
"allowed_to_operate": true
}
],
"lookups_remaining": 0,
"unlimited": true
}/v2/monitoringAdds a DOT to the paid monitoring list — seeds a full snapshot when available, with a partial census snapshot for very large carriers.
201 newly watched; 200 already on list; 404 not in warehouse; 409 at capacity.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dot_number | body JSON | string | yes* | USDOT |
dot | body JSON | string | yes* | Accepted alias |
curl -X POST "https://mds.motorcarrier.ai/v2/monitoring" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"dot_number": "54283"}'| Field | Type | Notes |
|---|---|---|
item | object | Same lean watch shape as list items |
created | boolean | true if newly added |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"item": {
"dot_number": "54283",
"watched_at": "2026-09-01T12:00:00.000Z",
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"dba_name": null,
"status_code": "A",
"allowed_to_operate": true
},
"created": true,
"lookups_remaining": 0,
"unlimited": true
}/v2/monitoring/{dot}Removes a DOT from the paid monitoring list.
404 if not currently on the list.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dot | path | string | yes | USDOT |
curl -X DELETE "https://mds.motorcarrier.ai/v2/monitoring/54283" \
-H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
removed | boolean | |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"removed": true,
"lookups_remaining": 0,
"unlimited": true
}/v2/monitoring/eventsCursor-paged change feed for watched DOTs — honest warehouse fields only, areas limited to authority, insurance, and safety.
Events are produced by a poll cycle that diffs each watch's current warehouse snapshot against its stored baseline. No invented scores; census/contact/status-only diffs are not emitted here.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
cursor | query | string | no | none | Opaque cursor from a prior response's next_cursor |
limit | query | integer | no | 100 | Max 500 |
curl "https://mds.motorcarrier.ai/v2/monitoring/events?limit=100" -H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
events | array | May be empty |
events[].id | string | uuid |
events[].dot_number | string | |
events[].occurred_at | string | ISO timestamp |
events[].area | string | authority | insurance | safety |
events[].field | string | |
events[].kind | string | changed | added | removed |
events[].before | string | null | |
events[].after | string | null | |
next_cursor | string | null | Pass back as cursor to continue; null means caught up |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"events": [
{
"id": "8f6c9e2a-2f0a-4e2b-9a7a-1d9b6a7f3c11",
"dot_number": "54283",
"occurred_at": "2026-09-17T12:00:00.000Z",
"area": "authority",
"field": "common_status",
"kind": "changed",
"before": "A",
"after": "I"
}
],
"next_cursor": "MjAyNi0wOS0xN1QxMjowMDowMC4wMDBafDhmNmM5ZTJhLTJmMGEtNGUyYi05YTdhLTFkOWI2YTdmM2MxMQ",
"lookups_remaining": 0,
"unlimited": true
}/v2/monitoring/webhooksRegisters an https:// endpoint to receive signed POSTs for new monitoring events instead of polling.
The secret is returned once at creation — store it, then verify X-MDS-Signature as sha256= + hex HMAC-SHA256 of X-MDS-Timestamp + . + the raw body using that secret, and reject timestamps older than 5 minutes.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
url | body JSON | string | yes | https:// endpoint |
curl -X POST "https://mds.motorcarrier.ai/v2/monitoring/webhooks" -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -d '{"url": "https://example.com/mds-webhook"}'| Field | Type | Notes |
|---|---|---|
id | string | uuid |
url | string | |
secret | string | Shown once — save it now |
created_at | string | ISO timestamp |
{
"id": "3b1c9e2a-2f0a-4e2b-9a7a-1d9b6a7f3c22",
"url": "https://example.com/mds-webhook",
"secret": "mds_whsec_5f0c1a2b3d4e5f60718293a4b5c6d7e8",
"created_at": "2026-09-17T12:00:00.000Z"
}/v2/monitoring/webhooksLists active webhook registrations for the key's account — no secrets returned.
None — lists every active webhook owned by the key's account.
curl "https://mds.motorcarrier.ai/v2/monitoring/webhooks" -H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
webhooks | array | May be empty |
webhooks[].id | string | uuid |
webhooks[].url | string | |
webhooks[].created_at | string | ISO timestamp |
{
"webhooks": [
{
"id": "3b1c9e2a-2f0a-4e2b-9a7a-1d9b6a7f3c22",
"url": "https://example.com/mds-webhook",
"created_at": "2026-09-17T12:00:00.000Z"
}
]
}/v2/monitoring/webhooks/{id}Revokes a webhook — delivery stops immediately.
404 if the id isn't an active webhook owned by this key's account.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Webhook id from register/list |
curl -X DELETE "https://mds.motorcarrier.ai/v2/monitoring/webhooks/3b1c9e2a-2f0a-4e2b-9a7a-1d9b6a7f3c22" -H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
revoked | boolean |
{
"revoked": true
}/v2/exportsQueues an async CSV export over the same filter spirit as carrier list — up to 10,000 rows, built by a background worker. Same all-source universe, filters and order as carrier list. Contact columns (phone, cell_phone, email, contact_name) are included by default for paid keys.
Max 3 non-terminal (queued/building) exports per owner at once — a 4th returns 409. Consumes one paid lookup on enqueue, not on status polling. authority (other than any) returns 503 filter_unavailable, without consuming a lookup, until the first all-source index refresh; the other filters work before it. Body booleans accept JSON true/false or the strings true/false, integers accept numbers or digit strings, and an empty string counts as omitted.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
power_units_min | body JSON | integer | no | 11 | Min power_units |
renewal_days_min | body JSON | integer | no | 85 | Inclusive; 0–365 |
renewal_days_max | body JSON | integer | no | 95 | Inclusive; 0–365 |
renewal_date_min, renewal_date_max, state, exclude_state, lower48, operating_status, authority, has_mc | body JSON | as carrier list | no | — | Same values and 400 rules as GET /v2/carriers; state and exclude_state may also be arrays |
email_when_ready | body JSON | boolean | no | false | Best-effort email when the CSV is ready |
include | query or body JSON | string | string[] | no | — | contacts — accepted as a compatibility no-op |
curl -X POST "https://mds.motorcarrier.ai/v2/exports" -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -d '{"power_units_min": 11, "renewal_days_min": 85, "renewal_days_max": 95, "email_when_ready": true}'| Field | Type | Notes |
|---|---|---|
id | string | Export job id — poll with GET /v2/exports/{'{id}'} |
state | string | queued | building | ready | failed | expired |
include_contacts | boolean | true when the CSV has the contact columns |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"id": "6a9f2b5e-1e2c-4a3b-9c1d-8f7e6d5c4b3a",
"state": "queued",
"include_contacts": true,
"lookups_remaining": 0,
"unlimited": true
}/v2/exports/{id}Polls an owned export job — returns an absolute short-lived signed CSV URL once state is ready.
404 if the id does not exist or is not owned by this key's account. Status rechecks current per-DOT suppression before signing and purges a stale contact export. Poll status again for a fresh URL after 5 minutes.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Export job id from the enqueue response |
curl "https://mds.motorcarrier.ai/v2/exports/6a9f2b5e-1e2c-4a3b-9c1d-8f7e6d5c4b3a" -H "Authorization: Bearer YOUR_API_KEY"| Field | Type | Notes |
|---|---|---|
id | string | |
state | string | queued | building | ready | failed | expired |
url | string | null | Absolute signed CSV URL; present only when ready and valid for 5 minutes |
error | string | null | Failure detail when state is failed |
row_count | number | null | Rows written; present once building finishes |
include_contacts | boolean | true when the CSV has the contact columns |
lookups_remaining | number | May be 0 for unlimited keys |
unlimited | boolean | Interpret the numeric balance with this flag |
{
"id": "6a9f2b5e-1e2c-4a3b-9c1d-8f7e6d5c4b3a",
"state": "ready",
"url": "https://storage.example.com/signed/export.csv",
"error": null,
"row_count": 4218,
"include_contacts": true,
"lookups_remaining": 0,
"unlimited": true
}/api/privacy/opt-outPublic, no API key. Starts an opt-out for an email address (required) plus an optional phone and USDOT number. We email a confirmation link; nothing changes until the person confirms it.
People can use the page at mds.motorcarrier.ai/opt-out or write to privacy@motorcarrier.ai. Once confirmed, the email comes back as null on /v2/profile, /v2/carriers, exports and Studio. The phone is suppressed (for that carrier only) when it is on file with the verified email for that USDOT number; otherwise our team reviews it within 10 business days. The 202 body is the same whether or not we hold the address. If your own customers ask you to stop using their details, forward the request to privacy@motorcarrier.ai.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
email | body | string | yes | Trimmed and lowercased |
phone | body | string | no | 10-digit US number or E.164 |
dot_number | body | string | no | The phone is suppressed for this carrier when it and the verified email are both on file for it; otherwise it is reviewed within 10 business days |
curl -X POST "https://mds.motorcarrier.ai/api/privacy/opt-out" -H "Content-Type: application/json" -d '{"email":"owner@example.com","phone":"555-201-3344","dot_number":"54283"}'| Field | Type | Notes |
|---|---|---|
ok | boolean | true on 202 |
message | string | Same text for every valid request |
{
"ok": true,
"message": "If that address can receive email, a confirmation link is on its way. Open it within 24 hours to finish the opt-out."
}pagination.next_cursor until it is nullstate: no_data / risk_index.state: unavailable honestly — do not retry-spamitemsdot_number to addsecretX-MDS-Signature as sha256= + hex HMAC-SHA256 of X-MDS-Timestamp + . + the raw body using that secret, and reject timestamps older than 5 minutesnext_cursor each callstate is ready or failedurl promptly — the signed link is short-lived and the artifact itself expires after 24hemail_when_ready for a best-effort nudge instead of tight polling