DHL eCommerce API

Public DHL eCommerce API documentation.

Developer - DHL API Documentation

Living document

Department : DHL MDP Development

Introduction

This document is a developer’s guide and provides the necessary information to integrate your websites and mobile apps with our DHL API. Our API endpoints are implemented as RESTful web services so they can be easily integrated on any programming platform.

Basic prior knowledge on JSON, HTTPS and an understanding of software programming is assumed.

A quick overview on all endpoints of the DHL API can be found in our documentation gateway: https://api-gw.dhlparcel.nl/docs/

In this document some of our most important API endpoints are discussed, giving their business context and some examples on how to use specific features provided by the endpoints. The documentation present at the previous URL is generated automatically and therefore more correct over this manually created document. Please use that as the leading technical description of our API.

Please note that our APIs are continually evolving, and as such additional functionality and data may become available over time. Of course, we guarantee backwards compatibility and will never change the contents or semantics of existing fields. However, certain additional fields may appear in the returned JSON, and we expect all clients to be able to deal with this. As such, we consider added fields to be backwards-compatible changes.

The DHL shipping interfaces are there to help you to give the best possible experience to your end users. But if you think there is any information missing, incorrect or you wish to provide us with suggestions, please feel free to contact us at: CIM eCommerce BNL.

Flow

This documentation is ordered in the natural flow when using the api:

1 Authentication and Authorization

1.1 Intro

The DHL API endpoints (but not all) make use of JWT (JSON Web Tokens) for secure authentication and authorization. DHL secure endpoints are identified by a lock in the API docs (see right hand side of the specific endpoint).

The JWT token is necessary to test and work in the DHL production environment when dealing with secured endpoints. This token is to be provided in the Authorization header of the HTTP request using the ‘Bearer’ scheme.

DHL has chosen JWT not just for authentication but also for the secure exchange of JSON information pertaining to the user account.

Precondition

1.2 Services

1.2.1 Get your user-id and key

To get an authentication token, you will need the user-id and user key for your application. These unique values can be generated under the user account on the My DHL Portal application page.

By selecting ‘Settings’ in the user dropdown menu and clicking the button ‘CREATE API KEY’ in the tab ‘API KEYS’, the user-id and key are generated. Hold on to this information, since it will only be given out once. When pressing the button again, a new user-id and key will be generated, overwriting and invalidating the previous one.

My DHL Portal API Keys

1.2.2 Get your authorization token

The user-id and key are used to make the initial call to the Authenticate API key endpoint. As a response, the endpoint returns both an access token and a refresh token.

The access token is valid for a limited time, indicated by the expiration time in the response attribute ‘accessTokenExpiration’. When this time (expressed as a unix time stamp) has expired, the secure access can again be established by obtaining a new access token using the refresh token and the Authenticate refresh token endpoint. Please keep in mind that this refresh token also has an expiration date time, but it is significantly longer than that of the access token.

The response of the refresh endpoint is the same as the initial call to the Authenticate API key endpoint; it also results in an access and a refresh token with expiration date times.

The resulting access tokens contain some encoded information about your access rights, including a list of account numbers. By default, access tokens give access to all account numbers assigned to your API key user. To limit this list, you may provide the optional accountNumbers field in your authentication request.

Example of response body (200) of the /api-key:

{
  "accessToken":"yJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwOGZkMTRhMC05YWYzLTRkZDMtODU3YS1hNzUyYWY3ZjUyYTciLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMDMyNDMxNSwiZXhwIjoxNTEwMzI1MjE2LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.D9Zf0hnDXhPXoWar42wzSiZHRKLBYriyKQyj1zERrBw",
  "accessTokenExpiration": 1510325216 ,
  "refreshToken":
  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhMWQ5MDMyMi04YmRiLTQ1NjQtOTMxMy04OTg5N
ThmMzgwNDQiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRp
b25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMDMyNDMxNSwiZXh
wIjoxNTEwOTI5MTE2LCJyb2xlcyI6WyJhdXRoLXNlcnZpY2UuUkVGUkVTSCJdLCJhY2NvdW50cyI6WyIwODUwMD
AwMSJdfQ.fi7hn6u3mFwcJ4AG8cYEh8OJFm2NDwOt407aP7sENSo",
  "refreshTokenExpiration": 1510929116,
  "accountNumbers": ["1234567"]
}

The accessToken to be used in the HTTP header for authentication. The accessTokenExpiration is the unix time stamp for the expiration of the token (in this case, 2017-11-10 14:46:56Z).

The refreshToken may be used to obtain a new accessToken without having to re-supply credentials. It has a longer expiration (refreshTokenExpiration) than the access token. This makes it possible to set up a longer-running session without the need to store original credentials.

The accountNumbers field lists all account numbers that the access token grants permission to use.

1.3 API Usage

Description URL
API to get your tokens https://api-gw.dhlparcel.nl/authenticate/api-key
API to be used with the refresh token https://api-gw.dhlparcel.nl/authenticate/refresh-token

1.3.1 Get access token

Request examples

Curl
curl -X POST "https://api-gw.dhlparcel.nl/authenticate/api-key" -H "Accept:application/json" -H "Content-Type: application/json" -d "{\"userId\": \"f36abdfa- 9894-4d1f-bb6e-e471a953c04d\", \"key\": \"1c8545e1-767f-4531-9c6b-5f5f80737562\"}"
PHP
<?php
$auth_string = '{"userId":"{userID}","key":"{key}"}';
$ch = curl_init('https://api-gw.dhlparcel.nl/authenticate/api-key');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $auth_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Accept:
application/json'));
$auth_response = curl_exec($ch);
$api_key = json_decode($auth_response);
$accessToken = $api_key->{'accessToken'};
?>

Responses

Success (code 200)
{
  "accessToken": "_Your token_",
  "accessTokenExpiration": 1510138597,
  "refreshToken": "_Your refresh token _",
  "refreshTokenExpiration": 1510742497,
  "accountNumbers": ["1234567"]
}

1.3.2 Refresh token

Request examples

Curl
curl -X POST "https://api-gw.dhlparcel.nl/authenticate/refresh-token" -H "Accept:application/json" -H "Content-Type: application/json" -d "{\"refreshToken\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwMWVlYjBkMy1hZmM0LTRiYjEtYTgzZS0wZDkxYzE4ZjVhZDUiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMDIxMDcxNSwiZXhwIjoxNTEwODE1NTE2LCJyb2xlcyI6WyJhdXRoLXNlcnZpY2UuUkVGUkVTSCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.y-Hm3T6_moUWXF_v2uyOXcX7tu1uddyhG6fsDQliPXw\"}"

Responses

Success (code 200)
{
  "accessToken": "_Your token_",
  "accessTokenExpiration": 1510138597,
  "refreshToken": "_Your refresh token _",
  "refreshTokenExpiration": 1510742497,
  "accountNumbers": ["1234567"]
}

1.4 Testing

These test cases with their positive outcomes are merely suggestions and it is not an extensive test set, e.g. tests with a negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Create an authorization token (initial request) An access token and a refresh token with expiration are returned by the My DHL Portal application.
Create an new authorization with refresh token An access token and a refresh token with expiration are returned by the My DHL Portal application.

2 Capabilities

2.1 Intro

The Capabilities endpoint lists the available shipment options (and their exclusions) given a certain country, parcel type and whether the recipient of the parcel is a business or a consumer.

The purpose of the endpoint is twofold: it offers all available options to choose from for a given situation, and can then validate the interdependency of all variables for a shipment, serving as a validation tool for your shipment request.

Per situation you should think of what is possible in terms of the kind of shipment, if it is a business-to-business or business-to-consumer shipment, does your account allow you to create return shipments or a same day delivery.

The Create Label endpoint makes use of the capabilities endpoint, thereby checking the validity of a shipment the same way.

Preconditions

No preconditions are applicable.

2.2 Services

2.2.1 Capabilities

In order to get the correct capabilities for your shipment, in addition to the sender type (mandatory), at least the top three fields in the table below should be given in order to get the applicable set of options for a specific shipment. Without these parameters, the request will result in a too broad dataset to be useful for a single shipment.

In certain cases, it is better to not supply the ‘parcelType’ and ‘shipmentOptions’ fields. The input fields work like a filter, returning only valid product combinations; when provided with an impossible combination of options, the endpoint will not return an error message, but simply return an empty list.

For example, when Saturday delivery (‘S’) is present and toBusiness is set to true, the call will be successful, but the response will not contain possible shipment options. In fact that means that there are none, since these options are incompatible with each other.

Parcel types can be cross-referenced through the Parcel type endpoint. This is useful since available parcel types can differ per country. The same applies for the Shipments options endpoint, where options differ per origin/destination country pair.

Field Description
fromCountry Country code of origin
toCountry Country code of destination
toBusiness Does it concern a delivery to a business? True or false
parcelType Check Parcel type API. A parcel type is available or valid depending on the ‘senderType’ and the values of ‘toBusiness’ and ‘fromCountry’. See Ad 1.
shipment options Check Shipment options API. Depending on the values of ‘senderType’, ‘parcelType’, ‘fromCountry’ and ‘toBusiness’ options are available. Some options are excluded based on the chosen option(s). See Ad 2.

As a result of a ‘successful’ call the API will return all possible parcel types, shipment options with its exclusions.

Ad 1. For example parcel Type “PALLET” is known in the Netherlands, but not in Spain. In order to get the right parcel types from the sender’s point of view (country code), the Parcel type endpoint should be used.

This is just one example why the input needs to be cross-referenced with the Parcel types (or with the Shipment options) endpoint. As already mentioned, the input in itself will not be validated through the Capabilities endpoint. Providing non-existent or incompatible options will just yield an empty list.

[{
  "key": "SMALL",
  "minWeightKg": 0,
  "maxWeightKg": 5,
  "dimensions": {
    "maxLengthCm": 25,
    "maxWidthCm": 20,
    "maxHeightCm": 5
  }
},{
  "key": "MEDIUM",
  "minWeightKg": 5,
  "maxWeightKg": 15,
  "dimensions": {
    "maxLengthCm": 60,
    "maxWidthCm": 50,
    "maxHeightCm": 25
  }
},{
  "key": "LARGE",
  "minWeightKg": 16,
  "maxWeightKg": 31,
  "dimensions": {
    "maxLengthCm": 120,
    "maxWidthCm": 60,
    "maxHeightCm": 60
  }
},{
  "key": "BULKY",
  "minWeightKg": 0,
  "maxWeightKg": 31,
  "dimensions": {
    "maxLengthCm": 200,
    "maxWidthCm": 120,
    "maxHeightCm": 80
  }
}]

Ad 2. The option “PS”, meaning delivery to a DHL Servicepoint, and the option “DOOR”, delivery at the door, of course do not go together. If chosen together in the Capabilities endpoint the response code is 200, but the result will be an empty array.

In the snippet of the Shipment options endpoint below you can see that “DOOR” is listed as an exclusion to the shipment option “PS”, indicating their incompatibility.

{
  "key": "PS",
  "description": "Delivery to the specified DHL Parcelshop or DHL Parcelstation",
  "rank": 1,
  "code": 21,
  "inputType": "text",
  "exclusions": [
    {
      "key": "EVE",
      "rank": 13,
      "code": 14
    },
    {
      "key": "S",
      "rank": 11,
      "code": 15
    },
    {
      "key": "NBB",
      "rank": 14,
      "code": 36
    },
    {
      "key": "HANDT",
      "rank": 12,
      "code": 56
    },
    {
      "key": "DOOR",
      "rank": 2,
      "code": 0
    },
    {
      "key": "COD_CASH",
      "rank": 17,
      "code": 0,
      "inputType": "number"
    },
    {
      "key": "COD_CHECK",
      "rank": 18,
      "code": 0,
      "inputType": "number"
    },
    {
      "key": "EXP",
      "rank": 15,
      "code": 1
    },
    {
      "key": "H",
      "rank": 4,
      "code": 21
    },
    {
      "key": "BOUW",
      "rank": 19,
      "code": 0
    },
    {
      "key": "EXW",
      "rank": 20,
      "code": 0
    },
    {
      "key": "SSN",
      "rank": 16,
      "code": 0,
      "inputType": "address"
    },
    {
      "key": "RECAP",
      "rank": 21,
      "code": 0,
      "inputType": "text"
    },
    {
      "key": "BP",
      "rank": 3,
      "code": 91
    },
    {
      "key": "SDD",
      "rank": 7,
      "code": 6
    },
    {
      "key": "NO_TT",
      "rank": 22,
      "code": 0
    }
  ]
}

If, for example, a “SMALL” parcel type is chosen and the delivery of the parcel is to a business (toBusiness = true) and the chosen option is “PS”, again the response will be successful, but there is no result.

It might be better to not have shipment option(s) and or parcel types as input. The endpoint will then return all parcel types and options available based on the base input (toBusiness, fromCountry and toCountry).

Then, in your application, show a list of returned options the end-user can choose from and validate each option against its exclusions.

If no shipment option is entered as input for the endpoint, like in the last example (toBusiness = true, fromCountry=NL and toCountry=NL) , the shipment option “PS” will only show up in the result of certain parcel types.

