Extracting Delivery Terms (Incoterms) From a Purchase Order
9 min read · updated August 11, 2026
A delivery term is not free text. It is one of eleven codes from a published, dated vocabulary, followed by a place, and the two together decide who pays for carriage, who bears the risk, and who clears customs. Extracting the three letters alone extracts the least useful third of it.
The eleven rules
The Incoterms rules are published by the International Chamber of Commerce; the current revision, Incoterms 2020, entered into force on 1 January 2020. The US International Trade Administration’s summary of the 2020 rules lists them in two groups, and the grouping is the first validation you get for free.
Seven rules apply to any mode or modes of transport:
EXW— Ex WorksFCA— Free CarrierCPT— Carriage Paid ToCIP— Carriage and Insurance Paid ToDAP— Delivered At PlaceDPU— Delivered At Place UnloadedDDP— Delivered Duty Paid
Four apply only to sea and inland waterway transport: FAS (Free Alongside Ship), FOB (Free On Board), CFR (Cost and Freight) and CIF (Cost, Insurance and Freight).
That split is a usable check. A term from the sea-only group on a shipment that is moving by air or road, or on containerised cargo handed over at an inland terminal, is a common commercial error rather than an extraction error — but your pipeline is the place it becomes visible. The ITA notes that DPU replaced the older DAT, with the added requirement that the seller unload the goods from the arriving means of transport.
The revision is part of the term
“FCA” on its own is ambiguous across revisions, and the revisions differ in ways that matter. DAT existed in Incoterms 2010 and does not exist in 2020; DDU existed in earlier revisions and was dropped; the insurance level required under CIP changed between revisions. Parties remain free to contract on an older revision if they name it, and plenty of long-running supply agreements do.
So the correct reading of a purchase order clause is the rule plus the revision the document names, and where the document names none, that fact is itself the extraction. Do not default the revision to the current one silently. Return null, record that the document did not state it, and let the contract or the supplier master supply it — a defaulted revision is an assumption that will be indistinguishable from a fact six months later.
A document reading “DAT Antwerp” is a genuinely interesting output: either it is an Incoterms 2010 term, in which case the revision is knowable, or somebody has used a retired code under a 2020 heading, which is worth a query. Returning null and recording why is the general pattern for handling a missing required field.
The named place is not optional
Each rule is followed by a named place, and the rule is close to meaningless without it. “FCA” says the seller delivers to a carrier; where that happens decides who pays for the leg before it. “FCA Seller’s Works, Stuttgart” and “FCA Port of Hamburg” allocate materially different costs.
The place also differs in kind between rules. For the C-group rules the named place is the destination to which the seller has contracted carriage, while the risk transfers earlier — which is the single most misunderstood point in the whole vocabulary, and a reason to keep the place as an extracted string rather than trying to infer where risk sits.
Practically, this means the extractor must return two fields and tolerate a messy second one. Places arrive as “Rotterdam”, as a UN/LOCODE such as NLRTM, as a full street address, as a plant code from the buyer’s own system, or as “buyer’s nominated warehouse”. Normalise where you can against your own location master; keep the raw string always.
Strings that are not Incoterms
A purchase order’s delivery-terms field attracts a lot of text that resembles an Incoterm and is not one. Matching a three-letter token without checking it against the closed set produces confident nonsense.
- Retired codes.
DATandDDUare real terms from earlier revisions, not typos, and they should be extracted with the revision they belong to rather than corrected to a current code. - Informal abbreviations.
C&Fis trade shorthand for CFR and is not itself an Incoterm code.CNFappears for the same thing. - US domestic delivery terms. “FOB Origin” and “FOB Destination” are American domestic usage governed by commercial law rather than the ICC rules, and they mean something different from the ICC’s FOB — which applies only to sea and inland waterway carriage. On a US domestic PO, “FOB Destination” is almost certainly not an Incoterm at all. Extract it, flag the ambiguity, and do not map it onto the ICC vocabulary.
- Carriage instructions. “Prepaid”, “Collect”, “Freight prepaid and add” describe who is billed for carriage. They frequently sit in the same field and they are not delivery terms.
- Payment terms in the wrong box.
CADfor cash against documents andCODfor cash on delivery both look like three-letter codes and are neither Incoterms nor currencies — thoughCADis also a currency code, which is exactly the kind of collision a closed-set check exists to catch.
Schema and validation
{
"delivery_terms": {
"rule": "DPU", // must be one of the 11
"revision": "2020", // null if the document does not state it
"named_place": "Manchester, Trafford Park Depot",
"named_place_code": "GBMNC", // normalised, nullable
"mode_class": "any_mode", // derived: any_mode | sea_inland
"as_printed": "DPU Manchester (Incoterms 2020)",
"flags": ["revision_stated"]
}
}Four assertions do the work. The rule must be a member of the eleven for the stated revision, or of the set for the revision the document names. The named place must be present and non-empty; a rule with no place is incomplete and should be flagged rather than accepted. A sea-only rule on a shipment your own data says is moving by air or road is a flag. And as_printed must contain the extracted rule as a substring, which catches a model that produced a plausible code from context rather than from the page.
The reason to get this right is downstream: the term decides whether freight belongs on the supplier’s invoice at all, which is the check described in extracting freight and handling charges separately, and a change of term between PO revisions is a commercial change that must not be lost in a reprint diff, as in matching a purchase order to its amendments.