Freight Invoice Accrual

Overview

This scenario demonstrates the best practices on how to perform freight invoice accrual in Shipwell. The diagram below (click to view a larger version) is an overview of the process.

Freight Invoice Accrual - Recommended Approach

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 Accrual-Related Events in a Webhook

Receive notifications when freight invoices accrue charges (i.e. carriers or service providers generate invoices), shipment charge line items are modified, 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
curljavascriptpythonjava
Copy
Copied
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": [
            "shipment.status.updated",
            "shipment.charge_line_item.created",
            "shipment.charge_line_item.deleted",
            "shipment.charge_line_item.updated"
        ],
        "event_version": 1,
        "error_contact_email": "jane.doe@example.com"
}'
Copy
Copied
const payload = {
  "status": "ENABLED",
  "url": "https://example.com/your-endpoint-url",
  "enabled_events": [
      "shipment.status.updated", 
      "shipment.charge_line_item.created",
      "shipment.charge_line_item.deleted",
      "shipment.charge_line_item.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);
Copy
Copied
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": [
      "shipment.status.updated",
      "shipment.charge_line_item.created",
      "shipment.charge_line_item.deleted",
      "shipment.charge_line_item.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)
Copy
Copied
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\": [ \"shipment.status.updated\", \"shipment.charge_line_item.created\", \"shipment.charge_line_item.deleted\", \"shipment.charge_line_item.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
Copy
Copied
{
    "id": "01J7EDHQTV6C4F2RGAQ4MF2515",
    "status": "ENABLED",
    "created_at": "2025-11-26T19:39:49.951432Z",
    "url": "https://example.com/your-endpoint-url",
    "secret": "...",
    "enabled_events": [
        "shipment.status.updated",
        "shipment.charge_line_item.created",
        "shipment.charge_line_item.deleted",
        "shipment.charge_line_item.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 Initial Freight Invoice Accrual and Starting Amounts

There are three common starting points for the shipment freight accrual process (i.e. freight charges accrued before invoice payment). When the shipment or stop status is:

  • Booked by Carrier
  • Picked Up by Carrier
  • Delivered by Carrier

Settlements Freight Invoice Accrual Most Common Starting Points

Tip

The list of possible shipment statuses may be obtained from the Shipwell Reference Data.

Example shipment status update webhook payload
Copy
Copied
{
    "id": "01J6WNRHBZ9N5FPDY25KYT3WT6",
    "occurred_at": "2025-09-08T19:28:35.600304Z",
    "event_name": "shipment.status.updated",
    "details": {
        "1": {
            "id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
            "new_data": {
                "status": "delivered"
            },
            "old_data": {
                "status": "tendered"
            },
            "self_link": "/v2/shipments/6586aebf-e7b6-410e-ba6f-75d3de072ee7/",
            "resource_type": "shipment"
        }
    },
    "source": {
        "publishing_system": "backend",
        "company_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
        "user_id": "90c64b3b-a24a-4a12-8784-a607dfde8705",
        "request_id": "00-66d76363000000002bfdfeca35e3e591-699a3794f49b014a-01"
    },
    "pending_webhooks": 0,
    "resource_type": "event",
    "self_link": "https://sandbox-api.shipwell.com/events01J6WNRHBZ9N5FPDY25KYT3WT6"
}

Depending on your freight accrual starting point, when the correct shipment/stop status is triggered then you (as the shipper/customer) would obtain/pull/get the shipment information from one of the get shipment routes:

  • GET /v2/shipments list/query API endpoint (see API reference ) and querying for the shipment by reference_id , purchase_order_number , or other criteria
  • GET /v2/shipments/{shipmentId}/ API endpoint (see API reference ) with the shipmentId/shipment_id of the particular shipment

Then retrieve the charge line items and sum the total of the charge line items for the initial accrual amount from shipment's relationship_to_vendor.customer_charge_line_items array/list property (see API reference).

Example customer_charge_line_items section of shipment object
Copy
Copied
// ...
"relationship_to_vendor": {
    // ...    
    "customer_charge_line_items": [{
            "id": "1ad144b7-272d-4480-ac91-afe43ec4ae8c",
            "unit_name": "Freight",
            "unit_quantity": 1.0,
            "unit_amount": 2850.0,
            "charge_code": "400",
            "category": "LH",
            "amount": 2850.0,
            "unit_amount_currency": "USD",
            "prepaid_amount": 0.0,
            "effective_amount": 2850.0,
            "custom_data": null,
            "created_at": "2025-09-08T19:27:13.708818Z",
            "updated_at": "2025-09-08T19:27:13.741060Z"
        },
        {
            "id": "22410338-4db5-4fb5-8849-a5c5eff96b74",
            "unit_name": "Demurrage",
            "unit_quantity": 2.0,
            "unit_amount": 100.0,
            "charge_code": "DEM",
            "category": "ACC",
            "amount": 200.0,
            "unit_amount_currency": "USD",
            "prepaid_amount": 0.0,
            "effective_amount": 200.0,
            "custom_data": null,
            "created_at": "2025-09-08T19:27:13.750871Z",
            "updated_at": "2025-09-08T19:27:13.781489Z"
        }
    ],
    // ...
}
// ...

The total initial accrual amount for this shipment is $3050 USD = $2850 USD + $200 USD.

4. Handle Updates to Freight Invoice Charges

As shipment charges / charge line items are updated the following events and associated webhook payloads will be triggered:

  • shipment.charge_line_item.created
  • shipment.charge_line_item.updated
  • shipment.charge_line_item.deleted

Click the details below to expand or collapse examples of shipment charge line item webhook payloads.

Example shipment charge line item webhook payloads

shipment.charge_line_item.created

Copy
Copied
{
  "id": "01J6WNDAZYFP3J6RWVMQXM86HH",
  "occurred_at": "2025-09-08T19:22:29.161524+00:00",
  "source": {
    "user_id": "90c64b3b-a24a-4a12-8784-a607dfde8705",
    "company_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "request_id": "00-66d761f5000000003118c7c143ae41e4-bd09e0a6d2c0bba8-01",
    "publishing_system": "backend",
    "environment": "sandbox"
  },
  "event_name": "shipment.charge_line_item.created",
  "webhook_id": "01J6WN655FNEB7PAXT58SKJA24",
  "custom_data": null,
  "details": {
    "id": "6792f7e0-8e11-44b1-965c-96e81d5c5b3c",
    "category": "LH",
    "shipment": {
      "id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
      "self_link": "/v2/shipments/6586aebf-e7b6-410e-ba6f-75d3de072ee7/",
      "resource_type": "shipment"
    },
    "unit_name": "Freight",
    "charge_code": "400",
    "unit_amount": 2750,
    "resource_type": "shipment_charge_line_item",
    "unit_quantity": 1,
    "booking_party_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "service_provider_id": "9e675145-4e5f-4cc0-8cbc-11bd70ccc1ab"
  }
}

shipment.charge_line_item.updated

Copy
Copied
{
  "id": "01J6WNF7QG2ZW6ZG99CNGW61F7",
  "occurred_at": "2025-09-08T19:23:31.628572+00:00",
  "source": {
    "user_id": "90c64b3b-a24a-4a12-8784-a607dfde8705",
    "company_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "request_id": "00-66d76233000000006f3067dc0a0ae9ca-4d24758adee65067-01",
    "publishing_system": "backend",
    "environment": "sandbox"
  },
  "event_name": "shipment.charge_line_item.updated",
  "webhook_id": "01J6WN655FNEB7PAXT58SKJA24",
  "custom_data": null,
  "details": {
    "id": "6792f7e0-8e11-44b1-965c-96e81d5c5b3c",
    "new_data": {
      "category": "LH",
      "unit_name": "Freight",
      "charge_code": "400",
      "unit_amount": 2850,
      "unit_quantity": 1
    },
    "old_data": {
      "category": "LH",
      "unit_name": "Freight",
      "charge_code": "400",
      "unit_amount": 2750,
      "unit_quantity": 1
    },
    "shipment": {
      "id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
      "self_link": "/v2/shipments/6586aebf-e7b6-410e-ba6f-75d3de072ee7/",
      "resource_type": "shipment"
    },
    "resource_type": "shipment_charge_line_item",
    "booking_party_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "service_provider_id": "9e675145-4e5f-4cc0-8cbc-11bd70ccc1ab"
  }
}

shipment.charge_line_item.deleted

Copy
Copied
{
  "id": "01J6WNDB0507VN0H4BNM19V40W",
  "occurred_at": "2025-09-08T19:22:29.161524+00:00",
  "source": {
    "user_id": "90c64b3b-a24a-4a12-8784-a607dfde8705",
    "company_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "request_id": "00-66d761f5000000003118c7c143ae41e4-abee1a18cc44a965-01",
    "publishing_system": "backend",
    "environment": "sandbox"
  },
  "event_name": "shipment.charge_line_item.deleted",
  "webhook_id": "01J6WN655FNEB7PAXT58SKJA24",
  "custom_data": null,
  "details": {
    "id": "2fe76956-4071-4f6e-93e2-91b030e64f9e",
    "shipment": {
      "id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
      "self_link": "/v2/shipments/6586aebf-e7b6-410e-ba6f-75d3de072ee7/",
      "resource_type": "shipment"
    },
    "resource_type": "shipment_charge_line_item",
    "booking_party_id": "78a5d350-bd7f-4d1b-9eda-97d95e58fd8e",
    "service_provider_id": "9e675145-4e5f-4cc0-8cbc-11bd70ccc1ab"
  }
}
Note

Some charge line updates may appear as a deleted then created event or webhook payload.

When you receive and process these webhook payloads, the details.shipment.id or details.shipment.self_link may be referenced to obtain the shipmentId/shipment_id of the shipment.

Details about the charge line items may be obtained by calling:

  • GET /v2/shipments list/query API endpoint (see API reference ) and querying for the shipment by reference_id , purchase_order_number , or other criteria
  • GET /v2/shipments/{shipmentId}/ API endpoint (see API reference ) with the shipmentId/shipment_id of the particular shipment
Example shipment details section of shipment charge line item-related webhook payload
Copy
Copied
"details": {
    // ...
    "shipment": {
      "id": "6586aebf-e7b6-410e-ba6f-75d3de072ee7",
      "self_link": "/v2/shipments/6586aebf-e7b6-410e-ba6f-75d3de072ee7/",
      "resource_type": "shipment"
    }
    // ...
}

If needed, retrieve the current state of the full list of shipment charge line items (i.e. what your users have entered into Shipwell for the charge line items) at any time by calling Shipwell Shipments API and inspecting the charge line items from the shipment's relationship_to_vendor.customer_charge_line_items array/list property (see API reference).

5. 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.

Copy
Copied
{
  "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.

Copy
Copied
    "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.

Copyright © Shipwell 2024. All right reserved.