TruckTabs API · v1

Quotes

A quote is priced by the same engine as trucktabs.com. It works out the states on the route, adds oversize/overweight permits where the load is over a state's legal limits, and returns every fee.

Create a quote

POSThttps://trucktabs.com/api/v1/quotes

Needs a write key. Every quote becomes a draft order on our side, which is what lets the carrier pay from resume_url, so send an Idempotency-Key if you might retry.

Request body

FieldTypeRequiredNotes
permit_typesarrayYesAny of trip, fuel, osow. Oversize/overweight is added by us in each state where the load needs it, so you rarely ask for it.
route.originplaceYes*Where the trip starts. See Places below.
route.destinationplaceYes*Where the trip ends.
route.statesarrayYes*Instead of origin and destination: the states crossed, in order, each { "state": "OR", "miles": 210 }. Use it when your system already has the miles. The miles are yours: we price what you send, in whole miles (at least 1 a state).
route.stopsarrayNoNot supported yet. A request with stops is refused with UNSUPPORTED rather than priced wrong.
vehicle.vehicle_typecodeYesFor example tractor_trailer. See vehicle types.
vehicle.trailer_typecodeSemisFor example step_deck. See trailer types.
vehicle.trailer_lengthmeasureSemisThe trailer length. At least 10 ft.
vehicle.power_unit_axlesintegerSemisAxles on the tractor or truck.
vehicle.trailer_axlesintegerSemisAxles on the trailer.
vehicle.total_axlesintegerSingle unitsEvery vehicle type other than tractor_trailer and truck_trailer.
vehicle.combined_lengthmeasureSingle unitsThe vehicle's overall length. At least 10 ft.
load.gross_weight_lbsintegerYesGross weight in pounds, including the load.
load.lengthmeasureSometimesLength, width and height are required when the load could be oversize (for example an open trailer or an osow request). A missing one is listed in details.missing.
load.widthmeasureSometimesDecides whether a state needs an oversize permit.
load.heightmeasureSometimesOverall height from the road, at least 24 in. Legal height differs by state, so this can change the answer at a state line.
load.categorycodeNoSee load categories.
load.descriptionstringNoUp to 500 characters, for example "Excavator".
external_refstringNoYour own reference, up to 64 characters. Echoed back.
metadataobjectNoUp to 10 keys of 1 to 40 characters. Values are strings of up to 200 characters, numbers, booleans or null. Echoed back, never read by us.

* Send route.origin and route.destination, or route.states, not both. A measure is { "value": 48, "unit": "ft" } with a unit of ft or in and at most 2 decimal places. A value far too big or too small for its field, such as a length over 500 feet or a 13-inch height, is refused as a likely unit slip. Codes also accept the display names and common aliases shown in the reference, in any case.

Places

A place is an object in one of these forms. To choose between similar names before quoting, use GET /places.

FieldTypeRequiredNotes
city + statestringNo{ "city": "Portland", "state": "OR" }. Only a match in that state counts. Add postal_code to pick between places of the same name in that state.
postal_codestringNo{ "postal_code": "97201" }. Only a place with that ZIP code counts. If none has it, the quote is refused with PLACE_NOT_FOUND.
lat + lng + statenumberNo{ "lat": 45.52, "lng": -122.68, "state": "OR" }. Used as given, once we have checked the point with Mapbox. Coordinates far outside the United States are refused with INVALID_INPUT. A point that isn't inside that state, or isn't in any US state, is refused with PLACE_MISMATCH.
querystringNo{ "query": "Portland, OR" }. Free text. A state code or ZIP code at the end narrows it. If it matches places in more than one state and nothing narrows it, the quote is refused with the candidates.

Example

curl
curl https://trucktabs.com/api/v1/quotes \
  -H "Authorization: Bearer $TRUCKTABS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d @quote.json
quote.json
{
  "permit_types": ["trip", "fuel"],
  "route": {
    "origin": { "city": "Portland", "state": "OR", "postal_code": "97201" },
    "destination": { "city": "Boise", "state": "ID" }
  },
  "vehicle": {
    "vehicle_type": "tractor_trailer",
    "trailer_type": "step_deck",
    "trailer_length": { "value": 48, "unit": "ft" },
    "power_unit_axles": 3,
    "trailer_axles": 2
  },
  "load": {
    "category": "construction_farm_equipment",
    "gross_weight_lbs": 92000,
    "length": { "value": 38, "unit": "ft" },
    "width": { "value": 10, "unit": "ft" },
    "height": { "value": 13, "unit": "ft" },
    "description": "Excavator"
  },
  "external_ref": "LOAD-284113",
  "metadata": { "shipment_id": "284113" }
}

