How to Extract Data from a Bill of Lading: Fields, Cargo Lines and the Checks That Catch Bad Reads
To extract data from a bill of lading, decide which fields you need, read each bill into those fields and its cargo table into one row per line, check the result against the totals on the bill, and only then send it to your TMS or a spreadsheet. The reading is the easy part to describe and the hard part to get right: every carrier draws its own bill, and the cargo table rarely fits on one page.
In brief
- To extract data from a bill of lading, first fix the list of fields you need, then read each B/L into those fields, validate them, and send them to your TMS or a spreadsheet.
- A bill of lading has two parts to extract: header fields such as B/L number, parties, ports, vessel and dates, and a table of cargo lines with marks, packages, description, weight and volume.
- The cargo lines are the hard part: descriptions wrap across lines, a table can continue on a rider page, and weights may be stated in kilograms or pounds.
- Deterministic checks catch most bad reads: line weights and packages that add up to the totals, container numbers that pass the ISO 6346 check digit, and dates in a plausible order.
What a bill of lading actually contains
A bill of lading (B/L, or BOL in trucking) is three things at once: the carrier's receipt for the goods, the evidence of the contract of carriage and, for a negotiable ocean bill, the document of title. Whatever the mode, the data you want from it falls into two parts. The header describes the movement, and the cargo table describes what moved.
The header of an ocean bill holds the B/L number, the shipper, the consignee and the notify party, the carrier, the vessel and voyage, the place of receipt, the ports of loading and discharge, the place of delivery, the freight terms (prepaid or collect), the number of originals issued, the place and date of issue and the shipped on board date. A house bill from a forwarder carries the same fields plus a reference to the master bill the carrier issued.
The cargo table holds, for each container or group of packages, the container and seal numbers, the marks and numbers, the package count and type, the description of goods, the gross weight and the volume. A domestic truck bill of lading is shorter on ports and vessels, but adds the PRO number, the carrier SCAC, handling units, the freight class and NMFC item, and a flag for hazardous materials.
2
parts to extract from every bill: the header and the cargo table
4
checks run on the example extraction below, none of them needing judgment
11
characters in an ISO 6346 container number, the last one a check digit
Why bill of lading data entry goes wrong
Most shipping desks still retype bills into the TMS or a spreadsheet. It works at low volume and breaks quietly as volume grows, because the errors are small and look plausible.
Every carrier has its own layout
Carriers, NVOCCs and forwarders each print their own form. The B/L number sits top right on one and in a box at the bottom on the next. Parties are free-text address blocks, so the consignee's name, street and tax reference run together, and "to order of" bills put a bank or the word "order" where a company name would be.
The cargo table spills over
A consolidated shipment can list dozens of lines. When they do not fit, the bill says "see attached list" or "as per rider" and continues on extra pages, often with different column widths. Descriptions wrap across two or three lines, and the "said to contain" wording and the marks share the same column. The lines that sit on page three are the ones most often missed.
Units and numbers drift
Weights appear in kilograms on one bill and pounds on the next, sometimes both on the same bill. Volume is in cubic meters or cubic feet. A container number is eleven characters, and one transposed digit sends a tracking request for a box that is not yours.
Cargo lines on rider pages
Container / seal numbers
Weight units (kg vs lb)
Party address blocks
Dates (issue vs on board)
Freight terms
Step 1: decide the fields before you read a single bill
Start from what the downstream system needs, not from what the bill happens to print. If the TMS books a shipment from the B/L number, parties, ports, vessel and container list, those are your fields. If finance also matches carrier invoices to the bill, add the freight terms and any charges the bill shows. Write each field down with a name, a type and a unit: gross_weight_kg is a number in kilograms, not a string that may say "21,160 LBS".
Model the cargo table as a list of lines, not as one long text field. Each line gets its own container, seal, marks, packages, package type, description, gross weight and volume. That one decision is what later lets you add the lines up, compare them with a packing list, or load them into a spreadsheet one row per line. The guide to designing extraction schemas covers how to type fields, model tables and version the schema when a new field is needed.
Keep header names consistent with the other documents in the same shipment. If the packing list extraction calls it gross_weight_kg, the bill of lading should too: a cross-check between documents is then a comparison of two fields with one name.
Step 2: read each bill into those fields
There are three ways to fill the fields. Manual entry needs no setup and does not scale. Fixed zone templates, which read a field from the same spot on the page each time, work for one carrier's form and must be built again for every other one and every time a carrier redesigns its bill. Model based extraction reads the bill the way a person does, by meaning rather than position, and fills the schema whatever the layout.
Whichever you use, read the whole document, rider pages included, and keep the original next to the result so a reviewer can see where each value came from. When bills arrive bundled with an invoice, a packing list and a certificate of origin in one PDF, split and classify the batch first, so the bill of lading template only ever sees bills of lading.
curl -X POST https://api.parserai.co/documents/upload \ -H "Authorization: Bearer $PARSER_API_KEY" \ -F "file=@MBL-5521093.pdf" \ -F "entity_group_id=$BL_TEMPLATE_ID"# 202 Accepted# {"documentId": "...", "extractedDocumentId": "..."}Step 3: normalize what came back
Raw values need a small amount of cleaning before they can be compared or loaded. Convert weights to one unit and volumes to another, keeping the original value when the bill stated both. Write dates in ISO format and keep the shipped on board date separate from the date of issue, because they answer different questions: the first is the shipment date that letters of credit and sales contracts refer to, the second only dates the paper. Strip spaces and dashes from container numbers. Map port names to the codes your TMS uses.
{ "bl_number": "MBL-5521093", "bl_type": "master", "shipper": { "name": "Example Ceramics Co.", "address": "12 Harbor Rd, Valencia, ES" }, "consignee": { "name": "Orion Ltd.", "address": "400 Commerce Ave, Savannah, GA, US" }, "notify_party": { "name": "Same as consignee" }, "carrier": "Sample Ocean Lines", "vessel_voyage": "MV Example Star 031W", "port_of_loading": "Valencia, ES", "port_of_discharge": "Savannah, US", "shipped_on_board_date": "2026-10-02", "date_of_issue": "2026-10-03", "freight_terms": "Prepaid", "cargo_lines": [ { "container": "CSQU3054383", "seal": "SL-449120", "marks": "ORION 1-40", "packages": 40, "package_type": "pallet", "description": "Glazed ceramic floor tiles, 60 x 60 cm", "gross_weight_kg": 9600, "volume_cbm": 18.4 }, { "container": "CSQU3054383", "seal": "SL-449120", "marks": "ORION 41-52", "packages": 12, "package_type": "pallet", "description": "Tile adhesive, 25 kg bags", "gross_weight_kg": 8400, "volume_cbm": 14.2 } ], "total_packages": 52, "total_gross_weight_kg": 18000, "checks": [ { "rule": "line_weights_equal_total", "sum": 18000, "total": 18000, "status": "pass" }, { "rule": "line_packages_equal_total", "sum": 52, "total": 52, "status": "pass" }, { "rule": "container_check_digit", "value": "CSQU3054383", "status": "pass" }, { "rule": "on_board_not_after_issue", "status": "pass" } ]}The cargo table came back as two lines in the same container, each with its own marks, packages and weight, and the checks at the end record that the lines add up to the totals printed on the bill.
Step 4: validate before anything is loaded
A bad read that reaches the TMS costs far more than one caught at extraction. Most errors on a bill of lading can be caught by rules that need no judgment, because the bill contains its own totals.
- Lines add up. The sum of cargo line weights equals the total gross weight, and the sum of packages equals the total package count. A missing rider page fails this rule at once.
- Container numbers are valid. Recompute the ISO 6346 check digit from the owner code, category letter and serial number. A single misread character almost always fails it.
- Dates are in order. The shipped on board date is not after the date of issue, and neither is in the future.
- Required fields are present. No bill leaves without a B/L number, a consignee and at least one cargo line.
Bills that pass go straight through. Bills that fail go to a person with the rule, the values it compared and the page they came from. Before you let the rules decide on their own, label a small set of real bills and measure accuracy field by field, with extra weight on the cargo lines.
The bill checks itself
Step 5: send the data where it is used
Once validated, the data goes to the TMS through its API, into a spreadsheet with one row per cargo line and the header repeated, or as a CSV for a system that imports files. The same fields serve more than booking. The container list feeds tracking and demurrage monitoring. The parties, packages and weights are the bill's side of the cross-check against the commercial invoice and packing list, and the bill is one of the references in a freight invoice audit. Extracting it once, completely, saves reading it again for each of those.
Checklist: extracting bill of lading data
- List the fields the TMS or spreadsheet needs, each with a name, a type and a unit.
- Model the cargo table as a list of lines, not a single text field.
- Use the same field names as the packing list and commercial invoice extractions.
- Read every page, including riders and attached cargo lists.
- Convert weights and volumes to one unit, and write dates in ISO format.
- Check that line weights and packages add up to the totals on the bill.
- Validate container numbers with the ISO 6346 check digit.
- Send failures to a person with the rule, the values and the page.
Where Parser fits
Parser reads bills of lading against an extraction template you define: the header fields and a table of cargo lines, named and typed the way your TMS expects. Bills come in by upload, e-mail or the API, and the result goes out as JSON, Excel or CSV, or to your system by webhook. The bill of lading page lists the fields a typical template returns, and the logistics and freight page shows the other documents the same desk handles.