Customs
When shipping between countries, it is often required to declare customs. This guide will go through how to add customs to your shipment request, so that these documents can be generated.
Customs implementation
Whether or not a product requires customs it can be found from the /products endpoint. If the field customs_declaration_required is true, a customs object should always be there.
The customs_declaration_required field under destination_country is deprecated, use the one under the product itself.
The customs part of a shipment request is an object that contains overall data for customs, as well as an array of goods associated with it. In the object itself, only the currency code is required.
Declaring the goods is done through the goods array. Here you define quantity, country_code (ISO 3166-1 alpha-2), content, commodity_code (tariff code), unit_value of the items, and unit_weight of the items. If there are more than one type of item, a separate goods object is added to the goods array. Following example is a simple version of customs declaration:
{
...
"customs": {
"currency_code": "DKK",
"goods": [
{
"quantity": 2,
"country_code": "NO",
"content": "T-shirt",
"commodity_code": "61091000",
"unit_value": 30.10,
"unit_weight": 1000
}
]
}
}
The customs object is then added to the shipment request.
{
"own_agreement": true,
"product_code": "DHLE_EW",
"service_codes": "",
"parties": [
{
"type": "sender",
"name": "Shipmondo",
"address1": "Hvilehøjvej 25",
"postal_code": "5220",
"city": "Odense SØ",
"country_code": "DK",
"email": "firma@email.dk",
"phone": "70400407"
}
{
"type": "receiver",
"name": "University of Oslo",
"address1": "Problemveien 7",
"postal_code": "0315",
"city": "Oslo",
"country_code": "NO",
"email": "lene@email.dk",
"phone": "50607080"
}
],
"parcels": [
{
"weight": 2000,
"length": 10,
"width": 10,
"height": 10
}
],
"print": true,
"print_at": {
"host_name": "LAPTOP-PKL",
"printer_name": "GK420D",
"label_format": "zpl"
},
"customs": {
"currency_code": "DKK",
"goods": [
{
"quantity": 2,
"country_code": "NO",
"content": "T-shirt",
"commodity_code": "61091000",
"unit_value": 30.10,
"unit_weight": 1000
}
]
},
"reference": "Order 44"
}
It is possible to declare other properties that are relevant for customs. Use only the ones agreed with the carrier.
{
...
"parties": [
...
{
"type": "importer",
"name": "Min Virksomhed A/S",
"attention": null,
"address1": "Hvilehøjvej 25",
"address2": null,
"postal_code": "5220",
"city": "Odense SØ",
"state": null,
"country_code": "DK",
"phone": "80808080",
"email": "jim@minvirksomhed.dk",
"attributes": [
{
"name": "vat_no",
"value": "DK12345678"
},
{
"name": "customer_number",
"value": "12345678"
}
]
}
],
"customs": {
"export_reason": "other",
"freight_cost": 200.42,
"insurance_cost": 100.42,
"billed_to_custom_invoice_text": "Custom invoice text under \"Import\"",
"sender_custom_invoice_text": "Custom invoice text under \"Sender\"",
"receiver_custom_invoice_text": "Custom invoice text under \"Delivery\"",
"currency_code": "DKK",
"goods": [
{
"quantity": 2,
"country_code": "NO",
"content": "T-shirt",
"commodity_code": "61091000",
"unit_value": 30.10,
"unit_weight": 1000
}
]
},
"contents": "Goods",
"term_of_trade": "DAP"
}
Goods validation
The objects in the goods array gets validated on a set of rules.
A general rule is that all fields should be present and they should have a value.
Field specific rules are as follows
quantitymust be greater than 0country_codemust be a valid ISO 3166-1 alpha-2 country codecontentmust have a length greater than 0commodity_codemust be a string that only include digits and have a length of either 6, 8, 10 or 12 digitsunit_valuemust be greater than 0unit_weightmust be greater than 0
If one or more objects fails to validate these rules, an error is returned with the fields affected.
An example of this could be:
{
...
"customs": {
"currency_code": "DKK",
"goods": [
{
"quantity": 2,
"country_code": "NO",
"content": "T-shirt",
"commodity_code": "61091000",
"unit_value": 30.10,
"unit_weight": 0
}
]
}
}
unit_weight fails to validate since it does not have a value greater than 0.
So the API would return the error "One or more customs goods are missing or have invalid values in unit weight".
Export reason
export_reason defines the category of the export.
The valid values are:
giftdocumentscommercial_samplesreturned_goodsothersale_of_goods
sale_of_goods is only available for some specific carriers. If you use it for any other carrier it will be set as other
Importer party
Importer party (type = "importer") is used for importer information relevant for customs. When this is provided it overrides the "Importer" on the customs invoice.
Term of trade (Incoterm)
term_of_trade refers to the Incoterm of the shipment. While Incoterm is not directly linked to customs, it is used to indicate the payer of VAT and customs duty.
The most common Incoterm is DAP (Delivery At Place) where the receiver has to pay VAT and customs duty.
On the contrary DDP (Delivered Duty Paid) sets the sender as the payer of VAT and customs duty.
If term_of_trade is not provided, it defaults to DAP.