Amounts, descriptions and miles in these examples are illustrative, not current rates.

201 Created · status quoted
{
  "id": "5b0f6c1e-8a7d-4c1e-9f3a-2d6b7c8e9f01",
  "reference": "48213",
  "status": "quoted",
  "currency": "USD",
  "subtotal": 424,
  "processing_fee": 21.2,
  "total": 445.2,
  "states": [
    {
      "state": "OR",
      "state_name": "Oregon",
      "miles": 211,
      "permits": ["trip", "fuel", "osow"],
      "amount": 159,
      "osow_auto_applied": true,
      "osow_not_needed": false,
      "lines": [
        { "kind": "state_fee", "permit": "trip", "description": "Oregon Trip Permit", "amount": 43 },
        { "kind": "state_fee", "permit": "fuel", "description": "Oregon Fuel Permit", "amount": 56 },
        { "kind": "state_fee", "permit": "osow", "description": "Oregon OS/OW Permit", "amount": 60 }
      ]
    },
    {
      "state": "ID",
      "state_name": "Idaho",
      "miles": 219,
      "permits": ["trip", "fuel", "osow"],
      "amount": 105,
      "osow_auto_applied": true,
      "osow_not_needed": false,
      "lines": [ … ]
    }
  ],
  "fees": [
    { "kind": "service_fee", "description": "TruckTabs service fee — OR, ID", "amount": 160 },
    { "kind": "processing_fee", "description": "Processing fee (5%)", "amount": 21.2 }
  ],
  "oversize_notice": {
    "title": "Oversize/overweight permits added",
    "message": "This load is over the legal limits in Oregon and Idaho, so an OS/OW permit is included in each."
  },
  "advisories": [],
  "route": {
    "origin": { "label": "Portland, Oregon 97201", "city": "Portland", "state": "OR", "postal_code": "97201", "lat": 45.5152, "lng": -122.6784 },
    "destination": { "label": "Boise, Idaho", "city": "Boise", "state": "ID", "postal_code": null, "lat": 43.615, "lng": -116.2023 },
    "mileage_source": "route"
  },
  "repriced": false,
  "external_ref": "LOAD-284113",
  "metadata": { "shipment_id": "284113" },
  "created_at": "2026-09-15T17:42:09.311Z",
  "resume_url": "https://trucktabs.com/permits?resume=…"
}

A quote our team must look at first comes back as needs_review. That happens for unusual dimensions, very large amounts, or a state we can't price automatically. It has no total, and every amount in the breakdown is null. The carrier can still open resume_url, and nothing is charged until the team confirms the price.

201 Created · status needs_review
{
  "id": "…",
  "reference": "48214",
  "status": "needs_review",
  "currency": "USD",
  "estimated_total": 1873.4,
  "review_message": "Orders this size get a second look before we charge the card. Submit it and we'll confirm the total with you.",
  "states": [
    {
      "state": "OR",
      "amount": null,
      "lines": [ { "kind": "state_fee", "permit": "osow", "description": "Oregon OS/OW Permit", "amount": null }, … ],
      …
    }
  ],
  "fees": [ { "kind": "service_fee", "description": "TruckTabs service fee — OR, ID", "amount": null }, … ],
  …
}

A legal_load means you asked only for osow and the load is within every state's legal limits, so there is nothing to buy.

201 Created · status legal_load
{
  "id": "…",
  "reference": "48215",
  "status": "legal_load",
  "currency": "USD",
  "total": 0,
  "states": [
    { "state": "OR", "permits": [], "amount": 0, "osow_not_needed": true, "lines": [], … }
  ],
  "fees": [],
  …
}

Response fields

