LIVE LTL RATES
LA → SF$182/palletQuote →|LA → MIA$405/palletQuote →|LA → DAL$351/palletQuote →|LA metro$93/palletQuote →|LA → LV$192/palletQuote →|NJ → NYC$148/palletQuote →|LA → ATL$315/palletQuote →|LA → NJ$434/palletQuote →|MIA metro$131/palletQuote →|NJ → DAL$254/palletQuote →|LA → DEN$283/palletQuote →|LA → SEA$325/palletQuote →|LA → PHX$200/palletQuote →|LA → SLC$219/palletQuote →|CHI → DAL$279/palletQuote →|CHI → LA$256/palletQuote →|LA → CHI$407/palletQuote →|LV → LA$208/palletQuote →|DAL → CHI$298/palletQuote →|NJ → MIA$264/palletQuote →|ATL metro$130/palletQuote →|LA → AUS$383/palletQuote →|LA → SD$192/palletQuote →|LA → PDX$292/palletQuote →|NJ → CHI$253/palletQuote →|LA → COL$329/palletQuote →|HOU → LA$248/palletQuote →|LA → TPA$393/palletQuote →|DEN metro$153/palletQuote →|CHI → HOU$270/palletQuote →|DEN → MIA$403/palletQuote →|MIA → HOU$229/palletQuote →|SF → LA$223/palletQuote →|CLT metro$144/palletQuote →|DAL → PDX$269/palletQuote →|HOU → NYC$285/palletQuote →|LA → SAT$380/palletQuote →|SF metro$197/palletQuote →|CHI → MIA$283/palletQuote →|MIA → LA$248/palletQuote →|ORL metro$118/palletQuote →|TPA metro$121/palletQuote →|IND metro$128/palletQuote →|HOU metro$129/palletQuote →|NYC → NJ$148/palletQuote →|ATL → MIA$211/palletQuote →|CHI → PDX$277/palletQuote →|MIA → NJ$211/palletQuote →|NJ → ATL$228/palletQuote →|NJ → DEN$330/palletQuote →|LA → RDU$405/palletQuote →|MKE → MIA$307/palletQuote →|PHL → NJ$192/palletQuote →|CHI → MSP$230/palletQuote →|PHL → MIA$274/palletQuote →|CHI → NJ$223/palletQuote →|COL → LA$275/palletQuote →|DAL → MIA$282/palletQuote →|NJ → HOU$244/palletQuote →|PDX metro$142/palletQuote →|SLC metro$121/palletQuote →|COL metro$162/palletQuote →|NJ → SAT$328/palletQuote →|PHL → NYC$206/palletQuote →|MEM → NYC$294/palletQuote →|View all rates →LA → SF$182/palletQuote →|LA → MIA$405/palletQuote →|LA → DAL$351/palletQuote →|LA metro$93/palletQuote →|LA → LV$192/palletQuote →|NJ → NYC$148/palletQuote →|LA → ATL$315/palletQuote →|LA → NJ$434/palletQuote →|MIA metro$131/palletQuote →|NJ → DAL$254/palletQuote →|LA → DEN$283/palletQuote →|LA → SEA$325/palletQuote →|LA → PHX$200/palletQuote →|LA → SLC$219/palletQuote →|CHI → DAL$279/palletQuote →|CHI → LA$256/palletQuote →|LA → CHI$407/palletQuote →|LV → LA$208/palletQuote →|DAL → CHI$298/palletQuote →|NJ → MIA$264/palletQuote →|ATL metro$130/palletQuote →|LA → AUS$383/palletQuote →|LA → SD$192/palletQuote →|LA → PDX$292/palletQuote →|NJ → CHI$253/palletQuote →|LA → COL$329/palletQuote →|HOU → LA$248/palletQuote →|LA → TPA$393/palletQuote →|DEN metro$153/palletQuote →|CHI → HOU$270/palletQuote →|DEN → MIA$403/palletQuote →|MIA → HOU$229/palletQuote →|SF → LA$223/palletQuote →|CLT metro$144/palletQuote →|DAL → PDX$269/palletQuote →|HOU → NYC$285/palletQuote →|LA → SAT$380/palletQuote →|SF metro$197/palletQuote →|CHI → MIA$283/palletQuote →|MIA → LA$248/palletQuote →|ORL metro$118/palletQuote →|TPA metro$121/palletQuote →|IND metro$128/palletQuote →|HOU metro$129/palletQuote →|NYC → NJ$148/palletQuote →|ATL → MIA$211/palletQuote →|CHI → PDX$277/palletQuote →|MIA → NJ$211/palletQuote →|NJ → ATL$228/palletQuote →|NJ → DEN$330/palletQuote →|LA → RDU$405/palletQuote →|MKE → MIA$307/palletQuote →|PHL → NJ$192/palletQuote →|CHI → MSP$230/palletQuote →|PHL → MIA$274/palletQuote →|CHI → NJ$223/palletQuote →|COL → LA$275/palletQuote →|DAL → MIA$282/palletQuote →|NJ → HOU$244/palletQuote →|PDX metro$142/palletQuote →|SLC metro$121/palletQuote →|COL metro$162/palletQuote →|NJ → SAT$328/palletQuote →|PHL → NYC$206/palletQuote →|MEM → NYC$294/palletQuote →|
Freight API

The API changelog.

Every change to the /api/v1 surface, dated and human-written. This page cannot silently rot: the build fails whenever the OpenAPI spec changes without a recorded snapshot and a matching entry here, so what you read is what shipped.

Hand-written entries · machine-enforced honesty · RFC 8594 deprecations

Live all-inclusive rates

2026-09-04addedOutbound webhooks: booking.created and checkout.completed, signed with HMAC-SHA256

Register up to five https endpoints per account with POST /webhooks (list with GET, remove with DELETE /webhooks/{id}). Every delivery carries Warp-Signature: t=<unix>,v1=<hex>, where v1 is HMAC-SHA256 with the endpoint secret over `${t}.${rawBody}`, plus Warp-Event-Id. booking.created fires for every booking made with the account's key; checkout.completed fires when a buyer books on a hosted quote page carrying the account's quote and a client_reference_id. Events are attempted immediately and retried at 1m, 5m, 30m, 2h, 6h and 12h before being marked dead. POST /webhooks/{id}/test sends a signed webhook.test and returns what your server answered. Tracking stays poll-based in this release; shipment status events follow.

