HaulageBoard

Loads

Three calls. Post one, list them, read one back.

Post a load

POST https://app.haulageboard.com/api/v1/loads
Authorization: Bearer hb_live_...
Content-Type: application/json
Idempotency-Key: your-own-job-reference

{
  "type": "PALLETS",
  "vehicleClass": "SEVEN_FIVE_T",
  "weightBand": "T_1_3",
  "pallets": 4,
  "fromPostcode": "LE1 1AA",
  "toPostcode": "M1 2AB",
  "collectDate": "2026-09-14",
  "collectByTime": "09:00",
  "deliverDate": "2026-09-15",
  "deliverByTime": "14:30",
  "pricingMode": "QUOTES",
  "termsDays": 30,
  "externalRef": "JOB-88213",
  "dimsNote": "2 cages, 1.8m tall",
  "notes": "Tail lift needed at delivery"
}
201 Created

{
  "load": {
    "id": "clx...",
    "ref": "HB-1042",
    "externalRef": "JOB-88213",
    "status": "POSTED",
    "isTest": false
  },
  "miles": 96,
  "guide": { "lowPence": 22000, "highPence": 28000 },
  "carriersAlerted": 14
}

guide is what work like this usually goes for, so you can sanity check a quote against it. carriersAlerted is how many carriers were told, and is null on a test key because nobody was told.

Always send an Idempotency-Key

Use your own reference for the job. If a request times out and you retry it, we return the load we already made, with repeated: true, instead of making a second one. Without the header a retry posts the job twice and two carriers ring your dispatcher about the same load.

Keys are remembered for a week, which is longer than any sensible retry.

Fields

typeFULL_LOAD, PART_LOAD, PALLETS, PARCELS
vehicleClassSMALL_VAN, LWB_VAN, LUTON, SEVEN_FIVE_T, EIGHTEEN_T, ARTIC, FLATBED, LOW_LOADER
weightBandUNDER_50KG, KG_50_250, KG_250_1000, T_1_3, T_3_7, T_7_15, T_15_PLUS
fromPostcode
toPostcode
As written. We look them up and work out the distance.
collectDateYYYY-MM-DD
collectWindowAM, PM or Anytime. A preference.
collectByTimeHH:MM, for a booked collection slot. A mover sees this differently from a window, because it is something they have to be somewhere for.
deliverDateYYYY-MM-DD, or leave it out when there is no deadline. Cannot be before the collection.
deliverWindowAM, PM or Anytime. A preference rather than a commitment.
deliverByTimeHH:MM, for a booked slot. Needs a deliverDate. A mover sees this differently from a window, because it is something they have to plan a day around.
pricingModeQUOTES, or BOOK_NOW with a bookNowPence
bookNowPenceWhat the job pays, in pence, when you are naming a price. Send this if your own system already knows the figure: without it the board shows Quotes and no number, and we never put an estimate of ours where your price goes.
termsDaysHow long until you pay the carrier. Shown on the load before anybody quotes. Defaults to your usual.
pallets, parcelsWhichever suits the type
adr, tailLift, fragile, isBackloadBooleans, all optional
notesFree text, up to 1000 characters. Anything a driver needs to know.
dimsNoteDimensions in whatever words suit. Optional.
externalRefYour own job number. Comes back on every response and inside every webhook, so you never need a table mapping our references to yours. Optional, and not checked for uniqueness, because some systems reuse one across amendments.

Money is always integer pence, never a decimal, so nothing is lost to rounding on the way through.

List your loads

GET https://app.haulageboard.com/api/v1/loads?status=POSTED
Authorization: Bearer hb_live_...

Newest first, up to a hundred. You see loads your firm is on at either end, the ones you posted and the ones you won, and nothing else whatever you ask for.

Read one back

GET https://app.haulageboard.com/api/v1/loads/{id}
Authorization: Bearer hb_live_...

{
  "load": {
    "ref": "HB-1042",
    "status": "BOOKED",
    "termsDays": 30,
    "podUrl": "/files/...",
    "quotes": [
      { "id": "...", "amountPence": 24500, "status": "ACCEPTED", "createdAt": "..." }
    ]
  }
}

Quotes come cheapest first. A load your firm is on neither end of answers 404 rather than 403, so nobody can work out which loads exist by asking.

Statuses

POSTEDOn the board, taking quotes
BOOKEDA carrier has it
IN_TRANSITCollected
DELIVEREDDelivered, proof of delivery in
CONFIRMEDThe poster has confirmed it
CANCELLEDCalled off
EXPIREDCollection date passed with nobody booked
DISPUTEDSomething went wrong and both sides are being heard

Do not poll for these. Use webhooks, and the status arrives as it happens.