FieldTypeRequiredNotes
idstringAlwaysThe quote id, for GET /quotes/{id}.
referencestringAlwaysOur order number. Short enough for a charge description, and what our team will ask for.
statusstringAlwaysquoted, needs_review or legal_load. On a later read, also ordered or canceled.
currencystringAlwaysUSD.
subtotalnumberquotedState permit fees and service fees.
processing_feenumberquotedCharged once per order.
totalnumberquoted, legal_loadWhat the carrier pays. Never present on needs_review. 0 on legal_load.
estimated_totalnumberneeds_reviewPresent only when every state priced. An estimate: the team confirms the price before anything is charged.
review_messagestringneeds_reviewWhy a person needs to look at it, in a sentence you can show the carrier.
states[]arrayAlwaysPer state: state, state_name, miles, permits, amount (its permit fees, the sum of its lines), osow_auto_applied, osow_not_needed and lines.
fees[]arrayAlwaysOrder-level lines: service fees and the processing fee. The states' amounts plus these add up to total.
amounts on needs_reviewNoEvery amount in states, lines and fees is null, so nothing adds up to a price the team hasn't confirmed.
oversize_noticeobjectNotitle and message when we added oversize/overweight permits you didn't ask for; otherwise null.
advisories[]arrayAlwaysPlain sentences worth showing the carrier.
routeobjectAlwaysThe places we priced, and mileage_source: route, straight_line (no drivable route was found; confirmed by hand) or provided (you sent route.states).
repricedbooleanAlwaysfalse when created. On a later read, true if the carrier changed the trip since. See Get a quote.
resume_urlstringNoA link where the carrier reviews the quote, adds their details and pays. It works like a password to this order: give it only to the carrier. Null once the order is placed or canceled.
external_ref, metadataNoWhat you sent.
created_atstringAlwaysISO 8601, UTC.

The response also has a Location header pointing at the quote.

Errors

StatusCodeWhen
422INVALID_INPUTA value is wrong (details.invalid) or missing (details.missing). Both lists are complete. This includes a value too big or small for its field, which is usually a unit slip.
422UNSUPPORTEDSomething we don't quote yet, such as route.stops.
422PLACE_AMBIGUOUSA place matches more than one state. details.candidates lists them; send the one you mean with its state, or its lat, lng and state.
422PLACE_NOT_FOUNDWe couldn't find a place, or no place has the postal_code you sent. details.field says which.
422PLACE_MISMATCHCoordinates you sent aren't in the state you sent with them. details.field says which.
422NO_STATESThe route doesn't cross any US state we permit.
422INCOMPLETEThe quote couldn't be priced with what was sent. The message says what to add.
409IDEMPOTENCY_MISMATCHThe Idempotency-Key already created a quote from a different body.
409IDEMPOTENCY_IN_PROGRESSThe first request with this key is still running. Retry after a moment.
429RATE_LIMITEDToo many writes or quotes this minute. Wait Retry-After seconds.
429QUOTE_LIMIT_REACHEDYour daily allowance is used. Every quote that reaches pricing counts. It resets at midnight UTC.
502 / 503ROUTING_FAILED, ROUTING_UNAVAILABLEWe couldn't look up places or miles. Retry, or send route.states with miles.
500 / 503INTERNAL, QUOTE_FAILED, SAVE_FAILED, UNAVAILABLEOur problem. Retry with the same Idempotency-Key and you get one quote back. A failure during pricing can leave an unfinished draft on our side, which counts toward the daily allowance. If it persists, send us the request_id.
422 · PLACE_AMBIGUOUS
{
  "error": {
    "code": "PLACE_AMBIGUOUS",
    "message": "The origin matches places in more than one state. Add the state.",
    "details": {
      "field": "route.origin",
      "candidates": [
        { "label": "Portland, Oregon", "city": "Portland", "state": "OR", "postal_code": null, "lat": 45.5152, "lng": -122.6784 },
        { "label": "Portland, Maine", "city": "Portland", "state": "ME", "postal_code": null, "lat": 43.6591, "lng": -70.2568 }
      ]
    }
  },
  "request_id": "req_Qm3v8Kx1Tn5bW2pL9sR4"
}

Get a quote

GEThttps://trucktabs.com/api/v1/quotes/{id}

Returns a quote your account created, in the same shape as when it was created, with status brought up to date. Nothing is priced again. A quote that belongs to another account is 404 NOT_FOUND.

  • ordered: the carrier completed the order, or our team took it on. ordered_at is set and resume_url is null.
  • canceled: the order was canceled. canceled_at is set and resume_url is null.
  • Otherwise the original status, with a working resume_url.

The carrier can change the trip after opening resume_url, and our team can take an order over. If either moved the price or put the order on hold, repriced is true. The per-state breakdown is still the one you were quoted, with every amount set to null. total is the order's current price, and it is left out while the order is held for review.

curl
curl https://trucktabs.com/api/v1/quotes/5b0f6c1e-8a7d-4c1e-9f3a-2d6b7c8e9f01 \
  -H "Authorization: Bearer $TRUCKTABS_API_KEY"