2026-09-03fixeditems[] manifests: up to 26 lines accepted; over-limit manifests rejected instead of silently trimmed

Mixed-dimension items[] manifests on /ltl/quote and /ltl/market-options previously kept only the first 10 lines and dropped the rest without any indication, so a 17-pallet manifest was quoted, booked and documented as 10 pallets. The line limit now matches the real equipment bound of 26 pallet positions, and a manifest over 26 lines or 26 total pallets is rejected with 400 EXCEEDS_PALLET_LIMIT naming both limits. Nothing about a manifest is ever silently altered.

2026-09-03changedPOST /book: delivery address required on every booking; /rebook retired; lane memory no longer stores consignee addresses

Addresses now come from the request, exactly as sent, always. patch.delivery is required on every POST /book (400 DELIVERY_REQUIRED when absent, 400 INCOMPLETE_DELIVERY with missing_fields when partial); the previous fallback that reused the consignee from your last booking on the lane is removed, because a shipper with multiple consignees in one ZIP region could book freight to whichever one shipped most recently. POST /rebook, which booked entirely from that stored history, is retired and returns 410 REBOOK_RETIRED. GET /lanes no longer returns last_consignee. Warp no longer stores consignee identity in lane memory at all: lane rows keep only lane_id, counts and dates. No observed integration used any of the removed behavior.

2026-09-02changedPOST /book: pickup address follows the same all-or-nothing rule; empty-string fields count as supplied

patch.pickup now follows the same contract as patch.delivery: a supplied address must be complete and is used exactly as sent, never combined with the saved default_shipper (400 INCOMPLETE_PICKUP with missing_fields otherwise). Additionally, for both stops, sending any address field even as an empty string counts as supplying the address: it triggers the completeness check instead of being treated as absent, so a lone company: "" can no longer cause the saved consignee to be reused. POST /rebook now requires both saved addresses to be complete (not just zip-bearing) and echoes pickup_address and delivery_address in the response so callers can verify exactly which stored consignee shipped.

2026-09-02changedPOST /book: delivery address is all-or-nothing; saved-consignee reuse is guarded

A supplied patch.delivery must now be complete (zipCode, city, state, street, contactName, phone, email) and is used exactly as sent — it is never combined field-by-field with a previously saved address. Incomplete addresses are rejected with 400 INCOMPLETE_DELIVERY and a missing_fields list instead of being silently filled from lane history. Omitting patch.delivery entirely still reuses the consignee from your last booking on the lane, but only whole and only when its ZIP matches the destination the quote priced; otherwise the API returns 400 DELIVERY_REQUIRED. company omitted on a complete address falls back to contactName on the BOL, as documented.

2026-08-31changedDocumented the response fields for GET /bookings and /quote-history

The list endpoints documented their array items as an empty object, so a client generated from the spec couldn't know the shipment/quote fields (a dashboard would guess). GET /bookings items now document shipment_id, shipment_number, tracking_number, lane_id, mode, origin_zip, destination_zip, pickup_date, delivery_date, pallet_count, price_usd, status, booked_at, cancelled_at. GET /quote-history items now document quote_id, mode, origin_zip, destination_zip, pallets, price_usd, created_at. No behaviour change: the endpoints already returned these fields; only the spec caught up.

2026-08-29fixedContainer load: mixed-orientation packing, plus the straight-load pallet count

POST /tools/container-load tested only two pure pallet orientations and kept the better one, so it under-reported every ocean container. A 48x40 pallet came back as 8 in a 20 ft and 18 in a 40 ft, when real loads take 10 and 20. It now packs mixed orientations, including pinwheel blocks of four pallets in a (long + short) square, which is how containers are actually loaded. pallets_floor keeps its documented meaning (best achievable) and its 53 ft value of 30, so no existing field or example changes. A new field, pallets_floor_straight, reports the uniform-orientation count instead: 26 for that same trailer, which is the figure Warp quotes for a full truckload and the safer one to plan against, because not every dock and forklift crew can pinwheel. effective_floor_straight is the same number with the payload cap applied. Purely additive.

2026-08-20fixedParcel quote: city and state documented as required (they always were)

POST /parcel/quote documented from/to as needing only postal_code + country, with city and state optional. Parcel carriers rate on the FULL address, so a request without them was rejected upstream with a raw validation string naming a field this API doesn't expose ('city_locality'). The spec, the reference page, and its copy-paste example now list postal_code, country, city and state as required, and the endpoint checks them itself — a missing one returns 400 MISSING_ADDRESS naming each field (e.g. to.city) instead of forwarding the carrier's wording. Worth calling out for anyone coming from the freight endpoints: those quote on ZIP alone, parcel does not.

2026-08-20addedParcel rates on the API: POST /parcel/quote

Live multi-carrier parcel rates for small packages, completing the mode family — one Warp key now prices a pallet (/ltl, /ftl, /van, /box-truck), a container or air freight (/intl/quote), and a box (/parcel/quote). Send from / to addresses plus one or more packages and every connected carrier that can take the shipment quotes back cheapest-first, with an all-inclusive price_usd (resale margin already applied). Dimensions are optional but strongly recommended: most carriers bill dimensional weight, so a weight-only request can understate the rate. When Warp's same-day metro network covers the lane, those options return separately under same_day — they ship from a Warp pickup location rather than the caller's from-address, so they are deliberately not ranked against the carrier rows. Keyless, like every other quote endpoint. Buying a parcel label is NOT yet an API action; these quotes are for pricing and comparison.

2026-08-20addedLive international rates: POST /intl/quote prices ocean and air from Asia to any US ZIP

The first live international freight rates on the public API: POST /intl/quote returns tiered ocean (FCL or shared space) and air rates from real sailing and flight schedules, from China, Vietnam, India, Taiwan, and South Korea to any US door. Keyless, snake_case, same conventions as the domestic quote family. Tiers come back as cheapest / fastest / balanced with price_usd, transit_days, door_service, and valid_until. Origins outside the live rail return 422 NEEDS_TEAM_QUOTE and route to the team, which prices within one business day. Slow by nature (the upstream searches hundreds to thousands of real routes): allow up to 110 seconds. Locking a tier stays on wearewarp.com/ocean and /air for now. Also ships as two new warp-agent-mcp tools, warp_ocean_quote and warp_air_quote, in the next package release.

