What ETD Replaces #
On a traditional international shipment, the commercial invoice is a piece of paper. You print several copies, put them in a document pouch on the box, and customs reads them at the border. If the pouch is lost or a copy is missing, the shipment stops.
Electronic Trade Documents send those documents to FedEx digitally as part of the shipment request, so customs receives them before the box arrives.
In one line
ETD lives inside requestedShipment.customsClearanceDetail in the FedEx Ship API. You either let FedEx generate the commercial invoice from the customs data you supply, or you upload your own document — and either way, the accuracy of the customs data is what decides whether the shipment clears.
An honest note on this one: unlike most posts here, this is a docs-and-integration guide rather than a war story. The customs-data specifics below are the parts that caused real problems; the ETD mechanics themselves come from FedEx's published API.
Where It Sits in the Request #
Everything customs-related hangs off one branch of the shipment request:
requestedShipment:
customsClearanceDetail:
commodities: [ ... ] # what is in the box
dutiesPayment: # who pays duty — see incoterms below
paymentType: SENDER | RECIPIENT
commercialInvoice: { ... } # invoice-level fields
shippingDocumentSpecification: # what FedEx should produce / you supply
shippingDocumentTypes: [ COMMERCIAL_INVOICE ]
etdDetail:
requestedDocumentTypes: [ COMMERCIAL_INVOICE ]
Two routes, and picking the right one early saves rework:
| FedEx generates it | You upload your own | |
|---|---|---|
| Effort | Low — supply customs data, FedEx renders the document | Higher — you generate a PDF and attach it |
| Control of layout | None | Full |
| When you need it | Standard shipments | When your invoice must carry specific local fields or branding |
If your invoice has to carry country-specific tax registration numbers, a declaration line, or an authorised signature block, you will usually end up generating it yourself.
The Four Fields That Actually Cause Holds #
ETD does not make customs data more forgiving — it makes bad data arrive faster. These are the fields worth being pedantic about.
- HS code, at the right number of digits
Harmonised codes are internationally six digits, extended nationally to eight or ten. Different carriers and lanes expect different lengths, and sending the wrong number of digits gets rejected at booking or queried at the border. Store the full code and trim per lane rather than storing one truncated value.
- Country of manufacture, per commodity
Not the ship-from country. If you sell goods made in several places, this is per line, and getting it wrong is a misdeclaration rather than a typo.
- Declared value that matches what the buyer paid
Under-declaring to reduce duty is a customs offence, not a tactic. The value on the invoice should reconcile with the marketplace order.
- Incoterm, chosen deliberately
Who pays the duty — you or the buyer. Leave it defaulted and you will discover the answer when a buyer is asked for money at the door, which becomes a support ticket and often a refund.
Watch field lengths on the printed document. A long company name plus a long address plus a tax registration number can overflow the invoice's address block and silently truncate. A truncated tax number on an export document is not cosmetic — it can invalidate the declaration. Test with your longest real address, not a short sample one.
The Bit Everyone Forgets: Cancelling Labels #
Not strictly ETD, but it belongs in the same conversation because it becomes a problem the moment you automate document generation.
Every label you create is a shipment as far as the carrier is concerned — including the ones created by a bug, a duplicate click, or a test run. Cancel the ones you do not ship:
PUT /ship/v1/shipments/cancel
Cancellation is valid only before the package is tendered. Build the cancel path at the same time as the create path, not after your first billing surprise, and make it easy for an operator to reach — because they will need it on their first day.
Testing It Sensibly #
FedEx gives you a sandbox, which puts it well ahead of some carriers. Two things to know before you rely on it:
- The Ship API is enabled separately from tracking. A project with tracking working is not a project that can create labels. If label calls fail with an authorisation error while tracking works fine, check which APIs are actually enabled on the project rather than debugging your credentials.
- Sandbox labels are not shippable, which is the point. Do your envelope and document work there, and treat moving to production as a separate, deliberate step with its own checks.
Most defects in this area are in document construction rather than the round trip, so assert on the request you build — the commodity lines, the code lengths, the value totals — rather than only on the response. That is testable offline and it is where the bugs live.
Same lane, other carrier: DHL India's CSB-V route handles customs very differently, and why Buy Shipping doesn't cover export explains how you end up owning this work in the first place.
FAQ #
What is FedEx ETD?
Electronic Trade Documents — a way to submit customs paperwork such as the commercial invoice digitally with the shipment request, so customs receives it electronically instead of reading printed copies from a pouch on the box.
Where does ETD go in the FedEx Ship API request?
Customs data sits in requestedShipment.customsClearanceDetail, with the document behaviour controlled by shippingDocumentSpecification and etdDetail. You can have FedEx generate the commercial invoice from your customs data, or upload your own document.
Should I let FedEx generate the commercial invoice or upload my own?
Let FedEx generate it unless your invoice must carry specific local content — tax registration numbers, declaration wording, a signature block or branding. Those requirements usually push you to generating the PDF yourself.
How many digits should an HS code have?
Six internationally, extended to eight or ten nationally. Requirements vary by carrier and lane, so store the full code and trim per lane rather than storing a pre-truncated value.
How do I cancel a FedEx label I created by mistake?
PUT /ship/v1/shipments/cancel with the account and tracking number, valid only before the package is tendered. Build the cancel path alongside label creation rather than after the first billing surprise.
Why do my FedEx label calls fail when tracking works?
The Ship API is enabled separately from tracking on a FedEx developer project. Tracking working does not mean labels are enabled — check which APIs are on the project before suspecting your credentials.
Related guides
Shipping APIs
DHL India CSB-V: The SOAP API That Returns a Delimited String
Integrating India's CSB-V commercial export lane means a SOAP service with 142 positional fields, no sandbox, and responses that are delimited strings rather than parseable XML. Here's what CSB-V actually is, the four things about this API that break normal SOAP tooling, and how to test an integration that has no test environment.
Read guide →Shipping APIs
FedEx Open Ship: The Consolidation API Hiding in the Ship API
Consolidating export parcels under one master shipment is often run by hand through a desktop tool, on the assumption that the shipping API can't do it. It can — FedEx's Ship API exposes it as Open Ship. Here's what Open Ship is, the request shape that actually works, and the four things about it the docs gloss over.
Read guide →Shipping APIs
DHL's Hybrid API: Mother-Baby Consolidation That Actually Has an API
Consolidating many parcels under one master airway bill is standard practice for export, and with most carriers it means a desktop app and manual data entry. DHL India exposes it as a real SOAP operation — one call carrying a General block, a Mother, and an array of Babies. Here's how the structure works, and the gate you should keep it behind until you've seen a live response.
Read guide →Don't want to build this yourself?
I set this up for sellers and agencies every week. Book a free 30-minute audit of your Amazon data & PPC setup — you'll leave with a plan either way, whether we work together or not.