We have a brand new API docs site at developers.sendle.com!

Go there to see the new Developer Hub including improved explanations, diagrams, and more up-to-date information!

NAV Navbar
Logo

Introduction

Welcome to the Sendle API!

You can use our Application Programming Interface (API) to book Sendle parcels, manage shipping, and oversee past and present orders any way you like!

example of a Sendle API call using Curl:

  curl 'https://api.sendle.com/api/quote?pickup_suburb=Wonglepong&pickup_postcode=4275&delivery_suburb=Foul%20Bay&pickup_country=AU&delivery_postcode=5577&delivery_country=AU&weight_value=2.0&weight_units=kg&volume_value=0.01&volume_units=m3'
  -H 'Content-Type: application/json'

Sendle API uses JSON. You can view code examples in the rightmost column.

For all examples in this guide, we will be using cURL from the command line, but you are encouraged to make requests in whichever method you are most comfortable with.

API Endpoints

The Sendle API services different tasks which can be accessed through GET, POST, or DELETE requests through specific urls.

endpoint request task
/api/ping GET Connection Test
/api/quote GET Quoting
/api/orders POST Booking Orders
/api/orders/{id} GET View Order {id}
/api/{label_url} GET View a Label
/api/tracking/{ref} GET Track a Parcel
/dashboard/prepare_form - Prepare Form URL

Getting Started

Requests should be made with the following headers:

  Content-Type: application/json
  Accept: application/json

cURL authorization looks like:

 -U "sendleAPI:42RRTjYz5Z4hZrm8XY3t4Vxt"

Before anything else, you will need to have a Sendle Account

From the Sendle Dashboard visit the Settings tab from the sidebar. Visit your Integrations tab to get your Sendle ID and your API Key.

Requests to the API require the use of HTTP Basic Authentication using your account’s Sendle ID as the user name and your API key as the password.

API Settings

Be sure to use Sendle’s sandbox environment for testing first! (See below for more)

Sandbox Server

Sendle provides access to a sandbox server at https://sandbox.sendle.com. You will need to create a new account for the sandbox server – just like you did for Sendle and set up a sandbox credit card.

Any orders created on the sandbox server will be created in the test mode, they will not result in actual consignments that can be used to send a parcel. Using a valid credit card in Sandbox will not work, so please review Stripe’s test credit card numbers (below).

Create an Account

Response Without Email Confirmation

  {
    "error": "precondition_failed",
    "error_description": "The account associated with this API key has not yet had the email confirmed. Please check your email and confirm the account, or visit your Sendle Dashboard to resend the confirmation email."
  }

Response Without Dangerous Goods Terms Accepted

  {
    "error": "precondition_failed",
    "error_description": "The account associated with this API key has not accepted the dangerous goods terms. Please visit your Account Settings in your Sendle Dashboard to view and accept these terms."
  }

To create orders with the Sendle API you must make sure you have confirmed your email address. To do this, check your inbox for the email and click the confirmation link.

You must also accept the dangerous goods terms in your Pickup Settings.

Set Up Payments

Response Without Payment Details

  {
    "error": "payment_required",
    "error_description": "The account associated with this API key has no method of payment. Please go to your Account Settings in your Sendle Dashboard and add a payment method."
  }

To use the Sendle API you need to attach a credit card in the currency you are going to be creating orders for to your Sendle account for invoicing. You can do this on the Billing page of your Sendle Dashboard.

If you are creating orders in Australia, you will need to have an AUD Credit Card set up, or if you are creating orders in the US you will need to have a USD Credit Card set up in your billing account to create an order in the relevant currency.

Ping Server

GET /api/ping

[ GET /api/ping ]

Status 200:

  {
    "ping": "pong",
    "timestamp": "2018-04-05T15:52:48+10:00"
  }

The ping endpoint has been specifically created so that you can test out some of the more administrative aspects of our API’s functionality, without any risk of creating live orders on our system.

You can use it to test:

Other endpoints can be quite complex, and it is easier to determine what kind of error has occurred if the test-endpoint doesn’t do much. Thus, ping returns a very simple response.

It returns a simple ping/pong key-pair, and a timestamp showing when the response was generated on our system.

Testing Account settings

If you have not yet confirmed the email on your account, set up payment settings or accepted the dangerous goods terms, the ping-response will give the relevant errors. This is as opposed to other ‘public’ endpoints such as the quote-request endpoint.

Thus, ping can be useful for testing whether your settings are valid before trying out the order-creation endpoint.

See Getting started for more details on these settings and the relevant error messages.

Testing Authentication

All API interactions will require your Sendle ID and your API Key as username and password for HTTP Basic Authentication (Make sure to replace sendleID and APIKey with your Sendle ID & API key.)

  curl 'https://api.sendle.com/api/ping'
  -u sendleID:APIKey
  -H "Content-Type: application/json"
  -H "Accept: application/json"

Sendle uses your Sendle ID together with your own API Key to grant access to the server. Together this allows you to access the API so that you may book and follow up with orders, as well as view past orders you have sent or received.

You must include your credentials in every request, or you will be denied. If you only you include your Sendle ID, you will be prompted to enter your API key (password).

Status 200:

  {
    "ping": "pong",
    "timestamp": "2018-04-05T15:52:48+10:00"
  }

When the api receives a request with a Sendle ID and an API Key the server responds with a JSON string containing the relevant details.

Without credentials

  curl 'https://api.sendle.com/api/ping'

Response:

  HTTP Basic: Access denied.

Response With incorrect Credentials:

  {
    "error": "unauthorised",
    "error_description": "The authorisation details are not valid. Either the Sendle ID or API key are incorrect."
  }

Testing Idempotency keys

Repeating a request without idempotency

  curl 'https://api.sendle.com/api/ping'
  -u sendleID:APIKey
  -H "Content-Type: application/json"
  -H "Accept: application/json"

Responses will all be different:

  {"ping": "pong","timestamp": "2018-04-05T15:52:48+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:50+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:51+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:52+10:00"}

Repeating a request with the same idempotency-key

  curl 'https://api.sendle.com/api/ping'
  -u sendleID:APIKey
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -H "Idempotency-Key: 6f4aba46-91d4-6ef3-af23-f523375ed5f6"

Responses will all be the same:

  {"ping": "pong","timestamp": "2018-04-05T15:52:48+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:48+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:48+10:00"}
  {"ping": "pong","timestamp": "2018-04-05T15:52:48+10:00"}

The ping endpoint contains a timestamp in the response so that you can test idempotency and check that it is working.

You will know that the idempotency-key is successfully working because if you keep requesting with the same key, you will get the same timestamp back.

Getting Quotes

GET /api/quote

[GET /api/quote]

Empty Request

  curl 'https://api.sendle.com/api/quote'

Response

  {
    "messages": {
      "pickup_suburb": ["can't be blank"],
      "pickup_postcode": ["can't be blank"],
      "delivery_suburb": ["can't be blank"],
      "delivery_postcode": ["can't be blank"],
      "weight": {
        "value": ["is not a number"],
        "units": ["can't be blank"]
      }
    },
    "error": "unprocessable_entity",
    "error_description": "The data you supplied is invalid. Error messages are in the messages section. Please fix those fields and try again."
  }

Authenticated Request (recommended)

  curl 'https://api.sendle.com/api/quote?pickup_suburb=Camberwell%20North&pickup_postcode=3124&pickup_country=AU&delivery_suburb=Barangaroo&delivery_postcode=2000&delivery_country=AU&weight_value=2.0&weight_units=kg&volume_value=0.01&volume_units=m3' \
    -u "sendleID:APIKey"
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json'

200 Response

  [
    {
      "quote": {
        "gross": {
          "amount": 13.95,
          "currency": "AUD"
        },
        "net": {
          "amount": 12.68,
          "currency": "AUD"
        },
        "tax": {
          "amount": 1.27,
          "currency": "AUD"
        }
      },
      "plan_name": "Premium",
      "eta": {
        "days_range": [0, 4],
        "date_range": ["2018-02-13", "2018-02-19"],
        "for_pickup_date": "2018-02-13"
      }
    }
  ]

Request with plan_name (deprecated)

  curl 'https://api.sendle.com/api/quote?pickup_suburb=Camberwell%20North&pickup_postcode=3124&pickup_country=AU&delivery_suburb=Barangaroo&delivery_postcode=2000&delivery_country=AU&weight_value=2.0&weight_units=kg&volume_value=0.01&volume_units=m3&plan_name=Premium' \
  -H 'Content-Type: application/json'

200 Response

  [
    {
      "quote": {
        "gross": {
          "amount": 13.95,
          "currency": "AUD"
        },
        "net": {
          "amount": 12.68,
          "currency": "AUD"
        },
        "tax": {
          "amount": 1.27,
          "currency": "AUD"
        }
      },
      "plan_name": "Premium",
      "eta": {
        "days_range": [0, 4],
        "date_range": ["2018-02-13", "2018-02-19"],
        "for_pickup_date": "2018-02-13"
      }
    }
  ]

The quoting API operates in three modes, two of which are deprecated:

  1. (Recommended) Requesting a quote with your Sendle ID and API key will return the quote for the relevant account’s plan only.
  2. (Deprecated) Requesting a quote without providing your Sendle ID and API key will return all quotes for all publicly available plans.
  3. (Deprecated) Requesting a quote without providing your Sendle ID and API key, but providing a plan_name will return a quote for just that plan.

Modes 2 and 3 are deprecated and will be removed in a future version. All new integrations should make authenticated quote requests (mode 1), as this ensures the API always returns the right quote for the account, even if the plan changes.

The ? after the quote endpoint initiates the query. Be sure to separate terms using <name>=<value> pairs in your request and use percent-encoding for all spaces or special characters in your query string like the example (right). If you need more information on GET & POST requests, the Treehouse blog has a nice summary.

For specific information about weight limits and parcel sizing, visit the Weights and Dimensions section.

The response also returns an approximate eta. The eta assumes the parcel is being picked up or dropped off on the next available business day. The eta section contains the approximate number of business days the parcel is likely to arrive, and the dates this corresponds to, as well as the assumed pickup/dropoff date.

The currency returned will be the relevant currency for the origin of the quote. When sending from Australia this will be AUD and when sending from the US this will be USD. This is the currency you will be charged in.

Parcels can be ‘picked up’ from a home or business address, or they can be 'dropped off’ at a Hubbed location (in Australia) or a USPS store (in the US). The availability of both varies on location, but generally we offer both services in Australia, and just drop off for now in the United States.

Fields in a successful response