[
  {
    "rank": 2,
    "fromCountryCode": "NL",
    "toCountryCode": "NL",
    "product": {
      "key": "EPL",
      "label": "EUROPLUS",
      "code": "04",
      "menuCode": "01",
      "businessProduct": true,
      "monoColloProduct": false,
      "softwareCharacteristic": "B2X",
      "returnProduct": false
    },
    "parcelType": {
      "key": "SMALL",
      "minWeightKg": 0,
      "maxWeightKg": 20,
      "dimensions": {
        "maxLengthCm": 80,
        "maxWidthCm": 50,
        "maxHeightCm": 35
      }
    },
    "options": [
      {
        "key": "DOOR",
        "description": "Delivery to the address of the recipient",
        "rank": 2,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          },
          {
            "key": "NO_TT",
            "rank": 22,
            "code": 0
          }
        ]
      },
      {
        "key": "H",
        "description": "Hold for collection",
        "rank": 4,
        "code": 21,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "EXP",
            "rank": 15,
            "code": 1
          },
          {
            "key": "BOUW",
            "rank": 19,
            "code": 0
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          },
          {
            "key": "DOOR",
            "rank": 2,
            "code": 0
          }
        ]
      },
      {
        "key": "REFERENCE",
        "description": "Reference",
        "rank": 5,
        "code": 0,
        "inputType": "text",
        "inputMax": "15"
      },
      {
        "key": "PERS_NOTE",
        "description": "E-mail to receiver",
        "rank": 6,
        "code": 0,
        "inputType": "text"
      },
      {
        "key": "ADD_RETURN_LABEL",
        "description": "Print extra label for return shipment",
        "rank": 8,
        "code": 0
      },
      {
        "key": "INS",
        "description": "All risks insurance",
        "rank": 10,
        "code": 0,
        "inputType": "number"
      },
      {
        "key": "S",
        "description": "Saturday delivery",
        "rank": 11,
        "code": 15,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EXP",
            "rank": 15,
            "code": 1
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "EXP",
        "description": "Expresser",
        "rank": 15,
        "code": 1,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "S",
            "rank": 11,
            "code": 15
          },
          {
            "key": "H",
            "rank": 4,
            "code": 21
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "SSN",
        "description": "Undisclosed sender",
        "rank": 16,
        "code": 0,
        "inputType": "address",
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "COD_CASH",
        "description": "Cash on delivery. Payment method cash.",
        "rank": 17,
        "code": 0,
        "inputType": "number",
        "exclusions": [
          {
            "key": "COD_CHECK",
            "rank": 18,
            "code": 0,
            "inputType": "number"
          },
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "BOUW",
        "description": "Delivery to construction site",
        "rank": 19,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "H",
            "rank": 4,
            "code": 21
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "EXW",
        "description": "Ex Works",
        "rank": 20,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 8
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "REFERENCE2",
        "description": "Reference",
        "rank": 22,
        "code": 0,
        "inputType": "text",
        "inputMax": "70"
      }
    ]
  }
]

2.3 API Usage

Description Production
Retrieve capabilities https://api-gw.dhlparcel.nl/capabilities/business?

2.3.1 Retrieve capabilities

Request examples

Curl
curl -X GET "https://api-gw.dhlparcel.nl/capabilities/business?fromCountry=NL&toCountry=NL&toBusiness=false&parcelType=SMALL&option=PS" -H "Accept: application/json"
PHP - WordPress
<?php
// {@see https://codex.wordpress.org/HTTP_API}
$response = wp_remote_get( 'https://api-gw.dhlparcel.nl/capabilities/business?fromCountry=NL&toCountry=NL&toBusiness=false&parcelType=SMALL&option=PS', array(
'headers' => array(
'Accept' => 'application/json',
),
) );

if (! is_wp_error( $response ) ) {
// The request went through successfully, check the response code against
// what we're expecting
if ( 200 == wp_remote_retrieve_response_code( $response ) ) {
// Do something with the response
// $body = wp_remote_retrieve_body( $response );
// $headers = wp_remote_retrieve_headers( $response );
} else {
// The response code was not what we were expecting, record the message
$error_message = wp_remote_retrieve_response_message( $response );
}
} else {
// There was an error making the request
$error_message = $response->get_error_message();
}
PHP cURL - WordPress
<?php
// Get cURL resource
$ch = curl_init();

// Set url
curl_setopt($ch, CURLOPT_URL, 'https://api-gw.dhlparcel.nl/capabilities/business?fromCountry=NL&toCountry=NL&toBusiness=false&parcelType=SMALL&option=PS');

// Set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

// Set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );

// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Accept: application/json",
]
);


// Send the request & save response to $resp
$resp = curl_exec($ch);

if(!$resp) {
die('Error: "'. curl_error($ch). '" - Code: '. curl_errno($ch));
} else {
echo "Response HTTP Status Code : ". curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nResponse HTTP Body : ". $resp;
}

// Close request to clear up some resources
curl_close($ch);

Responses

Success (code 200):
[
  {
    "rank": 2,
    "fromCountryCode": "NL",
    "toCountryCode": "NL",
    "product": {
      "key": "EPL",
      "label": "EUROPLUS",
      "code": "04",
      "menuCode": "01",
      "businessProduct": true,
      "monoColloProduct": false,
      "softwareCharacteristic": "B2X",
      "returnProduct": false
    },
    "parcelType": {
      "key": "PALLET",
      "minWeightKg": 50,
      "maxWeightKg": 1000,
      "dimensions": {
        "maxLengthCm": 240,
        "maxWidthCm": 100,
        "maxHeightCm": 200
      }
    },
    "options": [
      {
        "key": "DOOR",
        "description": "Delivery to the address of the recipient",
        "rank": 2,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          },
          {
            "key": "NO_TT",
            "rank": 22,
            "code": 0
          }
        ]
      },
      {
        "key": "H",
        "description": "Hold for collection",
        "rank": 4,
        "code": 21,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "EXP",
            "rank": 15,
            "code": 1
          },
          {
            "key": "BOUW",
            "rank": 19,
            "code": 0
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          },
          {
            "key": "DOOR",
            "rank": 2,
            "code": 0
          }
        ]
      },
      {
        "key": "REFERENCE",
        "description": "Reference",
        "rank": 5,
        "code": 0,
        "inputType": "text",
        "inputMax": "15"
      },
      {
        "key": "PERS_NOTE",
        "description": "E-mail to receiver",
        "rank": 6,
        "code": 0,
        "inputType": "text"
      },
      {
        "key": "ADD_RETURN_LABEL",
        "description": "Print extra label for return shipment",
        "rank": 8,
        "code": 0
      },
      {
        "key": "INS",
        "description": "All risks insurance",
        "rank": 10,
        "code": 0,
        "inputType": "number"
      },
      {
        "key": "EXP",
        "description": "Expresser",
        "rank": 15,
        "code": 1,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "S",
            "rank": 11,
            "code": 15
          },
          {
            "key": "H",
            "rank": 4,
            "code": 21
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "SSN",
        "description": "Undisclosed sender",
        "rank": 16,
        "code": 0,
        "inputType": "address",
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "COD_CASH",
        "description": "Cash on delivery. Payment method cash.",
        "rank": 17,
        "code": 0,
        "inputType": "number",
        "exclusions": [
          {
            "key": "COD_CHECK",
            "rank": 18,
            "code": 0,
            "inputType": "number"
          },
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "BOUW",
        "description": "Delivery to construction site",
        "rank": 19,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "H",
            "rank": 4,
            "code": 21
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "EXW",
        "description": "Ex Works",
        "rank": 20,
        "code": 0,
        "exclusions": [
          {
            "key": "PS",
            "rank": 1,
            "code": 21,
            "inputType": "text"
          },
          {
            "key": "EVE",
            "rank": 13,
            "code": 14
          },
          {
            "key": "EA",
            "rank": 9,
            "code": 58
          },
          {
            "key": "BP",
            "rank": 3,
            "code": 91
          }
        ]
      },
      {
        "key": "REFERENCE2",
        "description": "Reference",
        "rank": 22,
        "code": 0,
        "inputType": "text",
        "inputMax": "70"
      }
    ]
  }
]

2.4 Testing

These test cases with positive outcomes are merely suggestions and it is not an extensive test set, e.g. tests with a negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Check capabilities business to business Parcel type(s) with options are returned for a business based on the input of being a business, country code and shipment option(s) and or on a specific parcel type.
Check capabilities business to consumer Parcel type(s) with options are returned for a consumer based on the input of being a consumer, country code and shipment option(s) and or on a specific parcel type.

3 Find parcel shop location

3.1 Intro

The Parcel shop finder endpoint makes it possible to find parcel shops or DHL Servicepoints in a country based on address information and or a wildcard.

Preconditions

No preconditions are applicable.

3.2 Services

3.2.1 Find the nearest parcel shop location endpoint

The Find the nearest parcel shop location endpoint gets you a list of the nearby DHL Servicepoints based on the country code and address information or a wildcard (q) like a piece of the recipient’s address e.q. city and or name or the postal code of an address.

So in order to get a list of parcel shops the country code is required and at least one of these fields: free format location description, postal code, city.

Field Description
q free format location description, where multiple keywords can be entered. For example country code ‘NL’ and keywords ‘Tabak’ and ‘1055’ will return a parcel shop in Amsterdam (postal code with 1055 in it) and that has ‘Tabak’ in its name.
zipCode format depends on the country e.g. for the country code ‘NL’ it is ‘9999XX’, ‘ES’ is is ‘99999’ etc.

The more specific the address is the less DHL Servicepoints will be returned and the more accurate the result is. A query based on just the street name will not suffice. There is the option to limit the result with the input field ‘limit’.

The result is ordered ascending based on the geo location, meaning the nearest DHL ServicePoint is at the top.

The response contains the identification of a DHL ServicePoint. This id serves as extra input in the shipment option as explained in 3.3.1 Create Label when sending a shipment to a DHL ServicePoint.

3.2.2 Get specific DHL Servicepoint

The Find the information for a specific parcel shop location endpoint allows you to select a specific DHL ServicePoint. The country code is mandatory and the DHL ServicePoint id is needed. This id can be queried by using the Find the nearest parcel shop location endpoint.

3.3 API Usage

Description URL
Endpoint to get nearest parcel shops https://api-gw.dhlparcel.nl/parcel-shop-locations/?
Endpoint to get specific parcel shop https://api-gw.dhlparcel.nl/parcel-shop-locations//

3.3.1 Get nearest parcel shops

Request examples

Curl
curl - X GET "https://api-gw.dhlparcel.nl/parcel-shop-locations/ES?city=Madrid&showUnavailable=false" - H "Accept: application/json"

Response

Success (code 200)
[
  {
    "id": "5017-ES-0000104",
    "harmonisedId": "101",
    "psfKey": "ES-0000104",
    "shopType": "parcelShop",
    "name": "FOLDER PLAZA DEL ANGEL",
    "keyword": "DHL ServicePoint",
    "address": {
      "countryCode": "ES",
      "zipCode": "28012",
      "postalCode": "28012",
      "city": "MADRID",
      "street": "C/ PLAZA DEL ANGEL",
      "number": "16",
      "isBusiness": true
    },
    "geoLocation": {
      "latitude": 40.414381,
      "longitude": -3.702893
    },
    "distance": 284,
    "openingTimes": [
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 1
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 1
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 2
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 2
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 3
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 3
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 4
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 4
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 5
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 5
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 6
      },
      {
        "timeFrom": "16:30:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 6
      }
    ],
    "closurePeriods": []
  },
  {
    "id": "5017-ES-0001288",
    "harmonisedId": "101",
    "psfKey": "ES-0001288",
    "shopType": "parcelShop",
    "name": "WORKCENTER C/ SEVILLA",
    "keyword": "DHL ServicePoint",
    "address": {
      "countryCode": "ES",
      "zipCode": "28014",
      "postalCode": "28014",
      "city": "MADRID",
      "street": "C/ SEVILLA",
      "number": "4",
      "isBusiness": true
    },
    "geoLocation": {
      "latitude": 40.417446,
      "longitude": -3.699818
    },
    "distance": 446,
    "openingTimes": [
      {
        "timeFrom": "08:00:00.000",
        "timeTo": "21:00:00.000",
        "weekDay": 1
      },
      {
        "timeFrom": "08:00:00.000",
        "timeTo": "21:00:00.000",
        "weekDay": 2
      },
      {
        "timeFrom": "08:00:00.000",
        "timeTo": "21:00:00.000",
        "weekDay": 3
      },
      {
        "timeFrom": "08:00:00.000",
        "timeTo": "21:00:00.000",
        "weekDay": 4
      },
      {
        "timeFrom": "08:00:00.000",
        "timeTo": "21:00:00.000",
        "weekDay": 5
      },
      {
        "timeFrom": "10:00:00.000",
        "timeTo": "14:30:00.000",
        "weekDay": 6
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 6
      },
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:30:00.000",
        "weekDay": 7
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "21:30:00.000",
        "weekDay": 7
      }
    ],
    "closurePeriods": []
  },
  {
    "id": "5017-ES-0002224",
    "harmonisedId": "101",
    "psfKey": "ES-0002224",
    "shopType": "parcelShop",
    "name": "INFINITY COMICS",
    "keyword": "DHL ServicePoint",
    "address": {
      "countryCode": "ES",
      "zipCode": "28013",
      "postalCode": "28013",
      "city": "MADRID",
      "street": "C/ HILERAS",
      "number": "2",
      "isBusiness": true
    },
    "geoLocation": {
      "latitude": 40.416814,
      "longitude": -3.708361
    },
    "distance": 505,
    "openingTimes": [
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 1
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 1
      },
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 2
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 2
      },
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 3
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 3
      },
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 5
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 5
      },
      {
        "timeFrom": "11:00:00.000",
        "timeTo": "14:00:00.000",
        "weekDay": 6
      },
      {
        "timeFrom": "17:00:00.000",
        "timeTo": "20:30:00.000",
        "weekDay": 6
      }
    ],
    "closurePeriods": []
  }
]

3.3.2 Get specific parcel shop

Request examples

Curl
curl - X GET "https://api-gw.dhlparcel.nl/parcel-shop-locations/ES/5017-ES- 0000104 " -H "Accept: application/json"

Responses

Success (code 200)
{
  "id": "5017-ES-0000104",
  "harmonisedId": "101",
  "psfKey": "ES-0000104",
  "shopType": "parcelShop",
  "name": "FOLDER PLAZA DEL ANGEL",
  "keyword": "DHL ServicePoint",
  "address": {
    "countryCode": "ES",
    "zipCode": "28012",
    "postalCode": "28012",
    "city": "MADRID",
    "street": "C/ PLAZA DEL ANGEL",
    "number": "16",
    "isBusiness": true
  },
  "geoLocation": {
    "latitude": 40.414381,
    "longitude": -3.702893
  },
  "openingTimes": [
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 1
    },
    {
      "timeFrom": "17:00:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 1
    },
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 2
    },
    {
      "timeFrom": "17:00:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 2
    },
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 3
    },
    {
      "timeFrom": "17:00:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 3
    },
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 4
    },
    {
      "timeFrom": "17:00:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 4
    },
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 5
    },
    {
      "timeFrom": "17:00:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 5
    },
    {
      "timeFrom": "10:00:00.000",
      "timeTo": "14:00:00.000",
      "weekDay": 6
    },
    {
      "timeFrom": "16:30:00.000",
      "timeTo": "20:30:00.000",
      "weekDay": 6
    }
  ],
  "closurePeriods": []
}

3.4 Testing

These test cases with positive outcomes are merely suggestions and it is not an extensive test set, e.g. tests with a negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Place a request limit to 3 for specific country code and place Three parcel shops are returned in the given place by the Find the nearest parcel shop location endpoint
Place a request with the ID of a parcel shop The given parcel shop is returned by the Find the information for a specific parcel shop location endpoint.

