Confirm a booking
Turn a draft booking into a real one. You name the courier from your quote, a pickup date and the payment method; Transdirect charges the payment method and sends the booking to the courier.
POST /api/v5/bookings/{id}/confirmRequires your API key in the api-key header.
Before you confirm
Section titled “Before you confirm”Make sure both the sender and the receiver have the following. Send them in your quote request, or add them with update a booking:
name,email,phoneandaddresscompany_name, when the addresstypeisbusiness- a valid suburb, state and postcode (for Australian addresses)
Confirm checks these and refuses the booking if any are missing. Also send a goods_description (what is inside the parcels): a booking without one is held for a check before it goes to the courier.
Path parameters
Section titled “Path parameters”| Parameter | Type | Description |
|---|---|---|
id | integer | The Transdirect booking id from your quote. Not your order number. |
Request body
Section titled “Request body”Send JSON with Content-Type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
courier | string | Yes | The key of the quote you chose in the quote response’s quotes object, for example couriers_please or tnt_road_express. |
pickup_date | string | Yes, in practice | YYYY-MM-DD. Must be one of that quote’s pickup_dates. Leaving it out fails with Pickup dates invalid. pickup-date is accepted too. |
pickup_time | string | No | Pickup window as HH:MM-HH:MM, for example 09:00-16:00. See pickup times. pickup-time is accepted too. |
payment_method | string | No | nab_<id> or paypal_<id> from list payment methods, credit, or demo. Leaving it out bills your credit account. See payments. |
payment | object | No | The same choice as an object: {"method":"card","card_id":4821}, {"method":"paypal","agreement_id":377}, {"method":"credit"} or {"method":"demo"}. If you send both payment and payment_method, they must agree. |
batch | boolean | No | true to use Pay at end of day for a card or PayPal payment. |
tier | integer | No | A frequent-rate tier from the quote’s tiers[].identifier. See frequent rates. |
fedex_document_type | string | No | FedEx international document services only: business_correspondence, legal_contracts, bank_financial, marketing_materials, government_official or other_documents. Without it the shipment is declared as printed business documents and held for a check before it goes to FedEx. |
agreed_terms | boolean | No | Records that the Transdirect terms were accepted for this booking. You accepted them when you created your API key, so this is optional. |
agreed_warranty | boolean | No | Records that the courier’s transit warranty terms were accepted for this booking. Optional, as above. |
For acceptance fields, false, "false", 0, "0", "no" and "off" record no explicit acceptance. true, "true" and 1 record acceptance.
Other fields are ignored. Raw card details (card_number, cvv and similar) are refused.
Pickup times
Section titled “Pickup times”- Leave
pickup_timeout to use the courier’s standard window from the quote. Whenpickup_dateis today, the default is the first window still open today instead. If no window is still open today, the confirm fails with400and you need a laterpickup_date. - For couriers with a fixed window, such as Couriers Please and Aramex, any value is replaced by that window.
- Otherwise the window must fit the quote: start at one of
pickup_ready_from_times, end at one ofpickup_last_available_times, and be at leastpickup_window.minWindowMinuteslong. Older courier integrations instead check that it falls inside the quote’spickup_time.fromandpickup_time.to.
To refresh pickup options without quoting again, use pickup availability.
Example request
Section titled “Example request”curl -X POST https://api.transdirect.com.au/api/v5/bookings/623630/confirm \ -H "api-key: $TD_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "courier": "couriers_please", "pickup_date": "2026-10-19", "pickup_time": "09:00-16:00", "payment_method": "nab_4821" }'import { client, postApiV5BookingsByIdConfirm } from '@transdirect/api-sdk';
client.setConfig({ headers: { 'api-key': process.env.TD_API_KEY! } });
const { response, error } = await postApiV5BookingsByIdConfirm({ path: { id: '623630' }, body: { courier: 'couriers_please', pickup_date: '2026-10-19', pickup_time: '09:00-16:00', payment_method: 'nab_4821', },});
if (response.status !== 204) { console.error(response.status, error);}To test without paying, confirm with "courier": "demo" and "payment_method": "demo". See demo mode.
Response
Section titled “Response”204 No Content with an empty body. The booking is paid and on its way to the courier.
Then:
- Get the booking to follow
status_codetoconfirmedand read the connote. - Get the label when it is ready.
- Track the shipment after pickup.
Transdirect prices the booking again at confirm from its current details, and charges that amount.
Retries
Section titled “Retries”A confirm that names a payment method is safe to retry: if the booking is already paid, you get 204 again and nothing is charged twice. A confirm without one returns 400 {"errors":["Cannot update. Booking has been processed."]} once the booking is paid. See retrying a confirm safely.
Errors
Section titled “Errors”| Status | Body | Cause |
|---|---|---|
400 | {"errors":{"sender":{"phone":["Required"]},"receiver":{"email":["Required"]}}} | Sender or receiver details are missing or invalid. Each field lists its problems, such as Required, Invalid Value, Invalid Suburb or Invalid AU Postal Code. |
400 | {"errors":["Courier not currently supported"]} | courier is not a courier your key can book. Use a key from the quote’s quotes object. |
400 | {"errors":["No available quote from the chosen courier"]} | The courier no longer quotes this booking with its current details. Quote again. |
400 | {"errors":["Pickup dates invalid."]} | pickup_date is missing or is not in the courier’s pickup_dates. |
400 | {"errors":{"pickup_date":"No pickup window is still available today for TNT Road Express. Choose a later pickup-date."}} | pickup_date is today, but the courier has no pickup window still open today. Confirm with a later date from pickup_dates. |
400 | {"errors":{"pickup_time":"Invalid pickup window: Ready From / Last Time Available must follow this carrier's spec."}} | pickup_time does not fit the courier’s window. Older courier integrations return {"errors":{"pickup_time":"Invalid pickup time, must be with in the range of 09:00 and 17:00"}} instead, naming the quote’s window. |
400 | {"errors":["Cannot update. Booking has been processed."]} | The booking is already paid, and the request did not name a payment method. |
400 | {"success":false,"error":{"name":"ZodError","message":"..."}} or {"error":{"name":"ZodError","issues":[{"path":["courier"],"code":"invalid_type","message":"..."}]},"requestId":"..."} | The body failed validation: courier missing, a malformed payment_method, raw card details, or payment and payment_method that disagree. |
400 | Malformed JSON in request body (plain text) | The body sent with Content-Type: application/json is not valid JSON. |
401 | {"error":"missing_api_key"} or {"error":"invalid_api_key"} | No key, or a key that is not active. |
402 | {"errors":{"payment":["..."]},"payment_error":{"code":"...","user_message":"...","log_id":null,"method":"card"}} | The payment could not be completed. See payment errors. |
403 | {"error":"...","access_error":{"code":"NO_PAYMENT_METHOD","user_message":"..."}} | Nothing was charged: no credit account, credit limit reached, or API booking switched off. See 403 codes. |
404 | {"error":"booking_not_found"} | No booking with that id belongs to your account. |
409 | {"message":"This order can no longer be booked. Refresh your orders and try again."} | The booking is linked to an imported order that has already been booked or closed. |
422 | {"error":"tail_lift_unavailable","code":"TAIL_LIFT_UNAVAILABLE","message":"...","courier":"...","reason":"weight"} | The courier cannot take these items with the tail lift you asked for. reason is weight, dimensions or both. Choose another courier, or remove the tail lift if a forklift is available. |
429 | {"error":"rate_limited"} | More than 600 requests a minute on this key. Wait for the retry-after seconds. |
500 | {"errors":"Booking confirmation failed."} | Something failed inside Transdirect. Get the booking before retrying, in case it went through. |
Try it
Section titled “Try it”Open the API Explorer, add a demo-enabled key, and find Confirm a booking. Confirm with demo to try it without a charge.