Field Description
quote Section: contains all the pricing of the quote.
gross Pricing including taxes (if applicable).
net Pricing exclusive of taxes (if applicable).
tax Any applicable taxes.
plan_name The name of the plan for which this is the price.
eta Section: contains eta-relevant data
days_range How long delivery is likely to take expressed as a range. Always returned as an array. If there are two values, these are the min and max estimated days it will take. If only one number - it’s estimated to take about this long.
date_range Actual business dates that the eta days_range match, if pickup occurs on the given pickup_date.
for_pickup_date All etas are relevant to a given pickup-date. Sendle assumes the next available business day - and this is the pickup-date we are estimating based off.

Domestic Parcel Quote Requirements

Domestic request with authentication credentials

  curl 'https://api.sendle.com/api/quote?pickup_suburb=Camberwell%20North&pickup_postcode=3124&pickup_country=AU&delivery_suburb=Barangaroo&delivery_postcode=2000&delivery_country=AU&weight_value=2.0&weight_units=kg&volume_value=0.01&volume_units=m3&first_mile_option=drop%20off'
  -u 'sendleID:APIKey'
  -H 'Content-Type: application/json'

200 Response

  [
    {
      "quote": {
        "gross": {
          "amount": 14.95,
          "currency": "AUD"
        },
        "net": {
          "amount": 13.59,
          "currency": "AUD"
        },
        "tax": {
          "amount": 1.36,
          "currency": "AUD"
        }
      },
      "plan_name": "Standard",
      "eta": {
        "days_range": [1, 4],
        "date_range": ["2018-02-14", "2018-02-19"],
        "for_pickup_date": "2018-02-13"
      }
    }
  ]

Query-parameters

Parameter Description
pickup_address_line1
optional
First line of the street address for the pickup location.
pickup_address_line2
optional
Second line of the street address for the pickup location.
pickup_suburb Suburb must be real and match pickup postcode.
pickup_postcode Post code for the pickup address.
pickup_country
optional
ISO 3166 country code. Sendle currently supports AU for Australia and US for United States. If no pickup_country is provided this will default to AU.
delivery_address_line1
optional
First line of the street address for the delivery location.
delivery_address_line2
optional
Second line of the street address for the delivery location.
delivery_suburb Suburb must be real and match delivery postcode.
delivery_postcode Post code for the delivery address.
delivery_country
optional
ISO 3166 country code. Sendle currently supports AU for Australia and US for United States. If no delivery_country is provided this will default to AU.
weight_value Decimal string value of the weight. Max weight is 25 kilograms for Australia and 70lb for United States.
weight_units The unit of measurement. Most be one of kg (kilograms), g (grams), lb (pounds) or oz (ounces).
volume_value
optional
Decimal string value of the volume.
volume_units
optional
The unit of measurement for the volume. Most be one of l (litres), m3 (cubic metres), in3 (cubic inches) or ft3 (cubic feet).
first_mile_option Whether the parcel will be picked up or dropped off. pickup for parcels that are being picked up, or drop off for drop off (or US) parcels.
plan_name
deprecated
Without authenticating, the API will give quotes for all publicly available plans by default. If plan_name is specified, the API will respond with a quote for just the given plan. For authenticated requests, the API always returns the quote for the account’s current plan and ignores plan_name.
kilogram_weight
deprecated
Must be a decimal-value above 0 and less than weight limits. Max weight is 25 kilograms for Australia and 70lb for United States. Sendle recommends using the weight_value and weight_units parameters above instead.
cubic_metre_volume
optional, deprecated
Must be decimal-value between 0 and 1. To determine this measurement multiply length x width x depth of the parcel in metres. Sendle recommends using the volume_value and volume_units parameters above instead.

International Parcel Quote Requirements

International request with authentication credentials

  curl 'https://api.sendle.com/api/quote?pickup_suburb=Sydney&pickup_postcode=2000&delivery_country=New%20Zealand&weight_value=5&weight_units=kg'
  -u 'sendleID:APIKey'
  -H 'Content-Type: application/json'

200 Response

  [
    {
      "quote": {
        "gross": {
          "amount": 116.2,
          "currency": "AUD"
        },
        "net": {
          "amount": 116.2,
          "currency": "AUD"
        },
        "tax": {
          "amount": 0.0,
          "currency": "AUD"
        }
      },
      "plan_name": "Standard",
      "eta": {
        "days_range": [4, 11],
        "date_range": ["2018-02-19", "2018-02-28"],
        "for_pickup_date": "2018-02-13"
      }
    }
  ]
name Attributes
pickup_suburb Suburb must be real and match pickup postcode.
pickup_postcode Four-digit post code for the pickup address.
delivery_country Full name or ISO Alpha 2 code of the country the parcel is being delivered to.
weight_value Decimal string value of the weight. Max weight is 25 kilograms for Australia and 70lb for United States.
weight_units The unit of measurement. Most be one of kg (kilograms), g (grams), lb (pounds) or oz (ounces).
volume_value
optional
Decimal string value of the volume.
volume_units
optional
The unit of measurement for the volume. Most be one of l (litres), m3 (cubic metres), in3 (cubic inches) or ft3 (cubic feet).
plan_name
deprecated
Without authenticating, the API will give quotes for all publicly available plans by default. If plan_name is specified, the API will respond with a quote for just the given plan. For authenticated requests, the API always returns the quote for the account’s current plan and ignores plan_name.
kilogram_weight
deprecated
Must be a decimal-value above 0 and less than weight limits. Max weight is 25 kilograms for Australia and 70lb for United States. It is preferable to use weight_value and weight_units as this attribute will be removed in the future.
cubic_metre_volume
optional, deprecated
Must be decimal-value between 0 and 1. To determine this measurement multiply length x width x depth of the parcel in metres.. It is preferable to use volume_value and volume_units as this attribute will be removed in the future.

Creating Orders

POST /api/orders

[ POST /api/orders ]

To create an order, submit order data via POST command. The order will be rejected if the data fails validation and the API will respond with an HTTP error.

Identification matching the sender name on the label must be provided for the first three pickups of international parcels.

You can prevent duplicate orders by using an Idempotency Key header with this endpoint. Find out more about Idempotency Keys here

Your account will require a card for the currency you will be creating orders for.

If you are creating orders in Australia, you will need to have an AUD Credit Card set up, or if you are creating orders in the US you will need to have a USD Credit Card set up in your billing account to create an order in the relevant currency.

If you do not have the correct currency enabled for your card you will receive an error in the response.

Example Booking JSON

Example Booking

  curl "https://api.sendle.com/api/orders"
  -X POST
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -H "Idempotency-Key: 6f4aba46-91d4-6ef3-af23-f523375ed5f6"
  -d '{
    "pickup_date": "2015-11-24",
    "first_mile_option": "pickup",
    "description": "Kryptonite",
    "weight": {"value": "1", "units": "kg"},
    "volume": {"value": "0.01", "units": "m3"},
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "company": "LexCorp"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "email": "clarkissuper@dailyplanet.xyz",
        "company": "Daily Planet"
      },
      "address": {
        "address_line1": "80 Wentworth Park Road",
        "suburb": "Glebe",
        "state_name": "NSW",
        "postcode": "2037",
        "country": "Australia"
      },
      "instructions": "Give directly to Clark"
    }
  }'

Each collection within the example booking JSON is described in detail in the sections below.

Section Attributes
Parcel details Pickup date, a parcel description, weight, volume, and a customer reference for the shipment
Sender details Sender contact details, origin address, and pickup instructions
Sender address Origin Address Details
Receiver details Recipient contact details, destination address, and delivery instructions
Receiver address Destination Address Details
Weight Information about how heavy the package is
Volume Information about the volume of the package
API response JSON object returned with a valid booking
Labels Getting Shipping Labels

Parcel Details

Parcel details for a pickup

  {
    "pickup_date": "2015-11-24",
    "first_mile_option": "pickup",
    "description": "Kryptonite",
    "weight": {
      "value": "1",
      "units": "kg"
    },
    "volume": {
      "value": "0.01",
      "units": "m3"
    },
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "hide_pickup_address": false
  }

Parcel details for a drop off

  {
    "first_mile_option": "drop off",
    "description": "Kryptonite",
    "weight": {
      "value": "1",
      "units": "kg"
    },
    "volume": {
      "value": "0.01",
      "units": "m3"
    },
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "hide_pickup_address": false
  }
Data Field Attributes
pickup_date
“yyyy-mm-dd”
If you choose drop off as your first_mile_option, please omit pickup_date. Otherwise, if provided, the date must be at least one non-holiday, business day in the future. If pickup date is omitted it will be set to the first available pickup date option and returned in the order payload on subsequent requests.
first_mile_option Use pickup to get your parcel picked up (when available) or drop off to drop it off at the nearest drop off location in Australia or United States. In the US, only drop off is available. If first_mile_option is not specified, a default value of pickup will be used.
description Description is used by the customer to track the parcel on Sendle Dashboard. It does not show up on a label. It must be under 255 characters in length.
weight Object detailing how much the parcel weighs. See weight for full information about the weight object.
volume
optional
Object detailing the volume of the parcel. See volume for full information about the volume object.
customer_reference
optional
Reference will appear on the label for parcel identification. It must be under 255 characters in length.
metadata
optional
Up to 1MB of JSON key/value pairs which will be stored for this order. These are included when Viewing an Order and in some bulk reports available from the system.
hide_pickup_address
optional
For Australian domestic orders only. Can be used to omit the street address of the sender from a label. Overrides accounts preferences if passed in, account preferences will be respected if omitted. Ignored for export orders, or orders originating outside of Australia.
kilogram_weight
deprecated
Must be a decimal value greater than 0 and less than the maximum allowed weight of 25kg. This option has been deprecated, Sendle recommends that you use the weight object instead.
cubic_metre_volume
deprecated, optional
Must be a decimal value between 0 and 1. When included, value will be length x width x depth of parcel in metres. This option has been deprecated, Sendle recommends that you use the volume object instead. If both kilogram_weight AND the weight object is passed, weight will take precedence.

Sender Details

  {
    "sender": {
      "instructions": "Pick up from reception",
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "email": "me@lexluthor.com",
        "company": "LexCorp"
      }
    }
  }
sender
object
A collection of parcel origin details.
instructions
optional
Short message used as pickup instructions for courier. It must be under 200 chars in length, but is recommended to be under 40 chars due to label-size limitations.
contact
object
A collection of sender contact details.
name It must be under 255 characters in length.
email
optional
Leave this empty - it will be populated with your email based on your account.
phone
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.
company
optional
Business name for the Sender