4 Labels and Shipments

4.1 Intro

The Shipments and Labels endpoints make it possible to create and retrieve your own labels.

These endpoints are secured, therefore the use of an authorization header with ‘Bearer’ as prefix and your token is required.

Preconditions

4.2 Services

4.2.1 Create shipment

The Create shipment endpoint constructs a shipment.

In order to create a shipment, a unique identifier is needed as input for the shipment request. The format for this identifier is the Universally Unique Identifier (UUID). The use of UUIDs keeps our API idempotent. It ensures in this case that a shipment is created uniquely and just once, without needing to do any expensive and complicated synchronized bookkeeping.

Most programming languages and platforms have a built-in UUID generator that you can use for this purpose.A brief explanation on the other input data is given in the table below.

Be aware that the use of an authorization token in the header of the HTTP request is mandatory.

Field Type Mandatory Description
shipmentId string Y Use a UUID Generator
orderReference string N Your own reference for the shipment, can be used to retrieve the label, e.g. your order number.
receiver   Y Name and address
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
onBehalfOf   N Name and address. See Ad 1.
name     Requires at least firstName, lastName or companyName
firstName string    
lastName string    
companyName string    
additionalName string    
address     Depending on country, use designated endpoint for address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
shipper   Y Name and address
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
accountId string Y As provided by DHL. May only be empty for C2C customers
options array    
key string Y See Capabilities endpoint in API docs and Ad 2.
input   N See Ad 2.
returnLabel boolean N See Ad 3.
pieces   Y See Ad 4.
parcelType string Y See ParcelTypes endpoint in API docs
quantity integer N Number of parcels of this parcel type
weight number N Actual weight of the parcel in kilograms
dimensions   N Actual dimensions of the parcel, in centimeters
length number N Length in centimeters
width number N Width in centimeters
height number N Height in centimeters
customsDeclaration   N Customs details when sending to a customs destination
currency string N Currency of the invoice, ISO (EUR, CHF, NOK, GBP, USD)
invoiceNumber string N  
remarks string N Supplementary information, such as consignment remarks
invoiceType string N Type of invoice, e.g. commercial
exportType string N Permanent, Repair, Return, Temporary
exportReason string N Other, SaleOfGoods, ReturnedGoods, Gift, CommercialSample, Documents
incoTerms string N CFR, CIF, CIP, CPT, DAP, DAT, DDP, DDU, DDX, EXW, FCA, FOB; DDX means ‘DDP VAT Excl.’ EXW not applicable for UK exports. For Parcel Connect only DDU applicable to UK.
incoTermsCity string N Named place of delivery/destination/port
senderInboundVatNumber string N Sender VAT number for inbound country. Only applicable for shipments to GB. Mandatory for Parcel Connect shipments to GB
attachmentIds [string] N Specify uploaded custom attachments
defermentAccountVat String N Deferment Account VAT
defermentAccountDuties String N Deferment Account for Duties (if a separate account exits)
vatReverseCharge boolean N  
shippingFee     Additional shipping fee
currency string Y  
value string Y  
importerOfRecord   N Importer of the customs shipment
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
customsGoods   Y Customs goods in this declaration, at least one is required
code string Y HS-code of the goods, see Harmonized commodity description and coding System, to classify globally traded products. Always 8 or 10 positions.
description string Y Description of the goods
origin string Y Country of origin, ISO 3166-1 alpha-2 country code
quantity string Y Number of the products of this line
value string Y Total value of the goods of this line
weight string Y Net weight of the products of this line

Ad 1. An ‘on behalf of’ shipment

For destinations offering the ‘SSN’ shipment option (e.g. Benelux) it is possible to do a shipment on behalf of someone else. This is done by an extra information block called ‘onBehalfOf’. It has the same structure as the ‘shipper’ block.

"onBehalfOf": {
  "name": {
    "firstName": "Mr",
    "lastName": "Onbehalfof",
    "companyName": "DHL eCommerce",
    "additionalName": "Benelux"
  },
  "address": {
    "countryCode": "NL",
    "postalCode": "3542AD",
    "city": "Onbehalf",
    "street": "Onbehalfweg",
    "number": "2",
    "isBusiness": false
  },
  "email": "onhalf@gx.com",
  "phoneNumber": "0031612345678"
}

In addition to the onBehalfOn block the shipping option undisclosed sender (SSN) is required:

{
  "key": "SSN"
}

It is possible to do an onBehalfOf shipment outside the Benelux, but the original sender will not be anonymous in the Track & Trace info (DHL).

In the case of an onBehalfOf shipment outside the Benelux it also necessary to use the onBehalfOf json block, but the shipping option undisclosed sender should be left out of the request.

Ad 2. Adding shipment options

Some shipments options require specifying extra information. For example, in the case of a cash on delivery, the amount should be specified or in case of a reference, some text is needed as input. Whether additional information is necessary for the shipping option is determined by the ‘input type’ listed with the shipment option (See Shipment Options or Capabilities endpoint).

For example shipment option ‘REFERENCE’ will be returned like:

{
  "key": "REFERENCE",
  "description": "Reference",
  "rank": 5,
  "code": 0,
  "inputType": "text",
  "inputMax": "15"
}

When the extra information is required the field “input” can be used to specify this.

For example, in case of a delivery to a parcel shop, the parcel shop is identified by it’s id through the input field.

{
  "key": "PS",
  "input": "8004-NL-272403"
}

In case a parcel is to be delivered at a postbox of German PackStation, the syntax is first the id of the parcel station delimited by ‘|’ and then the postnummer of the recipient:

{
  "key": "PS",
  "input": "8003-4125530|12345"
}

In case of cash on delivery, the amount that needs to be paid by the recipient serves as input.

{
  "key": "COD_CASH",
  "input": 5
}

Ad 3. Create return label

A label is either a ‘normal’, so an initial label or a return label. By setting the value of the ‘returnLabel’ attribute to ‘true’, the endpoint will create a return label; a return label is marked as a RETURN label. Note that there must be a return product available (a setting for your account).

return label

When creating a return label, make sure the receiver and shipper information are set correctly. If a customer returns a package, the customer’s address becomes the shipper’s address and the company’s address becomes the receiver’s address.

To have a return label created automatically with the original label, supply the ADD_RETURN_LABEL shipment option to the shipment. Note that option is only supported on the ‘Create Shipment’ endpoint.

Ad 4. Mono/multi collo (pieces)

The create shipment service will produce one shipment per request, but it can contain more than one piece or package.

If a shipment contains for example two packages, a single piece can be specified with quantity 2 in case the packages are of an identical type, or both packages can be specified using two pieces.

See given examples of the created labels for quantity greater than 1.

multiple labels

Multi colli is only possible if the shipment is not a single piece product (mono collo). In general shipments meant for consumers are mono collo products, but not necessarily.

In the capabilities service you can determine if the product is a mono collo. See example of an excerpt from the capability service below, the attribute monoColloProduct is either true or false.

