> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goshippo.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.goshippo.com/feedback

```json
{
  "path": "/docs/International_Shipping/InternationalShipping",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# International shipping

> Ship internationally with the Shippo API by creating customs declarations and items to clear customs for your packages.

You can easily handle foreign addresses and customs forms directly through the Shippo API when shipping internationally (this includes shipping to US Territories for USPS). We've created a guide to make sure your packages clear customs and arrive safely!

## Create the Sender & Recipient Address Objects and Parcel Object

As with every Shipment, you need to first create or retrieve your two Address (sender and recipient) and Parcel objects first. Check out our [address validation tutorial](/docs/Addresses/AddressValidation) on how you can validate global addresses.

The only special requirement in this case is that the phone number of the sender and recipient are required. Apart from that there's nothing special about them for international shipments.

## Create a Customs Declaration and Customs Items

You will need to create a customs declaration and specify the items that are inside your international shipment. This is to ensure that the country you import goods into accepts your package at the border. The USPS website has a great [Shipping Restrictions](https://www.usps.com/ship/shipping-restrictions.htm) page with some general no-goes, as well as a more detailed [Index of Countries and Localities.](http://pe.usps.com/text/Imm/immctry.htm)

## What information do I need to submit for a Customs Declaration?

You can find an overview of all available fields in our [Customs Declaration reference section](/api-reference/customs-declarations/list-all-customs-declarations). Most carriers require you to specify `certify`, `certify_signer`, `contents_type`, `eel_pfc` and `incoterm`. Although not all carriers require it, we also recommend submitting the `items` field -- this significantly reduces the risk of the package being stuck in customs.

There are many optional fields that can be filled out depending on who you're shipping with, so please do your research ahead of time to make sure that you have all the required fields covered.

## Create your Customs Declaration and Items inline

To create a customs declaration, send a POST request with the necessary information to the Customs Declarations endpoint. You can create your Customs Items within the `items` attribute. Alternatively, you can create customs items individually via the [Customs Items API endpoint](/api-reference/customs-items/list-all-customs-items).

<CodeGroup>
  ```shell cURL theme={null}
  curl https://api.goshippo.com/customs/declarations/\
      -H "Authorization: ShippoToken <API_TOKEN>"\
      -H "Content-Type: application/json"\
      -d '{
            "contents_type": "MERCHANDISE",
            "non_delivery_option": "RETURN",
            "certify": true,
            "certify_signer": "Simon Kreuz",
            "incoterm": "DDU",
            "items": [{
                      "description": "T-shirt",
                      "quantity": 20,
                      "net_weight": "5",
                      "mass_unit": "lb",
                      "value_amount": "200",
                      "value_currency": "USD",
                      "tariff_number": "",
                      "origin_country": "US"
              }]
      }'
  ```

  ```python Python theme={null}
  customs_item = components.CustomsItemCreateRequest(
      description="T-Shirt",
      quantity=20,
      net_weight="1",
      mass_unit=components.WeightUnitEnum.LB,
      value_amount="200",
      value_currency="USD",
      origin_country="US",
  )

  customs_declaration = shippo_sdk.customs_declarations.create(
      components.CustomsDeclarationCreateRequest(
          contents_type=components.CustomsDeclarationContentsTypeEnum.MERCHANDISE,
          contents_explanation='T-Shirt purchase',
          non_delivery_option=components.CustomsDeclarationNonDeliveryOptionEnum.RETURN,
          certify=True,
          certify_signer='Simon Kreuz',
          items=[customs_item]
      )
  )
  ```

  ```php PHP theme={null}
  $customs_item = array(
      'description'=> 'T-Shirt',
      'quantity'=> '20',
      'net_weight'=> '1',
      'mass_unit'=> 'lb',
      'value_amount'=> '200',
      'value_currency'=> 'USD',
      'origin_country'=> 'US');

  $customs_declaration = Shippo_CustomsDeclaration::create(
  array(
      'contents_type'=> 'MERCHANDISE',
      'contents_explanation'=> 'T-Shirt purchase',
      'non_delivery_option'=> 'RETURN',
      'certify'=> 'true',
      'certify_signer'=> 'Simon Kreuz',
      'items'=> array($customs_item)
  ));
  ```

  ```typescript TypeScript theme={null}
  const customsItem: CustomsItem = {
      description: "T-Shirt",
      quantity: 20,
      netWeight: "1",
      massUnit: WeightUnitEnum.Lb,
      valueAmount: "200",
      valueCurrency: "USD",
      originCountry: "US",
  };

  const customsDeclaration = await shippo.customsDeclarations.create({
      contentsType: CustomsDeclarationContentsTypeEnum.Merchandise,
      contentsExplanation: "T-Shirt purchase",
      nonDeliveryOption: CustomsDeclarationNonDeliveryOptionEnum.Return,
      certify: true,
      certifySigner: "Simon Kreuz",
      items: [customsItem],
  });
  ```

  ```java Java theme={null}
  HashMap<String, Object> customsItemMap = new HashMap<String, Object>();
  customsItemMap.put("description", "T-Shirt");
  customsItemMap.put("quantity", 20);
  customsItemMap.put("net_weight", "1");
  customsItemMap.put("mass_unit", "lb");
  customsItemMap.put("value_amount", "200");
  customsItemMap.put("value_currency", "USD");
  customsItemMap.put("origin_country", "US");

  HashMap<String, Object> customsDeclarationMap = new HashMap<String, Object>();
  customsDeclarationMap.put("contents_type", "MERCHANDISE");
  customsDeclarationMap.put("contents_explanation", "T-Shirt purchase");
  customsDeclarationMap.put("non_delivery_option", "RETURN");
  customsDeclarationMap.put("certify", true);
  customsDeclarationMap.put("certify_signer", "Simon Kreuz");
  customsDeclarationMap.put("items", customsItemMap);

  CustomsDeclaration.create(customsDeclarationMap);
  ```

  ```csharp C# theme={null}
  CustomsItemCreateRequest customsItemCreateRequest = new CustomsItemCreateRequest()
  {
      Description = "T-Shirt",
      Quantity = 20,
      NetWeight = "1",
      MassUnit = WeightUnitEnum.Lb,
      ValueAmount = "200",
      ValueCurrency = "USD",
      OriginCountry = "US",
  };
  CustomsDeclaration customsDeclaration = await sdk.CustomsDeclarations.CreateAsync(
      new CustomsDeclarationCreateRequest()
      {
          ContentsType = CustomsDeclarationContentsTypeEnum.Merchandise,
          ContentsExplanation = "T-Shirt purchase",
          NonDeliveryOption = CustomsDeclarationNonDeliveryOptionEnum.Return,
          Certify = true,
          CertifySigner = "Simon Kreuz",
          Items = new List<CustomsItemCreateRequest>() { customsItemCreateRequest },
      }
  );
  ```
</CodeGroup>

## Create the Shipment, Get Rates, and Purchase Label

The only difference between this Shipment request and a domestic Shipment request is that you must include customs declaration in the Shipment API call. After that, you can retrieve Rates and create labels [just like for domestic shipments.](/docs/Guides_general/generate_shipping_label)

<CodeGroup>
  ```shell cURL theme={null}
  curl https://api.goshippo.com/shipments/\
      -H "Authorization: ShippoToken <API_TOKEN>"\
      -d address_from="d799c2679e644279b59fe661ac8fa488"\
      -d address_to="42236bcf36214f62bcc6d7f12f02a849"\
      -d parcels="7df2ecf8b4224763ab7c71fae7ec8274"\
      -d customs_declaration="b741b99f95e841639b54272834bc478c"\
      -d async=false
  ```

  ```python Python theme={null}
  # Create shipment object
  shipment = shippo_sdk.shipments.create(
      components.ShipmentCreateRequest(
          address_from="d799c2679e644279b59fe661ac8fa488",
          address_to="42236bcf36214f62bcc6d7f12f02a849",
          parcels=["7df2ecf8b4224763ab7c71fae7ec8274"],
          customs_declaration="b741b99f95e841639b54272834bc478c",
          async_=False
      )
  )
  ```

  ```php PHP theme={null}
  // Create shipment object
  $shipment = Shippo_Shipment::create(
      array(
          "address_from" => $fromAddress,
          "address_to" => $toAddress,
          "parcels" => array($parcel),
          "customs_declaration" => $customs_declaration -> object_id,
          "async" => False
      )
  );
  ```

  ```typescript TypeScript theme={null}
  // Create shipment object
  const shipment = await shippo.shipments.create({
      addressFrom: "d799c2679e644279b59fe661ac8fa488",
      addressTo: "42236bcf36214f62bcc6d7f12f02a849",
      parcels: ["7df2ecf8b4224763ab7c71fae7ec8274"],
      customsDeclaration: "b741b99f95e841639b54272834bc478c",
      async: false
  });
  ```

  ```java Java theme={null}
  HashMap<String, Object> createShipmentMap = new HashMap<String, Object>();
  createShipmentMap.put("address_to", addressToMap);
  createShipmentMap.put("address_from", addressFromMap);
  createShipmentMap.put("parcels", parcelMap);
  createShipmentMap.put("customs_declaration", customsDeclarationMap);
  createShipmentMap.put("async", false);

  Shipment.create(createShipmentMap);
  ```

  ```csharp C# theme={null}
  Shipment shipment = await sdk.Shipments.CreateAsync(
      new ShipmentCreateRequest()
      {
          AddressFrom = AddressFrom.CreateStr("d799c2679e644279b59fe661ac8fa488"),
          AddressTo = AddressTo.CreateStr("42236bcf36214f62bcc6d7f12f02a849"),
          Parcels = new List<Shippo.Models.Components.Parcels>()
          {
              Shippo.Models.Components.Parcels.CreateStr("7df2ecf8b4224763ab7c71fae7ec8274")
          },
          CustomsDeclaration = ShipmentCreateRequestCustomsDeclaration.CreateStr("b741b99f95e841639b54272834bc478c"),
          Async = false,
      }
  );
  ```
</CodeGroup>

You will get a response with a `rates` attribute. The `rates` usually contains multiple rates -- use your own business logic to filter out the rate you want to use and grab the corresponding Rate's object\_id.

```json theme={null}
{
   "object_created":"2014-07-17T00:04:06.163Z",
   "object_updated":"2014-07-17T00:04:06.163Z",
   "object_id":"89436997a794439ab47999701e60392e",
   "object_owner":"shippotle@shippo.com",
   "status":"SUCCESS",
   "address_from": {
        "object_id": "0943ae4e373e4120a99c337e496dcce8",
        "validation_results": {},
        "is_complete": true,
        "company": "",
        "street_no": "",
        "name": "Mr. Hippo",
        "street1": "215 Clayton St.",
        "street2": "",
        "city": "San Francisco",
        "state": "CA",
        "zip": "94117",
        "country": "US",
        "phone": "+15553419393",
        "email": "support@shippo.com",
        "is_residential": null
    },
    "address_to": {
        "object_id": "4c7185d353764d0985a6a7825aed8ffb",
        "validation_results": {},
        "is_complete": true,
        "name":"Mrs. Hippo",
        "street1":"200 University Ave W",
        "city":"Waterloo",
        "state":"ON",
        "zip":"N2L 3G1",
        "country":"CA",
        "phone":"+1 555 341 9393",
        "email":"support@shippo.com",
        "is_residential": false
    },
   "address_return":null,
   "parcels": [{
        "object_id": "ec952343dd4843c39b42aca620471fd5",
        "object_created": "2013-12-01T06:24:21.121Z",
        "object_updated": "2013-12-01T06:24:21.121Z",
        "object_owner": "shippotle@shippo.com",
        "template": null,
        "length":"5",
        "width":"5",
        "height":"5",
        "distance_unit":"in",
        "weight":"2",
        "mass_unit":"lb",
        "value_amount": null,
        "value_currency": null,
        "metadata": "",
        "line_items": [],
        "test": true
    }],
   "shipment_date":"2013-12-03T12:00:00Z",
   "extra":{
      "insurance": {
         "currency": "",
         "amount": "",
      },
      "reference_1": "",
      "reference_2": ""
   },
   "customs_declaration":"b741b99f95e841639b54272834bc478c",
   "rates": [
        {
            "object_created": "2014-07-17T00:04:06.263Z",
            "object_id": "545ab0a1a6ea4c9f9adb2512a57d6d8b",
            "object_owner": "shippotle@shippo.com",
            "shipment": "89436997a794439ab47999701e60392e",
            "attributes": [],
            "amount": "5.50",
            "currency": "USD",
            "amount_local": "5.50",
            "currency_local": "USD",
            "provider": "USPS",
            "provider_image_75": "https://cdn2.goshippo.com/providers/75/USPS.png",
            "provider_image_200": "https://cdn2.goshippo.com/providers/200/USPS.png",
            "servicelevel": {
               "name": "Priority Mail",
               "token": "usps_priority",
               "terms": ""
            },
            "days": 2,
            "arrives_by": null,
            "duration_terms": "Delivery in 1 to 3 business days.",
            "messages": [],
            "carrier_account": "078870331023437cb917f5187429b093",
            "test": false,
            "zone": 1
        },
        ...
    ],
   "carrier_accounts": [],
   "messages":[],
   "metadata":"Customer ID 123456"
}
```

POST to the Transaction endpoint with your Rate object\_id to purchase your international shipping label.

<CodeGroup>
  ```shell cURL theme={null}
  curl https://api.goshippo.com/transactions\
      -H "Authorization: ShippoToken <API_TOKEN>"\
      -d rate="cf6fea899f1848b494d9568e8266e076"
      -d label_file_type="PDF"
      -d async=false
  ```

  ```python Python theme={null}
  # Get the first rate in the rates results.
  # Customize this based on your business logic.
  rate = shipment.rates[0]

  # Purchase the desired rate.
  transaction = api.transactions.create(
      components.TransactionCreateRequest(
          rate=rate.object_id,
          label_file_type=components.LabelFileTypeEnum.PDF,
          async_=False
      )
  )

  # Retrieve label url and tracking number or error message
  if transaction.status == components.TransactionStatusEnum.SUCCESS:
      print(transaction.label_url)
      print(transaction.tracking_number)
  else:
      print(transaction.messages)
  ```

  ```php PHP theme={null}
  // Get the first rate in the rates results.
  // Customize this based on your business logic.
  $rate = $shipment["rates"][0];

  // Purchase the desired rate.
  $transaction = Shippo_Transaction::create( array( 
      'rate' => $rate["object_id"], 
      'label_file_type' => "PDF", 
      'async' => false ) );

  // Retrieve label url and tracking number or error message
  if ($transaction["status"] == "SUCCESS"){
      echo( $transaction["label_url"] );
      echo("\n");
      echo( $transaction["tracking_number"] );
  }else {
      echo( $transaction["messages"] );
  }
  ```

  ```typescript TypeScript theme={null}
  // Get the first rate in the rates results.
  // Customize this based on your business logic.
  const rate = shipment.rates[0];

  // Purchase the desired rate.
  const transaction = await shippo.transactions.create({
      rate: rate.objectId,
      labelFileType: LabelFileTypeEnum.Pdf,
      async: false
  });
  ```

  ```java Java theme={null}
  // Get the first rate in the rates results.
  // Customize this based on your own business logic
  Rate rate = rates.get(0);

  Map<String, Object> transactionParameters = new HashMap<String, Object>();
  transactionParameters.put("rate", rate.getObjectId());
  transactionParameters.put("async", false);
  Transaction transaction = Transaction.create(transactionParameters);

  if (transaction.getStatus().equals("SUCCESS")) {
      System.out.println(String.format("Label url : %s", transaction.getLabelUrl()));
      System.out.println(String.format("Tracking number : %s", transaction.getTrackingNumber()));
  } else {
      System.out.println(String.format("An Error has occured while generating you label. Messages : %s", transaction.getMessages()));
  }
  ```

  ```csharp C# theme={null}
  // Get the first rate in the rates results.
  // Customize this based on your own business logic.
  Rate rate = shipment.Rates[0];
  Transaction transaction = await sdk.Transactions.CreateAsync(
      CreateTransactionRequestBody.CreateTransactionCreateRequest(
          new TransactionCreateRequest()
          {
              Rate = rate.ObjectId,
              LabelFileType = LabelFileTypeEnum.Pdf,
              Async = false,
          }
      )
  );
  if (transaction.Status == TransactionStatusEnum.Success)
  {
      Console.WriteLine($"{transaction.LabelUrl}");
      Console.WriteLine($"{transaction.TrackingNumber}");
  }
  else
  {
      Console.WriteLine($"{transaction.Messages}");
  }
  ```
</CodeGroup>

You will receive a JSON serialized Transaction object with your label, commercial invoice, and tracking information.

```json theme={null}
{
    "object_state": "VALID",
    "status": "SUCCESS",
    "object_created": "2013-12-27T19:14:48.273Z",
    "object_updated": "2013-12-27T19:14:48.273Z",
    "object_id": "64bba01845ef40d29374032599f22588",
    "object_owner": "shippotle@shippo.com",
    "was_test": false,
    "rate": {
        "object_id": "cf6fea899f1848b494d9568e8266e076",
        "amount": "5.50",
        "currency": "USD",
        "amount_local": "5.50",
        "currency_local": "USD",
        "provider": "USPS",
        "servicelevel_name": "Priority Mail",
        "servicelevel_token": "usps_priority",
        "carrier_account": "078870331023437cb917f5187429b093",
    },
    "tracking_number": "ZW70QJC",
    "tracking_status": {
        "object_created": "2013-12-27T23:17:41.411Z",
        "object_id": "a21b3d6831c14ceaba6730179ce6e784",
        "status": "UNKNOWN",
        "status_details": "",
        "status_date": "2013-12-28T12:04:04.214Z"
    },
    "tracking_url_provider": "https://tools.usps.com/go/TrackConfirmAction.action?tLabels=ZW70QJC",
    "eta": "2013-12-30T12:00:00.000Z",
    "label_url": "https://shippo-delivery.s3.amazonaws.com/96.pdf?Signature=PEdWrp0mFWAGwJp7FW3b%2FeA2eyY%3D&Expires=1385930652&AWSAccessKeyId=AKIAJTHP3LLFMYAWALIA",
    "commercial_invoice_url": "",
    "metadata": "",
    "messages": []
}
```

### What about commercial invoices?

Most international shipments require you to add 3 commercial invoices in the package's "pouch", a special envelope attached on the package. Shippo automatically creates these 3 copies for you, which will be returned in the Transaction's `commercial_invoice` field.

## Country-specific shipping guidelines

### Shipping to Switzerland (CH)

* If shipping large value or large volume to Switzerland (greater than CHF 100,000 annual sales), you must register for Swiss VAT and pass that VAT number in your customs declaration `shipment.customs_declaration.exporter_identification.tax_id`.

### Shipping using APG

* If shipping to AU or NZ using APG, you must pass an ARN on the tax identifiers using `exporter_identification.tax_id` in your customs declaration.
* If shipping to an EU country using APG, you must pass an `IOSS` value on the tax identifiers using `Exporter_identification.tax_id` in your customs declaration.
