{"openapi":"3.1.0","info":{"title":"CarrierVet API","version":"1.3.0","summary":"Vet US motor carriers (trucking companies) by USDOT or MC number: authority, insurance, fraud signals, risk score, history and alerts.","description":"CarrierVet returns operating authority, insurance on file, out-of-service status, recent contact changes, shared-contact fraud signals and a 0-100 risk score for any US motor carrier, verified against official FMCSA records. Paid plans add change history and watchlist alerts by email or signed webhook. Cached carriers keep answering when FMCSA is slow or down.\n\nBeta: CarrierVet is in active testing. Verify critical decisions against FMCSA SAFER, and report anything that looks wrong to hello@carriervet.dev.\n\nAuth: send `Authorization: Bearer <api key>` on every /v1 route except signup, login and the Stripe webhook. Get a free key with POST /v1/signup (no card).\nRate limits: 30-600 requests/minute per account by plan, plus per-IP limits on public routes. A 429 carries a Retry-After header and error.retry_after (seconds). Wait that long, then retry.\nPlans: free 50 lookups/month, no card. Starter $49/mo, Pro $149/mo, Business $399/mo; yearly is 10x monthly. Paid plans open after beta; until then POST /v1/billing/checkout returns 403 paid_signups_paused.\nQuota: monthly lookups per plan; each carrier, risk, history or search call is one lookup. 202/503 FMCSA-degraded answers are not charged.\nVerdict: every carrier profile, risk and batch result has a top-level `verdict` (PASS, REVIEW or FAIL), `verdict_reasons` and `verdict_basis`. FAIL if any check is FAIL; REVIEW if any check is FLAG (the risk endpoint also counts the contact check and a risk level of elevated, high or severe); PASS otherwise. All earlier fields are unchanged.\nLookup receipts: every charged lookup response includes `receipt_id` (also in the `x-receipt-id` header). GET /v1/receipts/{id} returns the saved copy of that response with its time and SHA-256, to any API key on the same account. Saved a few seconds after the lookup; free to read.\nHistory: the history endpoint returns `fmcsa_history`, dated changes from FMCSA's daily files and the census, each with the date FMCSA recorded it, the date CarrierVet saw it, and before and after values. Recording started on 2026-10-27; earlier changes are not included.\nErrors always look like {\"error\":{\"code\",\"message\",\"docs_url\",\"retry_after?\"}}.\nMachine-readable guides: /llms.txt and /llms-full.txt. MCP server: POST /mcp (Streamable HTTP).\n\nData is derived from FMCSA records, provided as-is, may be delayed, and is not a consumer report under the FCRA. Do not use it to evaluate a natural person for credit, insurance, employment, or housing.","contact":{"name":"CarrierVet LLC","email":"hello@carriervet.dev","url":"https://carriervet.dev/docs"},"termsOfService":"https://carriervet.dev/terms","license":{"name":"Proprietary","url":"https://carriervet.dev/terms"}},"servers":[{"url":"https://carriervet.dev","description":"Production"}],"externalDocs":{"description":"Plain-language guide for AI agents","url":"https://carriervet.dev/llms.txt"},"security":[{"bearerAuth":[]}],"tags":[{"name":"Carriers","description":"Carrier profile, risk, history, search and batch lookups."},{"name":"Monitors","description":"Watchlist: get an email or signed webhook when a carrier's FMCSA record changes."},{"name":"Accounts","description":"Signup, login, API keys and usage."},{"name":"Billing","description":"Stripe checkout and customer portal."},{"name":"Service","description":"Health."}],"paths":{"/health":{"get":{"tags":["Service"],"operationId":"health","security":[],"summary":"Health check","description":"Returns {ok:true} when the API is serving. No auth. Cheap; safe to poll at most once every few seconds.","responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/signup":{"post":{"tags":["Accounts"],"operationId":"signup","security":[],"summary":"Create a free account and get an API key","description":"Creates a free sandbox account (50 lookups/month) and returns the API key once; store it. Requires accept_terms: true. Browser form signups include a Turnstile token; API/agent signups without one are allowed but limited to 3 per IP per hour. Use a real email you control.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","accept_terms"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":10},"accept_terms":{"type":"boolean","enum":[true],"description":"Must be true: you accept https://carriervet.dev/terms."},"cf-turnstile-response":{"type":"string","description":"Turnstile token from the browser widget. Optional for API clients."}}}}}},"responses":{"201":{"description":"Account created. api_key is shown once.","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string"},"webhook_secret":{"type":"string"},"account":{"type":"object"},"note":{"type":"string"}}}}}},"400":{"description":"Invalid input, or accept_terms missing (code terms_not_accepted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Turnstile token rejected (code turnstile_failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Email already registered (code email_taken); use /v1/login","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/login":{"post":{"tags":["Accounts"],"operationId":"login","security":[],"summary":"Mint a new API key with email and password","description":"Returns a new API key for an existing account. Older keys keep working until revoked.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"New API key","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"type":"string"}}}}}},"401":{"description":"Wrong email or password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/account":{"get":{"tags":["Accounts"],"operationId":"getAccount","summary":"Current account, plan, webhook secret and key prefixes","responses":{"200":{"description":"Account"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/usage":{"get":{"tags":["Accounts"],"operationId":"getUsage","summary":"Lookups used this UTC month, limits and plan features","description":"Free to call (does not count as a lookup). Check this before large jobs.","responses":{"200":{"description":"Usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageReport"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/keys":{"post":{"tags":["Accounts"],"operationId":"createKey","summary":"Create an additional API key","description":"Max 10 active keys per account. The secret is shown once.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":40}}}}}},"responses":{"201":{"description":"Key secret, shown once"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Key limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/keys/{id}/rotate":{"post":{"tags":["Accounts"],"operationId":"rotateKey","summary":"Replace a key with a new one and revoke the old one","parameters":[{"$ref":"#/components/parameters/KeyId"}],"responses":{"200":{"description":"Replacement key"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/keys/{id}":{"delete":{"tags":["Accounts"],"operationId":"revokeKey","summary":"Revoke an API key","parameters":[{"$ref":"#/components/parameters/KeyId"}],"responses":{"200":{"description":"Revoked"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Cannot revoke the last active key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/carriers/{dot}":{"get":{"tags":["Carriers"],"operationId":"getCarrierByDot","summary":"Carrier profile by USDOT number","description":"Use when you have a USDOT number (1-8 digits). Returns an overall verdict (PASS, REVIEW or FAIL) with verdict_reasons, then the carrier profile: legal/DBA name, MC dockets, authority status and age, insurance on file, out-of-service status, fleet size, address and contact. The verdict uses the authority, insurance, out-of-service, USDOT operating status and safety rating checks. One lookup. Header x-data-freshness tells you if the record is fresh, live, or stale while FMCSA is refreshed. The body includes receipt_id.","parameters":[{"$ref":"#/components/parameters/Dot"}],"responses":{"200":{"description":"Profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierEnvelope"}}}},"202":{"$ref":"#/components/responses/Pending"},"400":{"description":"Invalid USDOT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"404":{"description":"No FMCSA record for this USDOT (counts as a lookup)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/carriers/mc/{mc}":{"get":{"tags":["Carriers"],"operationId":"getCarrierByMc","summary":"Carrier profile by MC, FF or MX docket number","description":"Use when you have an MC number (e.g. MC123456 or just 123456). Same response as the USDOT lookup plus authority.matched_docket/matched_status for that docket; the verdict uses the matched docket status. One lookup.","parameters":[{"name":"mc","in":"path","required":true,"schema":{"type":"string","examples":["MC123456","123456","FF12345"]}}],"responses":{"200":{"description":"Profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierEnvelope"}}}},"202":{"$ref":"#/components/responses/Pending"},"400":{"description":"Invalid docket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"404":{"description":"No FMCSA record for this docket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/carriers/{dot}/risk":{"get":{"tags":["Carriers"],"operationId":"getCarrierRisk","summary":"Risk score 0-100 with reason codes","description":"Additive score from warning signs in the carrier's FMCSA record: 0-24 low, 25-49 elevated, 50-74 high, 75-100 severe. Each reason has a code, points and message. Hard failures (revoked, inactive or no authority; out-of-service; lapsed or missing insurance; inactive USDOT number; not allowed to operate; Unsatisfactory safety rating) are listed in `gates` and keep the score at 50 or more, so a carrier that fails one is never low or elevated. Also returns an overall verdict (PASS, REVIEW or FAIL) that adds the contact check and the risk level to the profile checks: REVIEW when the level is elevated, high or severe. Header x-data-freshness and body snapshot_date show how current the record is. Informational only, not a safety rating. One lookup.","parameters":[{"$ref":"#/components/parameters/Dot"}],"responses":{"200":{"description":"Risk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Risk"}}}},"202":{"$ref":"#/components/responses/Pending"},"400":{"description":"Invalid USDOT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"404":{"description":"No FMCSA record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/carriers/mc/{mc}/risk":{"get":{"tags":["Carriers"],"operationId":"getCarrierRiskByMc","summary":"Risk score by MC, FF or MX docket number","description":"Same as the USDOT risk endpoint, but the authority status used is that docket's own status (as on the MC profile lookup), so a revoked MC on a carrier with another active docket scores and reads as revoked. One lookup.","parameters":[{"name":"mc","in":"path","required":true,"schema":{"type":"string","examples":["MC123456","123456"]}}],"responses":{"200":{"description":"Risk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Risk"}}}},"202":{"$ref":"#/components/responses/Pending"},"400":{"description":"Invalid docket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"404":{"description":"No FMCSA record for this docket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/receipts/{id}":{"get":{"tags":["Carriers"],"operationId":"getReceipt","summary":"Saved copy of an earlier lookup response","description":"Returns what CarrierVet returned for an earlier lookup: created_at, endpoint, identifier, http_status, the response body, and response_sha256 (SHA-256 of the body as sent). Any API key on the account that made the lookup can read it. Receipts are saved a few seconds after the lookup. It is a record of that past response, not a new check. Free; not a lookup.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^rcpt_[0-9a-f]{24}$"}}],"responses":{"200":{"description":"Receipt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Receipt"}}}},"400":{"description":"Malformed receipt id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"No receipt with that id for this API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/carriers/{dot}/history":{"get":{"tags":["Carriers"],"operationId":"getCarrierHistory","summary":"Field changes detected by the daily FMCSA diff","description":"Newest first, up to 200 changes (address, phone, email, authority, insurance, OOS). Also fmcsa_history: dated changes from FMCSA's daily authority, insurance and revocation files and the census (MCS-150 updates), each with fmcsa_date (the date FMCSA recorded it, with fmcsa_date_basis naming the column), observed_at (when CarrierVet saw it), and old_value and new_value. Company officer name changes show both values as withheld. Rows are only ever added. Recording started on 2026-10-27; changes before that are not included. Recent contact changes are a common double-brokering sign. One lookup.","parameters":[{"$ref":"#/components/parameters/Dot"}],"responses":{"200":{"description":"Changes"},"400":{"description":"Invalid USDOT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"404":{"description":"Not stored yet; look the carrier up first","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/carriers/batch":{"post":{"tags":["Carriers"],"operationId":"batchLookup","summary":"Look up to 500 USDOT or MC numbers in one call (Pro, Business)","description":"Each unique identifier counts as one lookup. Uses stored snapshots when current and fetches from FMCSA otherwise, like single lookups; each result has snapshot_date and freshness (the x-data-freshness values: fresh, live, live-partial, cached-partial, stale-revalidating, stale-upstream-down).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"identifiers":{"type":"array","maxItems":500,"items":{"type":"string"},"examples":[["1234567","MC123456"]]},"dot_numbers":{"type":"array","items":{"type":"string"}},"mc_numbers":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Per-identifier results. Found carriers include verdict, verdict_reasons and verdict_basis; not-found results have null for those fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResults"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"403":{"description":"Plan does not include batch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/search":{"get":{"tags":["Carriers"],"operationId":"searchCarriers","summary":"Search stored carriers by legal or DBA name","description":"Substring match over carriers CarrierVet already stores; up to 25 results. Prefer USDOT/MC lookups when you have an identifier. One lookup.","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string","minLength":2}}],"responses":{"200":{"description":"Matches"},"400":{"description":"name missing, shorter than 2 or longer than 80 characters after cleanup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/QuotaExceeded"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/monitors":{"get":{"tags":["Monitors"],"operationId":"listMonitors","summary":"List the watchlist","responses":{"200":{"description":"Monitors"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Monitors"],"operationId":"createMonitor","summary":"Add a carrier to the watchlist","description":"Paid plans. Sends an email and/or HMAC-SHA256 signed webhook (Pro+) when the carrier's FMCSA record changes. The carrier must already be stored (look it up first).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["dot_number"],"properties":{"dot_number":{"type":"string"},"webhook_url":{"type":"string","format":"uri"},"alert_email":{"type":"string","format":"email"}}}}}},"responses":{"201":{"description":"Created"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"Monitor cap reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Plan cannot monitor, or webhooks need Pro","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already monitored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/monitors/{dot}":{"delete":{"tags":["Monitors"],"operationId":"deleteMonitor","summary":"Remove a carrier from the watchlist","parameters":[{"$ref":"#/components/parameters/Dot"}],"responses":{"200":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Not monitored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/export/monitors.csv":{"get":{"tags":["Monitors"],"operationId":"exportMonitors","summary":"CSV of monitored carriers (Business)","description":"Counts as one lookup.","responses":{"200":{"description":"CSV","content":{"text/csv":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Business plan only","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/billing/checkout":{"post":{"tags":["Billing"],"operationId":"startCheckout","summary":"Start Stripe Checkout for a paid plan","description":"Paid plans open after beta. Until then this returns 403 paid_signups_paused. The free plan is available now through POST /v1/signup.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan"],"properties":{"plan":{"type":"string","enum":["starter","pro","business"]},"interval":{"type":"string","enum":["month","year"]}}}}}},"responses":{"200":{"description":"Checkout URL"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Paid plans paused until after the beta (paid_signups_paused)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"description":"Stripe not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/billing/portal":{"post":{"tags":["Billing"],"operationId":"billingPortal","summary":"Stripe Customer Portal URL","responses":{"200":{"description":"Portal URL"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"No Stripe customer yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/v1/stripe/webhook":{"post":{"tags":["Billing"],"operationId":"stripeWebhook","security":[],"summary":"Stripe webhook receiver (Stripe only)","parameters":[{"name":"Stripe-Signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Event received"},"400":{"description":"Signature rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from POST /v1/signup or /v1/login, e.g. cv_live_..."}},"parameters":{"Dot":{"name":"dot","in":"path","required":true,"description":"USDOT number, 1-8 digits","schema":{"type":"string","pattern":"^[0-9]{1,8}$","examples":["1234567"]}},"KeyId":{"name":"id","in":"path","required":true,"schema":{"type":"string"}}},"headers":{"RetryAfter":{"description":"Seconds to wait before retrying","schema":{"type":"integer"}}},"responses":{"RateLimited":{"description":"Rate limited (code rate_limited). Wait Retry-After seconds.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing or invalid API key (code unauthorized)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"QuotaExceeded":{"description":"Monthly lookup quota used up (code quota_exceeded)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Pending":{"description":"Carrier not cached; fetching from FMCSA now (code fetching_from_fmcsa). Retry after Retry-After seconds. Not charged.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UpstreamUnavailable":{"description":"FMCSA slow, down or throttling and carrier not cached (code fmcsa_unavailable or fmcsa_throttled). Not charged.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","docs_url"],"properties":{"code":{"type":"string","examples":["rate_limited","unauthorized","quota_exceeded","not_found","invalid_request","fetching_from_fmcsa","fmcsa_unavailable"]},"message":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"retry_after":{"type":"integer","description":"Seconds; present on 429, 202 and 503"}}}}},"Verdict":{"type":"string","enum":["PASS","REVIEW","FAIL"],"description":"Overall result. FAIL if any check is FAIL; REVIEW if any check is FLAG (risk endpoint: also the contact check, or level elevated, high or severe); PASS otherwise."},"VerdictReason":{"type":"object","required":["code","check","result","message"],"properties":{"code":{"type":"string","examples":["revoked_authority","inactive_authority","no_authority","pending_authority","authority_under_90_days","insurance_lapsed","insurance_missing","insurance_unknown","out_of_service","usdot_inactive","not_allowed_to_operate","unsatisfactory_rating","conditional_rating","shared_phone","recent_address_change","multiple_contact_changes","risk_level_elevated"]},"check":{"type":"string","enum":["authority","insurance","out_of_service","operating_status","safety_rating","contact","data_quality","risk_level"]},"result":{"type":"string","enum":["FAIL","FLAG"]},"message":{"type":"string"}}},"VerdictReasons":{"type":"array","items":{"$ref":"#/components/schemas/VerdictReason"},"description":"Why the verdict is not PASS. FAIL reasons first, then FLAG. Empty when the verdict is PASS."},"VerdictBasis":{"type":"array","items":{"type":"string","enum":["authority","insurance","out_of_service","operating_status","safety_rating","contact","data_quality","risk_level"]},"description":"Inputs the verdict used. Profile and batch lookups: authority, insurance, out_of_service, operating_status, safety_rating. Risk endpoint: also contact and risk_level."},"CarrierEnvelope":{"type":"object","required":["verdict","verdict_reasons","verdict_basis","carrier"],"properties":{"verdict":{"$ref":"#/components/schemas/Verdict"},"verdict_reasons":{"$ref":"#/components/schemas/VerdictReasons"},"verdict_basis":{"$ref":"#/components/schemas/VerdictBasis"},"carrier":{"$ref":"#/components/schemas/Carrier"},"receipt_id":{"$ref":"#/components/schemas/ReceiptId"},"usage":{"$ref":"#/components/schemas/Usage"}}},"ReceiptId":{"type":"string","pattern":"^rcpt_[0-9a-f]{24}$","description":"Id of the saved copy of this response. Fetch it with GET /v1/receipts/{id} with any API key on the same account."},"Receipt":{"type":"object","properties":{"receipt_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"endpoint":{"type":"string","examples":["carrier","carrier_mc","risk","risk_mc","history","batch","search"]},"identifier":{"type":["string","null"]},"http_status":{"type":"integer"},"response_sha256":{"type":"string"},"response":{"type":"object"},"note":{"type":"string"}}},"BatchResults":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"identifier":{"type":"string"},"dot_number":{"type":["string","null"]},"verdict":{"oneOf":[{"$ref":"#/components/schemas/Verdict"},{"type":"null"}]},"verdict_reasons":{"oneOf":[{"$ref":"#/components/schemas/VerdictReasons"},{"type":"null"}]},"verdict_basis":{"oneOf":[{"$ref":"#/components/schemas/VerdictBasis"},{"type":"null"}]},"snapshot_date":{"type":["string","null"]},"freshness":{"type":["string","null"],"enum":["fresh","live","live-partial","cached-partial","stale-revalidating","stale-upstream-down",null]},"carrier":{"oneOf":[{"$ref":"#/components/schemas/Carrier"},{"type":"null"}]},"error":{"type":["object","null"]}}}},"receipt_id":{"$ref":"#/components/schemas/ReceiptId"},"usage":{"$ref":"#/components/schemas/Usage"}}},"Carrier":{"type":"object","properties":{"dot_number":{"type":"string"},"legal_name":{"type":["string","null"]},"dba_name":{"type":["string","null"]},"mc_numbers":{"type":"array","items":{"type":"object","properties":{"number":{"type":"string"},"type":{"type":["string","null"]},"status":{"type":"string"}}}},"authority":{"type":"object","properties":{"status":{"type":"string","enum":["active","inactive","revoked","pending","none"]},"grant_date":{"type":["string","null"]},"age_days":{"type":["integer","null"]},"age_source":{"type":["string","null"]},"matched_docket":{"type":["string","null"]},"matched_status":{"type":["string","null"],"description":"Motor-carrier authority status of the matched docket; none when that docket holds only broker or freight-forwarder authority."},"matched_docket_kind":{"type":["string","null"],"enum":["carrier","broker","forwarder",null]}}},"insurance":{"type":"object","properties":{"status":{"type":"string","enum":["on_file","missing","lapsed","unknown"]},"bipd_on_file":{},"bipd_required":{},"cargo_on_file":{},"cargo_required":{},"bond_on_file":{},"bond_required":{},"effective_date":{"type":["string","null"]},"cancel_date":{"type":["string","null"]},"policy_number":{"type":["string","null"]}}},"safety":{"type":"object","properties":{"out_of_service":{"type":"boolean"},"oos_date":{"type":["string","null"]},"safety_rating":{"type":["string","null"]},"allowed_to_operate":{},"usdot_status":{}}},"fleet":{"type":"object","properties":{"power_units":{"type":["integer","null"]},"drivers":{"type":["integer","null"]}}},"address":{"type":"object"},"phone":{"type":["string","null"]},"email":{"type":["string","null"]},"prior_revocation":{},"undeliverable_mail":{},"last_updated":{"type":"string","format":"date-time"},"snapshot_date":{"type":["string","null"]},"sources":{"type":"array","items":{"type":"string"}}}},"Risk":{"type":"object","properties":{"verdict":{"$ref":"#/components/schemas/Verdict"},"verdict_reasons":{"$ref":"#/components/schemas/VerdictReasons"},"verdict_basis":{"$ref":"#/components/schemas/VerdictBasis"},"dot_number":{"type":"string"},"mc_number":{"type":"string","description":"Present on the MC risk endpoint"},"score":{"type":"integer","minimum":0,"maximum":100},"level":{"type":"string","enum":["low","elevated","high","severe"],"description":"low 0-24, elevated 25-49, high 50-74, severe 75-100"},"gates":{"type":"array","items":{"type":"string"},"description":"Hard failures found. Any gate keeps the score at 50 or more."},"rules_version":{"type":"string","description":"Version of the scoring rules. A custom configuration adds +custom.<hash>."},"snapshot_date":{"type":["string","null"]},"last_updated":{"type":["string","null"],"format":"date-time"},"receipt_id":{"$ref":"#/components/schemas/ReceiptId"},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"points":{"type":"integer"},"message":{"type":"string"}}}},"usage":{"$ref":"#/components/schemas/Usage"}}},"Usage":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer"},"remaining":{"type":"integer"},"warning":{"type":["string","null"],"enum":["80","100",null]}}},"UsageReport":{"type":"object","properties":{"plan":{"type":"string"},"period":{"type":"string"},"lookups":{"$ref":"#/components/schemas/Usage"},"monitors":{"type":"object"},"rate_limit_per_minute":{"type":"integer"},"features":{"type":"object"}}}}}}