Push to Your TMS
Send approved shipment data to your TMS, broker system or import file, so it is keyed once: connections and their triggers, linking and filling a job, reviews and approvals, file mappings, and the GoFreight and NetCHB targets.
Overview
A connection sends a shipment’s approved data to one of your systems, so nobody types it in again. The data is the shipment’s record, built from the same corrected values the table export uses.
There are three ways in, depending on what your system allows:
| Way | What CargoLint does | Systems |
|---|---|---|
| Direct | Calls your system’s own interface with credentials you issue. The shipment is linked to its job, and each approved document’s values go into it. | GoFreight, NetCHB |
| Import file | Renders your system’s import layout as CSV or Excel. You import the file, or it is emailed to the address your import reads. | Any system with a CSV or Excel import, with starters for Boltrics and Customs City |
| Generic | Nothing system-specific: the REST API and signed webhooks let your own integration read the data. | Everyone else |
The push is one way. CargoLint writes to your system and reads back only what a safe write needs: the job it writes to, the job a person names, and lists such as trade partners that a write must name. It never imports jobs or documents from your system. Your system stays the system of record: a value someone changed there is never overwritten without an approval.
Plans. File connections are included on Professional and above. Direct connections are an add-on on Professional and above, bought per connected system in Billing; Enterprise includes one. A connection to a target still in preview takes no slot. The slots go to the active direct connections in the order they were created; one past the last slot stays listed, marked locked, with its history: it pushes nothing and its settings cannot change until a slot is free or added. Creating, changing and deleting connections needs an Owner or Admin, signed in.
This page describes record version 2026.11.03.1.
Create a connection
- Go to Settings > Integrations > Connections and click Add connection.
- Choose the target and fill in the fields it asks for. Credentials are stored encrypted and never shown again, in the app or the API.
- Choose the policies:
- When it pushes on its own, the trigger. See When a push runs.
- Fields your team also edits in the target, for a direct target. CargoLint writes these only under the protection described in Protection, or with an approval.
- Attach the corrected PDF exports, where the target can attach files. Only CargoLint’s generated exports are sent; the documents you uploaded never leave CargoLint.
- Delivery email, for a file connection.
- Click Create and test. Saving runs the target’s test and records the time, the outcome and any error. For a direct target the test is one signed-in read. For a file target it is the check of the mapping.
The connection list shows each connection’s target, trigger, last test and status. Pushes opens its pushes of the last 30 days, with the shipment, the operation, the outcome, the attempts and the last error.
When a push runs
Each connection has one trigger:
| Trigger | What it does | Default for |
|---|---|---|
| On approval | Each time a document of a shipment is approved, CargoLint links the shipment to its job if it has none yet and the target can find it, then fills the job with that document’s values | Direct targets |
| On settle | Settling the shipment sends one file | Import-file targets |
| Manual | Nothing on its own; a person sends from the shipment page, or calls POST /shipments/{id}/pushes |
Either |
A direct target offers On approval or Manual; an import-file target offers On settle or Manual. Sending by hand through a direct connection fills the job with every approved document’s values, linking it first, at any time; through a file connection it sends the file of a settled shipment.
A push waits for the checks that are due before it goes out: for a fill on approval, the approved document’s own checks and the shipment checks it feeds; otherwise the shipment checks. It waits up to 15 minutes, then goes ahead and says it was sent while checks were still running.
A transport error, a server error or a rate limit from the target is tried again, three attempts in all, where trying again cannot write twice. Any other refusal ends the push as failed. A push never changes the shipment or its documents.
A direct target: link, fill, review
Documents usually reach the desk over days, and the job usually exists in your system before they arrive. A direct connection works with that job as documents are approved, rather than once at the end.
Link the job
Before the first write, the shipment is linked to one job in the target:
- Found by the target’s keys. When the shipment has no link yet, each fill first searches the target by its keys, in order, and reads the job back to confirm it is the shipment’s. GoFreight searches by the master bill number, then by the shipment’s reference as a job ref. The push lists what was searched.
- By its reference. On the shipment page, Link job takes the job’s reference as your team reads it in the target. CargoLint reads that job, confirms it belongs to the shipment, and stores the link. A job that does not match, such as one carrying another master bill number, is refused with the reason. An Owner or Admin links and unlinks.
- From an email. A shipment forwarded to email intake with a reference in its subject takes that reference, which the target’s job-reference key then searches.
- Created. When no job exists, a create is offered once the documents a create needs are approved. A create needs an approval, and before anything is created the target is searched once more by its keys: a job that exists by then is linked instead, nothing is created, and its empty fields are filled next.
When nothing matches, the push says what was searched and what to do next: link the job by its reference, or review and create it. A link, however it was made, stays until a person unlinks it.
Fill what the job holds empty
Once linked, each approved document’s values go into the job. CargoLint reads the job first and writes a value only where the job holds the field empty. It then reads the job back to confirm what landed.
Every other value is left alone and listed on the shipment page with the reason:
| Left alone | Why |
|---|---|
| Changed in the target | The job holds a value CargoLint never sent. Your system is the system of record |
| Changed in CargoLint | The job still holds what CargoLint sent earlier, and CargoLint’s value moved since, such as after a revised invoice replaced the first. It waits for a review |
| Guarded | Your team also edits the field in the target, and the connection’s writes are not protected against a change made there meanwhile |
| A finding | A finding that needs fixing involves the document the value comes from. Resolve it first |
| Not on the job | The job has no record for the document, such as a house bill added after the job was linked |
A fill that writes nothing ends as Unchanged, with the values it left alone.
Review and approve
Some operations cannot be undone or touch what the job already holds. They are sent only once an Owner or Admin reviews and approves them:
- Create a record in the target, when the shipment has no job
- Write changed values, the ones listed as changed in CargoLint or in the target, and guarded fields
- Update in full a record in a target that cannot be read back
Review and send on the shipment page reads the job now and lists each value it would write, with what the job holds, and what stops it, if anything. The approval holds for 30 minutes and covers exactly what was reviewed: the shipment’s approved data, the connection’s settings, the job and the values. When any of them changed by the time it is approved, or by the time it is sent, nothing is written and the push asks for a new review. The organization’s API key cannot review or approve.
Settle
Settling no longer gates a direct target: the job is linked and filled as documents are approved. Settling sends the files of the connections that send on settle. Re-opening and settling again sends nothing new on its own: an unchanged record ends as Unchanged, a changed one as Changes pending, and a second file goes only when someone sends it on purpose (see A second file).
What a push’s outcome means
A push moves through these states. Only the last five end it, and each of those sends the webhook event of the same name.
| State | What it means |
|---|---|
| Queued | Waiting for the worker, or for the checks that are due |
| Sending | The write is going out. This is recorded before the target is called |
| Accepted, confirming | The target took the message and reports the outcome later; CargoLint asks it every minute |
| Outcome unknown | The target gave no clear answer. CargoLint reads the job every minute until it knows, and never writes again meanwhile |
| Sent | The record was created, the values were written and read back, the job was linked, or the file was rendered |
| Unchanged | Nothing new to send |
| Changes pending | The record changed since the last send, and the target cannot be updated safely. The changed fields are listed |
| Needs review | Nothing was written, and a person has to look: no job was found, the job or the data changed after an approval, or an outcome could not be confirmed |
| Failed | The target refused the push, every attempt failed, or the connection was disabled, deleted or locked first |
Only one write to a job runs at a time. When an answer is unclear or the worker stops mid-write, the next step is always a read of the job. If the outcome still cannot be confirmed after 30 minutes, the push ends as Needs review and asks you to check the job in the target.
Protection
How a write is protected against a change someone makes in the target between CargoLint’s read and its write:
| Level | Meaning |
|---|---|
| Vendor condition | The target refuses a write whose version condition is stale. Each write carries the version CargoLint read (an ETag in If-Match) |
| Read-compare | CargoLint reads the job immediately before the write and writes only fields that still hold what it read |
| None | The target cannot be read back, so every write after the first needs an approval |
A target that supports a vendor condition starts at read-compare on each connection. The vendor condition applies only once CargoLint has verified, on your test account, that the target refuses a stale write. Until then, a guarded field waits for an approval. The connection’s response says which level applies, protection.
Import files
A second file
A file goes out once. A file layout such as Boltrics’ creates a second record when the same file is imported again. When the record changed since the last file, the push ends as Changes pending with the changed fields listed, and Send again as a new file sends a second one. The earlier file stays where it was delivered.
The record
The record holds the shipment’s approved data:
- Shipment: the reference, the route with where each part came from, and the declared facts.
- Documents: each approved document’s kind, file name, number, date, parties by role, terms, currency, totals, transport fields and line items, with the corrected values.
- Evaluation: the overall status, each document’s Quality score, and each finding’s severity, reason code and message.
A document that was replaced stays out. So does a document still being read, or of a kind CargoLint recognizes but does not read, and the push names it as not included. HS codes are the declared or corrected codes, never a suggestion. An empty field is left out.
The fields a file mapping can use come from GET /config as pushRecordPaths, each with its label, its type and the document kinds that carry it. A path names a field by where it sits:
| Path | Reads |
|---|---|
shipment.reference |
The shipment’s reference |
shipment.route.destination |
The destination country |
documents[].number |
A document’s number |
documents[].parties[].name |
A party’s name, for the role the mapping names |
documents[].totals.InvoiceTotal |
An invoice total |
documents[].transport.BlNumber |
A bill of lading number |
documents[].lines[].HsCode |
A line item’s HS code |
evaluation.overallStatus |
The evaluation’s overall status |
File mappings
A file connection renders the record as CSV or Excel through its mapping. The mapping says whether a row is one line item or one document, which kind of document the rows come from, and each output column in order:
{
"rowPer": "line",
"documentKind": "Invoice",
"columns": [
{ "header": "Shipment No", "required": true, "source": { "path": "shipment.reference" } },
{ "header": "Consignee", "required": true, "source": { "path": "documents[].parties[].name", "role": "consignee" } },
{ "header": "B/L No", "required": false, "source": { "path": "documents[].transport.BlNumber" } },
{ "header": "Invoice Date", "required": false, "source": { "transform": "date", "path": "documents[].date", "format": "dd-MM-yyyy" } },
{ "header": "Quantity", "required": true, "source": { "transform": "decimal", "path": "documents[].lines[].Quantity", "separator": ",", "places": 2 } },
{ "header": "Warehouse", "required": true, "source": { "const": "AMS-01" } },
{ "header": "Mode", "required": false, "source": { "transform": "map", "path": "shipment.route.destination", "map": { "CA": "SEA", "US": "ROAD" }, "otherwise": "SEA" } },
{ "header": "Origin", "required": false, "source": { "transform": "concat", "separator": " / ", "parts": [ { "path": "documents[].transport.PortOfLoading" }, { "const": "CN" } ] } }
]
}
With this mapping, each invoice line item is one row.
Sources
- A path: a field of the record. A party path names its
role, one ofshipper,seller,exporter,consignee,buyer,notify,carrieroragent. A document path may name akind, such asBillOfLading, to read the first document of that kind. - A constant: the same text on every row.
date: a date in the given format. A date the document prints another way is read first.decimal: a number with the given decimal separator,.or,, and 0 to 6 decimal places.map: a value replaced by its code. When no entry matches,otherwiseis written, or the value itself whenotherwiseis empty.concat: paths and constants joined by the separator, skipping empty ones.
A document path without a kind reads the row’s own document. When that kind of document does not carry the field, or names no party in that role, the first document of the shipment that does is read. In the example, the bill of lading number comes from the bill of lading, though each row is an invoice line. A value no document carries leaves its cell empty. A value a transform cannot read, such as a date in a form CargoLint does not know, is written as it is.
Checks on save. A mapping saves only when every path is one of the record’s, every column marked required is bound, and every transform is complete. Otherwise the save is refused with every problem, named by its column, such as Qty: a required column is not bound.
From a sample file. From sample file in the mapping editor reads the header row of a CSV or Excel file your system imports, and makes one column per header, in order, each unbound until you bind it. The file is not kept. Through the API: POST /connections/mapping-from-sample with the file as multipart/form-data.
Starters. The editor offers two ready-made mappings. Each names the vendor document it was built from and the date that document was read. Both are Preview: they were built from the vendor’s public pages, and no customer has yet imported one unchanged. Check the first file against your own import before relying on it.
- Boltrics: Import Shipment (FMS), an Excel file with one row per invoice line item. Boltrics reads it through an Excel Import File Format you set up with the Import Shipment (FMS) application, mapping each column to a shipment or goods line field. Mark External Document No. as the Split Document field, so each shipment’s rows make one Boltrics shipment. Boltrics does not match existing shipments on import, so a second file creates a second shipment. Source: Boltrics Excel Import File Format.
- Customs City: Section 321 CSV, with the Section 321 shipment data elements Customs City lists publicly, in its order. Customs City’s own template downloads from inside its application, so compare its headers with these before the first upload. Bind SCN to the shipment control number your filer assigns. Source: Customs City Section 321 upload.
Delivery
A file push keeps the file for 30 days. It downloads from the shipment page or from GET /shipments/{id}/pushes/{pushId}/file.
A file connection can also email each file to a delivery address. The email address of a member of your organization is confirmed at once. Any other address gets a six-digit code by email, valid for 15 minutes, which is entered in the connection form. An unconfirmed address receives nothing. A file over 10 MB is not emailed and stays available for download.
Targets
| Target | Way | Status | What it does |
|---|---|---|---|
| File (CSV or Excel) | Import file | Available | Renders the record through the mapping; the starters are Preview |
| GoFreight | Direct | Preview | Links an ocean import job and fills it, or creates one with its house bills and containers |
| NetCHB | Direct | Preview | Stages a US customs entry without transmitting it, and amends it when approved |
Preview means the target was built from the vendor’s published documentation and has not yet been verified on a live account. A target becomes Available only after a person has run the live checklist on a customer’s account, and that run is recorded. A starter becomes Available after one customer has imported its file unchanged. Try a Preview target with a test shipment first.
What “Sent” means depends on how the target answers. GoFreight and NetCHB answer each call with its outcome, so Sent means the call succeeded, and for GoFreight that the job was read back. A target that only confirms receipt shows Accepted, confirming until it reports the outcome. Which kind a target is comes from GET /config as ackModel.
GoFreight
- Credentials: a gateway token, which GoFreight staff issue on request, and the API base URL,
https://api.core.gofreight.co. - Options: the office ref the master bills are filed under. Optional: ship mode (
FCL,LCL,FAKorBLK;FCLwhen empty), weight unit (KGwhen empty) and measurement unit (CBMwhen empty). - Finding the job: by the master bill number, then by the shipment’s reference read as a GoFreight job ref, when someone typed that reference (a reference CargoLint generated is not searched). More than one master bill with the number is refused, so you can link the right one by its ref. A job found or named is confirmed by reading it back: it must be an ocean import of the connection’s office, and carry no master bill number other than the shipment’s. Each house bill on the job is matched to the shipment’s house bill of the same number.
- Filling: the master bill’s number, vessel, voyage, ports, estimated arrival date and freight terms; the shipper, consignee and notify party of the master and of each house bill on the job; each house bill’s number and Incoterm.
- Guarded by default: the House Incoterm, which teams often set in GoFreight. It is filled only once the vendor condition is verified on the connection, and otherwise waits for an approval. The connection can guard other fields, or none.
- Version condition: GoFreight returns an ETag with each bill. Once verified on the connection, each write sends it as
If-Match, and GoFreight’s refusal of a stale one ends the push with that reason. - Creating: when no job exists, a create needs an approved bill of lading with an estimated arrival date, and the office ref on the connection. It makes one master bill with its house bills and containers in one call.
- Parties are matched to your GoFreight trade partners by name and country, and never created. When one does not match, nothing is written and the push names it.
- Ports are sent as UN/LOCODEs.
- Attachments: the corrected PDF exports, when the connection attaches them: of every document on a create, and of the documents whose values a fill wrote.
- Line items are not sent: GoFreight’s create call takes no commodity lines.
- A house bill added to the shipment after the job was linked is not created on the job. Its values are listed as not on the job; add the house bill in GoFreight, and the next fill matches it by its number.
NetCHB
- Credentials: the NetCHB username and password the entries are uploaded as.
- Options: the importer of record’s tax id, the processing port and the entry port as 4-digit CBP codes. Optional: entry type (
01when empty), bond type (00,08or09) and mode of transport (11or40by the documents, when empty). - Creating the entry is offered once the connection’s importer and ports are set and an approved invoice line carries an HS code, a country of origin and a value. An Owner or Admin approves it. It can be staged before the shipment is settled.
- The entry carries one invoice per invoice document with its line items: HS code, country of origin, value and quantities. It is checked against NetCHB’s published schema before it is sent. CargoLint never asks NetCHB to transmit it to CBP. Sent means NetCHB staged the entry and returned its entry number.
- A line without an HS code, a country of origin or a value is left out, and the push names it.
- Later changes end as Changes pending, because NetCHB cannot be read back. Review and send shows the changed fields; once approved, the entry is amended in full under its entry number, and values changed in NetCHB since are overwritten.
- An unclear answer to the upload ends as Needs review, because NetCHB cannot be searched: check NetCHB for the entry before creating it again.
Connection endpoints
These need an Owner or Admin, signed in; an API key receives 403. Writes return 403 with "code": "PLAN_FEATURE_UNAVAILABLE" for a connection the plan does not include, while reads keep working and mark each such connection locked.
GET /connections - the organization's connections
POST /connections - { "name", "targetId", "credentials", "options", "mappingJson", "trigger", "guardedFields", "attachArtifacts", "deliveryEmail" }
GET /connections/{id}
PUT /connections/{id} - the same fields, each optional; credentials replace the whole set
DELETE /connections/{id}
POST /connections/{id}/test
POST /connections/{id}/enable | disable
POST /connections/{id}/confirm-delivery-email - { "code": "123456" }
GET /connections/{id}/pushes - the last 30 days
POST /connections/mapping-from-sample - multipart/form-data with the file
triggerisapprovalormanualfor a direct target andsettleormanualfor a file target, the first when absent.guardedFieldslists record paths in their generic form, such asdocuments[].incotermordocuments[].parties[].name; absent keeps the target’s default, an empty list guards none. A file connection guards none.
A connection’s response says whether credentials are set, hasCredentials, and never carries them. It also carries trigger, guardedFields, protection and protectedWritesVerifiedAt. A refused save answers 400 with error and, for a mapping, problems, the list by column. The targets come from GET /config as pushTargets, with their fields, capabilities, ackModel, protection, lookupKeys, defaultGuardedFields and triggers. The starters come as pushStarterMappings, each with its availability, and the push states as pushStatuses.
The shipment’s pushes, the review, the approval and the links are on the shipment endpoints:
GET /shipments/{id}/pushes - the shipment's pushes and links
POST /shipments/{id}/pushes - send through one connection
POST /shipments/{id}/pushes/review - what a create, a write of changed values or a full update would do
POST /shipments/{id}/pushes/approvals - approve a review
POST /shipments/{id}/links - link a job by its reference
DELETE /shipments/{id}/links/{connectionId} - remove the link
GET /shipments/{id}/pushes/{pushId}/file - a file connection's file
What’s next
- Shipment Endpoints - send, review, approve and link
- Webhooks API - be told how each push ended
- Email Intake - a reference in the subject links the shipment to its job
- Export Formats - the table export the record shares its values with