Sender Address

  {
    "address": {
      "address_line1": "123 Gotham Ln",
      "address_line2": null,
      "suburb": "Sydney",
      "state_name": "NSW",
      "postcode": "2000",
      "country": "Australia"
    }
  }
address
object
A collection of origin address details.
address_line1 The street address where the parcel will be picked up. Addresses can be split over two lines using address_line1 and address_line2. Only address_line1 is mandatory. line2 will be displayed below line1 on the parcel label. Do not include postcode, state, or suburb in this field. It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
address_line2
optional
Second line of the street address for the pickup location. It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
suburb Suburb or town where the parcel is to be picked up. If Sendle cannot service this location, response will be a validation error stating that the suburb is not serviceable. Postcode and suburb must match. If they do not match, Sendle will return a set of alternates to choose from. If receiving an unserviceable error, you may want to check if the location is also listed under a different suburb name.
postcode Postcode or ZIP code of pickup location. It must be a four or five digit string for a valid location. If we cannot pick up parcels from the area, the response will be a validation error stating the location is unserviceable.
state_name Must be the origin location’s state or territory. For Australia these are: ACT, NSW, NT, QLD, SA, TAS, VIC, WA, with the long-form (i.e. “Northern Territory”) also accepted. For United States these are the states 2 letter representation such as CA, NY.
country
optional
Sendle only works within Australia & the United States. If absent, Sendle assumes orders are in Australia. String value under 255 characters in length. If included, must read “Australia” or “United States”.

Receiver Details

  {
    "receiver": {
      "instructions": "ATL but knock loudly",
      "contact": {
        "name": "Clark Kent",
        "email": "clarkissuper@dailyplanet.xyz",
        "phone": "0287654321",
        "company": "Daily Planet"
      }
    }
  }
receiver
object
A collection of parcel recipient details.
instructions Short message used as delivery instructions for courier. It must be under 200 chars, but is recommended to be under 40 chars due to label-size limitations. Note: “Signature on Delivery” is always ignored for satchels sent within Australia, even if entered here.
contact
object
A collection of receiver details.
name It must be under 255 characters in length.
email
optional
Recipient email allows Sendle to send parcel updates to the recipient.
phone
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian/US phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.
company
optional
Business name for the Receiver

Receiver Address

  {
    "address": {
      "address_line1": "80 Wentworth Park Road",
      "suburb": "Glebe",
      "state_name": "NSW",
      "postcode": "2037",
      "country": "Australia"
    }
  }
address
object
A collection of destination address details.
address_line1 The street address where the parcel will be delivered. Addresses can be split over two lines using address_line1 and address_line2. Only address_line1 is mandatory. line2 will be displayed below line1 on the parcel label. Do not include postcode, state, or suburb in this field. It must be under 255 chars in length, but best practice to keep under 40 chars due to label-size limitations.
address_line2
optional
Second line of the street address for the pickup location. It must be under 255 chars in length, but best practice to keep under 40 chars due to label-size limitations.
suburb Suburb or town where the parcel is to be delivered. If Sendle cannot service this location, the response will be a validation error stating that the suburb is not serviceable. Postcode and suburb must match if within Australia. If they do not match, Sendle will return a set of alternatives to choose from.
postcode Postcode or ZIP code of destination location. If we cannot deliver parcels to the area, the response will be a validation error stating the location is unserviceable.
state_name Must be the destination location’s state or territory. For Australia these are: ACT, NSW, NT, QLD, SA, TAS, VIC, WA, with the long-form (i.e. “Northern Territory”) also accepted. For United States these are the states 2 letter representation such as CA, NY.
country
optional
If absent, Sendle assumes orders are in Australia. String value under 255 characters in length. If included, must read “Australia” or “United States”. Sendle only supports international parcels sent from Australia.

Weight

  {
    "weight": {
      "value": "1",
      "units": "kg"
    }
  }

Contains information pertaining to the weight of the package. Either a weight object or kilogram_weight is required.

If both kilogram_weight AND the weight object is passed, weight will take precedence.

weight
object
A collection detailing the package weight.
value A string value detailing how heavy the parcel is.
units The unit of measurement for the weight. Most be one of kg (kilograms), g (grams), lb (pounds) or oz (ounces).

Volume

  {
    "volume": {
      "value": "0.01",
      "units": "m3"
    }
  }

Contains information pertaining to the volume of the package. Either a volume object or cubic_metre_volume is required.

If both a cubic_metre_volume value AND the volume object is passed, the volume will take precedence.

volume
object
A collection detailing the package volume.
value A string value detailing the volume of the parcel is.
units The unit of measurement for the volume. Most be one of l (litres), m3 (cubic metres), in3 (cubic inches) or ft3 (cubic feet).

API Response

201 Response

  {
    "order_id": "f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "state": "Payment",
    "order_url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "sendle_reference": "S3ND73",
    "tracking_url": "https://track.sendle.com/tracking?ref=S3ND73",
    "hide_pickup_address": false,
    "labels": null,
    "scheduling": {
      "is_cancellable": true,
      "pickup_date": "2015-11-24",
      "picked_up_on": null,
      "delivered_on": null,
      "estimated_delivery_date_minimum": "2015-11-26",
      "estimated_delivery_date_maximum": "2015-11-27"
    },
    "description": "Kryptonite",
    "kilogram_weight": "1.0",
    "weight": {
      "units": "kg",
      "value": "1.0"
    },
    "volume": {
      "units": "m3",
      "value": "0.0"
    },
    "cubic_metre_volume": "0.01",
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "email": "me@lexluthor.com",
        "company": "LexCorp"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "address_line2": null,
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "phone": null,
        "email": "clarkissuper@dailyplanet.xyz",
        "company": "Daily Planet"
      },
      "address": {
        "address_line1": "80 Wentworth Park Road",
        "address_line2": null,
        "suburb": "Glebe",
        "state_name": "NSW",
        "postcode": "2037",
        "country": "Australia"
      },
      "instructions": "Give directly to Clark"
    },
    "route": {
      "description": "Sydney to Sydney",
      "type": "same-city",
      "delivery_guarantee_status": "eligible"
    },
    "price": {
      "tax": {
        "currency": "AUD",
        "amount": 0.81
      },
      "net": {
        "currency": "AUD",
        "amount": 8.14
      },
      "gross": {
        "currency": "AUD",
        "amount": 8.95
      }
    }
  }

A successful response will be a full version of an Order object. Many of the fields sent in a booking response are confirmation of the details sent in a booking request and are covered in detail in the View an Order section. In addition to the booking details, information about the current State of the order, URLs for order details, and scheduling information is included.

The currency returned will be the relevant currency for the origin of the order. When sending from Australia this will be AUD and when sending from the US this will be USD. This is the currency you will be charged in.

Field Description
order_id The order’s individual identification in Sendle’s system.
state Identifies the current state of the order. Visit Check for Status Updates for more information.
order_url Specific url for order queries. After booking, this url becomes the point to check for updated information (state changes), labels and any other information related to the order.
sendle_reference Reference ID for a Sendle Order. References begin with an “S” and are an alphanumeric string six or more characters in length.
tracking_url The order’s public tracking page. Tracking page updates as the parcel progresses from sender to receiver. The url can be shared and viewed without a Sendle Account and contains no personal information about either party.
labels Covered in detail in the label section. Contains URLs to retrieve labels in different formats.
scheduling Information regarding the order’s delivery status and whether an order can be cancelled. picked_up_on and delivered_on will return null.
pickup_date is the date the courier has been requested to pick up the parcel. picked_up_on represents the date an order is collected by a courier.
estimated_delivery_date_minimum and estimated_delivery_date_maximum can change depending on courier conditions.
route Information about the route.
description is a human readable description of the route.
type is a machine readable version of the route type. One of same-city, national, remote, or export
delivery_guarantee_status only present when the account has enrolled in our 2-Day Delivery Guarantee. Values can be eligible or ineligible.
price The amount charged for this order.

Creating International Orders

POST /api/orders

[ POST /api/orders ]

To create an international order (an order that is sent from one country another, such as Australia to the United States), submit order data via POST command. The order will be rejected if the data fails validation and the API will respond with an HTTP error.

All strings must be provided using Latin character sets, find out more about Latin and non-Latin character sets

Example Booking JSON

Example Booking

  curl "https://api.sendle.com/api/orders"
  -X POST
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -d '{
    "pickup_date": "2015-11-24",
    "description": "Kryptonite",
    "weight": {"value": "1", "units": "kg"},
    "volume": {"value": "0.01", "units": "m3"},
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "email": "clarkissuper@dailyplanet.xyz"
      },
      "address": {
        "address_line1": "445 Mount Eden Road",
        "suburb": "Auckland",
        "postcode": "2025",
        "country": "New Zealand"
      },
      "instructions": "Give directly to Clark"
    },
    "parcel_contents": [
      {
        "description": "T-shirt",
        "value": "20.00",
        "country_of_origin": "China"
      }
    ]
  }'

Each collection within the example booking JSON is described in detail in the sections below.

Section Attributes
Parcel details Pickup date, a parcel description, weight, volume, and a customer reference for the shipment
Sender details Sender contact details, origin address, and pickup instructions
Sender address Origin Address Details
Receiver details Recipient contact details, destination address, and delivery instructions
Receiver address Destination Address Details
API response JSON object returned with a valid booking
Labels Getting Shipping Labels

International Parcel Details

  {
    "pickup_date": "2015-11-24",
    "description": "Kryptonite",
    "kilogram_weight": "1",
    "cubic_metre_volume": "0.01",
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "parcel_contents": [
      {
        "description": "T-shirt",
        "value": "20.00",
        "country_of_origin": "China"
      }
    ]
  }
Data Field Attributes
pickup_date
“yyyy-mm-dd”
If provided the date must be at least one non-holiday, business day in the future. If pickup date is omitted it will be set to the first available pickup date option and returned in the order payload on subsequent requests.
description Description is used by the customer to track the parcel on Sendle Dashboard. It does not show up on a label. It must be under 255 characters in length.
kilogram_weight Must be a decimal value greater than 0 and less than the maximum allowed weight of 25kg.
cubic_metre_volume
optional
Must be a decimal value between 0 and 1. When included, value will be length x width x depth of parcel in metres.
customer_reference
optional
Reference will appear on the label for parcel identification. It must be under 255 characters in length.
metadata
optional
Up to 1MB of JSON key/value pairs which will be stored for this order. These are included when Viewing an Order and in some bulk reports available from the system.
contents
object
(Deprecated) Details about the parcel contents
parcel_contents
array
A collection of details about the parcel contents
description Detailed description of the parcel contents for customs purposes. Must be between 3 and 300 characters in length. Examples: Shoes, hat, sunglasses
country_of_origin The country in which the goods where manufactured. This can be either the country name or ISO Alpha 2 code. Country names can vary between systems so it is recommended to use ISO country codes where possible.
value The total value of the parcel contents in $AUD, the total value of the parcel cannot exceed $2,000AUD

