Three documents in, a CAS shipment out
FreightParse reads a supplier invoice, a packing list and a bill of lading and writes the goods lines of the declaration. Here the same reading is written as the CustomsShipment document that the Customs4trade CAS Ingest API takes at POST /v1/customsshipments.
In
- Commercial invoice (PDF)
- Packing list (PDF)
- Bill of lading (PDF)
Out
passes the published schema- cas_example_NHH26-0915.json, the shipment
- cas_example_NHH26-0915.notes.txt, what it leaves out and why
The check is against the OpenAPI file CAS publishes, https://api.customs4trade.com/swagger/1.0/swagger.json, version 1.0, fetched 2026-09-24 (SHA-256 6530808b3e57197c). It runs in strict mode. The published schema leaves the objects written inline in an array open, a goods item among them, so a misspelt field there would pass it. Strict mode refuses any field the schema does not name, wherever it sits.
The shipment
{
"direction": "IN",
"externalReference": "NHH26-0915",
"storageLocationReference": "YOUR-CAS-LOCATION",
"messageType": "New",
"singleAdministrativeDocument": {
"invoiceCurrency": "USD",
"totalInvoiceAmount": 10316.0,
"totNumItems": 5,
"packaging": {
"quantity": 418
},
"importer": {
"name": "HOLLAND PARTS DISTRIBUTIE B.V.",
"businessPartnerReferences": [
{
"code": "NL854219663",
"type": "Eori"
}
]
},
"goodsShipment": {
"exporter": {
"name": "NINGBO HAILONG HARDWARE CO., LTD."
},
"tradeTerms": {
"termsCode": "FOB",
"place": "NINGBO"
},
"invoice": {
"number": "NHH26-0915",
"date": "2026-09-09"
},
"consignment": {
"transitOfficeCodes": [],
"transportEquipments": [
{
"seqNum": 1,
"identification": "MSCU7241881",
"seals": [
{
"seqNum": 1,
"identification": "CN884217"
}
]
}
],
"transportContractDocuments": [
{
"id": "MEDUNB4471902",
"typeCode": "N705"
}
]
},
"governmentAgencyGoodsItems": [
{
"seqNum": 1,
"commodity": {
"description": "HEX BOLTS ZINC PLATED",
"classifications": [
{
"code": "73181569",
"type": "CN"
}
],
"invoiceLine": {
"itemAmount": 3016.0
}
},
"goodsMeasure": {
"gmass": 3380.0,
"nmass": 3120.0,
"qty": 52000.0,
"uom": "PCS"
},
"packagings": [
{
"quantity": 104,
"type": "CT"
}
],
"origins": [
{
"country": "CN",
"type": "NonPreferentialOrigin"
}
]
},
{
"seqNum": 2,
"commodity": {
"description": "FLAT WASHERS DIN125",
"classifications": [
{
"code": "73182200",
"type": "CN"
}
],
"invoiceLine": {
"itemAmount": 1260.0
}
},
"goodsMeasure": {
"gmass": 2160.0,
"nmass": 1980.0,
"qty": 180000.0,
"uom": "PCS"
},
"packagings": [
{
"quantity": 90,
"type": "CT"
}
],
"origins": [
{
"country": "CN",
"type": "NonPreferentialOrigin"
}
]
},
{
"seqNum": 3,
"commodity": {
"description": "STEEL WIRE ROPE 6MM",
"classifications": [
{
"code": "73121081",
"type": "CN"
}
],
"invoiceLine": {
"itemAmount": 2232.0
}
},
"goodsMeasure": {
"gmass": 1680.0,
"nmass": 1536.0,
"qty": 2400.0,
"uom": "M"
},
"packagings": [
{
"quantity": 48,
"type": "CT"
}
],
"origins": [
{
"country": "CN",
"type": "NonPreferentialOrigin"
}
]
},
{
"seqNum": 4,
"commodity": {
"description": "PLASTIC ANCHOR PLUGS",
"classifications": [
{
"code": "39269097",
"type": "CN"
}
],
"invoiceLine": {
"itemAmount": 1152.0
}
},
"goodsMeasure": {
"gmass": 1008.0,
"nmass": 924.0,
"qty": 96000.0,
"uom": "PCS"
},
"packagings": [
{
"quantity": 96,
"type": "CT"
}
],
"origins": [
{
"country": "CN",
"type": "NonPreferentialOrigin"
}
]
},
{
"seqNum": 5,
"commodity": {
"description": "TOOL BOX STEEL 450MM",
"classifications": [
{
"code": "82059010",
"type": "CN"
}
],
"invoiceLine": {
"itemAmount": 2656.0
}
},
"goodsMeasure": {
"gmass": 1614.5,
"nmass": 1556.0,
"qty": 640.0,
"uom": "SETS"
},
"packagings": [
{
"quantity": 80,
"type": "CT"
}
],
"origins": [
{
"country": "CN",
"type": "NonPreferentialOrigin"
}
]
}
]
}
},
"metadata": [
{
"key": "sourceDocuments",
"value": "sample_bl.pdf;sample_invoice_cn.pdf;sample_packing_list.pdf"
}
]
}
What it leaves out, and why
- country_of_dispatch (DE 5/14) is not stated in any document; likely CN because the exporter's own address names it. Not written: that is the declarant's call
- Not written, because no invoice, packing list or transport document states them: the customs value and the statistical value (a valuation, not a reading), the declaration type, the procedure codes, the customs office, and the previous document an import follows (the temporary storage reference). CAS takes these from the customs flow the tenant configures, or the declarant adds them.
- direction IN, storageLocationReference YOUR-CAS-LOCATION and externalReference NHH26-0915 were given by the sender, not read
What goes where
The mapping follows the Annex B data elements. Every value is one a document states, written where CAS keeps that element, in the shape CAS asks for. Anything that does not fit stays out, and the notes say so.
| Read from the documents | CAS field | Rule |
|---|---|---|
| Description of goods (DE 6/8) | commodity.description | Up to 512 characters |
| Commodity code (DE 6/14) | commodity.classifications | 8 digits typed CN, 10 digits TARIC; any other length is not written |
| Item price (DE 4/14) | commodity.invoiceLine.itemAmount | |
| Gross and net mass (DE 6/5, 6/1) | goodsMeasure.gmass, nmass | |
| Quantity and unit | goodsMeasure.qty, uom | The invoice's own quantity and unit |
| Packages and their type (DE 6/10, 6/9) | packagings | A whole number and a two-character code, or nothing |
| Country of origin (DE 5/15) | origins | Typed NonPreferentialOrigin: a preferential origin needs a proof of origin |
| Exporter (DE 3/1, 3/2) | goodsShipment.exporter | EORI as a reference of type Eori |
| Importer (DE 3/15, 3/16) | importer | EORI as a reference of type Eori |
| Country of dispatch (DE 5/14) | goodsShipment.exportCountry | Only when a document states it; a likely value is a note, never a field |
| Delivery terms and place (DE 4/1) | goodsShipment.tradeTerms | |
| Invoice currency (DE 4/10) | invoiceCurrency | |
| Invoice number and date | goodsShipment.invoice | Only with exactly one invoice in the shipment |
| Invoice total as printed (DE 4/11) | totalInvoiceAmount | Never a sum of the lines |
| Total packages (DE 6/18) | packaging.quantity | |
| Container and seals (DE 7/2, 7/18) | consignment.transportEquipments | Seals are attached only when there is one container |
| B/L, air waybill or CMR number | consignment.transportContractDocuments | N705, N740, N730 by the document it was read from |
| The source files | metadata | A lookup attribute: the files to open to check a value |
What it never writes
The customs value and the statistical value, because they are a valuation and not a reading. The declaration type, the procedure codes and the customs office, because they are the declarant's choices; CAS takes them from the customs flow a tenant configures. The previous document, because the temporary storage reference an import follows is on no supplier's paperwork.
What the sender gives
Three fields are required by CAS and stated by no document: direction, storageLocationReference and externalReference. The sender supplies them. The reference defaults to the shipment's own number, which here is the invoice number. Two shipments are never written under one reference, because CAS would take the second as an update of the first.
FreightParse is not affiliated with Customs4trade. CAS and Customs4trade are theirs; the schema is the one they publish. The three documents are FreightParse's own samples, not a real shipment.
The reader runs on the declarant's own machine or in the browser, with nothing uploaded: try it on your own documents. Questions: danil@freightparse.com.