Skip to Content
Client API 2026-09Customs Declaration

Customs Declaration

Shipments that cross the EU customs border need a customs declaration. In the Client API it is the customsDetail object of POST /shipments: it is stored on the shipment, returned in customsDetail and transmitted to the carrier.

When it is required

customsDetail is mandatory when shipper and recipient are on different sides of the EU customs territory:

  • destinations outside the EU (United Kingdom, Switzerland, USA, …);
  • special territories of EU member states that are outside the customs territory: Canary Islands, Ceuta, Melilla (ES), Livigno and Campione d’Italia (IT), Helgoland and Büsingen (DE), Åland (FI), Mount Athos (GR) — matched by postal code.

Monaco, San Marino and Andorra are inside the customs territory and do not require it. For every other destination customsDetail is optional.

A missing declaration answers 422 validation_failed with a customsDetail error.

customsDetail object

FieldTypeRequiredDescription
customsValueMoneyYesTotal declared value. Must equal the sum of the commodity values (tolerance: 1 % or 1 currency unit)
incotermstringNoEXW, FCA, CPT, CIP, DAP (default), DPU, DDP, FOB, CFR, CIF
dutiesPaymentstringNoWho pays duties and taxes: SENDER, RECIPIENT (default), THIRD_PARTY
contentTypestringNoMERCHANDISE (default), GIFT, SAMPLE, DOCUMENTS, RETURN, REPAIR, PERSONAL_EFFECTS
exportReasonstringNoSALE (default), GIFT, SAMPLE, RETURN, REPAIR, PERSONAL
invoiceNumberstring (50)NoCommercial invoice number
invoiceDatedateNoYYYY-MM-DD
exporterobjectNoeori, vatNumber, taxId of the sender
importerobjectNoeori, vatNumber, taxId of the recipient
commodities[]Commodity[]Yes1 to 99 items

Commodity object

FieldTypeRequiredDescription
descriptionstring (255)YesDescription of the goods, in English where possible
harmonizedCodestringNoHS / TARIC code, 6 to 10 digits (see search below)
quantityintegerYes≥ 1
quantityUnitsstringNoPCS (default), PR, DOZ, KG, L, M, M2, M3, SET
unitValueMoneyYesValue per unit
totalValueMoneyNoDefault: unitValue × quantity
weightWeightYesWeight of the line
countryOfManufacturestring (2)YesCountry of origin, ISO 3166-1 alpha-2
midCodestring (30)NoManufacturer identification code (USA)
skustring (100)NoYour article code

Example

A shipment from Italy to Switzerland with two commodity lines:

{ "reference": "ORD-1234", "serviceType": "fedex-international", "recipient": { "name": "John Doe", "address": { "street": "Bahnhofstrasse 1", "street2": "2. OG", "city": "Zürich", "province": "ZH", "postalCode": "8001", "countryCode": "CH" }, "phone": "+41 44 000 00 00", "email": "john@example.com" }, "packages": [ { "weight": { "value": 1.5, "units": "KG" }, "dimensions": { "length": 30, "width": 20, "height": 10, "units": "CM" } } ], "options": { "contentDescription": "Clothing", "labelFormat": "PDF" }, "customsDetail": { "customsValue": { "amount": 120.00, "currency": "EUR" }, "incoterm": "DAP", "dutiesPayment": "RECIPIENT", "contentType": "MERCHANDISE", "exportReason": "SALE", "invoiceNumber": "FT-2026-001", "invoiceDate": "2026-09-01", "exporter": { "eori": "IT01234567890", "vatNumber": "IT01234567890" }, "importer": { "eori": null, "vatNumber": "CHE-123.456.789", "taxId": null }, "commodities": [ { "description": "Cotton T-shirt", "harmonizedCode": "610910", "quantity": 2, "quantityUnits": "PCS", "unitValue": { "amount": 25.00, "currency": "EUR" }, "totalValue": { "amount": 50.00, "currency": "EUR" }, "weight": { "value": 0.4, "units": "KG" }, "countryOfManufacture": "CN", "sku": "TS-001" }, { "description": "Leather belt", "harmonizedCode": "420330", "quantity": 1, "unitValue": { "amount": 70.00, "currency": "EUR" }, "weight": { "value": 0.3, "units": "KG" }, "countryOfManufacture": "IT" } ] } }

customsValue.amount (120) equals 2 × 25 + 1 × 70. The 201 response returns the declaration as stored in customsDetail.

Searching HS / TARIC codes

GET /taric?q=<term>&limit=25 — rate limit 60 / min

Searches the TARIC nomenclature by Italian or English description, or by code prefix. q needs at least 3 characters; limit defaults to 25 (max 100).

curl "https://<subdomain>.spedisci.online/api/2026-09/taric?q=t-shirt" \ -H "Authorization: Bearer <access_token>" \ -H "Accept: application/json"

What reaches the carriers

CarrierData transmitted
FedExOne commodity per line (description, HS code, origin, quantity, unit and total value, weight, SKU), totalCustomsValue, dutiesPayment (SENDER with the contract account, RECIPIENT; THIRD_PARTY falls back to RECIPIENT), commercial invoice (incoterm, purpose from exportReason), recipient customs id and sender TIN from EORI / VAT number, document-only flag for DOCUMENTS
DHL ExpressExport declaration with one line item per commodity (HS code, origin, price, quantity, weight, export reason, taxes-paid flag for DDP), invoice (invoiceNumber / invoiceDate, otherwise the order reference and today’s date), incoterm, declared value, EORI / VAT registration numbers of shipper and receiver
Poste Delivery BusinessOne item per commodity (TARIC, origin, quantity, value in cents, weight in grams), content code from contentType, total waybill value
Spring GDSOne product per commodity (description, HS code, quantity, value, origin, SKU), declared value of the shipment
UPSInternational forms (commercial invoice: number / date, reason for export, incoterm, currency, sold-to = recipient, one product per commodity with HS code, origin, quantity and unit value)

Shipments created without customsDetail from the web interface or from marketplace orders to non-EU destinations get an automatic declaration built from the order lines, enriched with the customs defaults of your product catalog (customs description, HS code, country of origin, MID code, declared value) as configured in the web interface. Keeping the catalog complete avoids customs holds.

Last updated on