API v1 ยท Live
The same pricing engine behind loadloom.com, in your own software: send shipment details, get back real bookable prices in about a second, each locked for 30 days by PriceLock 30 with a shareable booking link. JSON in, JSON out.
Create an API key in your account under Developers (free with any LoadLoom account). Send it as a Bearer token on every request. Keys are shown once, stored hashed, and revocable at any time.
Authorization: Bearer ll_live_your_key_here
POST https://loadloom.com/api/v1/quotes
curl https://loadloom.com/api/v1/quotes \
-H "Authorization: Bearer ll_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"category": "heavy-equipment",
"pickup": "Toronto, ON",
"dropoff": "Dallas, TX",
"details": {
"type": "excavator",
"lengthFt": 32, "widthFt": 10, "heightFt": 10.5,
"weightLbs": 48000,
"condition": "runs"
}
}'The category and its details fields mirror the website's quote forms exactly: heavy-equipment, vehicles, rv, boats, freight (pallets/FTL), moving, and containers each accept the same fields you see on their quote screens.
const res = await fetch("https://loadloom.com/api/v1/quotes", {
method: "POST",
headers: {
"Authorization": "Bearer ll_live_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
category: "freight",
pickup: "Montreal, QC",
dropoff: "Chicago, IL",
details: {
pallets: [{ lengthFt: 4, widthFt: 3.5, heightFt: 5, weightLbs: 900, stackable: true }],
hazmat: false,
},
}),
});
const quote = await res.json();
console.log(quote.tiers);import requests
quote = requests.post(
"https://loadloom.com/api/v1/quotes",
headers={"Authorization": "Bearer ll_live_your_key_here"},
json={
"category": "vehicles",
"pickup": "Calgary, AB",
"dropoff": "Vancouver, BC",
"details": {
"items": [{"desc": "2022 Ford F-150", "operable": True, "personalItems": False}],
"enclosed": False,
},
},
).json()
print(quote["tiers"]){
"object": "quote",
"id": "Q-8F3K2Q",
"url": "https://loadloom.com/q/Q-8F3K2Q",
"created_at": "2026-07-24T21:15:03.000Z",
"price_locked_until": "2026-08-23T21:15:03.000Z",
"currency": "CAD",
"miles": 1372,
"tiers": [
{ "id": "economy", "name": "Economy", "total": 4180.00, "perMile": 3.05, "transit": "6-9 days" },
{ "id": "standard", "name": "Standard", "total": 4680.00, "perMile": 3.41, "transit": "4-7 days" },
{ "id": "priority", "name": "Priority", "total": 5420.00, "perMile": 3.95, "transit": "3-5 days" }
]
}Totals are Direct-Pay (bank transfer) prices; the standard any-payment-method price is 11% higher, exactly as on the site. Responses may also carry a co2 object: a GLEC-aligned emissions estimate for the shipment (kg CO2e, display string, and a methodology link); treat it as informational, per /co2-methodology. The url opens the saved quote where your customer can book, sign, and pay, and the quote also appears in your account's Saved Quotes.
GET https://loadloom.com/api/v1/quotes/{id}
curl https://loadloom.com/api/v1/quotes/Q-8F3K2Q \ -H "Authorization: Bearer ll_live_your_key_here"
Returns the saved quote with its tiers, lock expiry, and booking URL. A key can only read quotes created under its own account; an expired PriceLock returns 410 so your integration knows to re-quote.
GET https://loadloom.com/api/v1/tracking?ref=LL-2026-8F3K2Q
curl "https://loadloom.com/api/v1/tracking?ref=LL-2026-8F3K2Q" \ -H "Authorization: Bearer ll_live_your_key_here"
Accepts a booking (LL-โฆ) or load (LD-โฆ) number and returns the same city-level milestone history the public tracking page shows: status, each milestone with its timestamp, and the route. Precise GPS and internal notes are never exposed.
Networks fail mid-request. To retry a POST safely, send an Idempotency-Key header with any unique string (a UUID is perfect, up to 255 characters). If we already completed a request under that key, we replay the stored response instead of running it again, marked with a Idempotent-Replayed: true header, so a retry can never create a duplicate quote or booking link. Keys live for 24 hours. Reusing a key with a different body returns 400 idempotency_error; a retry that lands while the first attempt is still running returns 409 (wait a moment, retry, and receive the stored result).
curl https://loadloom.com/api/v1/quotes \
-H "Authorization: Bearer ll_live_your_key_here" \
-H "Idempotency-Key: 4f9d2a1e-8c47-4b3a-9f21-7e5d6c8b0a13" \
-H "Content-Type: application/json" \
-d '{ ... same body as above ... }'Every API response carries an X-Request-Id header (like req_a3f9c2e17b4d8a05c6e1f2b9). Log it. When something looks wrong, quote that one id to developers@loadloom.com and we can find the exact call.
Same host, two worlds, decided by the key, exactly the Stripe pattern. A ll_live_ key works with real objects; a ll_test_ key (create one on the same Developers page) sees only test data, and the two never mix. In test mode: quotes are priced by the real engine and marked "livemode": false, but they can never be booked, never appear in your live lists, and never trigger emails; the bookings list returns one stable fixture booking (id LL-TEST-0001) in exactly the live field shape so your parser transfers unchanged; tracking answers only for the fixture ref LL-TEST-0001. No test request can ever create a contract, a charge, or an email. Build against your test key, then swap one environment variable to go live.
The version lives in the path (/api/v1/). Within v1 we only make additive changes: new fields and new endpoints may appear, but existing fields never change meaning or disappear. Anything breaking becomes /api/v2 with both versions running side by side and generous notice. Build against v1 with confidence. The machine-readable contract is the OpenAPI 3.1 spec (generate SDKs from it), and every change lands on the changelog, dated.
| Status | Type | Meaning |
|---|---|---|
| 401 | authentication_error | Missing, invalid, or revoked key |
| 400 | invalid_request_error | The engine could not price the request; the message names the problem |
| 404 | not_found_error | No such quote/shipment on this account |
| 410 | invalid_request_error | The quote's 30-day PriceLock expired; create a fresh quote |
| 400/409 | idempotency_error | Idempotency-Key reused with a different body (400) or first attempt still running (409) |
| 429 | rate_limit_error | Over 120 requests/hour per key |
| 500 | api_error | Our side; safe to retry |
| Endpoint | Key | Does |
|---|---|---|
| POST /api/v1/quotes | Account | Create a 30-day price-locked quote |
| GET /api/v1/quotes | Account | List your saved quotes |
| GET /api/v1/quotes/{id} | Account | Retrieve one quote |
| POST /api/v1/bookings | Account | Turn a quote + tier into a pre-selected checkout link |
| GET /api/v1/bookings, /{id} | Account | Your bookings with live statuses |
| GET /api/v1/tracking?ref= | Account | City-level milestone tracking |
| GET /api/v1/promo-assets | Account | Publisher content feed with your tracked links baked in |
| GET /api/v1/referrals/summary | Account | Your referral earnings, machine-readable |
| GET/POST /api/v1/broker/loads | Account (broker) | List and post your broker loads (verified brokers; same rules as the desk, idempotency supported) |
| GET /api/v1/broker/requests | Account (broker) | Pending carrier requests; pairs with broker_load.* webhook events (accepting stays on-platform: signatures are human acts) |
| GET /api/v1/carrier/loads | Carrier | The live AVAILABLE load feed (approved carriers) |
| GET /api/v1/carrier/settlements | Carrier | Your settlement statuses and payment references |
๐ญ Shippers, dealers & platforms
Quote, retrieve, hand your customer a pre-selected checkout link, then follow the booking and its tracking, all live today. Contract signature and payment always happen on LoadLoom: a legal signature belongs to a person, not a server. Next: status webhooks so your system hears about pickups instead of polling.
๐ Carriers & dispatch software
Live today: the load feed and your settlement statuses, straight into your TMS. Create carrier keys in the portal under API access (approved carriers). Requesting to haul stays in the portal, because a rate confirmation carries your signature. Next: load-matched notifications by webhook.
๐ฃ Publishers & affiliates
Pull every live promo asset with your tracked links already attached, pipe them into your newsletter or site, and read your clicks, quotes, bookings and balances by API. Every click still pays through the normal rails. Ideas for the feed: sales@loadloom.com.
Register an HTTPS endpoint from your Developers page and LoadLoom POSTs every tracking event on your shipments and tracking pages to your server as JSON: events tracking.updated and shipment.delivered. Each delivery carries an X-LoadLoom-Signature header, an HMAC-SHA256 of the raw body using your endpoint's secret (shown once at creation) prefixed sha256=, so your server can verify the sender. Respond with any 2xx inside 5 seconds; failed deliveries retry with backoff, and twenty consecutive failures pause the endpoint (we email you). Endpoints must be public HTTPS; a test event button lives beside the endpoint list.
Ready to build? Your first key takes 30 seconds.
Get an API keyUse of the API and webhooks is governed by the API and Webhooks Agreement.