{
  "openapi": "3.1.0",
  "info": {
    "title": "CarrierScrub API",
    "version": "1.0.0",
    "summary": "Check a US motor carrier's FMCSA record before a broker tenders a load.",
    "description": "Each check returns a GO, CAUTION or STOP verdict with dated reason codes. Every reason states a fact FMCSA published and its date; none is a conclusion about the company. Every result names the FMCSA record it used (record_source) and that record's date (record_as_of); the legacy record has been frozen since 2026-05-14. API keys work on every plan: on Pay-as-you-go and Small Brokerage each lookup uses one of the brokerage's 25 free lookups that month, then a $1.00 credit, and on Agency lookups are unlimited. How to get a key is in https://carrierscrub.com/auth.md. AI assistants can use the same checks through the MCP server at https://carrierscrub.com/mcp.",
    "contact": {
      "email": "support@carrierscrub.com",
      "url": "https://carrierscrub.com/contact"
    },
    "termsOfService": "https://carrierscrub.com/terms"
  },
  "externalDocs": {
    "description": "Getting access",
    "url": "https://carrierscrub.com/auth.md"
  },
  "servers": [
    {
      "url": "https://carrierscrub.com"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/lookup": {
      "get": {
        "operationId": "lookupCarrier",
        "summary": "Check one carrier by USDOT or MC number",
        "description": "Counts once toward the brokerage's daily API request limit (shared with the MCP server): 100 a day, or 1,000 on the Agency plan, resetting at 00:00 UTC. On Pay-as-you-go and Small Brokerage it uses one of the brokerage's free monthly lookups, then a credit; a carrier the brokerage already checked today is not charged again. Appears in the brokerage's audit log under the key's name.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "A USDOT number (\"USDOT 8893375\", \"DOT 8893375\" or \"8893375\") or an MC number (\"MC 123456\"). Bare digits are read as a USDOT number.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            },
            "example": "USDOT 8893375"
          },
          {
            "name": "load",
            "in": "query",
            "required": false,
            "description": "Optional load number, recorded with the check in the brokerage's lookup history and vetting file. Letters, digits, spaces and # . _ / - only; at most 40 characters.",
            "schema": {
              "type": "string",
              "maxLength": 40
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The carrier's verdict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Verdict"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/batch": {
      "post": {
        "operationId": "batchCheck",
        "summary": "Check a list of carriers from a CSV or XLSX file",
        "description": "One carrier per row, by USDOT or MC number. Files over 8 MB are refused; rows past the first 1,000 are reported back as skipped rather than dropped. Up to 50 carriers per file are refreshed live from FMCSA; the rest use CarrierScrub's stored record with its date. The same carrier listed more than once is checked once. The request counts once toward the daily API limit.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "A .csv or .xlsx file."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One result row per carrier in the file, in file order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobId": {
                      "type": "string"
                    },
                    "filename": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "description": "Each row carries the input value and either the carrier's verdict (the same fields as a single lookup) or the reason it could not be checked.",
                      "items": {
                        "type": "object"
                      }
                    },
                    "usage": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "413": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/fmcsa-activity": {
      "get": {
        "operationId": "getFmcsaActivity",
        "summary": "How many carriers' FMCSA authority, insurance and contact records changed in a week or on a day",
        "description": "The counts behind https://carrierscrub.com/news and https://carrierscrub.com/fmcsa-weekly-report, counted by comparing each day's copy of FMCSA's Motus Carrier and Company Census datasets with the day before. Aggregates only; no carrier is named. Public: no API key, and it does not count toward any limit. Counts begin 2026-10-06. The MCP tool get_fmcsa_activity returns the same answer.",
        "security": [],
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "\"week\" (default): the latest complete Monday-to-Sunday week, or the week containing `date`. \"day\": the latest day with counts, or `date`.",
            "schema": {
              "type": "string",
              "enum": [
                "week",
                "day"
              ],
              "default": "week"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "description": "A day, YYYY-MM-DD. For a week, any day in it.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-12"
          }
        ],
        "responses": {
          "200": {
            "description": "The period's counts with a dated `summary` to quote, the period's headlines for freight brokers (`carrierscrub_takeaway` is CarrierScrub's AI-written sentence), `url` to cite and `source`. A week also has `totals`, `days`, `complete`, `days_counted` and `change_vs_prior_week` (null unless both weeks are complete with all seven days counted); a day has `activity` (null when that day has no counts).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string",
                      "enum": [
                        "week",
                        "day"
                      ]
                    },
                    "summary": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "headlines": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "source": {
                      "type": "object"
                    }
                  },
                  "required": [
                    "period",
                    "summary",
                    "url",
                    "headlines",
                    "source"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/authority-history": {
      "get": {
        "operationId": "getAuthorityHistory",
        "summary": "Every dated grant, suspension, revocation and reinstatement of a carrier's operating authority",
        "description": "FMCSA's own authority history for one USDOT number, newest first: Motus (data.transportation.gov yu5v-wbh6), which includes the history imported from the legacy file, or the legacy AuthHist (9mw4-x3tu, frozen 14 May 2026) when Motus holds nothing. Each event keeps FMCSA's wording in `action`; `kind` (granted, reinstated, suspended, revoked, dismissed, other) names its direction. Facts beside the verdict, never a verdict. Public, cached a day per carrier, and limited per network and site-wide per day.",
        "security": [],
        "parameters": [
          {
            "name": "dot",
            "in": "query",
            "required": true,
            "description": "USDOT number.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,8}$"
            },
            "example": "2589590"
          }
        ],
        "responses": {
          "200": {
            "description": "`dot_number`, `source` (motus, legacy or none), `events` (date, docket, authority, action, kind; newest first, at most 40), `total` (all events on file) and `checked_at`. `source` none with no events is a real answer: FMCSA holds no authority changes for that number."
          },
          "400": {
            "description": "Not a USDOT number."
          },
          "429": {
            "description": "This network's daily limit, or the site-wide one, is reached until 00:00 UTC."
          },
          "503": {
            "description": "FMCSA could not be read just now. Nothing is inferred."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer cs_live_... An owner or admin of the brokerage, on any plan, creates keys in Admin, then API keys. A key that goes unused for 60 days stops working."
      }
    },
    "responses": {
      "Error": {
        "description": "The check was not completed. 401: no key, or the key is invalid, expired or revoked. 402 (code payg_credits_exhausted): the brokerage has used its free lookups this month and has no credits left; the hint says where to buy them. 404: no carrier for that number. 413: the file is too large. 429: daily limit reached. 503: FMCSA could not be reached and no dated record is on file.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "string"
                },
                "hint": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Verdict": {
        "type": "object",
        "required": [
          "dot_number",
          "verdict",
          "reasons",
          "data_as_of",
          "record_source",
          "record_as_of"
        ],
        "properties": {
          "dot_number": {
            "type": "string"
          },
          "legal_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "verdict": {
            "type": "string",
            "enum": [
              "GO",
              "CAUTION",
              "STOP"
            ]
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "code",
                "detail"
              ],
              "properties": {
                "code": {
                  "type": "string",
                  "description": "A reason code, e.g. OUT_OF_SERVICE_ORDER."
                },
                "detail": {
                  "type": "string",
                  "description": "Plain-language statement of the dated FMCSA fact."
                }
              }
            }
          },
          "days_until_suspension": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Days until an already-served revocation takes effect, when dated."
          },
          "data_as_of": {
            "type": "string",
            "description": "When CarrierScrub read this record."
          },
          "record_source": {
            "type": "string",
            "enum": [
              "motus",
              "legacy"
            ],
            "description": "Which FMCSA record the verdict rests on."
          },
          "record_as_of": {
            "type": "string",
            "format": "date",
            "description": "That record's date. A legacy record is as of 2026-05-14 at the latest."
          },
          "freshness": {
            "type": "object",
            "description": "How current this answer is. Check it before relying on a GO: a stored answer is CarrierScrub's saved record, with FMCSA's out-of-service orders and current authority, insurance and suspension notices re-checked on their own (see reasons).",
            "properties": {
              "source": {
                "type": "string",
                "enum": [
                  "live",
                  "stored"
                ],
                "description": "live: read from FMCSA for this request. stored: a saved answer."
              },
              "stale": {
                "type": "boolean",
                "description": "Part of the answer is not current: a stored answer more than 24 hours old, or the safety record could not be read."
              },
              "live_check_failed": {
                "type": "boolean",
                "description": "A live check was tried and FMCSA did not answer, so this is the stored answer."
              }
            }
          },
          "safety": {
            "type": [
              "object",
              "null"
            ],
            "description": "FMCSA safety rating with its date, 24-month roadside inspection and out-of-service counts, crash counts, and any acute or critical investigation finding, dated to the SMS snapshot (as_of). Most carriers have never been rated; that is not a finding."
          },
          "authority_granted_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "authority_reinstated_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "record_changes": {
            "type": [
              "object",
              "null"
            ],
            "description": "What changed on the carrier's FMCSA record and the day CarrierScrub's daily archive saw it, newest first. A fact beside the verdict, never a reason. null until the archive has a complete baseline; an empty events list means none seen since `since`. A phone is shown by its last four digits, an email by its domain, an address by its city and state. `control_notice` may also be set; see below.",
            "properties": {
              "since": {
                "type": "string",
                "format": "date"
              },
              "events": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "seen",
                    "source",
                    "text"
                  ],
                  "properties": {
                    "seen": {
                      "type": "string",
                      "format": "date"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "census",
                        "motus"
                      ]
                    },
                    "text": {
                      "type": "string"
                    },
                    "filed": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date",
                      "description": "The MCS-150 filing that came with a census change."
                    }
                  }
                }
              },
              "control_notice": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Set when an established carrier (registered with FMCSA three or more years) had its company officers and a phone, email or address change within a week of each other, in the last 30 days. A notice to confirm who you are dealing with: never a reason code, and it does not change the verdict. Most carriers it appears on have done nothing wrong; a sale or a retirement looks the same on FMCSA's record. null when there is none.",
                "properties": {
                  "seen": {
                    "type": "string",
                    "format": "date"
                  },
                  "text": {
                    "type": "string"
                  }
                },
                "required": [
                  "seen",
                  "text"
                ]
              }
            }
          }
        }
      }
    }
  }
}
