Book shipments API specification

Wuunder has multiple API’s to connect with:

1. A book shipments API

Where you can book a shipment at a specific carrier and using a specific service. We return the shipping label, track & trace url and the carrier name. If there’s a problem with the address or when the service is not possible for the shipment you want to book we return an error. 

2. A book draft shipments API

Where you can send draft shipments to Wuunder. Sending the specific carrier and service is optional. These draft shipments you can book at once using the bulk booking feature in MyWuunder. By clicking on this link you can find all relevant details. 

This technical manual contains all the information required to work with the Wuunder book draft shipments API. If you do have any questions, please, contact us.

General

The Wuunder API is a RESTful API, served over HTTPS. All data is sent and received as JSON and encoded in UTF-8.

Wuunder provides isolated staging and production environments:

API

ENVIRONMENT

BASE URL

Shipments created succesfully with our API are visible in:

ENVIRONMENT

BASE URL

Staging

Production

Mobile app on IOS & Android

Authentication

API calls are authenticated using API tokens.
Clients that wish to integrate with the Wuunder API will be assigned a per-client token. If you do not have an API key you can request one here.

API tokens must be included in the Authorization header.

 

     Authorization: Bearer TOKEN-HERE

 

Content type

Clients must specify the type of content they are sending through the Content-Type header. At this time, only application/json is supported:

 

     Content-Type: application/json

 

Versioning

Clients must specify the API version they wish to consume. Specifying the API version is done via the Accept header:

 

     Accept: application/json+v1

 

Errors

Errors use the appropriate HTTP status code where possible. Missing parameters for example will respond with a 422 Unprocessable Entity response.

 
     HTTP/1.1 422 Unprocessable Entity

     {
       “errors” : [
         { “field”: “weight”, “messages”: [“can’t be blank”] }
       ]
     }
 

Providing an invalid authentication token will result in a 401 Unauthorized:

 
     HTTP/1.1 401 Unauthorized

     {
        “error”: “unauthorized”
     }
 

HTTP Verbs

Where possible, the Wuunder API strives to use appropriate HTTP verbs for each action.

Verb

Description

GET

Used for retrieving resources.

Resources

All String fields must obey a maximum of 255 characters unless otherwise noted in the description.

NAME

REQUIRED

TYPE

DESCRIPTION

country

Y

String

ISO-2 country code, for example "NL" or "BE".

family_name

Y

String

Max length: 30.

given_name

Y

String

Max length: 30.

house_number

Y

String

Number including any additions. Max length: 8.

locality

Y

String

Max length: 30.

zip_code

Y

String

Max length: 9.

street_name

Y

String

Street part of the addresses. Max length: 35.

business

N

String

When included this addresses will be regarded a business address, otherwise a private address

email_address

N

String

Email address associated with this address. Max length: 40.

phone_number

N

String

Phone number associated with this address. E.123 format, for example +31683243251

chamber_of_commerce_number

N

String

Please use your own e-mail address for testing purposes because Wuunder will send a booking confirmation to the booker (optional), Shipping confirmation with the label to the sender (optional) and track & trace e-mail to the receiver (optional).

Create a shipment

This API allows to create shipments in the Wuunder system in a completely automated fashion.

     POST /api/shipments 

Request body

NAME

REQUIRED

TYPE

DESCRIPTION

description

Y

String

Description of the contents of the shipment in 50 characters or less.

value

Y

Numeric

Value of the whole package, VAT excluded, in eurocents.

kind

Y

String

One of "document", "package" or "pallet"

length

Y

Numeric

Length of the whole package, in centimeters

width

Y

Numeric

Width of the whole package, in centimeters

height

Y

Numeric

Height of the whole package, in centimeters

weight

Y

Numeric

Weight of the whole package in grams

delivery_address

Y

Address

Refer to the Address resource

pickup_address

Y

Address

Refer to the Address resource

personal_message

N

String

Personal message for the customer that will be included in the email sent to them

picture

N

Base64 String

Picture of the shipment

customer_reference

N

String

Free form customer reference for the web shop

is_return

N

Boolean

Indicates if this is a return shipment. Defaults to false.

drop_off

N

Boolean

Indicates if this is a shipment with a parcel shop drop off. Defaults to false.

preferred_service_level

Y

String

The preferred service level label as specified by the filter configuration. Check the available filters here

parcelshop_id

N

String

Id of the parcelshop where the shipment needs to be sent to

number_of_items

N

Integer

Number of same labels to book. Should be >= 1 <= 10.