International Sender Details

  {
    "sender": {
      "instructions": "Pick up from reception",
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "email": "me@lexluthor.com"
      }
    }
  }
sender
object
A collection of parcel origin details.
instructions
optional
Short message used as pickup instructions for courier. It must be under 200 chars, but is recommended to be under 40 chars due to label-size limitations.
contact
object
A collection of sender contact details.
name It must be under 255 characters in length.
email
optional
Leave this empty - it will be populated with your email based on your account.
phone
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.

International Sender Address

  {
    "address": {
      "address_line1": "123 Gotham Ln",
      "address_line2": null,
      "suburb": "Sydney",
      "state_name": "NSW",
      "postcode": "2000",
      "country": "Australia"
    }
  }
address
object
A collection of origin address details.
address_line1 The street address where the parcel will be picked up. Addresses can be split over two lines using address_line1 and address_line2. Only address_line1 is mandatory. line2 will be displayed below line1 on the parcel label. Do not include postcode, state, or suburb in this field It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
address_line2
optional
Second line of the street address for the pickup location.
suburb Suburb or town where the parcel is to be picked up. If Sendle cannot service this location, response will be a validation error stating that the suburb is not serviceable. Postcode and suburb must match. If they do not match, Sendle will return a set of alternates to choose from. If receiving an unserviceable error, you may want to check if the location is also listed under a different suburb name.
postcode Postcode of pickup location. It must be a four digit string for a valid location. If the area cannot be picked up from, response will be a validation error stating the location is unserviceable.
state_name Must be the pickup location’s state or territory. Valid options include: ACT, NSW, NT, QLD, SA, TAS, VIC, WA. Long-form (i.e. “Northern Territory”) is also accepted.
country
optional
If absent, Sendle assumes orders are in Australia. String value under 255 characters in length. If included, must read “Australia” or “AU”

International Receiver Details

  {
    "receiver": {
      "instructions": "ATL but knock loudly",
      "contact": {
        "name": "Clark Kent",
        "email": "clarkissuper@dailyplanet.xyz",
        "phone": "0287654321"
      }
    }
  }
receiver
object
A collection of parcel recipient details.
instructions Short message used as delivery instructions for courier. It must be under 200 chars, but is recommended to be under 40 chars due to label-size limitations. Note: “Signature on Delivery” is always ignored for satchels sent within Australia, even if entered here.
contact
object
A collection of receiver details.
name It must be under 255 characters in length.
email
optional
Recipient email allows Sendle to send parcel updates to the recipient.
phone
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.

International Receiver Address

  {
    "address": {
      "address_line1": "80 Wentworth Park Road",
      "suburb": "Glebe",
      "state_name": "NSW",
      "postcode": "2037",
      "country": "Australia"
    }
  }
address
object
A collection of destination address details.
address_line1 The street address where the parcel will be delivered. Addresses can be split over two lines using address_line1 and address_line2. Only address_line1 is mandatory. line2 will be displayed below line1 on the parcel label. Do not include postcode, state, or suburb in this field. It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
address_line2
optional
Second line of the street address for the destination location.
suburb Suburb or town where the parcel is to be delivered.
postcode
optional
Postcode of destination location.
state_name
optional
The destination location’s state or territory.
country A string of the destination location’s country. This can be either the country name or ISO Alpha 2 code. The list of countries that Sendle delivers to and their codes can be found here, the country name must match exactly so it is recommended to use the ISO country code where possible.

Merchant tax ID for EU parcels

{
  "sender": {
    "tax_ids": { "ioss": "IM0123456789" }
  }
}
sender
object
A collection of parcel origin details.
tax_ids
object
A collection of tax information.
ioss
optional
The IOSS tax ID for the parcel’s sender, for VAT collection purposes. This field is optional for personal items, but should be provided by commercial senders. Failure to do so may result in transit delays, or the receiver needing to pay unpaid VAT and administration fees. Must have the prefix IM followed by 10 digits.

Detailed parcel contents information

{
  "parcel_contents": [
    {
      "description": "Printed cotton t-shirt",
      "hs_code": "5210.21",
      "value": "20.00",
      "currency": "AUD",
      "quantity": 3,
      "country_of_origin": "china"
    },
    {
      "description": "Clear plastic umbrella",
      "hs_code": "6601.10",
      "value": "20.00",
      "currency": "AUD",
      "quantity": 1,
      "country_of_origin": "india"
    }
  ]
}
parcel_contents
array
A collection of details about the parcel contents
description Detailed description of the parcel contents for customs purposes. Must be between 3 and 300 characters in length.
country_of_origin The country in which the goods where manufactured. This can be either the country name or ISO Alpha 2 code. Country names can vary between systems so it is recommended to use ISO country codes where possible.
value The value of one unit of this item. Total value of the parcel for all items can not exceed $2,000AUD.
quantity
default: 1
The number of units of this item which are contained in the parcel.
currency
default: AUD
The currency in which value is expressed.
hs_code
optional
A Harmonized System code for this item which is appropriate for the destination country. Single HS tariff code only. Must only contain 6-10 digits with separating dots.

Deprecated format of parcel contents

{
  "contents": {
    "description": "T-shirt",
    "value": "20.00",
    "country_of_origin": "China",
    "currency": "AUD"
  }
}

For clients that do not yet support parcel_contents, the deprecated form of providing contents remains supported:

International API Response

201 Response

  {
    "order_id": "f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "state": "Payment",
    "order_url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "sendle_reference": "S3ND73",
    "tracking_url": "https://track.sendle.com/tracking?ref=S3ND73",
    "labels": null,
    "scheduling": {
      "is_cancellable": true,
      "pickup_date": "2015-11-24"
    },
    "description": "Kryptonite",
    "kilogram_weight": "1.0",
    "cubic_metre_volume": "0.01",
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "email": "me@lexluthor.com"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "address_line2": null,
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "phone": null,
        "email": "clarkissuper@dailyplanet.xyz"
      },
      "address": {
        "address_line1": "445 Mount Eden Road",
        "address_line2": null,
        "suburb": "Auckland",
        "postcode": "2025",
        "state_name": null,
        "country": "New Zealand"
      },
      "instructions": "Give directly to Clark"
    },
    "contents": {
      "description": "T-shirt",
      "value": "20.00",
      "country_of_origin": "China",
      "currency": "AUD"
    },
    "parcel_contents": [
      {
        "description": "T-shirt",
        "value": "20.00",
        "country_of_origin": "China",
        "quantity": 1,
        "currency": "AUD",
        "hs_code": null
      }
    ]
  }

A successful response will be a full version of an Order object. Many of the fields sent in a booking response are confirmation of the details sent in a booking request and are covered in detail in the View an Order section. In addition to the booking details, information about the current State of the order, URLs for order details, and scheduling information is included.

Field Description
order_id The order’s individual identification in Sendle’s system.
state Identifies the current state of the order. Visit Check for Status Updates for more information.
order_url Specific url for order queries. After booking, this url becomes the point to check for updated information (state changes), labels and any other information related to the order.
sendle_reference Reference ID for a Sendle Order. References begin with an “S” and are an alphanumeric string six or more characters in length.
tracking_url The order’s public tracking page. Tracking page updates as the parcel progresses from sender to receiver. The url can be shared and viewed without a Sendle Account and contains no personal information about either party.
labels Covered in detail in the label section. Contains URLs to retrieve labels in different formats.
scheduling Information regarding the order’s pickup date and whether an order can be cancelled
contents Legacy format of parcel contents, only included when parcel_contents has a single item. Clients should disregard this field in favour of parcel_contents.

Weights and Dimensions

A 20cm cube weighing 500g

{
  "weight": {"value": "0.5", "units": "kg"},
  "volume": {"value": "0.008", "units": "m3"}
}

Sendle uses weight and volume together to determine the size of your parcel.

Sendle will choose the parcel size that can accommodate the weight and volume of your request. If either unit is over, Sendle will select the next size for your parcel.

Note that as per our Terms and Conditions, parcels may be weighed and scanned during transit. If a parcel is found to be under-declared (either weight or volume), we may raise an adjustment charge to reflect the difference between the booked dimensions and the actual dimensions.

Weight

weight (required) when creating an order must be an object containing a unit and a value. The value must be a decimal value greater than 0 and less than or equal to the category/max weight allowed for that unit.

Volume

When using m3, the value must be a decimal value above zero and less than one.

To get the value, multiply length x width x depth of parcel in your unit (for example meters or in3).

We recommend that you always provide a weight, but the volume is optional. Items booked at a lower price due to insufficient information or underquoting may be refused at collection, or may attract adjustment charges.

The Sendle Dashboard uses several weight tiers to allow users to select dimensions, however the API allows any combination of weight and volume. This allows quoting and booking for both Domestic and International parcels.

Australian Domestic Parcels

A satchel

{
  "weight": {"value": "0.4", "units": "kg"},
  "volume": {"value": "0.001", "units": "m3"}
}

A shoebox

{
  "weight": {"value": "1.0", "units": "kg"},
  "volume": {"value": "0.01", "units": "m3"}
}

A Carry-on

{
  "weight": {"value": "5.2", "units": "kg"},
  "volume": {"value": "0.05", "units": "m3"}
}

Note that the weight when using a kg unit (5.2) has bumped the parcel to the carry-on size despite the relatively small volume.

Sendle Sizes

Sendle uses five standard sizes for parcel delivery:

Size Weight – kg (Max) Volume – m3 (Max)
Satchel 0.5kg 0.002
Shoebox 2kg 0.008
Briefcase 5kg 0.02
Carry-on 10kg 0.04
Luggage 25kg 0.1

Australian Domestic Satchel Specifics

Satchels sent from are special pouch-only mailers, and are available only for Domestic parcels. If delivery instructions are not provided it will be Authority To Leave (ATL) by default.

Requirements:

Australian International Parcels

When sending from Australia, International parcels can be up to 20kg. There are three main International zones, and pricing is calculated based on those zones, weight and volume.

United States Domestic Parcels

Micro

