SendifyAPI docs
Open Sendify

Shipping guides · 4 min read

How to Handle Shipments Outside of the EU?

Ship outside the EU with the customs data carriers need.

This guide explains how to process shipments that are destined for countries outside the European Union (EU) and therefore require customs documentation. It assumes you have followed our Getting Started guide and are familiar with the core flow of the Sendify API.

Note

All example requests use the sandbox URL https://app.dev.sendify.se/ and will require a sandbox API key.

Prerequisites

  1. Complete the Getting Started guide – you need a valid x-api-key.
  2. Have a shipment_id for which you want to handle customs.
  3. Know the destination country is outside the EU.
  4. Either attach customs_information in the create shipment request (recommended for non-EU shipments), or have the necessary customs document files (e.g., commercial invoice, ABD) ready for upload.

Creating Shipment

Note

For non-EU shipments, you can include a customs_information object directly in the POST /shipments request. If you do this, Sendify will automatically generate the customs invoice from your data and you do not need to upload a customs invoice document later.

Example request

bash
curl --location 'https://app.dev.sendify.se/external/v1/shipments' \
--header 'x-api-key: $YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "enable_bookable_validation": true,
    "from": {
        "name": "Sendify AB",
        "address": {
            "address_line_1": "Östra Larmgatan 16",
            "country_code": "SE",
            "postal_code": "41107",
            "city": "Göteborg"
        },
        "contact": {
            "name": "Support Agent",
            "phone": "0103303091",
            "email": "contact@sendify.se"
        }
    },
    "to": {
        "name": "Sendify Norway",
        "address": {
            "address_line_1": " Vulkan 1",
            "country_code": "NO",
            "postal_code": "0178",
            "city": "Oslo"
        },
        "contact": {
            "name": "Support Agent",
            "phone": "030814088588",
            "email": "kontact@sendify.de"
        },
        "is_private_individual": false
    },
    "reference_id": "Sendify Shipment",
    "packages": [
        {
            "depth_cm": 20,
            "height_cm": 20,
            "width_cm": 20,
            "weight_kg": 2,
            "quantity": 1,
            "description": "Swedish Fika",
            "type": "PACKAGE",
            "stackable": true
        }
    ],
    "customs_information": {
        "invoice_type": "commercial",
        "reason_for_export": "sale",
        "currency": "SEK",
        "sender_eori_number": "SE123456789012",
        "sender_vat_number": "SE556941164101",
        "sender_voec_number": "2012345",
        "receiver_eori_number": "NO123456789",
        "receiver_vat_number": "NO999999999MVA",
        "items": [
            {
                "description": "Coffee gift box",
                "material": "assorted",
                "quantity": 1,
                "unit_type": "pieces",
                "unit_weight": 2.0,
                "unit_value": 300,
                "hs_code": "090121",
                "country_of_origin": "SE"
            }
        ],
        "additional_information": "Non-EU shipment. No batteries, liquids or hazardous materials.",
        "insurance_costs": 0,
        "shipping_costs": 0,
        "other_costs": 0,
        "discount": 0,
        "signature": "Support Agent"
    },
    "system": "Sendify"
}'

Example response

json
{
  "id": "YOUR_SHIPMENT_ID",
  "reference_id": "Sendify Shipment"
}

1. Requesting Rates for Non-EU Shipments

For shipments to or from countries outside the European Union (EU), you must include included_non_eu_rates: true in your POST /shipments/rates request. This applies to both:

  • Exports from the EU to non-EU countries
  • Imports from non-EU countries into the EU

Without this flag, the API will not return rates and will redirect you to the Sendify website. We recommend always setting this flag to true for all shipments, as it was added for backward compatibility.

This ensures that you receive rates that are applicable for customs processing.

Example: Rate Request for a non-EU shipment (import or export):

bash
curl --location --request POST 'https://app.dev.sendify.se/external/v1/shipments/rates' \
--header 'x-api-key: $YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "shipment_id": "YOUR_SHIPMENT_ID",
    "requested_pickup_time": "2025-07-10T10:00:00+02:00",
    "included_non_eu_rates": true
}'

2. Identifying Required Documents

If a rate is for a non-EU shipment and requires customs documents, its response object in the /shipments/rates call will contain a required_documents array. This array lists the document_type strings for documents you must provide.

Possible values for document_type include:

  • customsinvoice (Commercial or Proforma Invoice)
  • abd (Ausfuhrbegleitdokument - German export declaration)
  • salesinvoice (Sales Invoice, if different from customs invoice)

Example Rate Response Snippet for a Non-EU Shipment:

json
{
  "rates": [
    {
      "price_rank": 1,
      "shipment_id": "YOUR_SHIPMENT_ID",
      "booking_token": "BOOKING_TOKEN",
      "carrier_name": "Example Carrier",
      "product_name": "Global Express",
      "price": "350",
      "currency": "SEK",
      "required_documents": ["customsinvoice", "salesinvoice"]
    }
  ],
  "warnings": []
}

In this example, both a customsinvoice and an salesinvoice document are required. You would save the booking_token for later.

3. Uploading Customs Documents

If you included customs_information when creating the shipment, a customs invoice will be generated automatically from that data and you do not need to upload a customsinvoice document. In that case, proceed directly to booking.

For each document_type listed in the required_documents array, you must upload the corresponding file. Use the POST /shipments/{shipment_id}/{document_type} endpoint. The request must be multipart/form-data.

A separate API call is needed for each document.

Placeholders:

  • {shipment_id}: Your shipment ID.
  • {document_type}: The document type (e.g., customsinvoice).

Make sure to replace "/path/to/your/..." with the actual path to your document file, don't remove the @.

Example: Uploading a Customs Invoice (customsinvoice)

bash
curl --location --request POST \
'https://app.dev.sendify.se/external/v1/shipments/{YOUR_SHIPMENT_ID}/customsinvoice' \
--header 'x-api-key: $YOUR_API_KEY' \
--form 'file=@/PATH/TO/YOUR/FILE.pdf' \
-w "HTTP Status: %{http_code}\n"

Upon successful upload, the API returns a 204 No Content status.

Example Response:

bash
HTTP Status: 204

4. Booking the Shipment

Once all documents specified in the required_documents array have been successfully uploaded, you can book the shipment using the booking_token obtained from the rate response (Step 2).

Example Booking Request:

bash
curl --location --request POST 'https://app.dev.sendify.se/external/v1/shipments/book' \
--header 'x-api-key: $YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "booking_token": "BOOKING_TOKEN"
}'

Example Booking Response:

json
{
  "shipment_id": "YOUR_SHIPMENT_ID",
  "main_tracking_id": "CARRIER_TRACKING_ID_EXAMPLE"
}

This confirms the booking. Sendify will forward the uploaded documents to the carrier.

5. Quick Recap

  1. Ensure your shipment (to or from a non-EU country) is created.
  2. Call POST /shipments/rates for the shipment_id, ensuring included_non_eu_rates: true is included in the JSON request body.
    • Check the response for rates with a required_documents array.
    • Save the booking_token for the desired rate.
  3. For each item in required_documents:
    • Call PUT /shipments/{shipment_id}/{document_type} with the file.
  4. Call POST /shipments/book with the booking_token.
  5. Your non-EU shipment is booked with customs documents handled!

Need help? Contact api@sendify.com and include the X-Sendify-Request-ID header from the relevant request if available.