Freight Invoice Processing and ERP Synchronization
Overview
This scenario demonstrates the best practices on how to get freight invoice data from the Shipwell platform into your ERP (Enterprise Resource Planning) system or another system [i.e. FMS (Financial Management System), accounting systems, etc.] and keep both systems synchronized when processing freight invoices. The diagram below (click to view a larger version) is an overview of the process that ensures that the systems are always up-to-date with shared invoice amounts and statuses.
Steps
1. Authenticate and Receive API Token
Authenticate to the API using these steps.
Note
Authorization HTTP headers in API requests, e.g. Authorization: YOUR_AUTHORIZATION_HEADER
, typically take the form of Authorization: Token <user-token>
. For more information on API authentication, navigate to the Authenticate documentation.
2. Subscribe to Freight Invoice-Related Events in a Webhook
Receive notifications when freight invoices are generated (typically received
from the carrier or service provider or sent
if you are a carrier or provider) or when a freight invoice changes status by subscribing to webhook events.
Subscribe to the particular webhook events outlined in the code samples below. For more information on webhook payloads, click here.
Tip
If you are not familiar with events and webhooks in the Shipwell platform, learn more here.
Example webhook subscription request
curl -i -X POST \
'https://sandbox-api.shipwell.com/webhooks' \
-H 'Authorization: YOUR_AUTHORIZATION_HEADER' \
-H 'Content-Type: application/json' \
-d '{
"status": "ENABLED",
"url": "https://example.com/your-endpoint-url",
"enabled_events": [
"freight_invoice.received",
"freight_invoice.received.status_updated",
"freight_invoice.sent",
"freight_invoice.sent.status_updated"
],
"event_version": 1,
"error_contact_email": "jane.doe@example.com"
}'
const payload = {
"status": "ENABLED",
"url": "https://example.com/your-endpoint-url",
"enabled_events": [
"freight_invoice.received",
"freight_invoice.received.status_updated",
"freight_invoice.sent",
"freight_invoice.sent.status_updated"
],
"event_version": 1,
"error_contact_email": "jane.doe@example.com"
};
const basePath = "";
const host = "sandbox-api.shipwell.com";
const targetUrl = `https://${host}${basePath}/webhooks`;
const resp = await fetch(
targetUrl,
{
method: "POST",
headers: {
"Authorization": "YOUR_AUTHORIZATION_HEADER",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
}
);
const data = await resp.json();
console.log(data);
import requests
base_path = ""
host = "sandbox-api.shipwell.com"
target_url = (
"https://"
+ host
+ base_path
+ "/webhooks/"
)
headers = {
"Authorization": "YOUR_AUTHORIZATION_HEADER",
"Content-Type": "application/json",
}
payload = {
"status": "ENABLED",
"url": "https://example.com/your-endpoint-url",
"enabled_events": [
"freight_invoice.received",
"freight_invoice.received.status_updated",
"freight_invoice.sent",
"freight_invoice.sent.status_updated"
],
"event_version": 1,
"error_contact_email": "jane.doe@example.com"
}
response = requests.post(target_url, headers=headers, json=payload)
data = response.json()
print(data)
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
OkHttpClient client = new OkHttpClient();
String basePath = "";
String host = "sandbox-api.shipwell.com";
String targetUrl = "https://" +
host +
base_path +
"/webhooks/";
String requestBody = "{\"status\": \"ENABLED\", \"url\": \"https:\/\/example.com\/your-endpoint-url\", \"enabled_events\": [ \"freight_invoice.received\", \"freight_invoice.received.status_updated\", \"freight_invoice.sent\", \"freight_invoice.sent.status_updated\ "], \"event_version\": 1, \"error_contact_email\": \"jane.doe@example.com\"}";
Request request = new Request.Builder()
.url(targetUrl)
.post(requestBody)
.header("Authorization", "YOUR_AUTHORIZATION_HEADER")
.header("Content-Type", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
response.body().string();
}
Example webhook subscription response
{
"id": "01J7EDHQTV6C4F2RGAQ4MF2515",
"status": "ENABLED",
"created_at": "2025-11-26T19:39:49.951432Z",
"url": "https://example.com/your-endpoint-url",
"secret": "...",
"enabled_events": [
"freight_invoice.received",
"freight_invoice.received.status_updated",
"freight_invoice.sent",
"freight_invoice.sent.status_updated"
],
"include_updated_object": false,
"event_version": 1,
"error_contact_email": "jane.doe@example.com",
"custom_data": null,
"resource_type": "webhook",
"self_link": "https://sandbox-api.shipwell.com/webhooks/01J7EDHQTV6C4F2RGAQ4MF2515"
}
3. Process Freight Invoice Status Changes Delivered via Webhook
Tip
View information about the freight invoice statuses and when they occur here.
Handle freight_invoice.received Webhook Payload
When a freight invoice is initially received by Shipwell from the carrier or service provider, the freight_invoice.received
webhook payload will be delivered via an HTTP POST
(over HTTPS
) to your webhook endpoint(s) that subscribe to the event. This occurs before the Shipwell AI and ML-based invoice First Pass Match is performed.
{
"id": "01J6WNKNW0RA12Q39S1TS2HW15",
"occurred_at": "2025-09-08T19:25:58.522688+00:00",
"source": {
"user_id": "6dd592ce-b09e-467b-b42b-bc11bedcf4c2",
"company_id": "905f4da3-70bc-4884-8f77-1ea9bdd183ac",
"request_id": "00-66d762c4000000000987496b933edb70-dcb436687a53f4ed-01",
"publishing_system": "settlements",
"environment": "sandbox"
},
"event_name": "freight_invoice.received",
"webhook_id": "01J6WN655FNEB7PAXT58SKJA24",
"custom_data": null,
"details": {
"id": "01J6WNKN1BZTXEERAT7HATJ1K1",
"notes": null,
"due_date": "2025-10-09",
"documents": [
{
"self_link": "https://example.com/documents/01J6WNKN1BZTXEERAT7HATJ1K1/custom-file-name_0KwmtZ_qhLKjm.pdf?abc=...",
"resource_type": "BOL"
}
],
"self_link": "/freight-invoices/01J6WNKN1BZTXEERAT7HATJ1K1",
"invoiceable": {
"id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
"type": "V2_SHIPMENT",
"references": [
{
"value": "SW2290892",
"qualifier": "BOL_NUMBER"
}
],
"total_amount": null,
"reference_number": "HUEW7C"
},
"total_amount": {
"value": "3050.00",
"currency": "USD"
},
"resource_type": "freight_invoice",
"invoice_number": "123456",
"invoice_source": "SHIPWELL_WEB",
"service_provider_name": "Carrier Name"
}
}
The invoiceable
object in the webhook payload contains details about the shipment associated with the invoice. The property id
in the invoiceable
object is the shipment id
.
"invoiceable": {
"id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
"type": "V2_SHIPMENT",
"references": [
{
"value": "SW2290892",
"qualifier": "BOL_NUMBER"
}
],
"total_amount": null,
"reference_number": "HUEW7C"
}
The details about the shipment may be retrieved by calling the GET /v2/shipments/{shipmentId}/
API endpoint (see API reference). Store or update as much or as little of the details about the invoice, invoice documents, or shipment as you need before the freight invoice changes status (you may also wait to store the details until a freight invoice status change occurs).
4. Update the ERP/FMS with Freight Invoice Details from Shipwell
When a freight invoice status changes, the freight_invoice.received.status_updated
event is triggered and the freight_invoice.received.status_updated
webhook payload for that status change event will be delivered via an HTTP POST
(over HTTPS
) to your webhook endpoint(s) that subscribe to the event. Depending on your needs, inspect the webhook payloads to see if the freight invoice is in any of these states: PASSED
, APPROVED
, or SCHEDULED
.
Important
- Freight invoices may change status several times in the lifecycle of an invoice and not every status needs to be stored in your ERP or external systems.
-
Inspect
freight_invoice.received.status_updated
webhook payloads for the freight invoice status ofPASSED
,APPROVED
, orSCHEDULED
in thenew_status
property of thedetails
object. -
If needed, the details about the shipment may be retrieved by calling the
GET /v2/shipments/{shipmentId}/
API endpoint (see API reference ) where theinvoiceable.id
property represents theshipmentId/shipment_id
.
Example freight_invoice.received.status_updated webhook payload
{
"id": "01J6WNRJ3S4W17ZDB2241QQJAN",
"occurred_at": "2025-09-08T19:28:38.516558+00:00",
"source": {
"user_id": null,
"company_id": null,
"request_id": "00-66d76363000000002bfdfeca35e3e591-9aa4b9e05b848a38-01",
"publishing_system": "settlements",
"environment": "sandbox"
},
"event_name": "freight_invoice.received.status_updated",
"webhook_id": "01J6WN655FNEB7PAXT58SKJA24",
"custom_data": null,
"details": {
"id": "01J6WNKN1BZTXEERAT7HATJ1K1",
"self_link": "/freight-invoices/01J6WNKN1BZTXEERAT7HATJ1K1",
"new_status": "PASSED",
"old_status": "DISPUTED",
"invoiceable": {
"id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
"type": "V2_SHIPMENT",
"reference_number": "HUEW7C"
},
"resource_type": "freight_invoice"
}
}
5. Update the Freight Invoice Status in Shipwell on Invoice Payment from your ERP/FMS
When a freight invoice is SCHEDULED
or PAID
in your ERP or financial management system (FMS), update the freight invoice status for that particular freight invoice in Shipwell using these steps to stop accruing freight charges (aka finalize the freight invoice). This ensures that the freight invoice statuses in your financial or ERP system and Shipwell are synchronized.
Note
Depending on your workflow(s) in your ERP or financial management systems, write back the freight invoice payment status to Shipwell using one of the following approaches:
-
Mirrored
-
The freight invoice status is mirrored as
SCHEDULED
and/orPAID
in your ERP and Shipwell. Shipwell receives either both of these status changes from your systems or only receives thePAID
status change.
-
The freight invoice status is mirrored as
-
Mapped (
SCHEDULED
Status Mapped ToPAID
)-
When a freight invoice payment is scheduled in the ERP or financial management system, then Shipwell freight invoice status is updated as
PAID
asPAID (SHIPWELL) = SCHEDULED (ERP)
instead of mapping toSCHEDULED (SHIPWELL) = SCHEDULED (ERP)
andPAID (SHIPWELL) = PAID (ERP)
.
-
When a freight invoice payment is scheduled in the ERP or financial management system, then Shipwell freight invoice status is updated as