{
  "weight": {"value": "0.5", "units": "lb"},
  "volume": {"value": "0.001", "units": "m3"}
}

Mini

{
  "weight": {"value": "1.0", "units": "lb"},
  "volume": {"value": "0.01", "units": "m3"}
}

Small

{
  "weight": {"value": "5", "units": "lb"},
  "volume": {"value": "173", "units": "in3"}
}

Medium

{
  "weight": {"value": "10", "units": "lb"},
  "volume": {"value": "518", "units": "in3"}
}

Large

{
  "weight": {"value": "20", "units": "lb"},
  "volume": {"value": "864", "units": "in3"}
}

Sendle Sizes

Sendle uses five standard sizes for parcel delivery in the US:

Size Weight – lb (Max) Volume – in3 (Max)
Micro 0.5lb 0.002
Mini 1lb 0.008
Small 5lb 173
Medium 10lb 518
Large 20lb 864

Size Calculator

Size Calculator

If you are ever unsure about your parcel size, the Dashboard Size Calculator will convert your parcel’s length, width, and height measurements together with the weight to display the litre volume and select the correct parcel size.

Deprecated Kilogram Weight / Cubic Metre Volume

Previously Sendle used a kilogram_weight key for detailing and a cubic_metre_volume key for detailing the volume of the package. As of January 2020 this has been deprecated, but will continue to be supported for the forseeable future.

You can still pass kilogram_weight and cubic_metre_volume in lieu of the volume and weight objects, but Sendle recommends using the weight and volume properties.

View an Order

GET /api/orders/{id}

[ GET /api/orders/{id} ]

  curl "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6"
    -u "sendleID:APIKey"
    -H "Content-Type: application/json"

200 Response

  {
    "order_id": "f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "state": "Pickup",
    "status": {
      "description": "Pickup Scheduled",
      "last_changed_at": "2015-11-23"
    },
    "order_url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "sendle_reference": "S3ND73",
    "tracking_url": "https://track.sendle.com/tracking?ref=S3ND73",
    "metadata": {
      "your_data": "XYZ123"
    },
    "labels": [
      {
        "format": "pdf",
        "size": "a4",
        "url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6/labels/a4.pdf"
      },
      {
        "format": "pdf",
        "size": "cropped",
        "url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6/labels/cropped.pdf"
      }
    ],
    "scheduling": {
      "is_cancellable": true,
      "pickup_date": "2015-11-24",
      "picked_up_on": null,
      "delivered_on": null,
      "estimated_delivery_date_minimum": "2015-11-26",
      "estimated_delivery_date_maximum": "2015-11-27"
    },
    "description": "Kryptonite",
    "kilogram_weight": "1.0",
    "weight": {
      "value": "1",
      "units": "kg"
    },
    "cubic_metre_volume": "0.01",
    "volume": {
      "value": "0.01",
      "units": "m3"
    },
    "customer_reference": "SupBdayPressie",
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678",
        "email": "lluthor@gmail.com",
        "sendle_id": "sendleID",
        "company": "LexCorp"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "address_line2": null,
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "phone": null,
        "email": "clarkissuper@dailyplanet.xyz",
        "company": "Daily Planet"
      },
      "address": {
        "address_line1": "80 Wentworth Park Road",
        "address_line2": null,
        "suburb": "Glebe",
        "state_name": "NSW",
        "postcode": "2037",
        "country": "Australia"
      },
      "instructions": "Give directly to Clark"
    },
    "route": {
      "description": "Sydney to Sydney",
      "type": "same-city",
      "delivery_guarantee_status": "eligible"
    },
    "price": {
      "tax": {
        "currency": "AUD",
        "amount": 0.81
      },
      "net": {
        "currency": "AUD",
        "amount": 8.14
      },
      "gross": {
        "currency": "AUD",
        "amount": 8.95
      }
    }
  }

Viewing an order will give you all the details associated with an existing Sendle Booking. Important details in an order include:

Field Description
order_id The order’s individual identification in Sendle’s system.
state Identifies the current state of the order. Visit Order states for more information.
status Extra information about order state: a user-friendly description, and last_changed_at is the date that the order changed to the current state
order_url Specific url for order queries. After booking, this url becomes the point to check for updated information (state changes), labels and any other information related to the order.
sendle_reference Reference ID for a Sendle Order. References begin with an “S” and are an alphanumeric string six or more characters in length.
tracking_url The order’s public tracking page. Tracking page updates as the parcel progresses from sender to receiver. The url can be shared and viewed without a Sendle Account and contains no personal information about either party.
labels Covered in detail in the label section. Contains URLs to retrieve labels in different formats.
scheduling Information regarding the order’s delivery status and whether an order can be cancelled. Some fields return null depending on the state of the order.
pickup_date is the date the courier has been requested to pick up the parcel. picked_up_on is the date the parcel was actually picked up.
estimated_delivery_date_minimum and estimated_delivery_date_maximum can change depending on courier conditions.
route Information about the route.
description is a human readable description of the route.
type is a machine readable version of the route type. One of same-city, national, remote, or export
delivery_guarantee_status only present when the account has enrolled in our 2-Day Delivery Guarantee. Values can be eligible or ineligible.
price The amount charged for this order.

Getting Labels

GET {label_url}

[ GET {label_url} ]

  curl "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6/labels/a4.pdf"
  -u "sendleID:APIKey"
  -o "local_label_filename.pdf"
  -L

A4/cropped label data within AU order response

  {
    "labels": [
      {
        "format": "pdf",
        "size": "a4",
        "url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6/labels/a4.pdf"
      },
      {
        "format": "pdf",
        "size": "cropped",
        "url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6/labels/cropped.pdf"
      }
    ]
  }

Letter/cropped label data within US order response

  {
    "labels": [
      {
        "format": "pdf",
        "size": "letter",
        "url": "https://api.sendle.com/api/orders/b152ecca-35a2-4da4-884d-c892bc912b82/labels/letter.pdf"
      },
      {
        "format": "pdf",
        "size": "cropped",
        "url": "https://api.sendle.com/api/orders/b152ecca-35a2-4da4-884d-c892bc912b82/labels/cropped.pdf"
      }
    ]
  }

Sendle currently has two labels to choose from:

Both labels are formatted as PDFs. Labels are stored within the order hash as an array (see example on right). Each label is a hash with a format, size, and url.

Using our order response, we can download the label by using cURL and our preferred label’s url. The label url will redirect you to a private PDF, do not cache this redirect URL as the access permissions expire after 1 minute.

Because of the redirect, special handling is needed. Adding the -L flag will follow the redirect to the label from within Sendle. If you are using cURL you can add the -O (Open) option to save the label with the remote file name, or -o <filename> to specify a file name locally.

This option is only valid once an order has been booked with a courier.

Track a Parcel

GET /api/tracking/{ref}

[ GET /api/tracking/{ref} ]

  curl "https://api.sendle.com/api/tracking/S3ND73"

200 Response

  {
    "state": "Delivered",
    "tracking_events":
      [
       {
          "event_type": "Pickup Attempted",
          "scan_time": "2015-11-23T01:04:00Z",
          "description": "We attempted to pick up the parcel but were unsuccessful",
          "reason": "Parcel not ready"
       },
       {
          "event_type": "Pickup",
          "scan_time": "2015-11-24T20:31:00Z",
          "description": "Parcel picked up"
        },
        {
          "event_type": "Info",
          "scan_time": "2015-11-25T01:04:00Z",
          "description": "In transit between locations"
        },
        {
          "event_type": "In Transit",
          "scan_time": "2015-11-25T01:14:00Z",
          "description": "In transit",
          "origin_location": "Sydney",
          "destination_location": "Brisbane"
        },
        {
          "event_type": "Info",
          "scan_time": "2015-11-26T19:46:00Z",
          "description": "Arrived at the depot for processing"
        },
        {
          "event_type": "Info",
          "scan_time": "2015-11-26T23:00:00Z",
          "description": "Parcel is loaded for delivery"
        },
        {
          "event_type": "Delivered",
          "scan_time": "2015-11-27T23:46:00Z",
          "description": "Parcel delivered"
        },
        {
          "event_type": "Info",
          "scan_time": "2015-11-27T23:47:00Z",
          "description": "Your parcel was signed for by JIMMY"
        },
      ],
      "origin": {"country": "AU"},
      "destination": {"country": "AU"},
      "scheduling": {
        "pickup_date": "2015-11-24",
        "picked_up_on": null,
        "delivered_on": null,
        "estimated_delivery_date_minimum": "2015-11-26",
        "estimated_delivery_date_maximum": "2015-11-27"
      }
    }

Order tracking gives the public details associated with a Sendle order based on the order’s Sendle Reference as a search key (as ref above). The API response returns two sections as described below. Order tracking does not contain personal location information.

Field Description
state The current state of the order
tracking_events The set of tracking scans from pickup to delivery (if any). See table below for description of fields
origin The origin of the parcel, this currently only shows the country. If there is no origin, this might be blank.
destination The destination of the parcel, this currently only shows the country. If there is no destination yet, this might be blank.
scheduling Information regarding the order’s delivery status. Some fields return null depending on the state of the order.
pickup_date is the date the courier has been requested to pick up the parcel. picked_up_on is the date the parcel was actually picked up.
estimated_delivery_date_minimum and estimated_delivery_date_maximum can change depending on courier conditions.

Tracking events

Each tracking event may include any of the following fields:

Field Description
event_type Type of scan event. Options usually are Pickup, Info, or Delivered, though there are many tracking event types explained on the table below.
scan_time Timestamp marker for a tracking event scan. Scans are set in the UTC time zone.
description A short description for the tracking event.
origin_location Marks the departure location of a parcel from a physical hub within an order’s transit.
destination_location Marks the arrival location of a parcel to a physical hub in the courier network.
location City, state, and country information from the tracking event (eg “SYDNEY, NSW, Australia”).
reason Some event types have a reason recorded (eg an attempted delivery will often record the reason why the parcel was not able to be picked up).
requester Some event types have a requester (eg if the customer has contacted us with an issue).
Event Type Description
Pickup Parcel successfully picked up.
Info Information received from courier.
In Transit Parcel in transit between courier hub locations.
Delivered Parcel successfully delivered.
Delivery Attempted Parcel delivery attempted, but unsuccessful.
Card Left Parcel delivery attempted, card left for receiver to arrange collection or re-delivery where available.
Left with Agent Parcel left with agent, this will be a parcel connect location, POPStation, or similar.
Delivery Failed Delivery failed.

Origin / Destination Address

