# Customs Guide

This guide will teach you how to pass the necessary customs information for shipping internationally. In this example, we will be sending a customer in the UK an EasyPost T-Shirt and hat from our office in the US.

When shipping internationally, you go through the same steps as shipping domestically, except that you need to add customs information to your shipment. EasyPost uses this information to automatically generate the necessary customs forms for your shipment. You need to pass customs information whenever you are shipping between two countries.

[Content omitted: getting started checklist rendered dynamically. Review the rendered documentation for complete setup steps.]

[Content omitted: related links and resources. Review the rendered documentation for navigation links.]

---

## Step 1: Creating Custom Items

When shipping internationally, carriers require that you add information about the contents of your package. This information is used by the customs process for the country to which you are shipping.

To add information about your package's contents, you need to create a CustomsItem object for each type of item you are shipping. If you have multiples of the same item in the package, you don't need to create a new CustomsItem for each. You just specify the number of items when creating the CustomsItem object.

When creating a CustomsItem you pass the following:

- **description** = A brief description of the item
- **quantity** = Number of that item contained in the package
- **weight** = Total weight in ounces of all the items of that type in the package
- **value** = Total value in US dollars of all the items of that type in the package
- **hs_tariff_number** = Harmonized System code used to classify the item for customs purposes. Typically 6 or 10 digits in length.
- **origin_country** = Where the item was manufactured or assembled.

To get the "hs_tariff_number", you'll need to look up the harmonization code associated with whatever product you are shipping. You can search for them on hts.usitc.gov.

Here is an example where we create a CustomsItem object for the T-shirt we're shipping:

#### Create CustomsItems

### Example: POST /customs_items

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/customs_items \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "customs_item": {
      "description": "T-shirt",
      "quantity": "1",
      "weight": "5",
      "value": "10",
      "hs_tariff_number": "123456",
      "origin_country": "US"
    }
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func create() {
	client := easypost.New("EASYPOST_API_KEY")

	customsItem, _ := client.CreateCustomsItem(
		&easypost.CustomsItem{
			Description:   "T-shirts",
			Quantity:      1,
			Value:         10.00,
			Weight:        5,
			OriginCountry: "US",
		},
	)

	fmt.Println(customsItem)
}
```

#### Java

```java
package customs_items;

import com.easypost.exception.EasyPostException;
import com.easypost.model.CustomsItem;
import com.easypost.service.EasyPostClient;

import java.util.HashMap;

public class Create {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("description", "T-shirt");
        params.put("quantity", 1);
        params.put("value", 10);
        params.put("weight", 5);
        params.put("origin_country", "US");
        params.put("hs_tariff_number", "123456");

        CustomsItem customsItem = client.customsItem.create(params);

        System.out.println(customsItem);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Parameters.CustomsItems.Create parameters = new()
            {
                Description = "T-shirt",
                Quantity = 1,
                Weight = 5,
                Value = 10,
                HsTariffNumber = "123456",
                OriginCountry = "US"
            };

            EasyPost.Models.API.CustomsItem customsItem = await client.CustomsItem.Create(parameters);