Example

 
     {
       “delivery_address”: {
         “business”: “Janssen BV”,
         “chamber_of_commerce_number”: null,
         “country”: “NL”,
         “email_address”: null,
         “family_name”: “Janssen”,
         “given_name”: “Jan”,
         “house_number”: “12”,
         “locality”: “Eindhoven”,
         “phone_number”: “+31612345678”,
         “street_name”: “Afleveradres”,
         “zip_code”: “1234AB”
       },
       “customer_reference”: “12345678”,
         “description”: “test”,
         “height”: “50”,
         “kind”: “package”,
         “length”: “10”,
         “personal_message”: “test”,
         “pickup_address”: {
           “business”: “Voorbeeldshop”,
           “chamber_of_commerce_number”: “21”,
           “country”: “NL”,
           “email_address”: “info@voorbeeldshop.nl”,
           “family_name”: “AchternaamContactpersoon”,
           “given_name”: “VoornaamContactpersoon”,
           “house_number”: “1”,
           “locality”: “Plaats”,
           “phone_number”: “+31612345678”,
           “street_name”: “Bedrijfsadres”,
           “zip_code”: “1111AA”
         },
         “picture”: null,
         “value”: “6900”,
         “weight”: “5000”,
         “width”: “20”,
         “is_return”: false,
         “drop_off”: false,
         “preferred_service_level”: “cheapest”,
         “number_of_items”: 1
     }
 

Successful response

 
     Status: 201 Created

     {
       “id”: “7db6bba2-9b85-4624-a22f-ab4c7ac57611”,
       “description”: “Printer”,
       “personal_message”: “Hier zijn de bestelde printers, veel plezier!”,
       “value”: 189,
       “kind”: “package”,
       “length”: 100,
       “width”: 100,
       “height”: 100,
       “weight”: 2000,
       “status”: “pending_label”,
       “is_return”: false,
       “customer_reference”: “12345678”,
       “customer_reference”: “reference”,
       “drop_off”: false,
       “parcelshop_id”: “7db6bba2-9b85-4624-a22f-ab4c7ac57611”,

       “pickup_address”: {
         “business”: “Mycompany B.V.”,
         “chamber_of_commerce_number”: “21”,
         “email_address”: “info@voorbeeldshop.nl”,
         “family_name” :”AchternaamContactpersoon”,
         “given_name”: “VoornaamContactpersoon”,
         “locality”: “Plaats”,
         “phone_number”: “+31612345678”,
         “street_name”: “Bedrijfsadres”,
         “house_number”: “1”,
         “zip_code”: “1111AA”,
         “country”: “NL”
       },

       “delivery_address”: {
         “business”: “Janssen BV”,
         “chamber_of_commerce_number”: null,
         “email_address”: “Jan@JanssenBV.nl”,
         “family_name”: “Janssen”,
         “given_name”: “Jan”,
         “locality”: “Eindhoven”,
         “phone_number”: “+31612345678”,
         “street_name”: “Bedrijfsadres”,
         “house_number”: “12”,
         “zip_code”: “1234AB”,
         “country”: “NL”
       },

       “label_url”: “https://api.wearewuunder.com/shipments/123/label”,
       “track_and_trace_url” :”https://api.wearewuunder.com/shipments/123/track_and_trace”,
       “picture_url” :”https://s3.amazonaws.com/some-bucket/printer.jpg”,
       “items_track_and_trace_details”: [ # one item per `number_of_items` in request
        {
          “track_and_trace_code”: “09986052524805”,
          “id”: “7133c9e1-424a-4eb4-86e4-27cc8543c5f0”,
          “correlation_id”: “B2C0998605252480520181121”
        }
      ]
     }
 

label_url and track_and_trace_url will not be available immediately, but only after the shipment is fully processed.

picture_url will contain a publicly accessible link pointing to the picture supplied in the payload, if any.

Error responses

HTTPS STATUS CODE

ERROR DESCRIPTION

422

Shipment was invalid, for example missing required fields.

Track and Trace Webhook

 

     {
       “action”: “track_and_trace_updated”,
       “track_and_trace_code”: “S3123”,
       “carrier_code”: “TNT”,
       “carrier_name”: “TNT Express”,
       “authentication_token”: “token” // JWT token
     }

 

It is expected that the system receiving the webhook responds with a 2xx status response. Any other response will be regarded as a failure, in which case the Wuunder system will start retrying the webhook using exponential back off.

Authentication token from the webhook response

Sample data:

Token

     

     “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJib29raW5
      nX2lkIjoiNzhkZTZjNDYtMWE2Ni00YmQxLTg0MmQtZTkzNmIw
      ZDg4MjRiIiwiZXhwIjoxNTAzNTc3MTExNjA2Ljk0OX0.Q4ED7N
      q2JUa5uZaxcaAG3m6oGI0oeFjcb_5Mz0HQOPw” 

 

Consist of:

HEADER: ALGORITHM & TOKEN TYPE

   

     json
     {
       “alg”: “HS256”,
       “typ”: “JWT”
     }

 

PAYLOAD: DATA

     

     json
     {
       “booking_id: “78de6c46-1a66-4bd1-e936b0d8824b”
       “exp”: 1503577111606.949
     }

 

Where booking_id is the identifier of processed booking and exp is
expiration time. Wuunder expects the webshop to validate that the expiry time
has not passed yet.

Webshops can verify the validity of the token by calculating the signature, using
their webshop token as the shared secret.

     

     exp = booking_inserted_at (unix time) + default_expiration_time (24 * 60 * 60)