Currently this only shows the country of the origin/destination as an ISO 3166-1 alpha-2 country code. For example “AU” for Australia, “US” for United States.

Field Description
country ISO 3166-1 alpha-2 country code. For example “AU” for Australia, “US” for United States. This might be blank if there is no origin/destination address yet.

Cancelling Orders

DELETE /api/orders/{id}

[ DELETE /api/orders/{id} ]

  curl "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6"
  -X DELETE
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -H "Accept: application/json"

200 Response

  {
    "order_id": "f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "state": "Cancelled",
    "order_url": "https://api.sendle.com/api/orders/f5233746-71d4-4b05-bf63-56f4abaed5f6",
    "sendle_reference": "S3ND73",
    "tracking_url": "https://track.sendle.com/tracking?ref=S3ND73",
    "customer_reference": "SupBdayPressie",
    "cancelled_at": "2015-10-15 00:56:51 UTC",
    "cancellation_message": "Cancelled by S6LRX64PV8MABbBbzu6DoBHD during picking up"
  }

As long as an order has not been collected by the courier, an order is cancellable. The value to review is:

is_cancellable If true, the order can be cancelled.

If a booking has already been collected by the courier, a failure response (422) will be returned. is_cancellable is found in the scheduling section of the JSON along with delivery estimates. For an example of where is_cancellable can be seen, check the View an Order section.

Note: the order is not deleted from the system and should still be viewable on your dashboard in the “cancelled” state.

Order states

A part of viewing an order

  {
    "state": "Pickup",
    "status": {
      "description": "Pickup Scheduled",
      "last_changed_at": "2015-11-23"
    }
  }

States

Sendle uses a handful of terms to describe an order’s state within the shipment process. These are similar to the states used in Sendle Dashboard to describe tracking progress, but are not an exact match.

Orders start in BOOKING, and typically proceed through each of the states until they either reach DELIVERED or end in one of the failure states (eg LOST).

The state workflow of a successful delivery looks like this:

BOOKING -> PICKUP -> IN_TRANSIT -> DELIVERED

All other states represent either deliberate cancellation of the order, or some kind of failure during the above process.

State Description
Booking Order is still being created and has not yet been scheduled for delivery.
Pickup Booking has been consigned and Courier is scheduled to pick up the parcel.
Pickup Attempted An unsuccessful parcel pickup was attempted.
Transit Parcel is in transit.
Delivered Parcel has been successfully delivered.
Cancelled A cancelled order.
Unable to Book An order which cannot be booked.
Lost An order marked as missing or lost.
Return to Sender An order which is being returned to the sender.

Status

The status section gives a bit more information about the current state of the order.

It currently contains two fields:

  1. description is a user-friendly description of the order-state
  2. last_changed_at this is the date at which the order changed to this state

Prepare Form URL

https://www.sendle.com/dashboard/prepare_form

[ https://www.sendle.com/dashboard/prepare_form ]

The Prepare Form URL pre-fills a Send Parcel Form with pickup and delivery details.

This service requires a valid Sendle account with a confirmed email address.

Parcel Pickup Details

There are two ways to provide parcel pickup details for the Prepare Form URL.

The recommended approach is to use the customer’s default Sendle pickup details. To do this, make sure that none of the pickup_address_* or sender_* parameters are provided.

The other approach is to provide the full set of pickup_address_* and sender_* fields. In this case, the users’ defaults are ignored. The form is filled with only the parameters provided. This means any missing or blank parameters need to be manually completed by the user. For example, if only sender_name and sender_contact_number are provided, the user will need to fill in pickup address and instructions on the form before sending.

Therefore, if providing any of these parameters we recommend populating the complete set. This will reduce the manual entry required by the user.

If the parcel is being dropped off, the pickup_address_ fields will be ignored.

The available sender fields are:

URL Parameters Details

https://www.sendle.com/dashboard/prepare_form?pickup_date=2017%2D04%2D03&customer_reference=Flower+Delivery&kilogram_weight=1&cubic_metre_volume=0.001&receiver_name=Oscar+Wilde&delivery_address_line1=2+Smith+Lane&delivery_address_suburb=Sydney&delivery_address_state=NSW&delivery_address_postcode=2000
Data Field Attributes
PARCEL DETAILS
Details about the parcel.
pickup_date
yyyy-mm-dd
optional
If provided the date must be at least one non-holiday, business day in the future. If pickup date is omitted it will be set to the first available pickup date option.
description Description is used by the customer to track the parcel on Sendle Dashboard. It does not show up on a label. It must be under 255 characters in length.
kilogram_weight
optional
Must be a decimal value greater than 0 and less than the maximum allowed weight of 25kg.
parcel_weight_value
optional
Must be one of kg, g, oz or lb. Takes precedence over kilogram_weight. Required if parcel_weight_units is provided.
parcel_weight_units
optional
Parcel weight in format specified in parcel_weight_value Takes precedence over kilogram_weight. Required if parcel_weight_value is provided.
cubic_metre_volume
optional
Must be a value between 0 and 0.1 (m³). When included, value will be length x width x depth of parcel in metres.
parcel_size_units
optional
Must be one of m3, in3 or ft. Takes precedence over cubic_metre_volume. Required if other parcel_size_* values are provided.
parcel_size_length
optional
Parcel length as specified in parcel_size_units. Takes precedence over cubic_metre_volume. Required if other parcel_size_* values are provided.
parcel_size_width
optional
Parcel height as specified in parcel_size_units. Takes precedence over cubic_metre_volume. Required if other parcel_size_* values are provided.
parcel_size_height
optional
Parcel height as specified in parcel_size_units. Takes precedence over cubic_metre_volume. Required if other parcel_size_* values are provided.
customer_reference
optional
Reference will appear on the label for parcel identification. It must be under 255 characters in length.
RECEIVER DETAILS
Details about the receiver.
delivery_instructions
optional
Short message used as delivery instructions for courier. It must be under 255 chars, but is recommended to be under 40 chars due to label-size limitations.
receiver_name
optional
It must be under 255 characters in length.
receiver_email
optional
Allows Sendle to send parcel updates to the recipient.
receiver_contact_number
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.
delivery_address_line1
optional
The street address where the parcel will be delivered. Addresses can be split over two lines using delivery_address_line1 and delivery_address_line2. delivery_address_line2 will be displayed below delivery_address_line1 on the parcel label. Do not include postcode, state, or suburb in this field. It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
delivery_address_line2
optional
Second line of the street address for the delivery location.
delivery_address_suburb
optional
Suburb or town where the parcel is to be delivered.
delivery_address_postcode
optional
Postcode of destination location. It must be a four digits.
delivery_address_state
optional
Must be the destination location’s state or territory. Valid options include: ACT, NSW, NT, QLD, SA, TAS, VIC, WA. Long-form (i.e. “Northern Territory”) is also accepted.
SENDER DETAILS
We recommend omitting these. If you provide one, provide all. See Parcel Pickup for details.
sender_name
optional
It must be under 255 characters in length.
sender_email
optional
Allows Sendle to send parcel updates to the sender.
sender_contact_number
optional
Used to coordinate pickup if the courier is outside attempting delivery. It must be a valid Australian phone number (including area code), or fully qualified international number. Examples: (02) 1234 1234, +1 519 123 1234, +61 (0)4 1234 1234.
pickup_instructions
optional
Short message used as pickup instructions for courier. It must be under 255 chars, but is recommended to be under 40 chars due to label-size limitations.
pickup_address_line1
optional
The street address where the parcel will be picked up. Addresses can be split over two lines using pickup_address_line1 and pickup_address_line2. pickup_address_line2 will be displayed below pickup_address_line1 on the parcel label. Do not include postcode, state, or suburb in this field It must be under 255 char in length, but best practice to keep under 40 chars due to label-size limitations.
pickup_address_line2
optional
Second line of the street address for the pickup location.
pickup_address_suburb
optional
Suburb or town where the parcel is to be picked up.
pickup_address_postcode
optional
Postcode of pickup location. It must be a four digits.
pickup_address_state
optional
Must be the pickup location’s state or territory. Valid options include: ACT, NSW, NT, QLD, SA, TAS, VIC, WA. Long-form (i.e. “Northern Territory”) is also accepted.

Validation Errors

Example response - single error

  {
    "messages": {
      "pickup_date": [
        "must be a business day and at least one business day in the future."
      ]
    },
    "error": "unprocessable_entity",
    "error_description": "The data you supplied is invalid. Error messages are in the messages section. Please fix those fields and try again."
  }

Example response - multiple errors

  {
    "messages": {
      "pickup_date": [
        "must be a business day and at least one business day in the future."
      ],
      "cubic_metre_volume": [
        "must be less than or equal to 0.5"
      ],
      "description": [
        "is too long (maximum is 255 characters)"
      ],
      "sender": [
        {
          "contact": [
            {
              "phone": [
                "must be a valid phone number. 13, 1300, and 1800 numbers are not allowed."
              ]
            }
          ],
          "intructions": [
            "is too long (maximum is 200 characters)"
          ]
        },
      ],
      "receiver": [
        {
          "contact": [
            {
              "email": [
                "must be a valid email address"
              ],
              "name": [
                "is too long (maximum is 200 characters)"
              ]
            }
          ]
        }
      ]
    },
    "error": "unprocessable_entity",
    "error_description": "The data you supplied is invalid. Error messages are in the messages section. Please fix those fields and try again."
  }

The following validations will apply during order creation. Each has an example of the error that is returned if the validation fails.

Each of these will be returned with a 422 HTTP error code. See also HTTP Error codes for other kinds of errors that can occur.

The "messages", "error" and "error_description" sections use the same structure for all error responses. In the examples that detail individual errors (on your right), I will omit the error/error_description sections so as not to continually repeat them. I will only show the contents of the messages section.

Required fields

Minimum mandatory field list

  description
  kilogram_weight OR cubic_metre_volume
  sender
    contact
      name
    address
      address_line1
      suburb
      postcode
      state_name
      country
  receiver
    contact
      name
    address
      address_line1
      suburb
      postcode
      state_name
      country
    instructions

Example with minimum mandatory fields

curl "https://api.sendle.com/api/orders"
  -X POST
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -d '{
    "description": "Kryptonite",
    "kilogram_weight": 1,
    "sender": {
      "contact": {
        "name": "Lex Luthor"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "suburb": "Sydney",
        "state_code": "NSW",
        "postcode": "2000"
      }
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent"
      },
      "address": {
        "address_line1": "80 Wentworth Park Road",
        "suburb": "Foul Bay",
        "state_name": "South Australia",
        "postcode": "5577"
      },
      "instructions": "receiver instructions"
    }
  }'