{
  "rank": 2,
  "fromCountryCode": "NL",
  "toCountryCode": "NL",
  "product": {
    "key": "DFY-SDD",
    "label": "DFY",
    "code": "00",
    "menuCode": "07",
    "businessProduct": true,
    "monoColloProduct": true,
    "softwareCharacteristic": "B2X",
    "returnProduct": false
  },
  "parcelType": {
    "key": "MEDIUM",
    "minWeightKg": 20,
    "maxWeightKg": 31,
    "dimensions": {
      "maxLengthCm": 80,
      "maxWidthCm": 50,
      "maxHeightCm": 35
    }
  },
  "options": [
    {
      "key": "DOOR",
      "description": "Delivery to the address of the recipient",
      "rank": 2,
      "code": 0,
      "exclusions": [
        {

Ad 5. Customs

When sending to a customs destination, a customsDeclaration should be specified in the shipment request so that we can send the commercial invoice of a customs declaration.

"customsDeclaration" : {
  "currency": "GBP",
  "invoiceNumber": "123.A01",
  "type": "COMMERCIAL",
  "exportReason": "SaleOfGoods",
  "products": [
    {
      "code": "85365019",
      "description": "Air flow switch",
      "origin": "NL",
      "quantity": 1,
      "value": 745,
      "weight": 0.8
    },
    {
      "code": "90269000",
      "description": "Adaptor",
      "origin": "DE",
      "quantity": 2,
      "value": 12.5,
      "weight": 0.3
    },
    {
      "code": "85444290",
      "description": "Cable connector",
      "origin": "PL",
      "quantity": 3,
      "value": 62.5,
      "weight": 0.35
    }
  ],
  "incoTerms": "CFR",
  "importerOfRecord": {
    "name": {
      "firstName": "Mr",
      "lastName": "Importer",
      "companyName": "DHL eCommerce",
      "additionalName": "Britain"
    },
    "address": {
      "countryCode": "GB",
      "postalCode": "E11 1AB",
      "city": "London",
      "street": "Store Road",
      "number": "1",
      "isBusiness": true
    },
    "email": "imporer@gx.com",
    "phoneNumber": "0031612345678",
    "vatNumber": "GB123456789",
    "eori": "GB123456789"
  }
}

Depending on input details, a CN23 form or invoice is generated as well.

When a customsDeclaration is provided, the generated customsDeclarationId is included in the response. This can be used to retrieve the declaration and generated documents through Get customs declaration by id.

Generated documents can also be retrieved through Get customs forms by shipment id

Multiple custom attachments can be included, but the combined size of all attachments is limited to 2.5 MB for Benelux.

4.2.2 Create label

*Deprecated, please use Create shipment to create a shipment and retrieve labels using the shipment response information or the get multiple labels endpoint. While this endpoint will be supported, new features will be added only to the Create shipment

The Create label endpoint constructs one label at a time, which can be either a standard label or a return label.

In order to create a label, a unique identifier is needed as input for the label request. The format for this identifier is the Universally Unique Identifier (UUID). The use of UUIDs keeps our API idempotent. It ensures in this case that a label is created uniquely and just once, without needing to do any expensive and complicated synchronized bookkeeping.

Most programming languages and platforms have a built-in UUID generator that you can use for this purpose.A brief explanation on the other input data is given in the table below.

Be aware that the use of an authorization token in the header of the HTTP request is mandatory.

Field Type Mandatory Description
labelId string Y Use a UUID Generator
labelFormat string N Determines label binary representation included in the JSON response. Defaults to ‘pdf’.
orderReference string N Your own reference for the label(s), e.g. your order number.
parcelTypeKey string Y See ParcelTypes endpoint in API docs
receiver   Y Name and address
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
onBehalfOf   N Name and address. See Ad 1.
name     Requires at least firstName, lastName or companyName
firstName string    
lastName string    
companyName string    
additionalName string    
address     Depending on country, use designated endpoint for address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
shipper   Y Name and address
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
email string N  
phoneNumber string N  
accountId string Y  
options array    
key string Y See Capabilities endpoint in API docs and Ad 2.
input   N See Ad 2.
returnLabel boolean N See Ad 3.
pieceNumber integer N See Ad 6.
quantity integer N  
automaticPrintDialog boolean N If true, PDF labels will include a flag that opens the print dialog in supported software (Acrobat reader).

Ad 6. Multi collo (pieces)

The create label service will produce just one label per request, but if the shipment contains more than one piece or package it is possible to specify this on the label through ‘pieceNumber’ and ‘quantity’ request attributes.

If a shipment contains for example two packages, the label service needs to be called twice. The information set for first call to label service would be pieceNumber 1, quantity 2. For the second label this information is set to pieceNumber 2, quantity 2.

See given examples of the created labels.

multiple labels

Multi colli is only possible if the shipment is not a single piece product (mono collo). In general shipments meant for consumers are mono collo products, but not necessarily.

In the capabilities service you can determine if the product is a mono collo. See example of an excerpt from the capability service below, the attribute monoColloProduct is either true or false.

Multi colli shipments will get a shipment tracker code assigned (in addition to the individual piece tracker codes). When this tracker code is generated by the label service, the shipmentTrackerCode field will be present in the response. However, in certain cases the shipment tracker code will be generated later in the logistical workflow, and therefore the shipment tracker code is not known by the label service API.

{
  "rank": 2,
  "fromCountryCode": "NL",
  "toCountryCode": "NL",
  "product": {
    "key": "DFY-SDD",
    "label": "DFY",
    "code": "00",
    "menuCode": "07",
    "businessProduct": true,
    "monoColloProduct": true,
    "softwareCharacteristic": "B2X",
    "returnProduct": false
  },
  "parcelType": {
    "key": "MEDIUM",
    "minWeightKg": 20,
    "maxWeightKg": 31,
    "dimensions": {
      "maxLengthCm": 80,
      "maxWidthCm": 50,
      "maxHeightCm": 35
    }
  },
  "options": [
    {
      "key": "DOOR",
      "description": "Delivery to the address of the recipient",
      "rank": 2,
      "code": 0,
      "exclusions": [
        {

4.2.3 Get label id by tracking code or order reference

The Find labels endpoint by tracker code or order reference is used to retrieve label information.

The endpoint will return, among other identifying information (but not the label), the registered label id to use with the get label by id endpoint.

The use of the authorization token in the header of http request is mandatory.

4.2.4 Get label by id

With the label id, as fetched with the endpoint Get label id by tracking code or order reference, a specific label can be retrieved through Get label endpoint by id.

The Get label endpoint by id result depends on the content of the Accept header.

Accept Result
application/json Detailed label information, including organization id
application/pdf PDF document with the specified label(s)
application/zpl ZPL document with the specified label(s)

4.2.5 Get multiple labels

The Get multiple labels endpoint is used to retrieve multiple labels in a single document, based on the content of the Accept header.

Accept Result
application/pdf PDF document with the specified label(s)
application/zpl ZPL document with the specified label(s)

All documents are sent using chunked transfer encoding.

4.2.5.1 Specify labels to include

The request body specifies the labels to include:

Field Type Mandatory Description
labelIds array N Include all labels with the specified ids
shipmentIds array N Include all labels for the shipments with the specified ids
trackerCodes array N Include all labels with the specified tracker codes
shipmentTrackerCodes array N Include all labels for the shipments with the specified tracker codes

Any combination of fields can be used to retrieve labels. If no labels are specified, the request fails and no document is returned.

The use of the authorization token in the header of http request is mandatory.

4.2.5.2 Ordering

Generally, labels are rendered in the following order:

  1. Field order as described above, so first all labels requested by labelIds are included, then all labels requested by shipmentIds, etc.
  2. Specified order in the array for the requested field, so first the label in the first position, then the label in the second position, etc.
  3. Piece number in case of multiple labels for a single element, so first piece number one for a shipment, then piece number two, etc.

In some cases, labels for a single request can have various sizes demanding different paper layouts. In that case we aim to preserve paper by grouping labels with the same layout. The order of labels within each group is preserved. This behaviour can be disabled by setting the ordering field to original.

4.2.5.3 Non-existing labels

When requesting multiple labels, a non-existing label can be specified. By default any request with a non-existing label fails and no document is returned. In some cases, it might be convenient to silently skip any non-existing labels by setting the missingLabelPolicy field to skip.

In case all specified labels do not exist, the request fails regardless of the specified option.

4.2.5.4 PDF specific rendering options

When getting multiple labels as PDF, additional options can be specified.

Field Type Mandatory Description
autoPrintDialog boolean N Automatically show print dialog when PDF is opened using a PDF reader that supports that option.
pageSize string N Render every label in their original size on a single page, or arrange labels on a larger page (a4).
pageOptions object N Additional options when arranging labels.
pageLayout string N Physical page layout affects how labels are arranged in landscape mode. Ignored for A4 sized labels (always 1 per page) and A6 labels (always 4 per page in portrait mode).
mixedLayoutPolicy string N Can be specified to ensure a certain label arrangement always matches the physical page layout.
firstPageOffset string N Rendering option that allows to continue printing on re-used paper.

4.3 API Usage

Description URL
Create shipment endpoint https://api-gw.dhlparcel.nl/shipments
Endpoint to get label information by tracking code https://api-gw.dhlparcel.nl/labels?trackerCodeFilter=”your_tracking_code”
Endpoint to get label information by order reference https://api-gw.dhlparcel.nl/labels?orderReferenceFilter=”your_order_reference”
Endpoint to get the label of a specific package https://api-gw.dhlparcel.nl/labels/your_labelId

4.3.1 Create shipment

Request examples

Curl
curl -X POST "https://api-gw.dhlparcel.nl/shipments" \
     -H "Accept: application/json" \
     -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhNzAxN2EzZi1jMGYzLTQ3ZTAtOGQzNC1mMmZhMDFjYTlkY2EiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzUwNywiZXhwIjoxNTExODY4NDA4LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.Qs79I-LW0ES4mO8hObOiZXvuuipBQ_-eJ7pd-10rrSQ" \
     -H "Content-Type: application/json" \
     -i \
     -d "{
     		\"shipmentId\": \"331708e4-e876-4f9a-94f3-c74bd482988b\",
     		\"orderReference\":\"myReference\",
     		\"receiver\": {
     			\"name\": {
     				\"firstName\": \"John\",
     				\"lastName\": \"Doe\",
     				\"companyName\": \"ACME Corp.\",
     				\"additionalName\": \"Benelux\"
     			},
     			\"address\": {
     				\"countryCode\": \"NL\",
     				\"postalCode\": \"3542AD\",
     				\"city\":\"Utrecht\",
     				\"street\": \"Reactorweg\",
     				\"number\": \"25\",
     				\"isBusiness\": true,
     				\"addition\": \"A\"
     			},
     			\"email\": \"mrparcel@dhl.com\",
     			\"phoneNumber\":\"0031612345678\"
     		},
     		\"shipper\": {
     			\"name\": {
     				\"firstName\": \"John\",
     				\"lastName\":\"Doe\",
     				\"companyName\": \"ACME Corp.\",
     				\"additionalName\": \"Benelux\"
     			},
     			\"address\": {
     				\"countryCode\": \"NL\",
     				\"postalCode\": \"3542AD\",
     				\"city\": \"Utrecht\",
     				\"street\": \"Reactorweg\",
     				\"number\": \"25\",
     				\"isBusiness\": true,
     				\"addition\": \"A\"
     			},
     			\"email\": \"mrparcel@dhl.com\",
     			\"phoneNumber\":\"0031612345678\"
     		},
     		\"accountId\": \"01234567\",
     		\"options\": [
     			{ \"key\": \"DOOR\" }
     		],
     		\"returnLabel\": false,
     		\"pieces\": [
     			{
	     			\"parcelType\": \"SMALL\",
	     			\"quantity\": 1,
	     			\"weight\": 1.5
     			}
     		]
     	}"
PHP
<?php
// Get cURL resource
$ch = curl_init();

// Set url
curl_setopt($ch, CURLOPT_URL, 'https://api-gw.dhlparcel.nl/shipments');

// Set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');


// Set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );

// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json; charset=utf-8",
"Authorization: Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkYWFkNzU3ZC03NGY4LTQ5YzktOWI4OC1kMzEyN2
Q2ZDczMDAiLCJzdWIiOiI5MWQ5NGZiZC0xODk2LTQyMTctODlkNy0wM2M4ZTY4Y2YwYTAiLCJvcmdhbml6YXRpb
25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzczMSwiZXhw
IjoxNTExODY4NjMyLCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJ
hY2NvdW50cyI6WyI3NDY1NjE3MCIsIjEyMzQ1Njk4IiwiNDU5MDAxMDAiLCI0MDA0NDU4OSIsIjg3NjU0MzIxIi
wiMzMzMzMzMzMiLCIwNTkyMDUxNyIsIjA4NTAwMDAxIiwiMTIzNDU2NzgiLCIwNTk1Nzg0MCJdfQ.KywXOWovoS
Vf1WJ-CWAJ9j4rUXuMp-f0q2c2PKkOZno",
"Accept: application/pdf",
]
);
// Create body
$json_array = [
"accountId" => "01234567",
"labelId" => "85146e8f-c5c6-40a5-9a1b-25548d607cd7",
"receiver" => [
"email" => "s.krampus@lechio.com",
"phoneNumber" => "0031612345678",
"name" => [
"firstName" => "Slab",
"companyName" => "Lechio",
"lastName" => "Krampus"
],
"address" => [
"countryCode" => "NL",
"number" => "74",
"isBusiness" => true,
"street" => "Baan",
"city" => "Rotterdam",
"postalCode" => "3011CD"
]
],
"shipper" => [
"email" => "shipper@dhlparcel.nl",
"phoneNumber" => "0031612345678",
"name" => [
"firstName" => "Jan",
"lastName" => "Jansen"
],
"address" => [
"street" => "Reactorweg",
"city" => "Utrecht",
"number" => "25",
"postalCode" => "3542AD",
"isBusiness" => true,
"addition" => "A",
"countryCode" => "NL"
]
],
"options" => [
[
"key" => "DOOR"
],
[
"key" => "COD_CASH",
"input" => "5"
]
],
"returnLabel" => false,
"pieces" => [
[
"parcelType" => "SMALL",
"quantity" => 1
]
]
];
$body = json_encode($json_array);

// Set body
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

// Send the request & save response to $resp
$resp = curl_exec($ch);

if(!$resp) {
die('Error: "'. curl_error($ch). '" - Code: '. curl_errno($ch));
} else {
echo "Response HTTP Status Code : ". curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nResponse HTTP Body : ". $resp;
}

// Close request to clear up some resources
curl_close($ch);
PHP cURL - WordPress
<?php
// Create JSON body
$json = json_encode( array(
'accountId' => '01234567',
'labelId' => '1e877014-fa2f-424c-95e7- 2 e2e8a05af44',
'receiver' => array(
'email' => 's.krampus@lechio.com',
'phoneNumber' => '0031612345678',
'name' => array(
'firstName' => 'Slab',
'companyName' => 'Lechio',
'lastName' => 'Krampus'
),,
'address' => array(
'countryCode' => 'NL',
'number' => '74',
'isBusiness' => true,
'street' => 'Baan',
'city' => 'Rotterdam',
'postalCode' => '3011CD'
),
),,
'shipper' => array(
'email' => 'shipper@dhlparcel.nl',
'phoneNumber' => '0031612345678',
'name' => array(
'firstName' => 'Jan',
'lastName' => 'Jansen'
),,
'address' => array(
'street' => 'Reactorweg',
'city' => 'Utrecht',
'number' => '25',
'postalCode' => '3542AD',
'isBusiness' => true,
'addition' => 'A',
'countryCode' => 'NL'
),
),,
'options' => array(
array(
'key' => 'DOOR'
),,
array(
'key' => 'COD_CASH',
'input' => '5'
),
),,
'pieces' => array(
'parcelType' => 'SMALL',
'quantity' => 1 ,
),,
'returnLabel' => false
) );

// {@see https://codex.wordpress.org/HTTP_API}
$response = wp_remote_post( 'https://api-gw.dhlparcel.nl/shipments', array(
'headers' => array(
'Content-Type' => 'application/json; charset=utf-8',
'Authorization' => 'Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkYWFkNzU3ZC03NGY4LTQ5YzktOWI4OC1kMzEyN2
Q2ZDczMDAiLCJzdWIiOiI5MWQ5NGZiZC0xODk2LTQyMTctODlkNy0wM2M4ZTY4Y2YwYTAiLCJvcmdhbml6YXRpb
25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzczMSwiZXhw
IjoxNTExODY4NjMyLCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJ
hY2NvdW50cyI6WyI3NDY1NjE3MCIsIjEyMzQ1Njk4IiwiNDU5MDAxMDAiLCI0MDA0NDU4OSIsIjg3NjU0MzIxIi
wiMzMzMzMzMzMiLCIwNTkyMDUxNyIsIjA4NTAwMDAxIiwiMTIzNDU2NzgiLCIwNTk1Nzg0MCJdfQ.KywXOWovoS
Vf1WJ-CWAJ9j4rUXuMp-f0q2c2PKkOZno',
'Accept' => 'application/pdf',
),
'body' => $json,
) );

if (! is_wp_error( $response ) ) {
// The request went through successfully, check the response code against
// what we're expecting
if ( 200 == wp_remote_retrieve_response_code( $response ) ) {
// Do something with the response
// $body = wp_remote_retrieve_body( $response );
// $headers = wp_remote_retrieve_headers( $response );
} else {
// The response code was not what we were expecting, record the message
$error_message = wp_remote_retrieve_response_message( $response );


}
} else {
// There was an error making the request
$error_message = $response->get_error_message();
}

Responses

Success (code 201)
{
  "shipmentId": "15916857-2a31-4238-a45b-e7ba32e0e320",
  "shipmentTrackerCode": "0123456789",
  "pieces": [
    {
      "labelId": "061091e9-f6cf-453e-951d-5a276303d060",
      "trackerCode": "JVGL08500001813590386271",
      "parcelType": "SMALL",
      "pieceNumber": 1,
      "weight": 1
    }
  ],
}

4.3.2 Create Label

Request examples

Curl
curl -X POST "https://api-gw.dhlparcel.nl/labels" -H "Accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhNzAxN2EzZi1jMGYzLTQ3ZTAtOGQzNC1mMmZhMDFjYTlkY2EiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzUwNywiZXhwIjoxNTExODY4NDA4LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.Qs79I-LW0ES4mO8hObOiZXvuuipBQ_-eJ7pd-10rrSQ" -H "Content-Type: application/json" -d "{ \"labelId\": \"331708e4-e876-4f9a-94f3-c74bd482988b\",\"labelFormat\": \"pdf\", \"orderReference\":\"myReference\",\"parcelTypeKey\": \"SMALL\", \"receiver\": { \"name\": { \"firstName\": \"John\",\"lastName\": \"Doe\", \"companyName\": \"ACME Corp.\", \"additionalName\": \"Benelux\"}, \"address\": { \"countryCode\": \"NL\", \"postalCode\": \"3542AD\", \"city\":\"Utrecht\", \"street\": \"Reactorweg\", \"number\": \"25\", \"isBusiness\": true,\"addition\": \"A\" }, \"email\": \"mrparcel@dhl.com\", \"phoneNumber\":\"0031612345678\" }, \"shipper\": { \"name\": { \"firstName\": \"John\", \"lastName\":\"Doe\", \"companyName\": \"ACME Corp.\", \"additionalName\": \"Benelux\" },\"address\": { \"countryCode\": \"NL\", \"postalCode\": \"3542AD\", \"city\":\"Utrecht\", \"street\": \"Reactorweg\", \"number\": \"25\", \"isBusiness\": true,\"addition\": \"A\" }, \"email\": \"mrparcel@dhl.com\", \"phoneNumber\":\"0031612345678\" }, \"accountId\": \"01234567\", \"options\": [ { \"key\": \"DOOR\" }], \"returnLabel\": false,\"pieceNumber\": 1, \"quantity\": 1,\"automaticPrintDialog\": true}"
PHP
<?php
// Get cURL resource
$ch = curl_init();

// Set url
curl_setopt($ch, CURLOPT_URL, 'https://api-gw.dhlparcel.nl/labels');

// Set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');


// Set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );

// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json; charset=utf-8",
"Authorization: Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkYWFkNzU3ZC03NGY4LTQ5YzktOWI4OC1kMzEyN2
Q2ZDczMDAiLCJzdWIiOiI5MWQ5NGZiZC0xODk2LTQyMTctODlkNy0wM2M4ZTY4Y2YwYTAiLCJvcmdhbml6YXRpb
25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzczMSwiZXhw
IjoxNTExODY4NjMyLCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJ
hY2NvdW50cyI6WyI3NDY1NjE3MCIsIjEyMzQ1Njk4IiwiNDU5MDAxMDAiLCI0MDA0NDU4OSIsIjg3NjU0MzIxIi
wiMzMzMzMzMzMiLCIwNTkyMDUxNyIsIjA4NTAwMDAxIiwiMTIzNDU2NzgiLCIwNTk1Nzg0MCJdfQ.KywXOWovoS
Vf1WJ-CWAJ9j4rUXuMp-f0q2c2PKkOZno",
"Accept: application/pdf",
]
);
// Create body
$json_array = [
"accountId" => "01234567",
"labelId" => "85146e8f-c5c6-40a5-9a1b-25548d607cd7",
"receiver" => [
"email" => "s.krampus@lechio.com",
"phoneNumber" => "0031612345678",
"name" => [
"firstName" => "Slab",
"companyName" => "Lechio",
"lastName" => "Krampus"
],
"address" => [
"countryCode" => "NL",
"number" => "74",
"isBusiness" => true,
"street" => "Baan",
"city" => "Rotterdam",
"postalCode" => "3011CD"
]
],
"shipper" => [
"email" => "shipper@dhl.com",
"phoneNumber" => "0031612345678",
"name" => [
"firstName" => "Jan",
"lastName" => "Jansen"
],
"address" => [
"street" => "Reactorweg",
"city" => "Utrecht",
"number" => "25",
"postalCode" => "3542AD",
"isBusiness" => true,
"addition" => "A",
"countryCode" => "NL"
]
],
"parcelTypeKey" => "SMALL",
"pieceNumber" => 1 ,
"quantity" => 1 ,
"automaticPrintDialog" => false,


"options" => [
[
"key" => "DOOR"
],
[
"key" => "COD_CASH",
"input" => "5"
]
],
"returnLabel" => false
];
$body = json_encode($json_array);

