API introduction
The Transdirect API is a standard REST API with JSON responses for instant live quoting, booking, label generation, and tracking across 30+ couriers.
There are two API generations, both live today:
- v5 — the recommended path for new integrations. Served from
https://api.transdirect.com.auwith the version in the path (/api/v5/...). It ships an official typed TypeScript SDK (@transdirect/api-sdk), a published OpenAPI spec at/openapi.json, and an interactive API Explorer generated from the same spec. - v4 — the existing API at
https://www.transdirect.com.au/api. It is fully supported: every current v4 integration keeps working, and the reference pages on this site document it in full.
Which should I use?
Section titled “Which should I use?”New integration: use v5. You get typed request/response shapes from the SDK
(generated from the OpenAPI spec, so types never drift from what the API
actually accepts), a machine-readable spec, and the Explorer to try calls
interactively. Existing v4 integration: stay put — v4 is fully supported, and
because the v5 booking routes mirror the v4 shapes (/api/v5/bookings/v4/...),
your mental model carries over whenever you choose to migrate. The full
comparison lives at v4 vs v5 — which should I use?.
Key details
Section titled “Key details”| Detail | v5 | v4 |
|---|---|---|
| Base URL | https://api.transdirect.com.au | https://www.transdirect.com.au/api |
| Version in path | /api/v5/... | /v4 on booking routes only (e.g. /api/bookings/v4/{id}) |
| Authentication | Api-Key header | Api-Key header or HTTP Basic (email + password) |
| Typed SDK | @transdirect/api-sdk | — |
| Format | JSON | JSON |
| Content-Type | application/json | application/json |
| Date format | ISO 8601 (e.g. 2025-08-27T14:00:00+1000) | ISO 8601 |
| Currency | AUD | AUD |
Important notes
Section titled “Important notes”Access model
Section titled “Access model”API access is open by default, on both API generations. As soon as you have an API key you can:
- Get quotes for any route immediately — no approval step.
- Make live bookings as long as you can pay for them (see below).
A booking becomes live when one of the following is true:
- You supply a saved
payment_method(credit card or PayPal) and it charges successfully, or - You have a Transdirect credit account with available credit (the default when
payment_methodis omitted), or - You explicitly mark the booking as a demo.
If none of these apply, the booking is refused with a 403 Forbidden and an actionable message asking you to add a payment method or set up a credit account. A credit-account booking that would take you past your limit is refused the same way, with CREDIT_LIMIT_REACHED. There is no longer a manual “validate your account to enable API access” step.
Note that a credit account is a separate arrangement most accounts do not have — having a card saved is not the same thing. If you have no credit account you must nominate a saved method in the request, using an id from GET /api/members/payment-methods. See how payments work.
Demo mode
Section titled “Demo mode”Demo mode works the same way on v4 and v5: it is a flag on your normal API
key, not a separate sandbox key. You can check whether it is on via
GET /bookings/v4/api_details.
You can confirm any booking as a demo (sandbox) booking — no charge, no
courier transmission — by passing payment_method: "demo" when
creating/confirming. Demo bookings:
- Are placed on the synthetic Demo courier and receive a
DEMO-XXXXXXXXconnote. - Produce a watermarked test label.
- Incur no charge and are never sent to a real courier.
See create a booking and confirm a booking for usage.
Rate limits
Section titled “Rate limits”The two generations enforce different limits and signal them differently.
Both return 429 Too Many Requests with a retry header when you exceed a
limit — but the numbers, headers, and error bodies below are version-specific.
v5 rate limits
Section titled “v5 rate limits”- Authenticated requests (
Api-Keyheader): 600 requests / minute. - Anonymous quotes: 10 per hour. To lift this, sign up for a member account and send your API key with each request — the 429 message says the same.
When you are limited, v5 responds with a lowercase retry-after header
(seconds to wait) and one of these JSON bodies:
{ "error": "rate_limited" }{ "error": "rate_limited_anonymous_quotes", "message": "...", "window_seconds": 3600}The message on the anonymous-quotes body tells you the fix directly: sign up
and send your API key.
v5 does not emit X-RateLimit-* headers — those are a v4 behaviour.
v4 rate limits
Section titled “v4 rate limits”v4 enforces two complementary limits per identity. An identity is your authenticated member account (when using Basic auth or an API key) or your IP address (for unauthenticated requests).
Requests per minute:
| Identity | Limit |
|---|---|
| Authenticated member | 60 requests / minute |
| Unauthenticated (per IP) | 30 requests / minute |
Concurrent in-flight requests:
| Identity | Limit |
|---|---|
| Authenticated member | 50 simultaneous requests |
| Unauthenticated (per IP) | 25 simultaneous requests |
The concurrency limit prevents a single integration from monopolising server resources by holding many long-running requests open at once. If your application needs to issue many quote requests, run them in batches that respect this limit rather than firing all of them in parallel.
Successful v4 responses include headers so you can track your usage:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Requests that exceed either v4 limit return 429 Too Many Requests with a
Retry-After header and a JSON error body:
{ "message": "Rate limit exceeded. Try again in 47 seconds.", "code": 429}Reading a 401
Section titled “Reading a 401”A 401 body carries a message that says which of the two problems you have:
- “No credentials were supplied…” — nothing we authenticate with reached the
API. If your client is setting a key, it is going out under the wrong header
name; where we can tell which one you used (
X-Api-Key,Apikey) the message names it. v4 reads the key fromApi-Key— anAuthorization: Bearerheader is not a scheme it accepts and is dropped before it reaches the application, so it looks the same as sending nothing. - “The credentials supplied were rejected…” — the key arrived and was not accepted. Check it is active and belongs to a live account.
Failed authentication
Section titled “Failed authentication”Each API key also has an authentication circuit breaker: 10 failed
authentication attempts within 5 minutes returns 429 Too Many Requests with
Retry-After: 300. If you see this, fix the credentials rather than retrying —
the window resets after five minutes.
Best practices
Section titled “Best practices”These apply on both generations:
- Implement exponential backoff and respect the retry header on any
429 - Cache quote results where possible rather than re-requesting
- Poll tracking at most every 5 minutes (there is no public tracking webhook)
- Run bulk operations sequentially or in small parallel batches rather than firing everything at once
Error responses
Section titled “Error responses”Errors are returned as JSON with an appropriate HTTP status code:
{ "error": "Invalid postcode", "message": "The sender postcode '0000' is not a valid Australian postcode."}| Status code | Meaning |
|---|---|
400 | Bad request — check your request body |
401 | Unauthorised — the message distinguishes credentials that were rejected from credentials that never arrived |
402 | Payment declined — the response includes a payment_error object |
403 | Forbidden — no payment capability, credit limit reached, or API access disabled (access_error object) |
404 | Not found — the booking or resource doesn’t exist |
422 | Unprocessable entity — validation errors |
429 | Rate limited — respect the Retry-After header |
500 | Server error — contact support if this persists |
Next steps
Section titled “Next steps”- Decide between the two generations: v4 vs v5 — which should I use?
- Set up authentication
- Install the typed TypeScript SDK (v5)
- Create your first booking/quote
- Understand the booking lifecycle