EU Regulatory Updates
To comply with new EU regulatory mandates, EasyPost now supports the required shipping data through the shipment and orders API. Most of the required information was already supported through existing fields; a few new parameters cover specific regulatory additions.
Most of these parameters are carrier-agnostic and are designed to satisfy the regulations directly rather than any individual carrier's requirements. Any carrier-specific requirements that cannot be covered by these additions (such as UPS's business/consumer classification) are supported separately and detailed in the carrier sections below.
This guide is organized top-down: the carrier-agnostic, API-level fields you send to EasyPost come first, then carrier-specific behavior, followed by how FedEx and UPS render or transmit them.
Three product identifiers must appear on customs documentation for EU-bound shipments starting November 1, 2026. They are optional today, but after the deadline qualifying EU-bound shipments without them may not clear customs. EasyPost does not make them mandatory, and most carriers do not currently require them — but you should start sending them ahead of the deadline.
| Identifier | EasyPost field | Status |
|---|---|---|
| M-PID — merchant product ID | code (existing) | No change |
| NS-PID — manufacturer product ID | manufacturer_product_id (new) | Start sending now |
| S-PID — standardized ID / GTIN-EAN | standardized_product_id (new) | Start sending now |
Since July 2026, a €3 customs duty per item line applies to B2C shipments into the EU valued ≤ €150. This is a regulatory customs duty, not a carrier surcharge. EU customs classifies and routes each shipment using data you should already be passing through existing fields, or carrier-specific fields for carriers like UPS:
- Tax identifiers — your IOSS or VAT registration on the commercial invoice. IOSS marks a B2C shipment eligible for the flat-fee fast lane; VAT marks a B2B shipment routed through full H1 customs processing.
- B2B vs. B2C classification — whether the shipper and consignee are a business or a consumer. This is carrier-specific today (see below).
These are the shipment-API fields you send to EasyPost, independent of which carrier ultimately moves the package.
Two new fields on each customs_item, alongside the existing merchant code, carry the three EU product identifiers. These are carrier-agnostic:
| Field | EU identifier | Notes |
|---|---|---|
code (existing) | M-PID (C127) | Merchant product ID — already supported |
manufacturer_product_id (new) | NS-PID (C128) | Manufacturer's product identifier |
standardized_product_id (new) | S-PID (C129) | Standardized identifier — GTIN/EAN |
codeis the existing merchant product ID field. No change; for EU customs it now doubles as the M-PID (C127).- Only
manufacturer_product_idandstandardized_product_idare new.
Starting November 1, 2026, these identifiers are mandatory on EU customs documentation. They are voluntary in the July 1 → October 31, 2026 window, so you can start sending them now. EasyPost makes these mandatory only when a specific carrier does; see the carrier-specific sections below.
How to use it:
{
"customs_item": {
"description": "Women's 100% Cotton T-Shirt, Navy, L",
"quantity": 1,
"value": "12.00",
"hs_tariff_number": "6109.10.0012",
"code": "123456",
"manufacturer_product_id": "SH123456",
"standardized_product_id": "00012345600012"
}
}- All fields are optional / nullable; max length 64.
- Carrier-agnostic — the same two fields also serve US CPSC (see the companion CPSC guide).
According to official European Commission DG Trade Guidance(opens in a new tab), if an item does not have a standardized barcode, the electronic customs declaration must include the official TARIC exemption code Y081 ("Declaration that there is no standardized identifier for the product"). Omitting the data entirely will cause the declaration to fail schema validation, as EU border systems expect either a valid S-PID (Code C129) or the Y081 exemption code.
On EasyPost, pass the literal string Y081 in customs_items.standardized_product_id when an item has no standardized identifier, rather than leaving the field empty or null.
The existing shipment.tax_identifiers[] array takes the list of tax registration numbers (VAT, IOSS, EORI, UKIMS, EIN, …) associated with the sender or recipient. This array is unchanged. If you have an IOSS number (or VAT, if applicable), it's important to add it now.
For EU-bound shipments these numbers are now surfaced on the commercial invoice where customs expects them (see the carrier-specific sections below), in various places depending on the carrier.
How to use it (unchanged shape):
{
"shipment": {
"tax_identifiers": [
{ "entity": "SENDER", "tax_id": "IM4420000191", "tax_id_type": "IOSS", "issuing_country": "IE" },
{ "entity": "SENDER", "tax_id": "GB362459274", "tax_id_type": "VAT", "issuing_country": "GB" },
{ "entity": "SENDER", "tax_id": "GB205672212000", "tax_id_type": "EORI", "issuing_country": "GB" }
]
}
}EasyPost passes through the numbers you provide and makes sure they appear correctly. EasyPost does not infer, generate, or choose between your tax IDs. If you provide both an IOSS and a VAT number for a FedEx shipment entering the EU under the new regulations, EasyPost will not choose between them — both will appear on the commercial invoice. It is your responsibility to understand the constraints and provide the correct information.
A new optional address on each entry of tax_identifiers lets you supply the registered address (and, through it, the registered name) tied to a tax registration — for example, the address behind an IOSS or VAT registration.
Carriers such as UPS now expect associated information such as Number + Name + Address for eligible EU-bound shipments. Previously tax_identifiers only accepted the ID number and type.
It is carrier-agnostic by design (it lives on the shared tax-identifier object, not under carrier_options), even though UPS IOSS is currently the only carrier that requests it explicitly. You can provide it in two ways:
How to use it
- Inline:
{
"shipment": {
"tax_identifiers": [
{
"entity": "SENDER",
"tax_id": "IM1234567890",
"tax_id_type": "IOSS",
"issuing_country": "DE",
"address": {
"name": "ACME GmbH",
"street1": "Friedrichstraße 1",
"city": "Berlin",
"zip": "10117",
"country": "DE"
}
}
]
}
}- Reference an existing saved address, the same convention as
to_address:
{
"tax_identifiers": [
{
"tax_id": "IM1234567890",
"tax_id_type": "IOSS",
"issuing_country": "IE",
"address": { "id": "adr_5843b8dd903611f19a3d0022480b361d" }
}
]
}addressreuses EasyPost's standard Address model.- It is optional; omitting it preserves prior behavior.
How each carrier renders or transmits the API-level data above. Nothing here is a new field you send — it describes carrier behavior.
For more background on the rules driving this, see FedEx's customer guide: FedEx De Minimis Customer Guide (EU)(opens in a new tab).
Important — make duty handling explicit. By default, FedEx bills the recipient for duties and taxes on international shipments. Rather than relying on that default, set who pays and make sure the recipient is reachable:
- Include the recipient's email in
to_address.emailwhen possible, so FedEx can contact them about any duties and taxes they're responsible for. - Say who pays duties and taxes with
options.duty_payment— settypetoSENDER,RECEIVER, orTHIRD_PARTY— and state the terms with the incoterm incustoms_info.incoterm(DDP= shipper pays,DDU/DAP= recipient pays). This is separate fromoptions.payment, which bills shipping, not duties. - Provide your IOSS number in
tax_identifiers[]if you have one (see Part 1) — the EasyPost equivalent of FedEx'sshipper.tins[].
For shipments into the EU, EasyPost now surfaces your VAT and IOSS numbers on the FedEx commercial invoice in two places:
-
The Tax ID field on the CI (exporter / importer tax ID). FedEx prints only the first tax ID on the CI that is sent, so a VAT or IOSS listed after another ID (e.g. an EORI) previously never appeared. EasyPost now floats VAT/IOSS to the front of the tax IDs sent to FedEx for EU destinations, so it prints in the exporter or importer tax ID field.
-
Declaration statement line on the CI. For EU-bound shipments, VAT and IOSS numbers are included within the commercial invoice's declaration statement. (UKIMS continues to be included on the declaration statement for all destinations, matching previous behavior.) Since this field has no character limit, any combination — one, two, or all three identifiers — can be displayed. If a shipment contains conflicting tax ID declarations (such as both IOSS and VAT for a flat-fee shipment to the EU), both are printed on the declaration statement. As noted, EasyPost does not make automated determinations on your behalf.
One caveat — US-origin shipments: when the shipment originates in the USA, FedEx omits VAT/IOSS from the rendered CI PDF, even though EasyPost includes them in the request. This is FedEx's own rendering behavior, not an EasyPost limitation. US → EU shippers should not expect to see VAT/IOSS on the printed invoice; non-US-origin EU-bound shipments (e.g. GB → DE, FR → DE) render as described.
This change only applies to shipments entering the EU:
- If you don't send
tax_identifiers, nothing changes. - If you already do, you simply start seeing VAT and/or IOSS on the CI for your EU shipments — no code changes required.
When possible, include the recipient's email in to_address.email so UPS can contact them about any duties and taxes they're responsible for.
Two UPS-specific carrier options, shipper_type and consignee_type, classify the shipper (sender) and consignee (recipient) as a business or a consumer. Because this is specific to UPS, it lives inside carrier_options.
EasyPost maps them to UPS's GlobalTaxInformation/ShipperTypeValue and GlobalTaxInformation/ConsigneeTypeValue. These are the values UPS has told customers it now requires.
UPS uses them for EU de minimis customs routing and handling, since the B2B/B2C indicator routes the shipment into the correct customs lane. UPS may hold or return EU-bound shipments that omit them.
They are found under options.carrier_options.ups; each is independent (send either, both, or neither):
{
"shipment": {
"options": {
"carrier_options": {
"ups": {
"shipper_type": "business",
"consignee_type": "consumer"
}
}
}
}
}- Accepted values (both):
business,consumer. Anything else is rejected with a clear validation error. - Both are optional and independent; omitting both leaves the shipment unchanged (no
GlobalTaxInformationsent). - Shared wire code set:
business→01,consumer→02. UPS-only for now; mirrors the existingcarrier_options.ups.premierpattern. - Capture-and-transmit only — EasyPost passes the values through; it does not infer or override them from your
residential/companyvalues.
How it appears:
<GlobalTaxInformation>
<ShipperTypeValue>02</ShipperTypeValue>
<ConsigneeTypeValue>02</ConsigneeTypeValue>
</GlobalTaxInformation>The carrier-agnostic tax_identifiers[].address field was added initially for UPS's IOSS requirements. While it is carrier-agnostic, UPS is currently the only carrier using the data.
UPS exposes structured IOSS fields (Number + Name + Address) on the ShipConfirm request. When an IOSS tax identifier carries an address, EasyPost emits it as an IOSSContact under ShipFrom/VendorInfo:
<ShipFrom>
<VendorInfo>
<VendorCollectIDTypeCode>0356</VendorCollectIDTypeCode> <!-- IOSS -->
<VendorCollectIDNumber>IM1234567890</VendorCollectIDNumber>
<IOSSContact>
<Name>ACME GmbH</Name>
<Address>
<AddressLine1>Friedrichstraße 1</AddressLine1>
<City>Berlin</City>
<PostalCode>10117</PostalCode>
<CountryCode>DE</CountryCode>
</Address>
</IOSSContact>
</VendorInfo>
</ShipFrom>A temporary guard rejects UPS Worldwide Economy duty-unpaid (DDU) rate and buy requests bound for Germany (DE). WWE duty-paid (DDP) and every non-WWE UPS service are unaffected. Under the new EU rules, UPS has communicated that WWE can no longer clear duty-unpaid volume into Germany, and such packages would be returned to sender. UPS has asked us to stop sending WWE DDU to DE for both BYOA and the DAP program. EasyPost rejects these up front with a 422 at rate/buy time, before any UPS call, so you don't buy labels that would just be returned to sender. UPS has not provided an ETA for when this restriction will be lifted.
What's blocked vs. kept:
- Blocked: WWE duty-unpaid (DDU / DAP incoterm) to DE for all account types (BYOA and the DAP program).
- Kept: WWE duty-paid (DDP) to DE, and all non-WWE UPS services.
What you'll see:
- Rating or buying a WWE DDU shipment to DE returns a 422:
UPS Worldwide Economy is temporarily unavailable for duty-unpaid (DDU) shipments to Germany (DE). On the DAP-program rate path the same rejection surfaces asSHIPMENT.RATES.UNAVAILABLE.
A note on the two "DAP"s: "duty-unpaid" here is the incoterm (DDU / DAP = "Delivered At Place"), not the UPSDAP account type. The block keys off destination + duty status only, so it applies to BYOA and the DAP program alike, and never touches WWE DDP.
| Change | Layer | What it does | Driver |
|---|---|---|---|
| VAT / IOSS tax identifiers | API (agnostic) | Existing tax_identifiers[]; no new field to send | EU de minimis clearance |
Tax identifier address | API (agnostic) | Optional address on each tax_identifiers[] (inline or {id: "adr_…"}); reuses Address model | Carrier IOSS name/address requirement |
| Product Identifiers | API (agnostic) | New manufacturer_product_id (NS-PID) + standardized_product_id (S-PID) on customs_item; code = M-PID. Accepted by the API now, but not yet transmitted to carriers. | EU PID mandate (voluntary July 1, mandatory November 1, 2026) |
| VAT / IOSS on FedEx CI | FedEx | Floats VAT/IOSS to front of tax IDs (prints in CI Tax ID field) + adds to declaration statement; EU only; UKIMS unchanged | EU de minimis clearance |
| UPS Shipper & Consignee Type | UPS | carrier_options.ups.shipper_type / consignee_type (business/consumer) → UPS ShipperTypeValue / ConsigneeTypeValue | EU B2B/B2C customs routing |
| Tax Identifier Address → IOSS | UPS | IOSS address → VendorInfo/IOSSContact (Name + Address) on ShipFrom | UPS IOSS name/address |
| WWE → Germany DDU block | UPS | Temporarily blocks WWE duty-unpaid (DDU) rate/buy to DE (422); keeps DDP | UPS cannot clear WWE DDU into DE |