2026-08-17addedConsolidation finder: POST /consolidate prices your loads together vs separately

Give POST /consolidate the 2-12 loads you plan to ship and it finds the ones that share a lane inside a pickup window (window_days, default 3) and together fit one 53' dry van (26 pallet positions / 44,000 lbs, non-stackable fit model, stated). Every cluster is priced BOTH ways through the real quote machinery: one combined FTL vs the sum of per-load LTLs, and both sides return bookable quote ids, so taking a proposal is a normal POST /book on the truck's quote_id. Loads that can't consolidate come back under unconsolidated with the reason (no_lane_partner, outside_window, exceeds_trailer, cluster_full) rather than disappearing, and a cluster whose truck prices above its LTLs is still shown with recommended:false. Auth optional; keyless requests price via the house quote account exactly like the quote endpoints.

2026-08-17addedShipper profile: GET/PUT /agents/profile — context an agent should read before asking

GET /agents/profile returns two halves: explicit owner-set preferences (default accessorials, preferred mode, standard pallet dims, max transit days, notes) and a derived picture aggregated from the account's own quotes and bookings (top lanes with ship counts, typical pallet count, usual pickup weekday, 180-day booked spend). PUT merge-updates the explicit half against a strict allowlist (unknown keys rejected by name; null clears a key); the derived half cannot be written. The response says what it is: context_not_permission. Nothing in the profile gates what an agent may do - spending limits remain in /agents/spend-policy, read-only.

2026-08-14addedCargo insurance on the multi-carrier market-options endpoint

POST /ltl/market-options now accepts insuranceInfo { commodity, insuredValue } — the same field the single-mode quote endpoints take. The response carries a shipment-level insurance block (premium, fees, total, and a bindable insuranceQuoteId) alongside the carrier spread. It is ONE policy for the whole shipment: pass its insuranceQuoteId to POST /book with whichever carrier's quote_id you chose and coverage binds to that booking. Previously insurance was only quotable through the single-mode endpoints, which for over-size freight substitute a dedicated truck instead of returning the marketplace LTL carriers — so you could get insurance or your chosen carrier, but not both. Now you can add coverage to any carrier option. Omit insuranceInfo for a freight-only spread, byte-identical to before.

2026-08-12changedDocs catch up to the unified quote id; warp_reference retired

Every documentation surface — the /agents/docs pages, /freight-api, llms.txt, llms-full.txt, and the language quickstarts — now shows the canonical quote id (PRICING_… / carrier option id) in examples instead of the retired wq_… format, and example booking URLs point at the real /q/ booking handoff. warp_reference has been removed from quote responses: since the id unification it carried a byte-identical copy of quote_id, and two fields holding one value is exactly the ambiguity the unification exists to end. Anything a warp_reference ever named still works — it IS the quote_id now, bookable and traceable everywhere. Legacy wq_… ids also remain accepted at every endpoint.

2026-08-11changedOne quote id everywhere: quote_id is now Warp's canonical (gw) id

quote_id in quote responses (the four mode endpoints, /quote, and bookable LTL market options) is now Warp's canonical offer id — the same id Warp operations trace and the same string our systems book against — instead of the internal wq_… format. Print it on BOLs and paperwork and book with it; there is no longer a second reference id to juggle (warp_reference remains as the same value for integrations that adopted it). booking_url and book_tool_call carry the same id. Every wq_… id ever issued keeps working at every endpoint, and booking with either id is idempotent against the same quote — integrations that pass quote_id straight back to /book need no changes. Sandbox responses keep their existing ids.

2026-08-11addedBook with the id on your BOL: warp_reference now works everywhere quote_id does

POST /book, GET /quote/{quote_id}/service-options and the /q/<id> booking page now accept the quote's warp_reference (the gw offer id: PRICING_… from the mode quote endpoints, or the option_id from LTL market options) as an alias for the wq_ quote_id. Resolution happens before any booking logic, so booking with one id and retrying with the other replays the same booking idempotently — never a double charge. Nothing changes for existing integrations: wq_ ids keep working exactly as before, and responses are unchanged. This closes the loop for operations teams who receive BOLs referencing the gw id: the id on the paperwork, the id in gw admin, and the id you book with can now all be the same string.

2026-08-08fixedPromo codes now actually apply on /book

promo_code has been accepted by POST /api/v1/book since the endpoint shipped, but no code ever discounted anything. The validation call was missing the /api path segment every other gateway call uses, so it returned 404, and the whole block was skipped without an error: the caller was charged full price with no indication the code had been ignored. A second defect sat behind it, so the fix would not have worked alone: the gateway wraps responses as {message, data}, and the code read status and voucher from the top level instead of from data. Both are corrected. Percentage codes are now supported alongside flat-rate ones, matching the customer dashboard. The discount applies to the freight price only and never to insurance. If the promo service cannot be reached the booking now returns 502 PROMO_UNVERIFIED instead of silently charging full price, and the success response reports promo_applied with discount_usd, the real amount taken off, so percentage codes report actual dollars.

2026-08-08changedRecurring automations hold a sudden price jump for the owner, even under the ceiling

