Reference for the Fare Freight Public API: live carrier rate quotes, plus consignment booking, manifesting and document downloads for orders already in Fare Freight. This page is the authoritative field-by-field reference.
| Rate base URL | ffspaurate.farefreight.com.au |
| Shipment base URL | any.farefreight.com.au |
| Auth header | X-FF-Secret-Key |
| Format | JSON, snake_case |
| Doc ref | FF-PUBRATE-API-v1 |
| Effective | 13 Sep 2026 |
The base URL is live production. A request may call real carrier rate APIs and is logged against the live account. Talk to your account manager before load-testing or running automated test suites.
Every request carries a per-account secret key in the X-FF-Secret-Key header. Fare Freight provisions one key per accountId when your integration is set up.
| Header | Value |
|---|---|
| X-FF-Secret-Key | Your account’s secret key, issued by Fare Freight. Treat it like a password — don’t expose it in client-side/browser code. |
A missing or incorrect key returns 401 with no response body. If you believe your key is compromised, contact Fare Freight to have it rotated — there is currently no self-service rotation.
| Convention | Detail |
|---|---|
| Money | Whole cents, as an integer or integral number (e.g. 4999 = $49.99). |
| Weight & dimensions | Managed entirely server-side from your product catalog — not something you send or compute. |
| Dates | ISO 8601 with a UTC offset, e.g. 2026-09-16T00:00:00+10:00. |
| State/territory | Standard AU abbreviations: NSW, VIC, QLD, WA, SA, TAS, ACT, NT. |
| Field casing | snake_case in every request and response body. |
| Method | Path | Host | Description |
|---|---|---|---|
| POST | /api/public/rate/{accountId} | ffspaurate.farefreight.com.au | Returns quotes for one cart/shipment. |
| POST | /api/public/consignment/{accountId} | any.farefreight.com.au | Book a consignment with the chosen carrier. |
| POST | /api/public/consignment-manifest/{accountId} | any.farefreight.com.au | Book a consignment and manifest it in one call. |
| POST | /api/public/manifest/{accountId} | any.farefreight.com.au | Manifest already-booked orders. |
| POST | /api/public/download/connote/{accountId} | any.farefreight.com.au | Download connotes as one merged PDF. |
| POST | /api/public/download/manifest/{accountId} | any.farefreight.com.au | Download manifests as one merged PDF. |
| POST | /api/public/download/label/{accountId} | any.farefreight.com.au | Download labels as one merged PDF. |
Returns quotes for one cart/shipment. {accountId} is the integer account ID Fare Freight assigned you.
| Header | Notes | |
|---|---|---|
| Content-Type | required | Always application/json. |
| X-FF-Secret-Key | required | See Authentication. |
| X-FF-Event-Type | optional | Free-text label for your own logs on our side. Defaults to FRESH_ORDER. |
| X-FF-Order-Id | optional | Your internal order ID (integer), attached to our request log for tracing. |
| X-FF-Order-Number | optional | Your internal order number (string), same purpose as above. |
The body is a single rate object. Every field below is either enforced (you’ll get a 400 without it) or genuinely used in rating — nothing decorative is required.
Don’t bother computing weight or dimensions. items[].variant_id is matched against the product catalog configured on your Fare Freight account — weight, dimensions and freight class are always looked up from there and override anything you send, box path or not.
rate.origin & rate.destination
| Field | Type | Notes | |
|---|---|---|---|
| postal_code | required | string | Australian postcode. Destination is capped at 20 characters. |
| city | required | string | Suburb / locality. |
| province | required | string | State/territory code — NSW, VIC, QLD, WA, SA, TAS, ACT or NT. Sent straight to almost every connected carrier for zone rating; there’s no fallback if it’s missing, so the quote is either wrong or rejected. |
| required on destination | string | Needed if your account has any customer-specific pricing rule configured. Not required on origin. | |
| country | optional | string | Assumed AU. |
| address1 / address2 | optional | string | Street address. Used by some carriers (BigPost, MachShip, Allied Express, Mothership) for consignment details; others rate on postcode/suburb/state alone. |
| name / company_name | optional | string | Passed through to carrier consignment labels where applicable. |
| address_type | optional | string | Residential or Business — overrides your account’s default delivery-type assumption. |
rate.items[]
| Field | Type | Notes | |
|---|---|---|---|
| variant_id | required | integer | Must match a variant configured in your Fare Freight product catalog. |
| quantity | required | integer | >= 1. |
| price | required | number | Line unit price, in cents. Drives free-shipping/margin/discount rule thresholds — a missing price is treated as $0 and silently skews any configured rule, so don’t omit it even though nothing forces the correct value. |
| product_id | optional | integer | Not used for rating. |
| name / sku | optional | string | Logging only. |
| properties._address_type | optional | string | Per-item override: Residential / Business. |
| properties._liftgate_delivery | optional | string | Per-item override: Y / N. |
rate.order_totals
| Field | Type | Notes | |
|---|---|---|---|
| subtotal_price | required | number | Sum of price × quantity across items[], in cents. Used to detect a split-shipment request (one of several parcels for the same order) — get it wrong and the wrong rate bucket gets returned. |
| total_price | optional | number | Accepted, not currently used in rating. |
| discount_amount | optional | number | Accepted, not currently used in rating. |
rate.currency and rate.locale are both optional and currently unused — the currency returned in the response comes from your account’s own configuration, not the request.
A successful call always returns 200 — including when rates comes back empty. An empty array means no configured carrier could quote this address/cart, not an error; don’t treat it as a failure in your integration.
| Field | Type | Notes |
|---|---|---|
| service_name | string | Display name for the quoted service. |
| service_code | string | Stable identifier for the quoted service — keep it on your order record if you need to reference which quote was chosen. |
| total_price | integer | Total price in cents. |
| currency | string | Always your account’s configured currency (typically AUD). |
| description | string | Human-readable delivery description, where configured. |
| min_delivery_date / max_delivery_date | string or null | ISO 8601 with offset. Only populated for carriers with delivery-date estimation enabled on your account; null otherwise. |
Rates are sorted cheapest first.
| Status | Meaning | Body |
|---|---|---|
| 400 | A required field is missing or invalid. See errors[] for exactly which. | {“errors”: […]} |
| 401 | Missing or incorrect X-FF-Secret-Key for that accountId. | empty |
| 429 | Rate limit exceeded. Response carries a Retry-After header. | empty |
| 500 | Unexpected server-side error. Safe to retry once with backoff; contact us if it persists. | Spring default error JSON |
Field names in errors[] follow the request’s Java structure (camelCase, e.g. variantId), not the snake_case spelling you send in JSON (variant_id). Match on the trailing field name if you’re parsing these programmatically.
These endpoints book, manifest and download documents for orders that already exist in Fare Freight (the orders synced from your Shopify store), identified by their fulfilment_order_id. They live on any.farefreight.com.au — a different host from the rate endpoint above — and use the same credentials: your accountId in the path and the X-FF-Secret-Key header. A missing or wrong key returns a bodyless 401.
| Method | Path | Description |
|---|---|---|
| POST | /api/public/consignment/{accountId} | Book a consignment with the chosen carrier. |
| POST | /api/public/consignment-manifest/{accountId} | Book a consignment and manifest it in one call. |
| POST | /api/public/manifest/{accountId} | Manifest already-booked orders. |
| POST | /api/public/download/connote/{accountId} | Download connotes as one merged PDF. |
| POST | /api/public/download/manifest/{accountId} | Download manifests as one merged PDF. |
| POST | /api/public/download/label/{accountId} | Download labels as one merged PDF. |
| status | HTTP | Meaning |
|---|---|---|
| SUCCESS | 200 | Done. |
| ERROR | 422 | The carrier or Fare Freight rejected the request (e.g. already booked, already manifested). message says why. |
| Status | Meaning | Body |
|---|---|---|
| 400 | Invalid payload, or an unknown fulfillment_type. | {“errors”: […]} / {“error”: “…”} |
| 401 | Missing/incorrect secret key, or the account isn’t active. | empty |
| 404 | A fulfilment_order_id doesn’t exist on your account, or (downloads) no document is available yet. | {“error”: “…”} |
| 409 | (Manifest) an order that hasn’t been booked yet. | — |
| 422 | Carrier/Fare Freight rejected it. | — |
| 502 | The carrier rejected or returned an unreadable document. Retry shortly. | {“error”: “…”} |
Same body for both. Books the order with the carrier connection you select. Supported carriers: NFM, MachShip, BigPost, KIS, Direct Freight, Allied Express and Australia Post. The body mirrors what the Fare Freight app sends when you book from the Orders screen.
Where the quote and carrier ID come from. quote is the service you selected from a Fare Freight consignment quote, and quote.ff_carrier_id is the ID of the carrier connection (Carrier Connections in the app) that should book it. The other quote fields are carrier-specific and passed through unchanged — send the quote exactly as it was returned.
| Field | Type | Notes | |
|---|---|---|---|
| fulfilment_order_id | required | integer | The Fare Freight fulfilment order to book. |
| quote | required | object | See above. |
| pickup_date | required | string | YYYY-MM-DD. |
| from_time / to_time | required | string | Pickup window, 24-hour HH:mm. |
| pickup_address | required | object | location_id (integer), city, zip, province_code required; name, address1, address2, province, country optional. |
| delivery_address | required | object | address1, city, zip, province_code, customer_name required; address2, country, phone, email, company optional. |
| items[] | required | array | At least one. |
Once an order has a connote number, booking it again as New Label is refused with 422 (“already been booked with consignment …”), so retrying after a timeout won’t double-book it — only a deliberate Reship/Return with confirm_duplicate_label creates a second booking.
consignment-manifest is not available for BigPost (BigPost has no manifest step): it returns 422 before booking anything — use consignment on its own for BigPost orders.
Supported carriers: NFM, MachShip, KIS, Direct Freight, Allied Express (no separate manifest step — the order is simply marked manifested) and Australia Post.
Up to 100 orders per call. If any carrier group fails you get 422 with each failure in message (for example MACHSHIP: This order has already been manifested with manifest ID …), and orders shows which orders did get manifested. An order that hasn’t been booked yet returns 409.
Same body as the manifest call. The response is a single merged application/pdf (as a file attachment) covering every requested order; on failure you get a JSON error instead.
| Document | Available for |
|---|---|
| label | NFM, MachShip, Direct Freight, KIS, Allied Express, Australia Post |
| connote | NFM, MachShip, Allied Express, Australia Post |
| manifest | NFM, MachShip, KIS |
Requesting a document a carrier doesn’t produce returns 422. A 404 means the carrier has nothing yet — for a manifest, the order usually hasn’t been manifested. Orders on different carriers are merged into the one PDF in request order, grouped by carrier.
Each account is limited to a burst of 30 requests, refilling at a sustained 60 requests per minute (~1/second). Once exhausted, further calls get 429 with a Retry-After: 60 header until the bucket refills.
These defaults are set for typical integration volume. If your expected call volume is significantly higher (e.g. a live storefront checkout rather than backend/batch calls), let your account manager know so we can size your account’s limit accordingly — this is a per-account setting, not a fixed platform ceiling.
The shipment endpoints have their own per-account allowance with the same limits (burst of 30, sustained 60 per minute) — calls to one don’t use up the other’s.
For credentials, catalog setup, rate-limit adjustments, or anything behaving unexpectedly, contact your Fare Freight account manager.
Fare Freight · Public API · v1 · Doc ref FF-PUBRATE-API-v1 · Effective 13 Sep 2026