Required fields errors

  {
    "messages": {
      "description": ["can't be blank"],
      "kilogram_weight": ["can't be blank"],
      "sender": [
        {
          "contact": [
            {
              "name": ["can't be blank"]
            }
          ],
          "address": [
            {
              "suburb": ["can't be blank"],
              "postcode": ["can't be blank"],
              "state_code": ["can't be blank"],
              "address_line1": ["can't be blank"],
              "state_name": ["can't be blank"]
            }
          ]
        }
      ],
      "receiver": [
        {
          "contact": [
            {
              "name": ["can't be blank"]
            }
          ],
          "address": [
            {
              "suburb": ["can't be blank"],
              "postcode": ["can't be blank"],
              "state_code": ["can't be blank"],
              "address_line1": ["can't be blank"],
              "state_name": ["can't be blank"]
            }
          ],
          "instructions": ["can't be blank"]
        }
      ]
    }
  }

Many fields are mandatory in order to book an order for pickup. At right is outlined the minimum-necessary set of fields required for an order and an example cURL script using them.

Note: Sendle will automatically populate the pickup-date with the next business day.

Parcel details

description is missing

  {
    "messages": {
      "description": ["can't be blank"]
    }
  }

description is too long

  {
    "messages": {
      "description": ["is too long (maximum is 255 characters)"]
    }
  }

pickup_date is not a business date in the future

  {
    "messages": {
      "pickup_date": [
        "must be a business day and at least one business day in the future."
      ]
    }
  }

weight/volume too much

  {
    "messages": {
      "kilogram_weight": ["must be less than or equal to 25.0"],
      "cubic_metre_volume": ["must be less than or equal to 0.1"]
    }
  }

weight/volume negative

  {
    "messages": {
      "kilogram_weight": ["must be greater than or equal to 0"],
      "cubic_metre_volume": ["must be greater than or equal to 0"]
    }
  }

neither weight nor volume supplied

  {
    "messages": {
      "kilogram_weight": ["can't be blank"]
    }
  }

customer_reference too long

  {
    "messages": {
      "customer_reference": ["is too long (maximum is 255 characters)"]
    }
  }

metadata not JSON

  {
    "messages": {
      "metadata": ["must be a JSON object"]
    }
  }

metadata too long

  {
    "messages": {
      "metadata": ["must be less than 1MB"]
    }
  }

Description

There must be a description. It must be under 255 characters in length.

Pickup date

The Pickup Date must either be valid (a business day in the future), or be left blank (which will be auto-populated with the Next Business Day) for parcels being picked up.

Weight and volume

The weight and volume must be greater than 0, and within range (25kg for weight, 0.1m^3 for volume).

Either kilogram_weight or cubic_metre_volume must be supplied

Customer Reference

The customer_reference must be under 255 characters in length.

Metadata

metadata must be a valid JSON object that is less that 1MB in size

Sender/Receiver details

Instructions too long

  {
    "messages": {
      "sender": [
        {
          "instructions": ["is too long (maximum is 200 characters)"]
        }
      ],
      "receiver": [
        {
          "instructions": ["is too long (maximum is 200 characters)"]
        }
      ]
    }
  }

Non-satchel and receiver instructions absent

  {
    "messages": {
      "receiver": [
        {
          "instructions": ["can't be blank"]
        }
      ]
    }
  }

Satchel and receiver instructions present

  {
    "messages": {
      "receiver": [
        {
          "instructions": [
            "No delivery instructions are allowed when booking at satchel rates - all satchels are 'Authority to Leave'"
          ]
        }
      ]
    }
  }

Instructions

Instructions (both sender and receiver) must be under 200 characters in length.

Receiver instructions

Receiver instructions must be populated if the order is not a satchel

Receiver instructions must be blank if the order will be a satchel - ie the weight is less than or equal to 500gm AND the volume less than or equal to 8 litres

Contact details

Name absent

  {
    "messages": {
      "receiver": [
        {
          "contact": [
            {
              "name": ["can't be blank"]
            }
          ]
        }
      ],
      "sender": [
        {
          "contact": [
            {
              "name": ["can't be blank"]
            }
          ]
        }
      ]
    }
  }

Name too long

  {
    "messages": {
      "receiver": [
        {
          "contact": [
            {
              "name": ["is too long (maximum is 255 characters)"]
            }
          ]
        }
      ],
      "sender": [
        {
          "contact": [
            {
              "name": ["is too long (maximum is 255 characters)"]
            }
          ]
        }
      ]
    }
  }

Phone format invalid or 1300

  {
    "messages": {
      "receiver": [
        {
          "contact": [
            {
              "phone": [
                "must be a valid phone number. 13, 1300, and 1800 numbers are not allowed."
              ]
            }
          ]
        }
      ],
      "sender": [
        {
          "contact": [
            {
              "phone": [
                "must be a valid phone number. 13, 1300, and 1800 numbers are not allowed."
              ]
            }
          ]
        }
      ]
    }
  }

Email/Sendle ID not valid

  {
    "messages": {
      "receiver": [
        {
          "contact": [
            {
              "email": ["must be a valid email address"],
              "sendle_id": ["doesn't exist"]
            }
          ]
        }
      ]
    }
  }

Name

There must be a Sender and a Receiver name. They must be under 255 characters in length.

Phone

Any provided phone must be a valid Australian number. (eg. “(02) 2222 2222” or “0411 111 111” or “+61 4 1111 1111”). 1300 and 1800 numbers are not permitted.

Email / Sendle ID

Any email provided must be valid email (see format) Any provided Sendle ID must be correct for a valid account on the server you are using.

Addresses

Country must be Australia

  {
    "messages": {

      "receiver": [
        {
          "address": [
            {
              "postal_code_lookup": ["- country must be Australia"],
              "state_name": ["New South Wales does not match any of our known states for your given country."]
            }
          ]
        }
      ]
    }
  }

Address details must be provided

  {
    "messages": {

      "receiver": [
        {
          "address": [
            {
              "suburb": ["can't be blank"],
              "state_code": ["can't be blank"],
              "state_name": ["can't be blank"],
              "postcode": ["can't be blank"]
            }
          ]
        }
      ]
    }
  }

Address lines must not be too long

  {
    "messages": {

      "receiver": [
        {
          "address": [
            {
              "address_line1": [
                "is too long (maximum is 255 characters)"
              ],
              "address_line2": [
                "is too long (maximum is 255 characters)"
              ]
            }
          ]
        }
      ]
    }
  }

Suburb doesn’t match postcode - single match

  {
    "messages": {
      "sender": [
        {
          "address": [
            {
              "suburb": [
                "Leura does not match the postcode: 2782. Perhaps try: Wentworth Falls"
              ],
              "postcode": [
                "2782 does not match the suburb: Leura. Perhaps try: 2780"
              ]
            }
          ]
        }
      ]
    }
  }

Suburb doesn’t match postcode - multiple matches

  {
    "messages": {
      "sender": [
        {
          "address": [
            {
              "suburb": [
                "Sydney does not match the postcode: 2780. Perhaps try: Katoomba, Katoomba DC, Leura, and Medlow Bath"
              ],
              "postcode": [
                "2780 does not match the suburb: Sydney. Perhaps try: 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 2000, and 2001"
              ]
            }
          ]
        }
      ]
    }
  }

Address details don’t match state

  {
    "messages": {
      "sender": [
        {
          "address": [
            {
              "state_name": [
                "We found your postcode and suburb, but they aren't in the state you gave: VIC instead they are in: QLD, perhaps you could change the state to match?"
              ]
            }
          ]
        }
      ]
    }
  }

Address is not serviceable by Sendle (eg a GPO)

  {
    "messages": {
      "sender": [
        {
          "address": ["is not yet serviced by Sendle"]
        }
      ]
    }
  }

Address doesn’t exist in Australia

  {
    "messages": {
      "sender": [
        {
          "address": [
            {
              "postal_code_lookup": ["- country must be Australia"],
              "state_name": [
                "Berkshire does not match any of our known states for your given country."
              ],
              "suburb": ["Slough does not match any of our known suburbs."],
              "postcode": ["9999 does not match any of our known postcodes."]
            },
            "is not yet serviced by Sendle"
          ]
        }
      ]
    }
  }

Country

country (if given) must be a valid country that we service. Currently we only service Australia.

Address lines 1 and 2

Must be under 255 characters in length.

Suburb, postcode, and state

Of suburb, postcode, state - all three must be present. You can provide either the state_name or state_code field (see descriptions in order creation )

For US orders, a ZIP code can be used as the value for postcode.

Due to our postal-code-lookup there may be errors on fields that you are not required to enter (eg state_code and postal_code_lookup) - fix the main fields and these will be resolved.

We usually refer to the combination of suburb+postcode+state as a location.

These fields must all match an existing location in Australia or the United States. We use the freely available Geonames database for validating, and we encourage integrations to use that same dataset.

Note that if the suburb/postcode/state are found but don’t match, the error message will try to suggest alternatives. This is sometimes useful if the state has been entered incorrectly (see the examples at right).

Servicability

The pickup and delivery addresses must be serviceable by Sendle. Check Sendle’s US and AU locations and coverage. An example of an unserviceable location would be a GPO or PO box.

HTTP Error Codes

The Sendle API uses the following error codes:

Error Code Meaning
400 Bad Request – The data provided by the client (typically in the body) is invalid or incorrectly structured.
401 Unauthorized – The authorisation details are invalid. Either the Sendle ID, the API key (or both) are incorrect and should be fixed.
402 Payment Required – The client does not yet have a payment-method set up on their account, and cannot create orders.
404 Not Found – The requested resource/URI was not found.
422 Unprocessable Entity – The server was unable to complete the request due to the data itself. For example, validations within the data may fail, or an upstream request may not be able to be fulfilled with the data. This is different to 400 Bad Request as 422 Unprocessable Entity suggests that the request sent by the client was structurally valid, and the request was attempted.
500 Internal Error – An unhandled error has occured with the Sendle API. Contact support@sendle.com if the problem persists.
503 Not Available – The server is currently unavailable, due to maintenance or upgrades.

400 Bad request

  curl -i "https://api.sendle.com/api/orders"
  -X POST
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -d ']'

400 Response Header information:

  HTTP/1.1 400 Bad Request
  Content-Type: text/html; charset=utf-8
  Content-Length: 0

Invalid request format

When an invalid request is sent to the API, there is no visible response. This will include mostly formatting errors.

