CargoWise One is the most widely used freight management system among mid-to-large Thai freight forwarders. KabyTech's AWB Intelligence API is designed to feed structured AWB data directly into CargoWise, eliminating manual data entry and reducing processing errors. This guide walks through the complete integration, from API key generation to production webhook pipeline.
This guide assumes you have: a KabyTech account on the Professional plan or above, a CargoWise One instance with eHub or eAdapter access, and a basic understanding of webhooks and REST APIs. If your CargoWise setup uses a third-party integration middleware (e.g., Chain.io or Youredi), the concepts are the same but the specific configuration steps will differ.
Log into the KabyTech Operations Portal at portal.kabytech.ai. Navigate to Settings > API Keys > Create New Key. Give the key a descriptive name (e.g., "CargoWise Production") and select the following scopes:
awb:parse — Required. Allows submitting documents for parsing.awb:read — Required. Allows retrieving parsed results.webhook:manage — Required. Allows registering and managing webhook endpoints.field-map:read — Optional but recommended. Allows retrieving the field mapping configuration via API.Copy the API key and secret. The secret is shown only once. Store it in your organization's secrets management system — not in a shared spreadsheet or email.
KabyTech uses webhooks to push parsed AWB data to your systems in real time. When a document is parsed, the structured JSON result is POSTed to your configured endpoint. For CargoWise integration, this endpoint is typically either:
Most Thai forwarders use the middleware approach because it gives more control over field mapping and error handling. Here is how to register the webhook in KabyTech:
POST https://api.kabytech.ai/v1/webhooks
Authorization: Bearer YOUR_API_KEY
{
"url": "https://your-middleware.example.com/kabytech-webhook",
"events": ["awb.parsed", "awb.validation_failed"],
"secret": "your-webhook-signing-secret",
"active": true
}
The awb.parsed event fires when a document is successfully parsed. The awb.validation_failed event fires when parsing succeeds but cross-validation checks detect inconsistencies (e.g., RTD totals don't match PPD/COL). You should handle both events — validation failures still contain the extracted data, but with flags indicating which fields need review.
This is the most detailed step. KabyTech's JSON output contains all 29 FWB sections as structured objects. CargoWise expects data in its Universal Shipment XML format. The table below maps the key fields:
awb.prefix + awb.serial → Shipment/SubShipmentCollection/SubShipment/WaybillNumberrouting.origin → Shipment/OrganizationAddressCollection[AddressType="ConsignorPickupDeliveryAddress"]/Port/Coderouting.destination → Shipment/OrganizationAddressCollection[AddressType="ConsigneePickupDeliveryAddress"]/Port/Codeflight_bookings[0].flight_number → Shipment/SubShipmentCollection/SubShipment/TransportLegCollection/TransportLeg/VoyageFlightNoflight_bookings[0].date → TransportLeg/EstimatedDepartureshipper.name → OrganizationAddressCollection[AddressType="ConsignorDocumentaryAddress"]/CompanyNameshipper.address → .../Address1, .../Address2shipper.city → .../Cityshipper.country → .../Country/Codeshipper.contact.phone → .../Phoneshipper.contact.email → .../Emailconsignee.* → Same structure with AddressType="ConsigneeDocumentaryAddress"rate_description[n].pieces → PackingLineCollection/PackingLine/PackQtyrate_description[n].rate_class → PackingLine/RateClass/Coderate_description[n].commodity_code → PackingLine/Commodity/Coderate_description[n].chargeable_weight → PackingLine/ChargeableWeightrate_description[n].rate → PackingLine/RateChargerate_description[n].total → PackingLine/TotalChargerate_description[n].nature_of_goods → PackingLine/GoodsDescriptioncharge_declarations.prepaid_collect_indicator → Shipment/ChargeCollection/Charge/PrepaidCollectIndicatorcharge_declarations.declared_value_carriage → Shipment/DeclaredValueForCarriagecharge_declarations.declared_value_customs → Shipment/DeclaredValueForCustomsprepaid_summary.weight_charge → ChargeCollection/Charge[ChargeType="WeightCharge"]/Amountother_charges[n].code + .amount → ChargeCollection/Charge[ChargeType="OtherCharge"]/ChargeCode + /Amountspecial_handling_codes[] → Shipment/NoteCollection/Note[NoteType="SpecialHandling"]oci[n].country_code + oci[n].information_id + oci[n].data → Shipment/CustomsEntryCollection/CustomsEntry/CustomsReferenceCollectionhts_codes[] → CustomsEntry/TariffCollection/Tariff/TariffCodeagent.iata_code → Shipment/AgentReferenceThe middleware service needs to perform three tasks:
When KabyTech sends a webhook, it includes an X-KabyTech-Signature header containing an HMAC-SHA256 signature of the request body, signed with your webhook secret. Always validate this signature before processing the payload. This prevents spoofed requests from creating shipments in your CargoWise instance.
Map the KabyTech JSON fields to CargoWise Universal Shipment XML using the field mapping table above. Key considerations for Thai forwarders:
2026-03-20T14:30:00+07:00). CargoWise expects yyyy-MM-ddTHH:mm:ss. Strip the timezone offset during transformation.PackingLine element in the Universal XML. Preserve the ordering — CargoWise uses the first packing line as the primary goods description.Submit the transformed XML to your CargoWise eAdapter endpoint. eAdapter will create or update the shipment record. Configure your eAdapter to return the CargoWise shipment reference number on success, and log this alongside the KabyTech-AWB ID for audit trail purposes.
A production integration needs robust error handling. We recommend the following:
Before going to production, test the complete pipeline with the following scenarios:
KabyTech provides a sandbox environment with test API keys for this purpose. Sandbox parsed results use the same JSON schema as production but are not billed against your monthly quota.
Our integration team has deployed KabyTech + CargoWise at 40+ Thai freight forwarders. We can help.