// Set body
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);

// Send the request & save response to $resp
$resp = curl_exec($ch);

if(!$resp) {
die('Error: "'. curl_error($ch). '" - Code: '. curl_errno($ch));
} else {
echo "Response HTTP Status Code : ". curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nResponse HTTP Body : ". $resp;
}

// Close request to clear up some resources
curl_close($ch);
PHP cURL - WordPress
<?php
// Create JSON body
$json = json_encode( array(
'accountId' => '01234567',
'labelId' => '1e877014-fa2f-424c-95e7- 2 e2e8a05af44',
'receiver' => array(
'email' => 's.krampus@lechio.com',
'phoneNumber' => '0031612345678',
'name' => array(
'firstName' => 'Slab',
'companyName' => 'Lechio',
'lastName' => 'Krampus'
),,
'address' => array(
'countryCode' => 'NL',
'number' => '74',
'isBusiness' => true,
'street' => 'Baan',
'city' => 'Rotterdam',
'postalCode' => '3011CD'
),
),,
'shipper' => array(


'email' => 'shipper@dhl.com',
'phoneNumber' => '0031612345678',
'name' => array(
'firstName' => 'Jan',
'lastName' => 'Jansen'
),,
'address' => array(
'street' => 'Reactorweg',
'city' => 'Utrecht',
'number' => '25',
'postalCode' => '3542AD',
'isBusiness' => true,
'addition' => 'A',
'countryCode' => 'NL'
),
),,
'parcelTypeKey' => 'SMALL',
'pieceNumber' => 1 ,
'quantity' => 1 ,
'automaticPrintDialog' => false,
'options' => array(
array(
'key' => 'DOOR'
),,
array(
'key' => 'COD_CASH',
'input' => '5'
),
),,
'returnLabel' => false
) );

// {@see https://codex.wordpress.org/HTTP_API}
$response = wp_remote_post( 'https://api-gw.dhlparcel.nl/labels', array(
'headers' => array(
'Content-Type' => 'application/json; charset=utf-8',
'Authorization' => 'Bearer
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkYWFkNzU3ZC03NGY4LTQ5YzktOWI4OC1kMzEyN2
Q2ZDczMDAiLCJzdWIiOiI5MWQ5NGZiZC0xODk2LTQyMTctODlkNy0wM2M4ZTY4Y2YwYTAiLCJvcmdhbml6YXRpb
25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzczMSwiZXhw
IjoxNTExODY4NjMyLCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJ
hY2NvdW50cyI6WyI3NDY1NjE3MCIsIjEyMzQ1Njk4IiwiNDU5MDAxMDAiLCI0MDA0NDU4OSIsIjg3NjU0MzIxIi
wiMzMzMzMzMzMiLCIwNTkyMDUxNyIsIjA4NTAwMDAxIiwiMTIzNDU2NzgiLCIwNTk1Nzg0MCJdfQ.KywXOWovoS
Vf1WJ-CWAJ9j4rUXuMp-f0q2c2PKkOZno',
'Accept' => 'application/pdf',
),
'body' => $json,
) );

if (! is_wp_error( $response ) ) {
// The request went through successfully, check the response code against
// what we're expecting
if ( 200 == wp_remote_retrieve_response_code( $response ) ) {
// Do something with the response
// $body = wp_remote_retrieve_body( $response );
// $headers = wp_remote_retrieve_headers( $response );
} else {
// The response code was not what we were expecting, record the message
$error_message = wp_remote_retrieve_response_message( $response );


}
} else {
// There was an error making the request
$error_message = $response->get_error_message();
}

Responses

Success (code 201)
{
  "labelId": "331708e4-e876-4f9a-94f3-c74bd482988b",
  "labelType": "B2X_Generic_A4_Third",
  "trackerCode": "JVGL01234567889003262926",
  "routingCode": "2LNL3542AD+04000000",
  "userId": "a86628b8-a4bd-436b-8d92-cd735223c9e5",
  "orderReference": "myReference",
  "pdf": "<pdf-label>"
}

4.3.3 Get Label (trackerCodeFilter)

Request examples

Curl
curl -X GET "https://api-gw.dhlparcel.nl/labels?trackerCodeFilter=JVGL08500001813590386271" -H "Accept:application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhNzAxN2EzZi1jMGYzLTQ3ZTAtOGQzNC1mMmZhMDFjYTlkY2EiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzUwNywiZXhwIjoxNTExODY4NDA4LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.Qs79I-LW0ES4mO8hObOiZXvuuipBQ_-eJ7pd-10rrSQ"

Responses

Success (code 200)
[
  {
    "labelId": "ecda3006-b605-413f-b3b1-e0dca32e987e",
    "orderReference": "393d649c-fdf4-4e16-b329-40c36e8cff48",
    "labelType": "B2X_Generic_A4_Third",
    "trackerCode": "JVGL08500001813590386271",
    "routingCode": "2LIC12342+04000001",
    "userId": "6bfc7561-4b41-4cb7-a1c3-dc31faf860db",
    "organizationId": "a40933de-bd17- 4944 - b7e9-23fc7ee9c835"
  }
]

4.3.4 Get pdf label specific shipment

Request examples

Curl
curl -X GET "https://api-gw.dhlparcel.nl/labels/ecda3006-b605-413f-b3b1-e0dca32e987e" -H "Accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhNzAxN2EzZi1jMGYzLTQ3ZTAtOGQzNC1mMmZhMDFjYTlkY2EiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzUwNywiZXhwIjoxNTExODY4NDA4LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.Qs79I-LW0ES4mO8hObOiZXvuuipBQ_-eJ7pd-10rrSQ"

Responses

Success (code 200):
{
  "labelId": "ecda3006-b605-413f-b3b1-e0dca32e987e",
  "labelType": "B2X_Generic_A4_Third",
  "trackerCode": "JVGL08500001813590386271",
  "routingCode": "2LIC12342+04000001",
  "userId": "6bfc7561-4b41-4cb7-a1c3-dc31faf860db",
  "organizationId": "a40933de-bd17- 4944 - b7e9-23fc7ee9c835",
  "orderReference": "393d649c-fdf4-4e16-b329-40c36e8cff48",
  "pdf": "<base64-encoded pdf-label>"
}

4.3.5 Create printless label

A printless label is not printed by the customer, but will be printed by DHL based on a QR-code at a DHL ServicePoint. By default, printless labels can be used for your B2C returns from NL.

printless label

By setting the value of the ‘returnLabel’ attribute to ‘true’ and adding the PRINTLESS option to a Create shipment request, the endpoint will create a printless QR code for the return shipment.

{
  "options": [
    {
      "key": "PRINTLESS"
     }
   ]
}

By default, shipment notifications including the generated QR code will be sent for return shipments. Triggering notifications can be disabled using the option input.

{
  "options": [
    {
      "key": "PRINTLESS",
        "input": {
          "notification": false
       }
     }
   ]
}

The response includes the printless codes, which can be used to generate customs QR codes.

{
    "shipmentId": "545d5455-c313-46fc-9546-9be146d5a056",
    "product": "DFY-B2C",
    "pieces": [
        {
            "printlessCode": "MDP5KLWYM4R",
            "parcelType": "MEDIUM",
            "pieceNumber": 1,
            "labelType": "PRINTLESS_QR"
        }
    ]
}

4.4 Testing

These test cases with positive outcomes are merely suggestions and it is not an extensive test set, e.g. test with negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Create a shipment A shipment is created and the identifying information is returned. Get label id by tracking code or order reference and the label identification is returned.
Create a label A label is created and the identifying information and pdf of the label is returned. Get label id by tracking code or order reference and the label identification is returned.
Get pdf label by id The pdf of the label is returned.

5 Track and Trace

5.1 Intro

With the Track & Trace endpoint a shipment can be tracked throughout the delivery process. The most important information from a business perspective will be discussed.

Preconditions

5.2 Services

5.2.1 Track and Trace

The Track & Trace endpoint is called with at least the tracker code, that is provided in the response of the Create label endpoint when the label has successfully been created.

A call to the T&T endpoint will result in a chain of events (technically an array), where each event falls into a category of the whereabouts of a shipment. A category holds a status which gives a more detailed description of what might be the exact current state of the shipment. Endpoints for the translation of these status fields can be found in the API gateway under Translations.

Status category Description
CUSTOMS The shipment is being processed by customs
DATA RECEIVED The shipment is registered
DELIVERED Delivered at door or DHL ServicePoint
EXCEPTION Something in the process went wrong, delay is expected
INTERVENTION An intervention occurred in the delivery process
IN DELIVERY The parcel is in transit
LEG Usually the trace of a domestic delivery will start with some LEG events. It means that the shipment is registered.
PROBLEM Same as exception
UNDERWAY The parcel is being sorted
UNKNOWN The status of the parcel is unknown

For more extensive information (shipment details) in the track & trace response the postal code of the receiver can be added in the request.

5.2.1.1 Delivery date

Initially there is no planned delivery date, but it can be calculated by deriving the transit time set for the country of origin and destination through the Transit-times endpoint.

Based on the country codes of origin, destination and the postal code, the transit time in days is given as a result by the endpoint. To calculate the planned delivery date simply add the transit time days to the shipment date.

As soon as a parcel has left the sorting center the planned delivery timeframe (‘plannedDeliveryTimeframe’) should be available in the next event.

This planned delivery timeframe can change or might not be available in the last event due to for example problems with the receiver’s address. The shipment gets marked with category PROBLEM or INTERVENTION and the shipment will need to be re-planned.

The fact that, and when, a parcel actually is delivered is communicated through the attribute ‘deliveredAt’ (at top level in the json response).

5.2.1.1 Proof of Delivery (POD)

If there is a signature available and the request has been made with the tracker code and the postal code of the receiver, the response contains a field pod that contains the URL for the POD image.

5.3 API Usage

Description URL
Get Track & Trace info https://api-gw.dhlparcel.nl/track-trace

5.3.1 Get Track & Trace info

Request examples

Curl
curl -X GET "https://api-gw.dhlparcel.nl/track-trace?key=3SBPB0000094346%2B9999AA" -H "Accept: application/json"

Responses