401 Unauthorised

401 Response after request without/incorrect Sendle ID or API Key

  {
    "error": "unauthorised",
    "error_description": "The authorisation details are not valid. Either the Sendle ID or API key are incorrect."
  }

Invalid sendle_id or api_key

If you have entered your Sendle ID or API Key incorrectly, you may want to double check your account details.

402 Payment Required

402 Response after POST valid order

  {
    "error": "payment_required",
    "error_description": "The account associated with this API key has no method of payment. Please go to your Account Settings in your Sendle Dashboard and add a payment method."
  }

Payment details not found

Without a credit card on file, booking orders will respond with a 402 error.

Non-booking queries will continue to work without payment and will not receive an error.

404 Not Found

404 Response when entering incorrect Order ID

  {
    "error": "not_found",
    "error_description": "The resource you requested was not found. Please check the URI and try again."
  }

Incorrect URI

If an Order ID or label url is incorrectly entered, a 404 error will be returned. Double-check the ID or url before continuing.

412 Precondition Failed

412 Response after POST valid order

  {
    "error": "precondition_failed",
    "error_description": "The account associated with this API key has not accepted the dangerous goods terms. Please visit your Account Settings in your Sendle Dashboard to view and accept these terms."
  }

Dangerous goods terms have not been accepted

Without accepting dangerous goods terms, booking orders will respond with a 412 error.

Non-booking queries will continue to work without accepting dangerous goods terms and will not receive an error.

422 Unprocessable Entity

Request with unallowable errors:

  curl "https://api.sendle.com/api/orders"
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -X POST
  -d '{
      "pickup_date": "2012-12-25",
      "description": "Showing 400 Error",
      "kilogram_weight": "1",
      "cubic_metre_volume": "1.1",
      "customer_reference": "Four hundred twenty two",
      "sender": {
        "contact": {
          "name": "Sendle API",
          "sendle_id": "sendleAPI",
          "phone": "1300 345 678"
        },
        "address": {
          "address_line1": "123 Test Ave",
          "suburb": "Acton",
          "state_name": "ACT",
          "postcode": "2601",
          "country": "Australia"
        },
        "instructions": "Just a test."
      },
      "receiver": {
        "contact": {
          "name": "Jim",
          "email": "emailaddress.com"
        },
        "address": {
          "address_line1": "80 Wentworth Park Road",
          "suburb": "Glebe",
          "state_name": "NSW",
          "postcode": "2037",
          "country": "Australia"
        },
        "instructions": "Please leave inside the door."
      }
    }'

422 Response

  {
    "messages": {
      "pickup_date": [
        "must be a business day and at least one business day in the future."
      ],
      "cubic_metre_volume": [
        "must be less than or equal to 0.5"
      ],
      "sender": [
        {
          "contact": [
            {
              "phone": [
                "must be a valid phone number. 13, 1300, and 1800 numbers are not allowed."
              ]
            }
          ]
        }
      ],
      "receiver": [
        {
          "contact": [
            {
              "email": [
                "must be a valid email address"
              ]
            }
          ]
        }
      ]
    },
    "error": "unprocessable_entity",
    "error_description": "The data you supplied is invalid. Error messages are in the messages section. Please fix those fields and try again."
  }

Data format was correct but contained unprocessable information

422 errors occur most commonly as users become more familiar with the API. These errors occur when the server receives your request, it is properly formatted, but the information can not be processed as is.

This error-code most often occurs when POSTing data to the API (eg when creating an order) and some of the sent data are invalid (eg a pickup date is in the past or the receiver address was missing). See the validation errors section for more detail.

Be sure to check the error messages as the server response will explain why the request could not be processed and often give suggestions.

503 Not Available

From time to time we might require a short outage to carry out maintenance or upgrades. In most cases the API will return a HTTP 503 error response.

503 Response

{
  "error":"service_unavailable",
  "error_description":"Service is temporarily unavailable. Please check back soon."
}

Idempotency keys

What are they and why do I want one?

Example ping request with idempotency

  curl 'https://api.sendle.com/api/ping'
  -u sendleID:APIKey
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -H "Idempotency-Key: 6f4aba46-91d4-6ef3-af23-f523375ed5f6"

Example order-creation request with idempotency

  curl "https://api.sendle.com/api/orders"
  -X POST
  -u "sendleID:APIKey"
  -H "Content-Type: application/json"
  -H "Accept: application/json"
  -H "Idempotency-Key: 6f4aba46-91d4-6ef3-af23-f523375ed5f6"
  -d '{
    "pickup_date": "2015-11-24",
    "description": "Kryptonite",
    "kilogram_weight": "1",
    "cubic_metre_volume": "0.01",
    "customer_reference": "SupBdayPressie",
    "metadata": {
      "your_data": "XYZ123"
    },
    "sender": {
      "contact": {
        "name": "Lex Luthor",
        "phone": "0412 345 678"
      },
      "address": {
        "address_line1": "123 Gotham Ln",
        "suburb": "Sydney",
        "state_name": "NSW",
        "postcode": "2000",
        "country": "Australia"
      },
      "instructions": "Knock loudly"
    },
    "receiver": {
      "contact": {
        "name": "Clark Kent",
        "email": "clarkissuper@dailyplanet.xyz"
      },
      "address": {
        "address_line1": "80 Wentworth Park Road",
        "suburb": "Glebe",
        "state_name": "NSW",
        "postcode": "2037",
        "country": "Australia"
      },
      "instructions": "Give directly to Clark"
    }
  }'

Idempotency keys are used to prevent duplicate actions occurring when you did not intend for them to be duplicates.

Let me outline two example order-creation scenarios you might use these for:

1) you have a web-form for people to enter order-details that are then submitted to us. Somebody accidentally manages to double-click on the “submit order” button, but you want to make sure that only one order is created.

2) you submit an order to us, but there’s a glitch in the internet and you don’t get a response back from us… how do you tell whether the order was successfully created or not? If you resend the order-create details, will it create a duplicate order?

Customers sometimes make mistakes, and the internet is sometimes flakey… but we want things to run smoothly anyway, if at all possible.

Idempotency keys help reduce these problems by giving us a little more surety that we don’t accidentally duplicate “mutating actions” (ie actions that have consequences).

They work as follows (we’ll use order-creation as the example):

In essence, it works a little like caching.

Also note that a “response” can include 4XX error responses, not just successful order creation. Any validation errors, for example, would be cached alongside the params that cause them, when using a given key.

5XX error responses are not cached and requests can be safely replayed using the same idempotency key.

Here is what happens in the two scenarios outlined above:

Scenario 1 (double-submit):

Scenario 2 (super flakey internet connection):

Which endpoints are they available on?

Idempotency is only really required for “mutating” endpoints - ie endpoints where something permanent changes each time you hit it… the best example is order-creation, of course. Each time you send params to order-creation, you, in theory, want a new order created.

Contrast this with order-cancellation. If you re-send a cancel to an order… we won’t double-cancel the order. It’ll still be just as cancelled at the end, whether it’s the first time or the thousandth time (though please don’t cancel a 1000 times :D), so it doesn’t need idempotency to protect it.

Right now the keys are available for order-creation, and we also have it on the ping-endpoint - not because it needs it, but to make it easier for you to test using idempotency keys. See examples of each of these to the right.

In the future, we will add them to any mutating endpoint that is not already idempotent-by-nature. As in the example above, order-cancellation is naturally idempotent and does not need idempotency-keys added. Likewise any GET request is naturally idempotent. If we were to implement an order-update endpoint, or any other create-endpoint, we would add idempotency to it.

How do I use them?

First you need to generate a unique string to serve as the idempotency key.

Keys cannot be reused for another transaction (eg if you change params), so it’s preferable not to use something like a customer number or an order-id, so we recommend something that is guaranteed unique such as a UUID or a hash of the order-id, customer-id and requested params.

You will pass the key to us in a special header called Idempotency-Key.

There are some examples to the right, and there are also examples given for the ping-endpoint which exists to help you to test Idempotency Keys

You then just need to periodically poll the endpoint (preferably with random backoff) until you receive a response from us.

Key validity, expiry etc

When you send a key to a different endpoint

  {
    "error": "conflict",
    "error_description": "The idempotency key you have requested already exists with different endpoint"
  }

When you send a key with different params

  {
    "error": "conflict",
    "error_description": "The idempotency key you have requested already exists with different params"
  }

You can technically use any string-value as your idempotency key, but keep in mind there are two constraints about how they will be used.

1) Your idempotency key must be unique for your account.

If you reuse a key, we will assume you are trying to do the same transaction again, not use a key in a different context. So for each transaction that you want to be unique, you must use a new key.

Thankfully, keys (and their stored responses) are destroyed after 72 hours - after which you can reuse them.

2) Once used, you cannot reuse the same key even if you change endpoint or params

We thought about how best to make this key-system have a fast response-time, and remain simple and clear. The best way to do that is to be zealous in ensuring that you cannot change endpoint or params once they have been associated with a key. This makes it easier to send you back the relevant response quickly.

This means that if your user enters invalid order-creation params, and receives an error telling them which fields to update… Then you will need to generate a new key to send with any updated params.

If you do try to send the same key with different params, (or to a different endpoint) then you will receive a conflict response (see example responses to the right).

Because of these constraints… we recommend using a new UUID every time you make a new submission, but it is also possible to use a hash-value of all of the relevant submission data (eg request-params, endpoint and the order-id+customer-id at your end) to provide a unique id.

Keys are stripped of whitespace before storage, so “ abc123 ” is the same as “abc123”. Likewise, you will receive an error if you try to submit a blank key.

I’m a multi-tenant site, what do I need to be aware of?

Keys need to be unique per Sendle-customer… ie you, not your customers. If two of your customers try to create an order with the exact same details (unlikely as that might be), then you need a way to make the idempotency-key for each of these two orders unique.

We always recommend using a UUID as it’s practically guaranteed to be unique, but if you instead want to hash relevant data, then we recommend adding the relevant customer-id into the hash just to add some uniqueness.

We definitely recommend using a long, randomised key. Shorter, meaningful-valued keys are not as secure. That is why we prefer a UUID.

Note that we check that parameters are the same for any given idempotency-key we see. In part this is for the safety of our multi-tenant customers as it makes it harder for any given malicious user to randomly spoof an idempotency-key and thus use it as a back-channel for gaining access to order-data. The malicious user would have to know not only the idempotency key, but also all the params that were sent with the original request that was made with that key.

Credits

This example API documentation page was created with Slate.