# UPS — EU Regulatory Updates

UPS caps `ProductID` at 100 characters. EasyPost transliterates non-ASCII values and truncates `code`, `manufacturer_product_id`, and `standardized_product_id` to the cap rather than failing the shipment. `code` accepts up to 128 characters at the EasyPost API, so it is the only one that can exceed 100 on length alone. Transliteration runs before truncation and can lengthen a value — `ß` and `ж` become two characters, `щ` becomes four.

## Background

- EasyPost is rolling out changes so you can supply the data UPS requests for the new EU regulation changes through the existing shipment API.
- Separately, UPS has temporarily suspended one Worldwide Economy lane it can no longer clear under the new rules. This guide covers all of these changes.
- For the broad, cross-carrier picture of the EU regulatory changes, see the [EU Regulatory Updates](/guides/eu-regulatory-updates-guide) guide.

---

## UPS Shipper & Consignee Type

- **What it is:** two UPS carrier options, `shipper_type` and `consignee_type`, that classify the **shipper** (sender) and the **consignee** (recipient) of a shipment as a **business** or a **consumer**.

  - EasyPost maps them to UPS's `GlobalTaxInformation/ShipperTypeValue` and `GlobalTaxInformation/ConsigneeTypeValue` fields on the shipment request.

- **Why it matters:** UPS uses these classifications for EU de minimis customs handling.
  - Providing them helps ensure shipments clear customs correctly; UPS may hold or return shipments into the EU that omit them.
  - EasyPost only passes the values through to UPS if set, and does not infer these values from other values (such as `residential` flags on an address).

Set them under `options.carrier_options.ups` when creating a shipment. Each is independent — send either one, both, or neither.

- Accepted values (both fields): `business`, `consumer`, `not_applicable`. Anything else is rejected with a clear validation error.
- Both are optional and independent. Omitting a field leaves that classification unsent; omitting both leaves the shipment unchanged from prior behavior (no `GlobalTaxInformation` sent).

**How to use it:**

```json
{
  "shipment": {
    "options": {
      "carrier_options": {
        "ups": {
          "shipper_type": "business",
          "consignee_type": "consumer"
        }
      }
    }
  }
}
```

These values are sent on the `GlobalTaxInformation` block on the UPS `ShipConfirm` request. `ShipperTypeValue` always precedes `ConsigneeTypeValue` per the UPS schema sequence.

For example, `shipper_type: "consumer"` + `consignee_type: "consumer"` produces:

```xml
<GlobalTaxInformation>
    <ShipperTypeValue>02</ShipperTypeValue>
    <ConsigneeTypeValue>02</ConsigneeTypeValue>
</GlobalTaxInformation>
```

---

## Tax Identifier Address

- **What it is:**

  - An optional `address` on each entry of a shipment's `tax_identifiers`, so you can supply the address (and, through it, the name) tied to a tax registration — e.g. the registered address behind an IOSS/VAT registration.

- **Why it matters:**
  - UPS exposes structured IOSS fields — Number + **Name** + **Address** — for shipments into the EU.
  - Previously EasyPost's `tax_identifiers` only accepted the ID number and type, so there was no way to pass the registered name/address UPS wants.
  - This change closes that gap.

```json
{
  "shipment": {
    "tax_identifiers": [
      {
        "tax_id": "IM1234567890",
        "tax_id_type": "IOSS",
        "issuing_country": "DE",
        "address": {
          "name": "ACME GmbH",
          "street1": "Friedrichstraße 1",
          "city": "Berlin",
          "zip": "10117",
          "country": "DE"
        }
      }
    ]
  }
}
```

Or, referencing an existing saved address:

```json
{
  "tax_identifiers": [
    {
      "tax_id": "IM1234567890",
      "tax_id_type": "IOSS",
      "issuing_country": "IE",
      "address": {
        "id": "adr_5843b8dd903611f19a3d0022480b361d"
      }
    }
  ]
}
```

- `address` accepts either a reference to an existing saved address (`{ "id": "adr_..." }`) or a full address object
- Optional; omitting it preserves current behavior.
- Fields are not specific to UPS and may be used by other carriers

When an IOSS tax identifier carries an `address`, EasyPost emits it as an `IOSSContact` under `ShipFrom/VendorInfo` on the UPS request:

```xml
<ShipFrom>
    <CompanyName>Example Shipper LLC</CompanyName>
    <AttentionName>Example Shipper</AttentionName>
    <Address>
        <AddressLine1>123 Example St</AddressLine1>
        <AddressLine2>Suite 100</AddressLine2>
        <City>Anytown</City>
        <StateProvinceCode>CA</StateProvinceCode>
        <PostalCode>90210</PostalCode>
        <CountryCode>US</CountryCode>
    </Address>
    <PhoneNumber>5555550100</PhoneNumber>
    <TaxIdentificationNumber>IMDEU1234567</TaxIdentificationNumber>
    <TaxIDType>
        <Code>IOSS</Code>
    </TaxIDType>
    <VendorInfo>
        <VendorCollectIDNumber>IMDEU1234567</VendorCollectIDNumber>
        <VendorCollectIDTypeCode>0356</VendorCollectIDTypeCode>
        <IOSSContact>
            <Name>ACME IOSS Ltd</Name>
            <Address>
                <AddressLine1>10 Rue de Rivoli</AddressLine1>
                <City>Paris</City>
                <PostalCode>75001</PostalCode>
                <CountryCode>FR</CountryCode>
            </Address>
        </IOSSContact>
    </VendorInfo>
</ShipFrom>
```

---

## Worldwide Economy to Germany: Duty-Unpaid Suspended (BYOA and DAP)

**What it is:** a temporary guard that rejects UPS **Worldwide Economy duty-unpaid (DDU)** rate and buy requests destined for **Germany (DE)**. WWE duty-paid (DDP) and every non-WWE UPS service are unaffected.

**Why it matters:** UPS asked EasyPost to temporarily stop sending WWE DDU to DE for **both** BYOA and the DAP program. EasyPost rejects these up front — a 422 at rate/buy time, before any UPS call — so you don't buy labels that would just be returned to sender. UPS currently has no ETA for when this service will be restored.

**What's blocked vs. kept:**

- **Blocked:** WWE duty-unpaid (DDU / DAP incoterm) to DE — 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 as `SHIPMENT.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 WWE DDU / DAP only, not WWE DDP.

This is a temporary restriction and will be removed once UPS lifts it.

## Summary

| Change | What it adds | Why it's required |
|---|---|---|
| `shipper_type` / `consignee_type` | `carrier_options.ups.shipper_type` / `consignee_type` (business/consumer/not_applicable) → UPS `ShipperTypeValue` / `ConsigneeTypeValue` | EU de minimis customs classification |
| `tax_identifiers[].address` | Optional `address` on `tax_identifiers[]` → UPS IOSS Name / Address | EU IOSS registered name/address |
| Worldwide Economy → Germany | Temporarily blocks WWE duty-unpaid (DDU) rate/buy to DE (422); keeps DDP | UPS cannot clear WWE DDU volume into DE |