Success (code 200)
[
  {
    "barcode": "3SBPB0000094346",
    "date": "2017-11-28T23:00:00.000Z",
    "events": [
      {
        "category": "LEG",
        "leg": {
          "accountId": "5880133",
          "debtorNumber": "5880133",
          "destinationFacility": "ARM",
          "destinationServiceArea": "ARM",
          "number": "7451930615",
          "network": "DAY_DEFINITE",
          "originFacility": "MAA",
          "originServiceArea": "MAA",
          "reference": "60832634"
        },
        "localTimestamp": "2017-11-29T00:00:00.000+01:00",
        "status": "LEG_CREATED",
        "timestamp": "2017-11-28T23:00:00.000Z",
        "type": "LEG_EVENT"
      },
      {
        "category": "LEG",
        "leg": {
          "network": "DAY_DEFINITE"
        },
        "localTimestamp": "2017-11-29T00:00:00.000+01:00",
        "status": "LEG_REFERENCE_ADDED",
        "timestamp": "2017-11-28T23:00:00.000Z",
        "type": "LEG_EVENT"
      },
      {
        "category": "LEG",
        "leg": {
          "network": "DAY_DEFINITE",
          "reference": "60832634"
        },
        "localTimestamp": "2017-11-29T00:00:00.000+01:00",
        "status": "LEG_REFERENCE_ADDED",
        "timestamp": "2017-11-28T23:00:00.000Z",
        "type": "LEG_EVENT"
      },
      {
        "category": "LEG",
        "leg": {
          "network": "DAY_DEFINITE",
          "reference": "3SDSP004644834"
        },
        "localTimestamp": "2017-11-29T00:00:00.000+01:00",
        "status": "LEG_REFERENCE_ADDED",
        "timestamp": "2017-11-28T23:00:00.000Z",
        "type": "LEG_EVENT"
      },
      {
        "category": "DATA_RECEIVED",
        "localTimestamp": "2017-11-29T21:56:54.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "PRENOTIFICATION_RECEIVED",
        "timestamp": "2017-11-29T20:56:54.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "LEG",
        "leg": {
          "accountId": "79807100",
          "network": "ECOMMERCE"
        },
        "localTimestamp": "2017-11-29T21:57:07.000+01:00",
        "status": "LEG_CREATED",
        "timestamp": "2017-11-29T20:57:07.000Z",
        "type": "LEG_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "RXD",
        "height": 14,
        "length": 18,
        "localTimestamp": "2017-11-29T23:50:00.000+01:00",
        "leg": {
          "network": "DAY_DEFINITE"
        },
        "powerOfAttorney": false,
        "remarks": "",
        "route": "0",
        "scannedManual": false,
        "serviceArea": "RXD",
        "status": "DEPART_FACILITY",
        "stopNumber": 0,
        "timestamp": "2017-11-29T22:50:00.000Z",
        "weight": 0.2,
        "width": 14,
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "DD/RXD",
        "localTimestamp": "2017-11-29T23:50:00.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "PARCEL_SORTED_AT_HUB",
        "timestamp": "2017-11-29T22:50:00.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "localTimestamp": "2017-11-30T00:11:27.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-01T14:00:00.000+01:00/2017-12-01T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-11-30T14:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "status": "INFORMATION_ON_DELIVERY_TRANSMITTED",
        "timestamp": "2017-11-29T23:11:27.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARM",
        "height": 14,
        "length": 18,
        "localTimestamp": "2017-11-30T03:55:00.000+01:00",
        "leg": {
          "network": "DAY_DEFINITE"
        },
        "plannedDeliveryTimeframe": "2017-11-30T08:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "powerOfAttorney": false,
        "remarks": "",
        "route": "0",
        "scannedManual": false,
        "serviceArea": "ARM",
        "status": "ARRIVED_AT_DELIVERY_FACILITY",
        "stopNumber": 0,
        "timestamp": "2017-11-30T02:55:00.000Z",
        "weight": 0.2,
        "width": 14,
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-11-30T04:42:41.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "20 17-12-01T14:00:00.000+01:00/2017-12-01T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-11-30T14:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "route": "1",
        "status": "DELIVERY_PLANNED_IN_ROUTE",
        "timestamp": "2017-11-30T03:42:41.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARM",
        "height": 14,
        "length": 18,
        "localTimestamp": "2017-11-30T08:04:00.000+01:00",
        "leg": {
          "network": "DAY_DEFINITE"
        },
        "plannedDeliveryTimeframe": "2017-11-30T08:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "powerOfAttorney": false,
        "remarks": "DHL eCommerce Arnhem Zuid",
        "route": "512150",
        "scannedManual": true,
        "serviceArea": "ARM",
        "status": "IN_ROUTE_THIRD_PARTY",
        "stopNumber": 1,
        "timestamp": "2017-11-30T07:04:00.000Z",
        "weight": 0.2,
        "width": 14,
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-11-30T08:05:15.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-01T14:00:00.000+01:00/2017-12-01T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-11-30T14:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "route": "2",
        "status": "DELIVERY_PLANNED_IN_ROUTE",
        "timestamp": "2017-11-30T07:05:15.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARM",
        "height": 14,
        "length": 18,
        "localTimestamp": "2017-11-30T08:46:00.000+01:00",
        "leg": {
          "network": "DAY_DEFINITE"
        },
        "plannedDeliveryTimeframe": "2017-11-30T08:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "powerOfAttorney": false,
        "remarks": "DHL eCommerce Arnhem Zuid",
        "route": "512150",
        "scannedManual": true,
        "serviceArea": "ARM",
        "status": "FORWARD_DESTINATION",
        "stopNumber": 1,
        "timestamp": "2017-11-30T07:46:00.000Z",
        "weight": 0.2,
        "width": 14,
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ETTPAK",
        "localTimestamp": "2017-11-30T09:11:09.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "route": "2",
        "status": "PARCEL_ARRIVED_AT_LOCAL_DEPOT",
        "timestamp": "2017-11-30T08:11:09.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "PROBLEM",
        "facility": "ARNPAK",
        "localTimestamp": "2017-11-30T09:11:10.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-01T14:00:00.000+01:00/2017-12-01T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-11-30T14:00:00.000+01:00/2017-11-30T18:00:00.000+01:00",
        "route": "2",
        "status": "MISSORT",
        "timestamp": "2017-11-30T08:11:10.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ETTPAK",
        "localTimestamp": "2017-11-30T09:11:40.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "route": "2",
        "status": "PARCEL_ARRIVED_AT_LOCAL_DEPOT",
        "timestamp": "2017-11-30T08:11:40.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "PI",
        "localTimestamp": "2017-12-01T20:55:13.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "PARCEL_SCANNED_AT_RETURN_HUB",
        "timestamp": "2017-12-01T19:55:13.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "PI",
        "localTimestamp": "2017-12-03T17:42:26.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "DEPOT_SCAN",
        "timestamp": "2017-12-03T16:42:26.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "PI",
        "localTimestamp": "2017-12-05T21:58:56.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "DEPOT_SCAN",
        "timestamp": "2017-12-05T20:58:56.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "EC&gt;144",
        "localTimestamp": "2017-12-06T18:04:40.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "status": "PARCEL_SORTED_AT_HUB",
        "timestamp": "2017-12-06T17:04:40.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "localTimestamp": "2017-12-06T18:07:37.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-08T14:00:00.000+01:00/2017-12-08T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-12-07T14:00:00.000+01:00/2017-12-07T18:00:00.000+01:00",
        "status": "INFORMATION_ON_DELIVERY_TRANSMITTED",
        "timestamp": "2017-12-06T17:07:37.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T04:14:46.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-08T14:00:00.000+01:00/2017-12-08T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-12-07T14:00:00.000+01:00/2017-12-07T18:00:00.000+01:00",
        "route": "1",
        "status": "DELIVERY_PLANNED_IN_ROUTE",
        "timestamp": "2017-12-07T03:14:46.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "UNDERWAY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T08:14:50.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "route": "1",
        "status": "PARCEL_ARRIVED_AT_LOCAL_DEPOT",
        "timestamp": "2017-12-07T07:14:50.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "IN_DELIVERY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T09:47:23.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-08T14:00:00.000+01:00/2017-12-08T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-12-07T14:00:00.000+01:00/2017-12-07T18:00:00.000+01:00",
        "route": "1",
        "status": "PARCEL_SCANNED_INTO_HAND-TERMINAL",
        "timestamp": "20 17-12-07T08:47:23.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "IN_DELIVERY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T10:15:18.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-08T14:00:00.000+01:00/2017-12-08T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-12-07T14:00:00.000+01:00/2017-12-07T18:00:00.000+01:00",
        "route": "1",
        "status": "OUT_FOR_DELIVERY",
        "timestamp": "2017-12-07T09:15:18.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "IN_DELIVERY",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T10:15:18.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "route": "1",
        "status": "PARCEL_HANDED_OVER_TO_COURIER",
        "timestamp": "2017-12-07T09:15:18.000Z",
        "type": "PIECE_EVENT"
      },
      {
        "category": "DELIVERED",
        "facility": "ARNPAK",
        "localTimestamp": "2017-12-07T16:58:41.000+01:00",
        "leg": {
          "network": "ECOMMERCE"
        },
        "nextPlannedDeliveryTimeframe": "2017-12-08T14:00:00.000+01:00/2017-12-08T18:00:00.000+01:00",
        "plannedDeliveryTimeframe": "2017-12-07T14:00:00.000+01:00/2017-12-07T18:00:00.000+01:00",
        "route": "1",
        "status": "DELIVERED",
        "timestamp": "2017-12-07T15:58:41.000Z",
        "type": "PIECE_EVENT"
      }
    ],
    "type": "SHIPMENT",
    "deliveredAt": "2017-12-07T16:58:41.000+01:00",
    "id": "5a1f1f5f014129d859716df6"
  }
]

5.4 Testing

These test cases with positive outcomes are merely suggestions and it is not an extensive test set, e.g. tests with a negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Place a request with tracker code Track and trace info is shown for given tracker code
Place a request with tracker code and zipCode of the receiver Track and trace info is shown for given tracker code and the address details

6 Pickup Requests

6.1 Intro

The Pickup Request services allow you to:

Pickups should be requested for any date after the date the pickup request was made.

Pickup status

When retrieving pickup requests, if the status of a given pickup request is available the response will contain a list of all statuses for this pickup request.

E.g. the statusList property might contain:

[
  {
    "status": "WillBePickedUp",
    "timestamp": "2018-06-29T10:30:57.397Z"
  },
  {
    "status": "PickupCompleted",
    "timestamp": "2018-06-29T11:30:57.397Z"
  }
]

If no status is available yet, the statusList will be empty.

Possible status codes
PickupCompleted
PickupDeliveredAtExternalParty
ClosedAddresseeOnVacationOrderCancelled
ClosedOrderCancelled
NoEmptyEuroPalletsPresent
EuroPalletsNotEmptyYet
NothingPickedUpOrderCancelled
NothingPickedUpGoodsAlreadyCollected
NothingPickedUpGoodsAreNotReadyYet
NothingPickedUpNoGoodsForToday
NothingPickedUpNoOrderGiven
NothingPickedUp
BacklogDeliveryOrderCancelled
WillBePickedUp

6.2 Services

6.2.1 Create a pickup request

Service to create a request to come and pick up a parcel by DHL.

Field Required Description
accountId Yes Customer account id. Depending on country the account id might have a different format.
pickupDate Yes Pickup date. Format: yyyy-MM-dd. Must be today + 1, except for Span and Portugal which support Same-Day-Pickup.
description No Optional description of what to pickup.
pickupLocation No Optional pickup location information.
numberOfPackages No Number of packages to pickup. Either numberOfPackages or numberOfPallets must be provided.
numberOfPallets No Number of pallets to pickup. Either numberOfPackages or numberOfPallets must be provided.
totalWeight No Optional total weight to pickup.
shipper Yes Full pickup contact information. See model.
receiver No Full receiver contact information. See model. When a value is provided for this field, the pickup driver will bring the associated label.
type Yes Only supported value ‘Once’.

6.2.2 Get pickup requests for a user

Retrieves pickup requests created by the user or to which the given user has access. The user id is obtained from the authorization token. If the status of a pickup request is available the response will contain a list of statuses. See Pickup Status for details.

Parameters Required Description
limit true Maximum number of records to return
skip true Number of records to skip (for pagination purposes)
query false Optional query for full text search. If provided only pickup requests matching this query will be returned
accountIds false Optional list of account ids for which the pickup request should be retrieved. If not provided pickup requests belonging to all accounts to which the user has access will be returned

See API for all supported options.

6.2.3 Get pickup request by id

Retrieves a single pickup request using its id. If the user sending the request is not authorized to access given pickup request or the given pickup request does not exist, not found (404) error code is returned.

If the status of the pickup request is available the response will contain a list of statuses. See Pickup Status for details.

6.3 API Usage

Description Method URL
Create a pickup request POST https://api-gw.dhlparcel.nl/pickup-requests
Get pickup requests for a user GET https://api-gw.dhlparcel.nl/pickup-requests
Get pickup request by id GET https://api-gw.dhlparcel.nl/pickup-requests/{id}

6.3.1 Create a pickup request

Request url

https://api-gw-accept.dhlparcel.nl/pickup-requests

Example request

curl -X POST "https://api-gw-accept.dhlparcel.nl/pickup-requests" -H "accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlMTNjZjNlZC1kYTE3LTQxZmQtOTc4Yy05OTdhYWUxYjcwNzkiLCJzdWIiOiIxYzlhMGE2Ni0wMTU4LTRiZjktYTk1Ny1mM2Y1MTQ5NjM0ODUiLCJvcmdhbml6YXRpb25JZCI6IjJlNDEzNGM0LTM1Y2MtNGU5Ni1hMmI4LTFjNjdmNzJkYzI1MSIsIm5iZiI6MTU0MDI5MTkwMywiZXhwIjoxNTQwMjkyODA0LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.RV2rU7Qjj25x_l-aoqNby9vt8VxQYYyo8IzU8d7nEs8" -H "content-type: application/json" -d "{ \"accountId\": \"08500001\", \"pickupDate\": \"2018-10-24\", \"numberOfPackages\": 1, \"shipper\": { \"name\": { \"firstName\": \"string\", \"lastName\": \"string\", \"companyName\": \"string\", \"additionalName\": \"string\" }, \"email\": { \"address\": \"string\" }, \"phoneNumber\": \"string\", \"address\": { \"countryCode\": \"NL\", \"postalCode\": \"1000AA\", \"city\": \"Amsterdam\", \"street\": \"Kalverstraat\", \"number\": \"10\", \"addition\": \"B\", \"isBusiness\": true, \"additionalInfo\": \"2nd Floor, 1st door on right.\" } }, \"receiver\": { \"name\": { \"firstName\": \"string\", \"lastName\": \"string\", \"companyName\": \"string\", \"additionalName\": \"string\" }, \"email\": { \"address\": \"string\" }, \"phoneNumber\": \"string\", \"address\": { \"countryCode\": \"NL\", \"postalCode\": \"1000AA\", \"city\": \"Amsterdam\", \"street\": \"Kalverstraat\", \"number\": \"10\", \"addition\": \"B\", \"isBusiness\": true, \"additionalInfo\": \"2nd Floor, 1st door on right.\" } }, \"timeSlot\": { \"from\": \"10:15\", \"to\": \"16:30\" }, \"type\": \"Once\", \"provideLabels\": false}"

Responses

Success (code 201)
{
  "id": "ed22518d-35f1-4fd9-a7fd-988d8436eb27",
  "userId": "1c9a0a66-0158-4bf9-a957-f3f514963485",
  "accountId": "08500001",
  "pickupDate": "2018-10-24",
  "numberOfPackages": 1,
  "shipper": {
    "name": {
      "firstName": "string",
      "lastName": "string",
      "companyName": "string",
      "additionalName": "string"
    },
    "email": {
      "address": "string"
    },
    "phoneNumber": "string",
    "address": {
      "countryCode": "NL",
      "postalCode": "1000AA",
      "city": "Amsterdam",
      "street": "Kalverstraat",
      "number": "10",
      "addition": "B",
      "isBusiness": true,
      "additionalInfo": "2nd Floor, 1st door on right."
    }
  },
  "receiver": {
    "name": {
      "firstName": "string",
      "lastName": "string",
      "companyName": "string",
      "additionalName": "string"
    },
    "email": {
      "address": "string"
    },
    "phoneNumber": "string",
    "address": {
      "countryCode": "NL",
      "postalCode": "1000AA",
      "city": "Amsterdam",
      "street": "Kalverstraat",
      "number": "10",
      "addition": "B",
      "isBusiness": true,
      "additionalInfo": "2nd Floor, 1st door on right."
    }
  },
  "confirmationNumber": "4031173P",
  "statusList": []
}

6.3.2 Get pickup requests for a user

Request url

Minimal request:
https://api-gw-accept.dhlparcel.nl/pickup-requests?limit={limit}&skip={skip}

With query and/or account ids:
https://api-gw-accept.dhlparcel.nl/pickup-requests?limit={limit}&skip={skip}&accountIds={accountId1}&accountIds={accountId2}&query={optionalQuery}

Example request

curl -X GET "https://api-gw-accept.dhlparcel.nl/pickup-requests?limit=5&skip=2" -H "accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlMTNjZjNlZC1kYTE3LTQxZmQtOTc4Yy05OTdhYWUxYjcwNzkiLCJzdWIiOiIxYzlhMGE2Ni0wMTU4LTRiZjktYTk1Ny1mM2Y1MTQ5NjM0ODUiLCJvcmdhbml6YXRpb25JZCI6IjJlNDEzNGM0LTM1Y2MtNGU5Ni1hMmI4LTFjNjdmNzJkYzI1MSIsIm5iZiI6MTU0MDI5MTkwMywiZXhwIjoxNTQwMjkyODA0LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.RV2rU7Qjj25x_l-aoqNby9vt8VxQYYyo8IzU8d7nEs8"

Responses

