Basic LPN Validation
This is a simple example of validating an LPN (License Plate Number) on an order.
The following example uses Python for reference, but an integration can be built in any language or framework that can make HTTP requests and receive webhooks.
The Flow
- You create a shipment with an order containing expected LPNs
- As pallets pass through the Kargo vision system, you receive webhook events
- You validate that each scanned LPN matches what was expected on the order
Step 1: Get Access Token
Request:
POST https://mykargo.us.auth0.com/oauth/token
Content-Type: application/json
{
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"audience": "https://api.kargo.zone/public_graphql",
"grant_type": "client_credentials"
}
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400,
"token_type": "Bearer"
}
Cache your access token! Tokens are valid for 24 hours. Only request a new token when the current one expires.
Step 2: Create Shipment and Order
Request:
POST https://api.kargo.zone/public_graphql
Authorization: Bearer <access_token>
Content-Type: application/json
GraphQL Mutation:
mutation CreateShipmentAndOrder($input: CreateShipmentAndOrderInput!) {
createShipmentAndOrder(input: $input) {
shipment {
id
orders {
items {
lpn
}
}
}
}
}
Variables:
{
"input": {
"shipment": {
"businessSlug": "your-business",
"facilitySlug": "your-facility",
"shipmentNumber": "SHIP-001",
"direction": "RECEIVING",
"status": "SCHEDULED",
"expectedArrivalAt": "2025-12-16T20:50:47.366Z"
},
"orders": [
{
"orderNumber": "ORD-001",
"direction": "INBOUND",
"expectedQuantity": 3,
"items": [
{ "lpn": "LPN1", "quantityUnit": "PALLET", "quantity": 1 },
{ "lpn": "LPN2", "quantityUnit": "PALLET", "quantity": 1 },
{ "lpn": "LPN3", "quantityUnit": "PALLET", "quantity": 1 }
]
}
]
}
}
Step 3: Receive Pallet Webhooks
As each pallet passes through the Kargo vision system, Kargo pushes a webhook to your endpoint. For the order above with three LPNs, you'll receive three webhooks:
Webhook 1: LPN1
{
"businessSlug": "your-business",
"facilitySlug": "your-facility",
"kargoShipmentId": "1562067",
"kargoPalletId": "121159700",
"occurredAt": "2025-12-16T14:30:00.000Z",
"url": "https://athena.mykargo.com/shipments/1562067/media?pallet=121159700",
"direction": "UNLOADING",
"orders": ["ORD-001"],
"dockId": "1",
"LPN": "LPN1"
}
Webhook 2: LPN2
{
"businessSlug": "your-business",
"facilitySlug": "your-facility",
"kargoShipmentId": "1562067",
"kargoPalletId": "121159701",
"occurredAt": "2025-12-16T14:32:15.000Z",
"url": "https://athena.mykargo.com/shipments/1562067/media?pallet=121159701",
"direction": "UNLOADING",
"orders": ["ORD-001"],
"dockId": "1",
"LPN": "LPN2"
}
Webhook 3: LPN3
{
"businessSlug": "your-business",
"facilitySlug": "your-facility",
"kargoShipmentId": "1562067",
"kargoPalletId": "121159702",
"occurredAt": "2025-12-16T14:35:45.000Z",
"url": "https://athena.mykargo.com/shipments/1562067/media?pallet=121159702",
"direction": "UNLOADING",
"orders": ["ORD-001"],
"dockId": "1",
"LPN": "LPN3"
}
See the Pallet Level Push documentation for full webhook payload details.
Validation Logic
The validation is simple: check if the LPN in the webhook matches one of the lpn values you submitted in the order.
def handle_pallet_webhook(webhook_payload: dict, expected_lpns: list):
"""Handle an incoming pallet webhook from Kargo."""
lpn = webhook_payload.get("LPN")
if lpn in expected_lpns:
print(f"✓ LPN {lpn} matches expected item")
# Add your business logic here
else:
print(f"✗ LPN {lpn} not found in expected items")