The per-shipment ceiling caps the maximum an automation will ever pay, but between a lane's normal price and that ceiling there was a band where the price could drift up and still book silently. Now the weekly runner also compares each week's best price to the price it last actually booked: if it has risen more than 10% (and by more than $50, so tiny lanes don't trip on noise), the week is held for the owner and emailed instead of booked — the same non-blocking hold as an over-ceiling week, so a later day in the lead window that settles back down still books on its own. First runs and price drops are unaffected. No request or response shape changed; this is autonomous-booking behavior.

2026-08-06changedRecurring bookings are bound to the approved lane, and every one leaves an authorization receipt

A standing order is the owner's approval for one lane at one ceiling, and the commit-time check now enforces all of it. Previously the confirmation-skip granted by a standing-order token verified the automation was active, owned by the calling account, and under the approved ceiling — but not that the booking was for the lane the owner approved. It now does: a booking whose origin or destination differs from the approved lane loses the bypass and falls back to owner confirmation rather than booking automatically. Spend caps were always enforced independently and were never bypassable. Alongside it, GET /api/v1/automations/receipts returns a per-booking authorization record showing every check that ran at commit time (lane match, price vs ceiling, automation active, quote live), the booked lane against the approved lane, and the resulting shipment id. The same record renders on the owner's automation page.

2026-08-05fixed/track response types now match what the endpoint actually returns

The spec declared upstream_tracking as an object. It is an array: the gateway returns one entry per tracking number requested, and since we request one, expect zero or one element. Anyone generating a client from the spec got the wrong type at exactly the point it matters. Both upstream_tracking and events were also declared as opaque objects with no inner shape, which forced callers to hand-roll those parts. Both now have full schemas: statusInfo.status with the carrier status vocabulary, location, and for events the eventName, message, when and details fields. Worth noting for anyone tracking schedule changes: the events feed carries updateAppointmentTimeAtDelivery and updateAppointmentTimeAtPickup, each with the new window under details.appointmentInfo, so a reschedule can be reacted to rather than polled for. No runtime behaviour changed; this is the documentation catching up to the response.

2026-08-04added/track now returns the live delivery schedule

delivery_date on /track is the date captured at booking time and never updates, which made it the wrong field to build reminders or ETA displays on. /track now also returns pickup_window and delivery_window, read live from the shipment record on every call, so if a delivery date moves the response moves with it. Each window carries from, to, and kind: appointment means a booked appointment (narrow and committed), scheduled means the planned window (which can be a broad same-day span). A schedule_live boolean distinguishes a genuinely unscheduled stop (null window with schedule_live true) from a failed live lookup (schedule_live false). All fields are additive; delivery_date is unchanged.

2026-08-05addedAutomation lifecycle: agent-side stop controls, skip weeks, end dates, auto-pause

POST /api/v1/automations/manage lets an agent stop what it set up — pause an active automation, cancel permanently, or skip the next pickup — because booking less is always the safe direction. There is deliberately no agent-side resume, reactivate, or ceiling change: every spend-increasing transition still happens only through the owner's emailed approval link. Proposals now accept an optional end_date (the automation retires itself and notifies the owner after the last pickup), duplicate proposals for the same lane and weekday return 409 with the existing automation instead of creating a twin, four consecutive unbooked weeks auto-pause the automation instead of emailing failures forever, and the owner's management page gains a one-click Skip next pickup.

2026-08-05addedRecurring lane automation: approve once, book every week

POST /api/v1/automations lets an agent propose a standing order: a lane, a weekly pickup day, a selection rule (lowest_price or fastest_transit), and a per-shipment price ceiling. Nothing activates until the account owner approves from email, matching the spend-controls doctrine: agents propose, owners decide. Once active, Warp re-quotes the lane fresh each week (quotes expire, so every run prices live), books the winning option automatically when it is at or under the approved ceiling, and emails the owner a receipt with tracking. Weeks where the best price lands above the ceiling book nothing and notify the owner instead. Owners can pause, resume, or cancel at any time from the emailed management page; no agent-facing API can change an automation's status.

2026-08-04addedSpending limits per account: caps, and human approval for big bookings

Accounts can now carry spending limits, set by the account owner in the dashboard and readable by agents at GET /api/v1/agents/spend-policy. A booking past the rolling-window cap or the per-booking maximum is refused with 402 SPEND_CAP_EXCEEDED or BOOKING_MAX_EXCEEDED, naming the limit and current usage; nothing is booked or charged. A booking over the confirmation threshold returns 202 CONFIRMATION_REQUIRED and is held while the account owner gets an approval email; approval only unlocks the hold, and the agent must call /book again with the same quote_id to complete, so an email click can never dispatch a truck. Poll a hold at GET /api/v1/book/hold. Agents cannot change or remove any limit: there is no write endpoint, by design. Existing accounts are unaffected (no limits until the owner turns them on); new accounts start with $10,000 per 30 days, $5,000 per booking, and confirmation above $2,500. Vocabulary follows the AP2 payment-mandate standard: the cap is an intent mandate, the approval step a cart mandate.

2026-08-04addedProof of execution: one call answers whether a shipment actually happened

GET /api/v1/proof?booking_id=... combines live delivery status, the bill of lading, the proof-of-delivery document, and the customer invoice into a single verdict: executed is true only when the shipment is delivered AND a POD is on file, never inferred. Anything not yet on file is named in a missing array, so an agent can distinguish pending paperwork from a shipment that never ran. Sandbox shipment ids work keylessly and produce watermarked fictional proof on the sandbox lifecycle clock, so the endpoint can be exercised end to end without an account or a real truck. Reconciled carrier-cost records remain internal and are deliberately not claimed by this endpoint.

2026-08-03fixedEvery market option now tells you when it expires

Carrier rates on a single lane do not share a deadline: a spread can hold options gw considers good for 24 hours next to others good for 7 days, and gw will occasionally return one it already considers dead. /api/v1/ltl/market-options previously stamped a flat 72-hour window on all of them and never surfaced it, so an expired rate could come back bookable:true. Because such a rate is often the cheapest on the lane, it sorted to rank 1 and was the natural pick, then failed at booking with an opaque upstream error. Each option now carries expires_at (the carrier own deadline, capped at 72 hours) and expires_in_seconds (the same value relative to Warp clock, so you need not trust clock alignment). An option the carrier already considers expired is returned for visibility with bookable:false and no quote_id, and is never minted as a bookable quote. Both fields are additive and ranks are unchanged, so existing integrations are unaffected.

2026-07-31fixedLTL quotes no longer present a dedicated truck as shared LTL

On lanes where Warp has no LTL service, gw substitutes a dedicated truck and reports that in its response — but /api/v1/ltl/quote never read the field back, so the price came through labelled 'LTL (shared)'. Spokane to New York returned $7,827 for a single 200 lb pallet while real LTL on that lane is about $583. The response now tells you: service.mode becomes 'ftl' and service.vehicle "53' dry van" (both already-documented enum values, so generated clients are unaffected), and a new optional mode_substituted block gives the reason and points at /ltl/market-options for the LTL carriers that do serve the lane. Backwards compatible: mode_substituted is additive and absent on every normal LTL quote, and no enum gained a new value. Prices are unchanged — only the labelling, which was wrong. Spec 1.12.0 to 1.13.0.

2026-07-31changedCorrected the /ltl/market-options accessorials wording

The endpoint description still said per-stop services were passed as pickup_services / delivery_services arrays and NOT the accessorials object. That is no longer true: accessorials { pickup: [], delivery: [] } is the same shape /ltl/quote takes, it is what this endpoint uses, and pickup_services / delivery_services are accepted aliases merged with it. The description said the opposite of the schema; it now matches.

2026-07-31changedUnknown accessorial slugs are now rejected, not silently dropped

POST /api/v1/ltl/quote used to filter unrecognised accessorial slugs out of your request and return a quote anyway, and POST /api/v1/ltl/market-options did not validate them at all. Either way a typo produced a quote you believed included an accessorial that was never priced or dispatched. Both endpoints now return 400 INVALID_ACCESSORIAL, naming the offending slug and listing every valid pickup and delivery slug. BREAKING for callers currently sending slugs outside the catalog: those requests used to succeed with the slug quietly removed and will now fail loudly. Spec 1.11.0 to 1.12.0.

2026-07-31fixed/ltl/market-options now honours the accessorials object too

POST /api/v1/ltl/market-options only read pickup_services / delivery_services. Callers sending the nested accessorials { pickup: [], delivery: [] } object — the same shape /ltl/quote accepts — had it silently ignored, so a request for liftgate-delivery returned base rates and the accessorial never reached dispatch. Both shapes are now accepted and merged, and accessorials is declared in the spec. If you send accessorials on this endpoint, expect higher, accurate rates and a possibly shorter carrier list, since carriers that cannot perform a requested service drop out. Spec 1.10.0 to 1.11.0.

2026-07-31fixedAccessorials now re-price the /ltl/market-options carrier spread

POST /api/v1/ltl/market-options accepted pickup_services and delivery_services but did not apply them upstream, so every carrier came back at its base rate. They are now passed correctly and each carrier re-prices for them; carriers that cannot perform a requested service drop out of the spread, so the option count can shrink. Expect higher, accurate rates when you request accessorials such as liftgate-delivery or residential-delivery. Both fields are also now declared in the spec (previously only mentioned in the endpoint description), so generated clients can send them. Spec 1.9.3 to 1.10.0.

2026-07-28fixedOver-height LTL pallets now return a clear error instead of a wrong price (POST /ltl/quote, POST /ltl/market-options)

LTL has no rate for a pallet taller than 85 in, and the two LTL endpoints previously turned that into misleading output instead of an error: /ltl/market-options fell through to its cached fallback and DISPLAYED the lane's last-good carrier spread — real carriers and real prices, but computed for a different, in-spec load — under a "comparison timed out" note; /ltl/quote clamped the height internally, so 90 in, 150 in and 300 in pallets all returned the SAME price and a bookable quote_id for freight that cannot move as LTL. Both now return 400 EXCEEDS_LTL_LIMITS before pricing, with a violations[] array naming the field, the value sent and the limit (plus the items[] line number for a manifest), and a pointer to /box-truck/quote, /ftl/quote or the all-modes /quote. height_in also carries maximum: 85 in the spec so generated clients and agents can validate before calling. ONLY height is enforced: length, width and weight beyond a standard 50 x 50 in / 2,000 lb pallet are priced by the rating engine at a higher rate rather than refused, so they are documented but deliberately not rejected. The boundary is inclusive — 85 in is accepted, 86 in is not — and in-spec requests are unchanged.

2026-07-23fixedCargo van now priced as a dedicated van (POST /van/quote, and the van row of POST /quote)

Cargo van is now quoted and booked as a dedicated vehicle (the rating engine's shipmentType FTL), so a van quote returns its true dedicated-van rate instead of a shared-LTL rate. A short-lived workaround had routed van through the LTL rail because the rating engine previously returned no rate for a dedicated van; that is reverted now that van/FTL capacity is rated (e.g. a 2-pallet LA-metro van now returns ~$467 rather than a ~$150-250 LTL rate). The same FTL mapping is used at booking time so a van quote and its booking never disagree on shipmentType (which the engine rejects). No request/response schema change; box truck, FTL, and LTL are unaffected. Van prices on affected lanes will be higher than the prior LTL-based number - that is the correction to true van pricing, not a surcharge.

2026-07-22addedQuote responses now include warp_reference (the traceable quote id)

Every quote response - POST /api/v1/{van,box-truck,ftl,ltl}/quote and each row of POST /quote - now carries warp_reference, the underlying pricing-engine quote id (e.g. PRICING_...). This is the reference to put on tenders, BOLs, and carrier paperwork so a shipment can be looked up by Warp operations; the wq_ quote_id remains your booking token (pass it to POST /book) and is not recognized outside the API. Purely additive and backward-compatible: quote_id is unchanged, booking is unchanged, and warp_reference is simply an extra field - present on quotes made with an API key, absent on keyless quotes (which cannot book anyway). Spec 1.9.2 to 1.9.3.

2026-07-21fixedCargo van quotes now return rates (POST /van/quote, and the van row of POST /quote)

Cargo van was being sent to the rating engine as shipmentType FTL, which has no dedicated cargo-van capacity, so every cargo-van quote came back 'A rate has not yet been determined for this route'. Cargo van now quotes as shipmentType LTL — the way the rating engine actually prices a van — so van lanes return real rates (e.g. LA to San Diego ~$317, LA to NYC ~$872). The same LTL mapping is applied at booking time so a van quote and its booking never disagree on shipmentType (which the rating engine rejects). No request/response schema change; box truck, FTL, and LTL are unaffected.

2026-07-21addedmarket-options: retryable/cached flags + cached-spread fallback on carrier-sweep timeout

POST /api/v1/ltl/market-options now returns retryable (boolean), cached (boolean), and as_of (when cached). The carrier aggregator polls 30+ carriers live and intermittently times out at ~30s on some lanes, returning an empty 200 that was indistinguishable from genuine no-coverage. Now: when a live sweep times out, the endpoint serves the last-good spread cached for that lane (marked cached:true + as_of, options display-only/bookable:false — re-run for live bookable quotes) instead of an empty list; and every response carries retryable so callers branch on a boolean instead of matching the note text (retryable:true = transient/timeout, retry; false = the sweep completed, an empty list means real no-coverage). Purely additive: successful spreads are unchanged aside from cached:false/retryable:false. The fast Warp rate at /ltl/quote is a separate endpoint and unaffected. Spec 1.9.1 to 1.9.2.

2026-07-18fixedSpec truth pass - docs now match the code everywhere we checked

Corrections from a full docs audit, all documentation-only (zero API behavior change): POST /quote's request schema now uses the field names the API actually reads (destination_zip, weight_lbs_per_pallet, top-level length_in/width_in/height_in - the previously documented dest_zip/weight_per_pallet_lbs/dimensions were never accepted); /book documents its real 402 (checkout_url), 409 BOOKING_IN_PROGRESS, and 503 responses plus promo_code and the idempotent-replay fields; /ltl/market-options documents pickup_services/delivery_services (accessorials/load_template_id/hazmat/freight_class/commodity are not read there), its real ~20s latency (allow 45s), and that aggregator failure degrades to 200 with an empty list rather than 5xx; /track's status enum is booked/cancelled with live movement documented under upstream_tracking.statusInfo.status; /documents documents its type/podType filters; /ltl/quote no longer over-requires commodity (optional, firms the price); van/box-truck docs state that out-of-range pallets/weights are clamped, not rejected; /quote-history is typed as the array it returns; and the error catalog now lists every code the API emits (QUOTE_NOT_FOUND, INVALID_PROMO, WALLET_TOPUP_FAILED, CANCEL_NOT_SELF_SERVE 410, and friends) with the wallet-vs-direct-charge refund behavior stated precisely. Spec 1.9.0 to 1.9.1.

2026-07-18addedOpt-in cargo insurance on quote and book

Quote endpoints (POST /api/v1/{ltl,ftl,van,box-truck}/quote) now accept an optional insuranceInfo { commodity, insuredValue }. When present, the quote response carries an insurance block { insuranceQuoteId, premium, processingFee, total, currency_code }. Pass that insuranceQuoteId to POST /api/v1/book to bind the policy with the shipment: the premium total is funded alongside the freight, and the booking response echoes insuranceStatus ("booked" or "failed"). If insuranceStatus is "failed" the freight still booked and the funded premium remains recoverable — no auto-refund. insuranceQuoteId must match the id issued for that quote_id, else 400 INSURANCE_QUOTE_MISMATCH. Fully opt-in and backward-compatible: callers that send no insuranceInfo/insuranceQuoteId are unaffected. Spec 1.8.1 to 1.9.0.

2026-07-18fixed/van/quote response docs: 429 entry restored to its own status

The /van/quote operation's 429 (RATE_LIMITED) response entry had been nested inside the 400 response object, so the rendered spec showed no 429 for /van/quote and was invalid OpenAPI for that operation (breaking strict validators/codegen). The 429 is now a proper sibling response, and the no-rate note added earlier today ('A rate has not yet been determined...' relayed as 400) now sits on the 400 description where it belongs. Documentation-only; no API behavior change.

2026-07-17changedNo-rate lanes now return 400 (matching upstream), not 502

When the rating engine has no rate for a lane + vehicle combination, the quote endpoints (/box-truck/quote, /van/quote, /ftl/quote, /ltl/quote) used to relay that answer with a generic 502 UPSTREAM_ERROR status, which monitoring and retry logic read as a server outage. It is a routine business answer - nationwide integrations hit it on lanes Warp does not currently price - so it is now relayed with the rating engine's own 400 status instead. The response BODY is byte-identical to before (same error message, same code UPSTREAM_ERROR), so JSON parsing and response.ok checks are unaffected; only the status number changes, and only for the 'A rate has not yet been determined for this route' answer. Real upstream failures (rating service down or unreachable) still return 502. Tip: POST /quote returns every mode's availability for a lane in one call, with unpriced modes as available:false rows instead of errors.

2026-07-15addedPer-stop company, street2, and appointment on POST /book

patch.pickup / patch.delivery now accept company (facility name - the BOL shipper/consignee line, defaulting to the contact name so it is never blank), street2 (suite/unit/dock line), and appointment {from,to} (structured appointment window, local to the stop, forwarded as a scheduled appointment rather than just an accessorial flag). Also fixed in this release: DEFAULT pickup/delivery windows are now computed in each stop's local timezone (8am-8pm local) - previously they were raw UTC, which rendered as 04:00-8pm on Eastern BOLs. All additive; existing requests unchanged.

2026-07-15changedCross-linked POST /quote and POST /ltl/market-options

Both quote-comparison surfaces now point at each other: /quote compares modes (one firm Warp rate each for cargo van, box truck, LTL, FTL), /ltl/market-options compares carriers within LTL. No behavior change.

2026-07-15addedPOST /quote - all modes in one call

New endpoint that quotes cargo van, box truck, LTL, and FTL in parallel from one payload and returns one row per mode, cheapest bookable first. Each priced row carries a quote_id that books through POST /book exactly like a single-mode quote; modes that cannot take the load return available:false with that mode's reason. Purely additive - the four per-mode endpoints are unchanged, and this endpoint prices through them, so it can never disagree with them. Not to be confused with LTL market options: /quote compares modes (one firm Warp rate each), market options compares carriers within LTL.

2026-07-07fixedBookingResponse now documents order_id, order_number, and tracking_dashboard

The booking response schema (POST /api/v1/book and /api/v1/freight/book) now documents three fields the API has always returned but the spec omitted: order_id and order_number (the order the shipment belongs to — pass order_id to GET /api/v1/documents), and tracking_dashboard (the customer tracking URL, always present on a successful booking, so no separate async buildout is needed). shipment_id and order_id are distinct identifiers on a real booking — shipment_id is what you pass to GET /api/v1/track as booking_id, order_id is what you pass to GET /api/v1/documents — and are identical in the sandbox mock. No behavior change; this corrects spec drift only. Spec 1.8.0 to 1.8.1.

2026-07-07addedWhite-glove service options: new accessorial slugs + per-quote option pricing

All quote and book endpoints now accept the self-serve service-option slugs from the Warp catalog: two-man-delivery, tiered inside pickup/delivery (living space/garage, back/side of the house, upstairs/mezzanine with trash removal), driver-assist, construction-site, and convention/trade-show. Requested options attach to the quote and are carried into the booking. Note: rates for premium add-ons are account-configured and not yet rated into price_usd by the API — confirm add-on pricing with your Warp contact. New GET /api/v1/quote/{quote_id}/service-options ships as a preview for per-option rates and currently returns 409 for most quotes until platform-side rating is enabled. Spec 1.7.0 to 1.8.0 (wording corrected same day: an earlier revision of this entry claimed options were priced into price_usd).

2026-06-23addedRead your prepaid wallet balance with GET /api/v1/balance

New GET /api/v1/balance returns your account's prepaid wallet balance in USD — your booking runway. Check it before booking to know whether the next POST /book settles from balance (charging nothing) or charges your saved card for the shortfall only. Read-only and scoped to your own account; returns 409 WARP_SESSION_REQUIRED until you sign in once at wearewarp.com/agents/account. Spec 1.6.1 to 1.7.0.

2026-06-23fixedClarified that LTL dims are always required (no dims-less 'indicative' quote)

The /ltl/quote docs implied an 'indicative' quote could be obtained by omitting fields, which led agents to drop length_in/width_in/height_in and hit 400 MISSING_DIMS. Dims (or a load_template_id / items[] manifest) are ALWAYS required; quote_tier 'indicative' only reflects a missing OPTIONAL field such as commodity. Wording corrected on the endpoint description and the quote_tier field. Spec 1.6.0 to 1.6.1.

2026-06-22fixedMulti-carrier LTL options are bookable with production API keys

POST /api/v1/ltl/market-options now mints a bookable quote_id for each carrier option when called with a production (wak_live_) key, so a selected option books directly via POST /api/v1/book. Previously only sandbox and keyless callers received bookable options; production keys fell through to a display-only house-account spread where every option returned bookable:false with no quote_id and could not be booked. Sandbox and keyless behavior is unchanged (display-only, priced on the house account).

2026-06-22changedDocumented pickup/delivery time windows on POST /book; removed the non-functional stackable field

POST /api/v1/book now documents optional pickup_window and delivery_window objects (each { from, to } as 24h HH:MM) that narrow the pickup or delivery time within the date. The field was already honored by the endpoint and is now in the spec. The stackable field has been removed from the LTL, multi-stop, and load-template request bodies: Warp prices LTL on weight, dimensions, and distance (FAK), and stackable never reached the rating engine, so it was a no-op. Backward-compatible: callers that sent stackable are unaffected. Spec 1.5.0 to 1.6.0.

2026-06-18addedMixed-dimension pallets via items[] on POST /api/v1/ltl/quote

LTL quotes now accept an optional items[] manifest so one shipment can carry pallets of different sizes and weights. Each entry is its own pallet profile ({ qty, weight_lbs_per_pallet, length_in, width_in, height_in }) and is priced as its own line item; identical pallets can be grouped with qty. When items[] is present it replaces the scalar pallets/weight_lbs_per_pallet/length_in/width_in/height_in fields, and the exact manifest is echoed back in assumptions.line_items and replayed verbatim at /api/v1/book. Backward-compatible: callers that send no items[] use the unchanged scalar path. Spec 1.4.0 → 1.5.0.

2026-06-15addedPer-stop reference numbers on POST /api/v1/book

patch.pickup.refNum and patch.delivery.refNum set the reference number that renders on each stop's "Reference Number" line on the BOL — e.g. a PO on the pickup line and an SO on the delivery line. One reference per stop. The top-level reference field is unchanged and remains shipment-level; per-stop refs never persist into your saved consignee, so they aren't reused on a later rebook. Backward-compatible: callers that send no refNum are unaffected. Spec 1.3.0 → 1.4.0.

2026-06-11addedSelf-serve outbound webhooks

New /api/v1/developer/webhook (GET reads, POST { url } registers — https only, one URL per account — DELETE removes) plus POST /api/v1/developer/webhook/test to fire a test delivery. Warp delivers shipment-milestone events to your URL in real time as JSON POSTs ({ event, timestamp, data }) — no more polling /track. Deliveries are NOT signed today: put an unguessable secret in your registered URL and reject requests that lack it; HMAC signing is on the roadmap. Requires a linked Warp session — sign in once at wearewarp.com/agents/account, otherwise 409 WARP_SESSION_REQUIRED. Spec 1.2.0 → 1.3.0.

2026-06-11changedRate limits on the keyless quote endpoints

POST /api/v1/{ltl,ftl,van,box-truck}/quote and /api/v1/ltl/market-options now enforce the published tier ceilings: 60 requests per hour per IP with no key, 1,000 per hour with a sandbox key, 10,000 per hour with a live key. 429 responses carry code RATE_LIMITED, Retry-After, and X-RateLimit-Limit/Remaining/Reset headers with the upgrade path in the error body. Generous for humans and builders; a hard ceiling for hammering.

2026-06-11addedIdempotent booking on quote_id

POST /api/v1/book now replays the original confirmation (idempotent_replay: true) when the same quote_id is re-sent by the same account, instead of charging the card twice. Safe for agent tool retries and network timeouts.

2026-06-11fixedquote_validity_minutes corrected to 4320

GET /api/v1/rate-card (and the OpenAPI example) reported quote_validity_minutes: 15 while the real quote TTL has been 72 hours. The field now reports 4320 everywhere.

2026-06-11addedThe living sandbox lifecycle

Sandbox bookings (wak_test_) now advance through the full production status sequence over ~10 minutes, served by GET /api/v1/track and /api/v1/events (keyless for sandbox ids). Documents follow the production rhythm: BOL after pickupSuccessful, POD after delivered. Pass "reference": "scenario:delay" on /book for a deterministic exception path.

2026-06-10addedcheckout_url on 402 PAYMENT_REQUIRED

POST /api/v1/book without a card on file now returns a Stripe-hosted checkout_url plus a retry hint in the 402 body, so a deferred card is recoverable from the terminal.

2026-06-10changedbooking_url now lands on wearewarp.com/q/{quote_id}

Quote responses' booking_url moved from the external portal form to an on-site handoff page that loads the quoted lane and books it inline. The quote_id in the URL prefills the lane by construction.

2026-05-27changedsnake_case /api/v1 surface is canonical

The canonical self-serve surface is /api/v1/{ltl,ftl,van,box-truck}/quote + /api/v1/book + GET /api/v1/track. The legacy camelCase /api/v1/freight/* routes carry RFC 8594 Deprecation/Sunset headers (sunset 2026-08-31) and are absent from the OpenAPI spec.

Spec source of truth: /.well-known/openapi.json · build provenance: /api/v1/version · live health: /status

Warp customers

WalmartGopuffKith
Warp · Fast Company Most Innovative Companies 2026
As seen in

Versioning and deprecation policy

The canonical surface is /api/v1 and changes are additive by default: new fields and endpoints arrive without breaking existing integrations, and response shapes documented in the OpenAPI spec stay stable within v1.

When something must be retired, it gets RFC 8594 Deprecation and Sunset headers and a dated entry below, with the replacement documented before the sunset lands (the legacy camelCase /api/v1/freight/* surface is the running example: sunset 2026-08-31).

The machine-checkable trail: every change here corresponds to a recorded spec snapshot in the public repository.

About the Warp freight network

More about the Warp freight network
70+cross-dock facilities
6,800+Warp LTL lanes
14,000+vans & box trucks
24,000+vetted FTL carriers

Warp is a technology-driven freight network that combines cargo van, box truck, LTL, and FTL capacity under one operating system. Shippers get instant rates, real-time tracking, and access to 70+ cross-dock facilities and 14,000+ cargo vans and box trucks — with 80%+ US LTL zip-to-zip coverage and nationwide FTL, box truck, and cargo van.

The network is supported by 24,000+ vetted FTL carriers.

Unlike traditional brokers, Warp uses AI to match the right vehicle to every load based on weight, dimensions, urgency, and cost targets. Cross-dock operations reduce transit time by eliminating unnecessary terminal transfers.

Pool distribution and zone-skipping programs help enterprise shippers lower per-unit delivery costs while maintaining tight appointment windows.

Self-serve shippers can quote, compare, and book freight online in under two minutes. Enterprise accounts get dedicated capacity planning, committed rate programs, and a named operations team. Every shipment includes scan-level visibility from pickup through final delivery.

Warp operates across the contiguous United States with regional density in the Southeast, Texas, Midwest, and Northeast corridors.

Cross-dock facilities in Atlanta, Chicago, Houston, New York, Savannah, Orlando, Charlotte, Indianapolis, Columbus, Denver, New Orleans, and Milwaukee support faster transfers and fewer touches on recurring lanes.

Freight modes and vehicle types

ModeMax payloadMax cubeBest for
Cargo van3,500 lbs400 cu ftTime-sensitive, last-mile, light pallets
Box truck10,000 lbs1,500 cu ftRegional distribution, no dock required
LTLPer-palletShared trailerLower per-pallet cost via cross-dock routing
Dry van / FTL42,000+ lbsFull 53-ft trailerHigh-volume lanes, recurring programs

Cargo vans handle loads up to 3,500 pounds and 400 cubic feet, ideal for time-sensitive deliveries, last-mile retail replenishment, and lightweight palletized freight.

Box trucks carry up to 10,000 pounds and 1,500 cubic feet, fitting most regional distribution and store delivery needs without requiring a loading dock.

Dry vans and full truckloads move 42,000+ pounds for high-volume lanes and recurring programs. LTL shipments share trailer space on optimized routes through Warp cross-docks, reducing per-pallet cost by consolidating multiple shippers on the same vehicle.

Warp does not default every shipment to a 53-foot trailer. The AI engine evaluates load weight, cube, delivery window, and cost to recommend the right vehicle. Shippers see all available mode options with live pricing in one comparison screen before booking.

Cross-dock operations

Cross-docking at Warp facilities keeps freight moving instead of storing it: inbound freight is sorted and transferred directly to outbound vehicles, typically within hours. When inventory does need to sit, Warp's fulfillment centers in Los Angeles, Dallas, Chicago and New Jersey hold it inside the same network, with same day delivery within 30 miles of each.

This reduces dwell time, lowers damage risk, and compresses delivery windows. Warp cross-docks support pallet-in, pallet-out operations with scan-level tracking at every handoff point.

  • Atlanta — Southeast retail flow
  • Chicago — Midwest manufacturing and replenishment
  • Houston — Texas industrial distribution
  • New York — dense Northeast delivery

Facility locations are selected for corridor density: Atlanta handles Southeast retail flow, Chicago serves Midwest manufacturing and replenishment, Houston covers Texas industrial distribution, and New York supports dense Northeast delivery. Each facility operates on appointment-based scheduling to prevent congestion and maintain throughput consistency.

Enterprise freight programs

Enterprise shippers get committed rate programs, dedicated account management, and custom SLA design. Warp builds lane-by-lane rate structures that account for volume commitments, seasonal variation, and mode flexibility. Operations teams monitor shipment execution daily and intervene proactively when exceptions occur.

Self-serve freight quoting

Shippers enter origin and destination, load details, and delivery requirements to see live rates across all available modes. Quotes include estimated transit time, vehicle type, and total cost.

Booking takes one click. After booking, shippers track every shipment with real-time GPS location, milestone updates, and proof of delivery documentation.

Industries and use cases

Retail shippers use Warp for store replenishment programs that deliver to hundreds of locations per week on tight appointment windows. Apparel brands use zone skipping to bypass regional parcel sortation and reduce per-unit delivery cost.

Food and beverage companies rely on time-definite delivery for perishable goods. Manufacturing operations use Warp for inbound vendor consolidation, combining multiple supplier shipments into fewer, fuller loads through cross-dock facilities.

Distribution companies use pool distribution to serve multiple delivery points from a single origin, splitting full truckloads at cross-docks into smaller last-mile vehicles.

Urgent freight recovery covers emergency capacity needs when primary carriers fail or demand spikes unexpectedly. Middle-mile optimization reduces cost and transit time on the longest segment of multi-leg shipments.

Ready to ship?

Get instant rates or talk to our team about a custom freight program.

Hand-written entries · machine-enforced honesty · RFC 8594 deprecations

Performance figures are computed from Warp network data. See our methodology.

$50off your first shipmentGet your rate