Success (code 200)
{
  "results": 14,
  "limit": 5,
  "skip": 2,
  "data": [
    {
      "id": "ed22518d-35f1-4fd9-a7fd-988d8436eb27",
      "userId": "1c9a0a66-0158-4bf9-a957-f3f514963485",
      "timeCreated": "2018-10-23T10:54:01.843Z",
      "accountId": "08500001",
      "pickupDate": "2018-10-24",
      "numberOfPackages": 1,
      "numberOfPallets": 0,
      "shipper": {
        "name": {
          "firstName": "string",
          "lastName": "string",
          "companyName": "string",
          "additionalName": "string"
        },
        "email": {
          "address": "string"
        },
        "phoneNumber": "string",
        "address": {
          "countryCode": "NL",
          "postalCode": "1000AA",
          "city": "Amsterdam",
          "street": "Kalverstraat",
          "number": "10",
          "addition": "B",
          "isBusiness": true,
          "additionalInfo": "2nd Floor, 1st door on right."
        }
      },
      "receiver": {
        "name": {
          "firstName": "string",
          "lastName": "string",
          "companyName": "string",
          "additionalName": "string"
        },
        "email": {
          "address": "string"
        },
        "phoneNumber": "string",
        "address": {
          "countryCode": "NL",
          "postalCode": "1000AA",
          "city": "Amsterdam",
          "street": "Kalverstraat",
          "number": "10",
          "addition": "B",
          "isBusiness": true,
          "additionalInfo": "2nd Floor, 1st door on right."
        }
      },
      "confirmationNumber": "4031173P",
      "statusList": []
    },
    ...
  ]
}

6.3.3 Get a pickup request by id

Request url

https://api-gw-accept.dhlparcel.nl/pickup-requests/{id}

Example request

curl -X GET "https://api-gw-accept.dhlparcel.nl/pickup-requests/b9b0c8d9-153d-4f59-815b-94759ccf1ddf" -H "accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJlMTNjZjNlZC1kYTE3LTQxZmQtOTc4Yy05OTdhYWUxYjcwNzkiLCJzdWIiOiIxYzlhMGE2Ni0wMTU4LTRiZjktYTk1Ny1mM2Y1MTQ5NjM0ODUiLCJvcmdhbml6YXRpb25JZCI6IjJlNDEzNGM0LTM1Y2MtNGU5Ni1hMmI4LTFjNjdmNzJkYzI1MSIsIm5iZiI6MTU0MDI5MTkwMywiZXhwIjoxNTQwMjkyODA0LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.RV2rU7Qjj25x_l-aoqNby9vt8VxQYYyo8IzU8d7nEs8"

Responses

Success (code 200)
{
   "id":"b615a70c-d320-4517-8710-983e45dbb52b",
   "userId":"f57117a6-b088-4cee-82bf-c8b561d704a6",
   "timeCreated":"2018-10-24T08:45:08.154Z",
   "accountId":"08500001",
   "pickupDate":"2018-11-02",
   "description":"Office no 1",
   "numberOfPackages":2,
   "numberOfPallets":0,
   "shipper":{
      "name":{
         "firstName":"John",
         "lastName":"Doe",
         "companyName":"JDC"
      },
      "email":{
         "address":"jdoe@jdc.com"
      },
      "phoneNumber":"+31611111111",
      "address":{
         "countryCode":"NL",
         "postalCode":"3542AD",
         "city":"Utrecht",
         "street":"Reactorweg",
         "number":"30",
         "isBusiness":true
      }
   },
   "confirmationNumber":"4031175P",
   "statusList":[]
}

6.4 Testing

These test cases with positive outcomes are merely suggestions and it is not an extensive test set, e.g. tests with a negative outcome should also be taken into scope. Please extend with test cases which are suitable for your line of business or wishes.

Suggested Test Cases Expected Result
Create a pickup request A new pickup request is created and returned.
Get pickup request. Try different scenario’s with pagination. Pickup requests for a user, organization or account id depending on the test case.

7 Customs Declarations

7.1 Intro

The Customs Declaration endpoint has the possibilities to upload customs attachments, generate customs documents and send the commercial invoice of a customs declaration for Benelux customers to DHL without creating labels.

To auto-generate customs documents and send the commercial invoice as part of a shipment use create shipment.

Preconditions

An authorization token in the header of the HTTP request is mandatory. (see Authentication and Authorization).

7.2 Services

7.2.1 Upload attachment

This endpoint allows uploading customs attachments through Upload customs attachment.

Attachments can be included when creating shipment labels with customs or when sending a separate customs declaration.

A single attachment cannot be larger than 2.5 MB. Note that there are also limitations for the total size of all attachments in a customs declaration.

To upload an attachment, the attachment file contents need to be included as the raw request body. Unfortunately this is not supported by the Swagger version we currently use. To upload an attachment use the equivalent of

curl -i -X POST https://api-gw.dhlparcel.nl/customs/attachments/your_attachment_uuid \
  -H "Authorization: Bearer your_api_token" \
  -H "Content-Type: application/pdf" \
  --data-binary "@path/to/file"

After a successful upload, attachments may be referenced using their UUID.

7.2.2 Get attachment by id

With the attachment id, a specific attachment can be retrieved through Get customs attachment by id.

The result depends on the content of the Accept header.

Accept Result
application/json Detailed attachment information
application/pdf PDF document with the attachment content

7.2.3 Generate documents

This endpoint allows generating customs documents through Create customs document.

Depending on input details, a CN23 form or invoice is generated.

All generated customs documents are stored as attachments using the id field specified in the request body and can be retrieved later using Get attachment by id.

The following fields are unique to this endpoint

Field Type Mandatory Description
id string Y Use a UUID Generator, attachmentId to store document

In addition, the fields documented in Customs definitions must be provided.

The result depends on the content of the Accept header.

Accept Result
application/json Detailed attachment information
application/pdf PDF document with the attachment content

7.2.4 Customs Declaration

This endpoint allows to send the commercial invoice of a customs declaration to DHL for Europlus (B2B) and Parcel Connect (B2C) shipments for Benelux customers with the option to generate customs documents as well through Create customs declaration.

All customs declarations are stored using the id field specified in the request body and can be retrieved later using Get declaration by id.

The following fields are unique to this endpoint

Field Type Mandatory Description
id string Y Use a UUID Generator, declaration ID
attachmentIds [string] N Specify custom attachments
createDocuments boolean N Generate and include CN23 form or invoice

In addition, the fields documented in Customs definitions must be provided.

Note: The combined size of all attachments is limited to 2.5 MB for Benelux.

7.2.5 Get Declaration by id

With the customs declaration id, a specific declaration can be retrieved through Get customs declaration by id.

7.3 Customs Definitions

Field Type Mandatory Description
accountId string Y Account id as provided by DHL
product string Y Product key as provided by the capabilities endpoint
pieceCount integer Y Number of pieces in the shipment
orderReference string N Reference for your own administration, should match REFERENCE shipment option when creating shipment labels
currency string N Currency of the invoice, ISO (EUR, CHF, NOK, GBP, USD)
invoiceNumber string N  
remarks string N Supplementary information, such as consignment remarks
invoiceType string N Type of invoice, e.g. commercial
exportType string N Permanent, Repair, Return, Temporary
exportReason string N Other, SaleOfGoods, ReturnedGoods, Gift, CommercialSample, Documents
incoTerms string N CFR, CIF, CIP, CPT, DAP, DAT, DDP, DDU, DDX, EXW, FCA, FOB; DDX means ‘DDP VAT Excl.’ EXW not applicable for UK exports. For Parcel Connect only DDU applicable to UK.
incoTermsCity string N Named place of delivery/destination/port
defermentAccountDuties string N Deferment Account for Duties (if a separate account exits for shipment to GB)
defermentAccountVat string N Deferment Account for VAT (if a separate account exits for shipment to GB)
vatReverseCharge boolean N  
shipper   Y Name and address
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
inboundVatNumber string N Sender VAT number for inbound country. Only applicable for shipments to GB. Mandatory for Parcel Connect shipments to GB
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
receiver   Y Name and address
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
importerOfRecord   N Importer of the customs shipment
email string N  
phoneNumber string N  
vatNumber string N  
eoriNumber string N  
name     Requires at least firstName, lastName or companyName
firstName string N  
lastName string N  
companyName string N  
additionalName string N  
address     Depending on country, use designated endpoint to check input address
countryCode string Y  
postalCode string   Mandatory and format is checked based on country code
city string Y  
street string Y  
number string N  
isBusiness boolean N Defaults to true
addition string N  
shippingFee     Additional shipping fee
currency string Y  
value string Y  
customsGoods   Y Customs goods in this declaration, at least one is required
code string Y HS-code of the goods, see Harmonized commodity description and coding System, to classify globally traded products. Always 8 or 10 positions.
description string Y Description of the goods
origin string Y Country of origin, ISO 3166-1 alpha-2 country code
quantity string Y Number of the products of this line
value string Y Total value of the goods of this line
weight string Y Net weight of the products of this line

7.4 Testing

The test system of the DHL-customer should be connected to the test system of DHL.

Please create test cases which are suitable for your line of business or wishes.

7.5 Customs Declarations V1 (deprecated)

*Deprecated, please use Customs Declarations V2 to create a shipment with customs information. While this endpoint will be supported, new features will be added only to Customs Declarations V2

7.5.1 Intro

The Customs Declaration endpoint has the possibility to send the commercial invoice of a customs declaration to DHL for Europlus (B2B) and Parcel Connect (B2C) shipments. This is only applicable for customs destinations. It is also possible to send the customs documents T1, T2, EU-A, EU-Z using this endpoint.

Preconditions

An authorization token in the header of the HTTP request is mandatory. (see Authentication and Authorization).

7.5.2 Services

7.5.2.1 Customs Declaration

*Deprecated, use Customs Declaration to create a customs declaration for Europlus or Parcel Connect shipments to customs destinations.

This endpoint creates a customs declaration for Europlus or Parcel Connect shipments to customs destinations.

In order to create a customs declaration, a unique identifier is needed as input for the request. The format for this identifier is the Universally Unique Identifier (UUID). The use of UUIDs keeps our API idempotent. It ensures in this case that a declaration is created uniquely and just once, without needing to do any expensive and complicated synchronized bookkeeping.

Most programming languages and platforms have a built-in UUID generator that you can use for this purpose. A brief explanation on the other input data is given in the table below.

Field Type Mandatory Description
orderNumber string Y OrderReference of the shipment. Together with your customernumber this is a reference number to the shipment
uuid String Y Use a UUID Generator
customerNumber string Y AccountID, accountnumber (received from DHL) you are using for the shipment.
numUnitsDocumented Integer Y Number of packages of the shipment (normally equal to number of labels created for DHL).
createdBy     Do not use
commercialInvoice   Y Commercial Invoice
incoterm String Y Supported incoterms: CFR, CIF, CIP, CPT, DAP, DAT, DDP, DDU, DDX, EXW, FCA, FOB.
DDX means “DDP VAT Excl.”
EXW is not supported for GB exports.
For Parcel Connect shipments to GB only DDU is supported.
incotermCity String Y Named place of delivery/destination/port
invoiceNumber String Y The invoice number
invoiceDate YYYY-MM-DD Y The date of the invoice
reasonForExportCode String N Supported Codes:
9 – Others
11 – Sale of goods
21 – Returned goods
31 – Gift
32 – Commercial sample
91 – Documents
In case no code provided, default value will be 11.
currency String Y Currency of the invoice, ISO (EUR, CHF, NOK, GBP, USD)
amount Number (19,2) Y Total value of the shipment.
freightCosts Number (19,2) N In case freight costs are separate on the invoice
insuranceCosts Number (19,2) N In case insurance costs are separate on the invoice
otherCosts Number (19,2) N In case other costs are separate in the invoice. Can be negative (for discounts)
totalWeightKg Number   Total weight in kg
defermentAccountVat String N Deferment Account VAT
defermentAccountDuties String N Deferment Account for Duties (if a separate account exits)
Receiver   Y Receiver of the goods (conform the invoice)
name String Y  
addressLine1 String Y  
addressLine2 String N  
addressLine3 String N  
postalCode String Y  
city String Y  
countryCode String (2) Y ISO-3166 alpha-2
phone String N Mandatory for shipments to GB
email String N Mandatory for shipments to GB
eoriCountryCode String (2) N First characters of the EORI number, indicating the country-code.
eoriNumber String N Remaining characters of the EORI number.
vatCountryCode String (2) N First characters of the VAT number, indicating the country-code. Mandatory for Europlus shipments to GB.
vatNumber String N Remaining characters of the VAT number. Mandatory for Europlus shipments to GB.
Shipper   Y Exporter of the goods (conform the invoice)
name String Y  
addressLine1 String Y  
addressLine2 String N  
addressLine3 String N  
postalcode String Y  
city String Y  
countryCode String (2) Y ISO-3166 alpha-2
eoriCountryCode String (2) Y First characters of the eori-number, indication the country-code.
eoriNumber String Y Remaining characters of the eori-number.
vatCountryCode String (2) Y First characters of the VAT-number, indication the country-code
vatNumber String Y Remaining characters of the VAT-number
phone String N  
email String N Mandatory for shipments to GB
inboundVatCountryCode String (2) N First characters of the inbound country VAT number, indicating the country-code. Mandatory for Europlus shipments to GB. Currently only applicable to shipments to GB. Mandatory for Parcel Connect shipments.
inboundVatNumber String N Remaining characters of the inbound country VAT number. Mandatory for Parcel Connect shipments.
InvoiceLines   Y At least one invoice line is mandatory
description String Y Description of the goods
hsCode Number-10 Y HS-code of the goods, see Harmonized commodity description and coding System, to classify globally traded products. Always 8 or 10 positions.
netWeightKg Number Y Total netto weight of the products of this line
numParts Number Y The number of the products of this line
countryOfOrigin String (2) Y ISO-3166 alpha-2
value Number Y The total value of the goods of this line. Should be higher than “0”
predeclaredDocuments   N Optional, only used in case a T1, T2 or EU-document is already created for the shipment.
documentType String (4) Y T1, T2, EU-A, EU-Z
documentNumber String Y The number of the document
Attachments   N The invoice (in PDF). Preferred the invoice is given in the API. The invoice must also be attached to the goods. The invoice is mandatory for shipments with destination GB.
name String Y  
mimeType String Y Always "application/pdf"
Content String Y The invoice in pdf-format (base-64).

7.5.3 API Usage