            Console.WriteLine(JsonConvert.SerializeObject(customsItem, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const customsItem = await client.CustomsItem.create({
    description: 'T-shirt',
    quantity: 1,
    value: 10,
    weight: 5,
    hs_tariff_number: '123456',
    origin_country: 'us',
  });

  console.log(customsItem);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$customsItem = $client->customsItem->create([
    'description' => 'T-shirt',
    'quantity' => 1,
    'weight' => 5,
    'value' => 10,
    'hs_tariff_number' => '123456',
    'origin_country' => 'US'
]);

echo $customsItem;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

customs_item = client.customs_item.create(
    description="T-shirt",
    quantity=1,
    value=10,
    weight=5,
    hs_tariff_number="123456",
    origin_country="us",
)

print(customs_item)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

customs_item = client.customs_item.create(
  description: 'T-shirt',
  quantity: 1,
  weight: 5,
  value: 10,
  hs_tariff_number: '123456',
  origin_country: 'us',
)

puts customs_item
```

[Content omitted: related links and resources. Review the rendered documentation for navigation links.]

---

## Step 2: Create a Customs Info Form

Once you've created the CustomsItem objects for the items you are shipping, you next need to associate them with the customs form that you will be adding to your shipment. We call this form the CustomsInfo object. You will need only one CustomsInfo object per shipment.

The Customsinfo object contains a bunch of attributes that are very specific to shipping goods across borders. Below we'll do our best to explain each though it can be a bit confusing. If you ever have any specific questions, don't hesitate to email us at support@easypost.com.

When creating a CustomsInfo object you need to pass:

- **customs_items** = An array of CustomsItem objects. This array should contain any items you are shipping in your package.
- **contents_type** = The type of item you are sending. You pass one of the following: 'merchandise', 'returned_goods', 'documents', 'gift', 'sample', 'other'.
- **contents_explanation** = If you specify 'other' in the 'contents_type' attribute, you must supply a brief description in this attribute.
- **restriction_type** = Describes if your shipment requires any special treatment / quarantine when entering the country. You pass one of the following: 'none', 'other', 'quarantine', 'sanitary_phytosanitary_inspection'.
- **restriction_comments** = If the "restriction_type" attribute is not "none", you must supply a brief description of what is required.
- **customs_certify** = This is a boolean value (true, false) that takes the place of the signature on the physical customs form. This is how you indicate that the information you have provided is accurate.
- **customs_signer** = This is the name of the person who is certifying that the information provided on the customs form is accurate. Use a name of the person in your organization who is responsible for this.
- **non_delivery_option** = In case the shipment cannot be delivered, this option tells the carrier what you want to happen to the package. You can pass either: 'abandon', 'return'. The value defaults to 'return'. If you pass 'abandon', you will not receive the package back if it cannot be delivered.
- **eel_pfc** = When shipping outside the US, you need to provide either an Exemption and Exclusion Legend (EEL) code or a Proof of Filing Citation (PFC). Which you need is based on the value of the goods being shipped.

- If the value of the goods is less than $2,500, then you pass the following EEL code: "NOEEI 30.37(a)"
- If the value of the goods is greater than $2,500, you need to get an Automated Export System (AES) Internal Transaction Number (ITN) for your shipment. ITN will look like "AES X20120502123456". To get an ITN, go to the AESDirect website.
- An ITN is required for any international shipment valued over $2,500 and/or requires an export license unless exemptions apply.
- The maximum number of items that can be included in customs info with UPS is 100.

The trickiest part of creating the CustomsInfo object is figuring out the values for the attributes. Once you've done that, it's simply a matter of passing those values to us. Here's an example of creating the CustomsInfo object for our shipment of T-shirt and Hat to the UK:

#### Create CustomsInfo (Customs Form)

### Example: POST /customs_infos

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/customs_infos \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "customs_info": {
      "customs_certify": "true",
      "customs_signer": "Steve Brule",
      "contents_type": "merchandise",
      "contents_explanation": "",
      "restriction_type": "none",
      "eel_pfc": "NOEEI 30.37(a)",
      "customs_items": [
        {
          "description": "T-shirt",
          "quantity": "1",
          "weight": "5",
          "value": "10",
          "hs_tariff_number": "123456",
          "origin_country": "US"
        }
      ]
    }
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func create() {
	client := easypost.New("EASYPOST_API_KEY")

	customsInfo, _ := client.CreateCustomsInfo(
		&easypost.CustomsInfo{
			CustomsCertify:      true,
			CustomsSigner:       "Steve Brule",
			ContentsType:        "merchandise",
			ContentsExplanation: "",
			RestrictionType:     "none",
			EELPFC:              "NOEEI 30.37(a)",
			CustomsItems: []*easypost.CustomsItem{
				&easypost.CustomsItem{
					Description:   "T-shirt",
					Quantity:      1,
					Value:         10.00,
					Weight:        5,
					OriginCountry: "US",
				},
			},
		},
	)

	fmt.Println(customsInfo)
}
```

#### Java

```java
package customs_info;

import com.easypost.exception.EasyPostException;
import com.easypost.model.CustomsInfo;
import com.easypost.model.CustomsItem;
import com.easypost.service.EasyPostClient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Create {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        HashMap<String, Object> customsItemMap = new HashMap<String, Object>();
        customsItemMap.put("description", "T-shirt");
        customsItemMap.put("quantity", 1);
        customsItemMap.put("value", 10);
        customsItemMap.put("weight", 5);
        customsItemMap.put("origin_country", "us");
        customsItemMap.put("hs_tariff_number", "123456");

        CustomsItem customsItem = client.customsItem.create(customsItemMap);

        List<CustomsItem> customsItemsList = new ArrayList<CustomsItem>();
        customsItemsList.add(customsItem);

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("customs_certify", true);
        params.put("customs_signer", "Steve Brule");
        params.put("contents_type", "merchandise");
        params.put("contents_explanation", "");
        params.put("eel_pfc", "NOEEI 30.37(a)");
        params.put("restriction_type", "none");
        params.put("customs_items", customsItemsList);

        CustomsInfo customsInfo = client.customsInfo.create(params);

        System.out.println(customsInfo);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Parameters.CustomsInfo.Create parameters = new()
            {
                CustomsCertify = true,
                CustomsSigner = "Steve Brule",
                ContentsType = "merchandise",
                ContentsExplanation = "",
                RestrictionType = "none",
                EelPfc = "NOEEI 30.37(a)",
                CustomsItems = new List<EasyPost.Parameters.CustomsItem.Create>()
                {
                    new()
                    {
                        Description = "T-shirt",
                        Quantity = 1,
                        Weight = 5,
                        Value = 10,
                        HsTariffNumber = "123456",
                        OriginCountry = "US"
                    }
                }
            };

            EasyPost.Models.API.CustomsInfo customsInfo = await client.CustomsInfo.Create(parameters);

            Console.WriteLine(JsonConvert.SerializeObject(customsInfo, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const customsInfo = await client.CustomsInfo.create({
    eel_pfc: 'NOEEI 30.37(a)',
    customs_certify: true,
    customs_signer: 'Steve Brule',
    contents_type: 'merchandise',
    contents_explanation: '',
    restriction_type: 'none',
    restriction_comments: '',
    customs_items: [
      {
        description: 'T-shirts',
        quantity: 1,
        weight: 5,
        value: 10,
        hs_tariff_number: '123456',
        origin_country: 'US',
      },
    ],
  });

  console.log(customsInfo);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$customsInfo = $client->customsInfo->create([
    'eel_pfc' => 'NOEEI 30.37(a)',
    'customs_certify' => true,
    'customs_signer' => 'Steve Brule',
    'contents_type' => 'merchandise',
    'contents_explanation' => '',
    'restriction_type' => 'none',
    'customs_items' => [
        [
            'description' => 'T-shirt',
            'quantity' => 1,
            'weight' => 5,
            'value' => 10,
            'hs_tariff_number' => '123456',
            'origin_country' => 'US'
        ]
    ]
]);

echo $customsInfo;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

customs_info = client.customs_info.create(
    eel_pfc="NOEEI 30.37(a)",
    customs_certify=True,
    customs_signer="Steve Brule",
    contents_type="merchandise",
    contents_explanation="",
    restriction_type="none",
    customs_items=[
        {
            "description": "Sweet shirts",
            "quantity": 2,
            "weight": 11,
            "value": 23,
            "hs_tariff_number": "654321",
            "origin_country": "US",
        }
    ],
)

print(customs_info)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

customs_info = client.customs_info.create(
  customs_certify: true,
  customs_signer: 'Steve Brule',
  contents_type: 'merchandise',
  contents_explanation: '',
  restriction_type: 'none',
  eel_pfc: 'NOEEI 30.37(a)',
  customs_items: [
    {
      description: 'T-shirt',
      quantity: 1,
      weight: 5,
      value: 10,
      hs_tariff_number: '123456',
      origin_country: 'US',
    },
  ],
)

puts customs_info
```

[Content omitted: related links and resources. Review the rendered documentation for navigation links.]

---

## Step 3: Create Shipment and Attach Customs Info

Now that you've created the required customs information, you can now create your international shipment. The only difference from a domestic shipment is that you need to also pass the CustomsInfo object when creating a shipment.

When you buy a shipping label for your shipment, we automatically create additional customs forms that you need. Most often, the customs form is integrated into the label and you can put it directly on your package. If you ever have any questions about a specific carrier, don't hesitate to email us.

![Customs Label](https://docs.easypost.com/images/guides/customs/customs-label.png)

Here's an example where we are creating an international shipment:

#### Create International Shipment

[Content omitted: API request example. Review the rendered documentation for complete request payloads, parameters, and code samples.]

[Content omitted: related links and resources. Review the rendered documentation for navigation links.]

---

Congratulations! You've just created your first international package with EasyPost! Check out our Full Reference API Documentation.

[Content omitted: related links and resources. Review the rendered documentation for navigation links.]