Skip to content

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}/confirm

Requires your API key in the api-key header.

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, phone and address
  • company_name, when the address type is business
  • 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.

ParameterTypeDescription
idintegerThe Transdirect booking id from your quote. Not your order number.

Send JSON with Content-Type: application/json.

FieldTypeRequiredDescription
courierstringYesThe key of the quote you chose in the quote response’s quotes object, for example couriers_please or tnt_road_express.
pickup_datestringYes, in practiceYYYY-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_timestringNoPickup window as HH:MM-HH:MM, for example 09:00-16:00. See pickup times. pickup-time is accepted too.
payment_methodstringNonab_<id> or paypal_<id> from list payment methods, credit, or demo. Leaving it out bills your credit account. See payments.
paymentobjectNoThe 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.
batchbooleanNotrue to use Pay at end of day for a card or PayPal payment.
tierintegerNoA frequent-rate tier from the quote’s tiers[].identifier. See frequent rates.
fedex_document_typestringNoFedEx 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_termsbooleanNoRecords that the Transdirect terms were accepted for this booking. You accepted them when you created your API key, so this is optional.
agreed_warrantybooleanNoRecords 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.

  • Leave pickup_time out to use the courier’s standard window from the quote. When pickup_date is today, the default is the first window still open today instead. If no window is still open today, the confirm fails with 400 and you need a later pickup_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 of pickup_last_available_times, and be at least pickup_window.minWindowMinutes long. Older courier integrations instead check that it falls inside the quote’s pickup_time.from and pickup_time.to.

To refresh pickup options without quoting again, use pickup availability.

Terminal window
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.

204 No Content with an empty body. The booking is paid and on its way to the courier.

Then:

  1. Get the booking to follow status_code to confirmed and read the connote.
  2. Get the label when it is ready.
  3. Track the shipment after pickup.

Transdirect prices the booking again at confirm from its current details, and charges that amount.

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.

StatusBodyCause
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.
400Malformed 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.

Open the API Explorer, add a demo-enabled key, and find Confirm a booking. Confirm with demo to try it without a charge.