Description URL
Create customs declaration (prod) https://api-gw.dhlparcel.nl/customsdeclarations

Note: For testing, collect your **Sandbox** API key in My DHL eCommerce

Responses
Success

Code 200

Failure:
    Code 400        Bad request
    Code 401        Unauthorized, invalid header Authorization: Bearer
    Code 500        Internal server error
    Code 503        Service unavailable, likely a database error
Code Integer Y  
Message String Y  

8 Interventions

8.1 Intro

Intervention endpoints require Authorization.

For more visual details, refer to the swagger documentation.

8.1.1 Headers

Source

The Source header is a mandatory custom header, which is expected to contain a String value that relates to the source of the user.

Technically speaking, this value can contain any possible String, but for appropriate usage, its value should be aligned with DHL’s naming convention.

Authorization

An authorization token in the header of the HTTP request is mandatory in the case of a few operations.

More details on the intricacies of the endpoints, and how to use them, can be found in the following sections.

8.2 Services

8.2.1 Request Intervention Options

This endpoint allows you to get all available intervention options based upon the input parameters provided. These include:

All Available Options:

Intervention type Description
agreed place request the parcel be put in a specific place, in close proximity to the recipients house, transferring responsibility to the recipient
ServicePoint change the parcel’s destination to a specific ServicePoint
neighbours change the parcel’s destination to the neighbours address
date time change the parcel’s delivery window to a later date/time
cancel(not yet implemented for this endpoint) cancel the delivery of the parcel, effectively returning it to the sender

The intervention options response will return:

Intervention Options Response

The following json is an example when the intervention-options endpoint is provided with a valid postalcode + tracking/parcel id combination.

{
    "interventionOptions": {
        "JVGL123": {
            "agreedPlaceIntervention": {
                "available": false,
                    "reasons": [
                    {
                        "code": 301,
                        "reason": "Feature no agreed place doesn't allow for this type of intervention"
                    },
                    {
                        "code": 303,
                        "reason": "This type of intervention is not allowed for a parcel that requires a signature upon delivery"
                    }
                ]
            },
            "dateTimeIntervention": {
                "available": true,
                "executionTimeframe": {
                    "from": "2022-04-15T09:00",
                    "to": "2022-04-15T13:00"
                },
                "nextTimeframe": {
                    "from": "2022-04-16T09:00",
                    "to": "2022-04-16T13:00"
                }
            },
            "neighboursIntervention": {
                "available": true,
                "executionTimeframe": {
                    "from": "2022-04-15T09:00",
                    "to": "2022-04-15T13:00"
                }
            },
            "servicePointIntervention": {
                "available": true,
                "deliveryDate": "2022-04-16"
            }
        }
    }
}

NotHomeCode

The not home code is a unique code that the driver leaves at the residence of the recipient when the recipient is not at home to receive one or more parcels.

This code links to one or more tracking codes / parcels.

When a nothome code is passed in id, the response body will contain the intervention options of each parcel linked to the notHomeCode, plus an aggregated result.

This aggregated result is the common denominator of availability, meaning it will only show those (intervention) options that are available to all parcels linked to the notHomeCode.

Reason Codes (why an intervention option is unavailable)

When an intervention option is not available, the api returns a reason code:

Validation Reasons:

AGREE_WITH_TERMS_NOT_SET         201        Agree with terms not set
NO_EMAILADDRESS                  202        Email address not set
INVALID_EMAILADDRESS             203        Email address invalid
INVALID_HOUSENUMBER              204        Housenumber is invalid or not set
INVALID_PLACE_DESCRIPTION        205        Place description is invalid
PARCEL_UNKNOWN                   206        Parcel is unknown or not set
POSTAL_CODE_NOT_SET              207        Postal code not set
DIFFERENT_POSTAL_CODES           208        Postal code of parcel address differs from supplied postal code
SERVICEPOINT_UNKNOWN             209        Servicepoint is unknown or not set
NO_NEXT_DELIVERY                 210        There is no next delivery
SERVICE_POINT_NOT_IN_REGION      211        ServicePoint not part of delivery region parcel
SERVICE_POINT_NOT_OPEN           212        ServicePoint is not open on next delivery date
NEXT_TIME_FRAME_NOT_SET          213        The next time frame is not set
NEXT_TIME_FRAME_NOT_VALID        214        The next time frame is not a delivery time frame
SOURCE_NOT_PROVIDED              215        Request does not contain the mandatory Source Header
SOURCE_INVALID                   216        Mandatory Source Header provided is invalid
NOTHOME_CODE_UNKNOWN             217        No parcels were found for this KIB / NotHomeCode
SERVICEPOINT_CLOSED_PERIOD       218        ServicePoint is closed until the endDate
IDENTIFIER_INVALID               219        Identifier provided is invalid
POSTAL_CODE_INVALID              220        Postal code is invalid
JSON_NOT_DESERIALIZABLE          221        Request was not deserializable
FRAUDINDICATION_NOT_SET          222        FraudIndication not set
REQUESTBODY_INVALID              223        Request body provided is invalid
REASON_TOO_LARGE_FOR_LOCKER      224        This parcel does not fit in a locker

A few examples on this response format whenever a parcel cannot be found, or is considered invalid:

{
  "parcels": {
    "JVGL123": [
      {
        "code": 208,
        "reason": "Postal code of parcel address differs from supplied postal code"
      }
    ]
  }
}
{
  "parcels": {
    "JVGL123": [
      {
        "code": 215,
        "reason": "Request does not contain the mandatory Source Header"
      }
    ]
  }
}

Verification Reasons:

REASON_FEATURE_NO_AGREED_PLACE              301     Feature no agreed place doesn't allow for this type of intervention
REASON_FEATURE_PIN                          302     This type of intervention is not allowed for a parcel that requires a pincode upon delivery
REASON_FEATURE_SIGNATURE                    303     This type of intervention is not allowed for a parcel that requires a signature upon delivery
REASON_FEATURE_NOT_AT_NEIGHBOURS            304     This parcel has a product feature that says it cannot be delivered at a neighbours' house
REASON_RETURN_TO_SENDER                     305     Interventions are not allowed for a parcel that is being returned to the consignor/shipper
REASON_SERVICEPOINT_PARCEL                  306     Interventions are not allowed for a parcel that is to be delivered to a ServicePoint
REASON_INVALID_DELIVERY_DATE                307     Delivery date is in the past or non-existent
REASON_INCOMPLETE_ADDRESS                   308     Address information on the parcel is incomplete
REASON_NO_ACTIVE_STATUS                     309     Parcel doesn't appear to have a status indicating it's in our possession
REASON_INVALID_STATUS                       310     The parcel's current status doesn't allow for interventions to be carried out
REASON_PARCEL_TOO_LARGE_OR_HEAVY            311     Parcel too large or too heavy for this type of intervention
REASON_PICKUP_ORDER                         312     This type of intervention is not available for a pickup order
REASON_NO_LASTMILE_PARCEL                   313     Parcel not in last mile
REASON_FEATURE_AGE_CHECK                    314     This type of intervention is not allowed for a parcel that requires an age check
REASON_FEATURE_NH2SP                        315     This type of intervention is not allowed for a parcel that requires a not-home-to-servicepoint action
REASON_POSTAL_CODE_BLACKLIST                316     This type of intervention is not allowed for a parcel in this postal code area
REASON_FRAUD_INDICATION                     317     This parcel has a fraud indication
REASON_IN_LAST_CONTRACT_STEP                318     The current delivery attempt is the last attempt
REASON_SORT_ERROR                           319     This parcel is delayed. Current delivery date is uncertain
REASON_TRIP_IN_FALLBACK                     321     intervention (request) can't reach the courier at this moment
REASON_SAME_DAY_DELIVERY                    322     This parcel needs to be delivered today

Intervention Details

Additional details can be retrieved such as a list of available ServicePoints, or delivery timeframes, by adding the details parameter.

When no details parameter is passed, it is equivalent to passing false.

The details query parameter can hold the following values:

Parameter Description  
false No extra’s, just the intervention options proper. default
true adding both the ServicePoint id’s and the timeframes to the response  

In addition to the Intervention Options Response, the following data is aggregated with details set to true.

{
  "interventionOptions": {},
  "servicepointIds": [
    "NL-727281",
    "NL-827281",
    "NL-997281"
  ],
  "timeFrames": [
    {
      "from": "2022-04-15T09:00",
      "to": "2022-04-15T13:00"
    },
    {
      "from": "2022-04-16T09:00",
      "to": "2022-04-16T13:00"
    },
    {
      "from": "2022-04-17T09:00",
      "to": "2022-04-17T13:00"
    }
  ]
}

8.2.2 Details endpoint

These details (ServicePoint id’s and delivery timeframes), can also be retrieved individually, without the intervention options.

For these endpoints you merely require:

More info can be found in the swagger documentation.

FAQ

  1. Where can I find the meaning of a certain API endpoint input field?

    In the API documentation you will see the option ‘model’ next to ‘Example Value’. When clicked on the type, a description per field is shown and if required (red asterisk).

  2. How can I integrate Track & trace?

    A shipment can be traced through the tracker code (response field in the Create label endpoint) and the receiver’s postal code.

    curl -X GET "https://api-gw.dhlparcel.nl/track-trace?key=3SBPB0000094346%2B9999AA" -H "Accept: application/json"
    

    The Track & trace service is something that DHL can provide. In your correspondence to your clients a URL can be communicated that a shipment is ready. For example, this Dutch shipment:

    https://www.dhlparcel.nl/nl/volg-uw-zending-0?tt=<tracker code>&pc=<postal code>
    

    Another way is to make use of the Track & trace endpoint.

  3. How do I use the authentication token?

    An example for the label service when posting a label could be like this in PHP :

    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Content-Type: application/json; charset=utf-8",
      "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkYWFkNzU3ZC03NGY4LTQ5YzktOWI4OC1kMzEyN2 Q2ZDczMDAiLCJzdWIiOiI5MWQ5NGZiZC0xODk2LTQyMTctODlkNy0wM2M4ZTY4Y2YwYTAiLCJvcmdhbml6YXRpb 25JZCI6ImE0MDkzM2RlLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzczMSwiZXhw IjoxNTExODY4NjMyLCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJ hY2NvdW50cyI6WyI3NDY1NjE3MCIsIjEyMzQ1Njk4IiwiNDU5MDAxMDAiLCI0MDA0NDU4OSIsIjg3NjU0MzIxIi wiMzMzMzMzMzMiLCIwNTkyMDUxNyIsIjA4NTAwMDAxIiwiMTIzNDU2NzgiLCIwNTk1Nzg0MCJdfQ.KywXOWovoS Vf1WJ-CWAJ9j4rUXuMp-f0q2c2PKkOZno",
      "Accept: application/pdf"
    ]
    );
    

    Example in cURL

    curl -X GET "https://api-gw.dhlparcel.nl/labels?trackerCodeFilter=JVGL08500001813590386271" -H "Accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhNzAxN2EzZi1jMGYzLTQ3ZTAtOGQzNC1mMmZhMDFjYTlkY2EiLCJzdWIiOiI2YmZjNzU2MS00YjQxLTRjYjctYTFjMy1kYzMxZmFmODYwZGIiLCJvcmdhbml6YXRpb25JZCI6ImE0MDkzM2lLWJkMTctNDk0NC1iN2U5LTIzZmM3ZWU5YzgzNSIsIm5iZiI6MTUxMTg2NzUwNywiZXhwIjoxNTExODY4NDA4LCJyb2xlcyI6WyJsYWJlbC1zZXJ2aWNlLkIyWCIsInBpY2t1cC1zZXJ2aWNlLkIyWCJdLCJhY2NvdW50cyI6WyIwODUwMDAwMSJdfQ.Qs79ILW0ES4mO8hObOiZXvuuipBQ_-eJ7pd-10rrSQ"
    
  4. I want to send a package to a mailbox how can I do that?

    A package can be sent to a mailbox by adding the shipment option with key “BP” to the post label request.

    See directions on context and syntax in 3.3.1 Create label, Adding shipment options.

  5. I want to send a package as an express shipment (delivery before 11.00 am)?

    A package for express delivery can be created by adding the shipment option key “EXP” in the post label request.

    See directions on context and syntax in 3.3.1 Create label, Adding shipment options.

  6. How do I create a shipment for a parcel shop or DHL ServicePoint?

    With the Find the nearest parcel shop location the id (as input) of the DHL ServicePoint can be derived. In the request you then need to define the shipment option key ‘PS’, like:

    {
    "key": "PS",
    "input": "8004-NL-272403"
    }
    

    See directions on context and syntax in 3.3.1 Create label, Adding shipment options.

  7. How can I create a same day delivery (Shipment option key ‘SDD’)?

    Same day delivery is a product that is not automatically available for all customers. If you want this enabled, please place your request at: CIM eCommerce BNL.

    Same day has the shipment option key ‘SDD’ and is used like :

    {
    "key": "SDD"
    }
    

    See directions on context and syntax in 3.3.1 Create label, Adding shipment options.

  8. I want to send a shipment to a German PackStation how can I do that?

    In the situation that a parcel is to be delivered at a postbox in a German PackStation, the syntax is first the id of the parcel station delimited by ‘|’ and then the recipient’s postnummer:

    {
    "key": "PS",
    "input": "8003-4125530|12345"
    }
    

    See directions on context and syntax in 3.3.1 Create label, Adding shipment options.

APPENDIX

A. Shipment options

This is the current (at time of writing) list of shipment options. For up-to-date information, including a basic description, please use the Shipment options endpoint of our API.

Shipment option Description
BOUW Delivery to construction site
COD_CASH Cash on delivery. Payment method cash
COD_CHECK Cash on delivery. Payment method check
DOOR Delivery to the address of the recipient
EA Extra Assurance
EVE Evening delivery
EXP Expresser
EXW Ex Works. The recipient pays for the transportation from factory to destination
H Hold for collection
HANDT Signature on delivery
HANDTPS Signature on delivery at parcel shop
INS All risk insurance
NBB No neighbor delivery
PS Delivery to the specified DHL Parcelshop or DHL Parcelstation
RECAP Additional proof of delivery
PERS_NOTE Email to the receiver (for MDP Business app only)
PRINTLESS Generates a printless label/return label with QR code
REFERENCE Reference on label
REFERENCE2 Extra reference label
ADD_RETURN_LABEL Include extra label for return shipment
S Saturday delivery
SSN Undisclosed sender
BP Mailbox delivery
NO_TRACK_TRACE No track and trace for shipment