Express
4 API calls in this section.
Package Entry
/express/package-entryAPI: Package Entry Endpoint: POST /express/package-entry Purpose: External endpoint for package entry. This API is called when a package is received at the facility. It either creates a new package record or updates an existing one. Authentication: - X-API-Key header (required) - No Bearer token required Request Body Fields (all optional): - weight (integer, optional): Package weight in grams from weighing system - customer_id (string, optional): Customer ID to lookup the galina customer - order_id (string, optional): Order ID that becomes our order_number - cargo_tracking_code (string, optional): Cargo tracking code provided by shipping partner (separate from order_id) - cargo_info (array of strings, optional): Additional cargo information such as item codes, AWB numbers, etc. - label_data (object, optional): Arbitrary JSON object for label payload/metadata Business Logic: 1. Validate customer exists using provided customer_id 2. Check if package already exists using order_id 3. If package exists: Update weight, shipping price, tracking code, cargo information, and mark as received 4. If package doesn't exist: Create new unclaimed package with status=received, quantity=1, currency=USD 5. Calculate shipping price based on weight 6. Return package and customer details with claimed/unclaimed status Response Field Notes: - is_claimed: true if customer has already claimed this order with invoice, false if package arrived before customer claim - store_name: Populated with store name if package was claimed by customer first, empty if unclaimed - package_type: Populated with package type if package was claimed by customer first, empty if unclaimed (filled only after customer claim) - order_id: The unique order identifier from the e-commerce platform (StarEx order_id parameter) - tracking_number: Our internal Galina tracking number for this package Error Responses: 400 - Missing Required Fields: 404 - Customer Not Found: 500 - Internal Server Error: 500 - Service Unavailable:
1curl --request POST "$ONDI_BASE_URL/express/package-entry" \2 --header "Content-Type: application/json" \3 --header "X-API-Key: {{api_key}}" \4 --header "Content-Type: application/json" \5 --data '{6 "weight": 1500,7 "customer_id": "GL222111",8 "order_id": "TREND-ORD-98765",9 "cargo_tracking_code": "AZO593623623",10 "cargo_info": [11 "1521235ATT35",12 "124125515"13 ],14 "label_data": {}15}'1{2 "weight": 1500,3 "customer_id": "GL222111",4 "order_id": "TREND-ORD-98765",5 "cargo_tracking_code": "AZO593623623",6 "cargo_info": [7 "1521235ATT35",8 "124125515"9 ],10 "label_data": {}11}Request body fields
weightExampleExample field from the request body.
customer_idExampleExample field from the request body.
order_idExampleExample field from the request body.
cargo_tracking_codeExampleExample field from the request body.
cargo_infoExampleExample field from the request body.
label_dataExampleExample field from the request body.
Headers
Content-TypeOptionalapplication/json
X-API-KeyOptional{{api_key}}
API key authentication (required)
Responses
1{2 "success": true,3 "data": {4 "package": {5 "tracking_number": "GL1706371234567",6 "order_id": "TREND-ORD-98765",7 "quantity": 1,8 "price": 25.5,9 "currency": "USD",10 "store_name": "Trendyol",11 "hs_code": "0000.00.00",12 "package_type": "general_goods",13 "status": "received",14 "is_claimed": true15 },16 "customer": {17 "first_name": "Ahmed",18 "last_name": "Al-Rahman",19 "phone_number": "+964987654321",20 "address": "123 Main Street, Erbil, Iraq",21 "id_pin": "GL222111"22 },23 "label": ""24 },25 "message": "Package received successfully"26}1{2 "success": true,3 "data": {4 "package": {5 "tracking_number": "GL1706371234568",6 "order_id": "NEW-ORD-12345",7 "quantity": 1,8 "price": 32.75,9 "currency": "USD",10 "store_name": "",11 "hs_code": "0000.00.00",12 "package_type": "",13 "status": "received",14 "is_claimed": false15 },16 "customer": {17 "first_name": "Fatima",18 "last_name": "Al-Zahra",19 "phone_number": "+964501234567",20 "address": "456 Al-Mansour Street, Baghdad, Iraq",21 "id_pin": "GL333222"22 },23 "label": ""24 },25 "message": "Package received successfully"26}1{2 "success": false,3 "error_code": "MISSING_REQUIRED_FIELDS",4 "message": "Missing required fields",5 "details": "Missing fields: weight, order_id, cargo_info"6}1{2 "success": false,3 "error_code": "CUSTOMER_NOT_FOUND",4 "message": "Customer not found",5 "details": "Customer with customer_id INVALID123 not found"6}1{2 "success": false,3 "error_code": "INTERNAL_SERVER_ERROR",4 "message": "Internal server error",5 "details": "Unable to process package update at this time"6}1{2 "success": false,3 "error_code": "MISSING_REQUIRED_FIELDS",4 "message": "Missing required fields",5 "details": "Missing fields: weight, customer_id, order_id"6}1{2 "success": false,3 "error_code": "CUSTOMER_NOT_FOUND",4 "message": "Customer not found",5 "details": "Customer with customer_id GL222111 not found"6}1{2 "success": false,3 "error_code": "INTERNAL_SERVER_ERROR",4 "message": "Internal server error",5 "details": "Unable to process new package at this time"6}Package Update
/express/package-updateAPI: Package Update Endpoint: POST /express/package-update Purpose: Update existing express package fields by order_id (same fields accepted by package entry). Recomputes international fee and, if linked delivery exists, recomputes domestic fee and updates the delivery. Authentication: - X-API-Key header (required) Request Body Fields: - order_id (string, required): Order ID to locate the package - weight (integer, optional): Updated weight in grams - cargo_tracking_code (string | string[], optional): External tracking code(s) - cargo_info (string[], optional): Tags like fragile, electronics Error Responses: - 400: order_id is required - 404: Package not found - 500: Internal server error
1curl --request POST "$ONDI_BASE_URL/express/package-update" \2 --header "Content-Type: application/json" \3 --header "X-API-Key: {{api_key}}" \4 --header "Content-Type: application/json" \5 --data '{6 "order_id": "{{order_id}}",7 "weight": 3200,8 "cargo_tracking_code": "STAREX-TRACK-123",9 "cargo_info": [10 "fragile",11 "electronics"12 ]13}'1{2 "order_id": "{{order_id}}",3 "weight": 3200,4 "cargo_tracking_code": "STAREX-TRACK-123",5 "cargo_info": [6 "fragile",7 "electronics"8 ]9}Request body fields
order_idExampleExample field from the request body.
weightExampleExample field from the request body.
cargo_tracking_codeExampleExample field from the request body.
cargo_infoExampleExample field from the request body.
Headers
Content-TypeOptionalapplication/json
X-API-KeyOptional{{api_key}}
API key authentication (required)
Responses
1{2 "success": true,3 "data": {4 "order_id": "TREND-ORD-98765",5 "weight": 3200,6 "cargo_tracking_code": "STAREX-TRACK-123",7 "cargo_info": [8 "fragile",9 "electronics"10 ]11 }12}1{2 "success": true,3 "data": { /* updated express_shipping_packages row */ }4}Webhook Status Update
/express/webhook-status-updateAPI: Webhook Status Update Endpoint: POST /express/webhookStatusUpdate Purpose: External webhook for package status updates. Called whenever package status changes during transit. Authentication: - X-API-Key header (required) - No Bearer token required Request Body Fields: - order_id (string, required): Order ID to identify the package - status (string, required): New status value from external system - timestamp (string, required): ISO 8601 timestamp when status change occurred - details (string, required): Human-readable details about the status change External statuses are mapped to internal statuses: - pending → pending - claimedByCustomer → claimed - executedByShipper → in_transit - inTransitInternational → in_transit_international - inWarehouseDomestic → in_warehouse - inProgressDomestic → out_for_delivery - delivered → delivered - canceled → cancelled - accepted_at_facility → in_transit - package_being_packaged → in_transit - in_transit_outside_iraq → in_transit_international - arrived_in_iraq → in_warehouse Business Logic: 1. Locate package using the provided order_id 2. Map external status to internal status representation 3. Update package status and maintain status history 4. Webhook always returns success response for reliability Success Response (Update Failed): Note: This endpoint always returns success status even if package is not found or update fails. This is intentional webhook design to prevent unnecessary retries. The processed field indicates whether the update was successfully applied. Possible Error Codes: - MISSING_REQUIRED_FIELDS: Missing order_id, status, timestamp, or details - INTERNAL_SERVER_ERROR: JSON parsing or severe system error
1curl --request POST "$ONDI_BASE_URL/express/webhook-status-update" \2 --header "Content-Type: application/json" \3 --header "X-API-Key: {{api_key}}" \4 --header "Content-Type: application/json" \5 --data '{6 "order_id": "TREND-ORD-98765",7 "status": "in_transit_outside_iraq",8 "timestamp": "2025-01-27T12:00:00Z",9 "details": "Package en route to Iraq"10}'1{2 "order_id": "TREND-ORD-98765",3 "status": "in_transit_outside_iraq",4 "timestamp": "2025-01-27T12:00:00Z",5 "details": "Package en route to Iraq"6}Request body fields
order_idExampleExample field from the request body.
statusExampleExample field from the request body.
timestampExampleExample field from the request body.
detailsExampleExample field from the request body.
Headers
Content-TypeOptionalapplication/json
X-API-KeyOptional{{api_key}}
API key authentication (required)
Responses
1{2 "success": true,3 "data": {4 "order_id": "TREND-ORD-98765",5 "status": "in_transit_outside_iraq",6 "processed": true,7 "timestamp": "2025-01-27T12:00:00Z"8 },9 "message": "Status update processed successfully"10}1{2 "success": true,3 "data": {4 "order_id": "NON-EXISTENT-ORDER",5 "processed": false6 },7 "message": "Webhook received but package not found"8}1{2 "success": false,3 "error_code": "MISSING_REQUIRED_FIELDS",4 "message": "Missing required fields",5 "details": "Missing fields: timestamp, details"6}1{2 "success": true,3 "data": {4 "order_id": "TREND-ORD-98765",5 "processed": false6 },7 "message": "Webhook received but package not found"8}1{2 "success": true,3 "data": {4 "order_id": "TREND-ORD-98765",5 "processed": false6 },7 "message": "Webhook received but status update failed"8}1{2 "success": false,3 "error_code": "INTERNAL_SERVER_ERROR",4 "message": "Internal server error",5 "details": "JSON parsing failed"6}Update Order
/express/update-order/TREND-ORD-98765API: Update Order Endpoint: POST /express/update-order/:order_id Purpose: Update order details after measurement or status changes. Only weight, size, and status fields are allowed. Authentication: - X-API-Key header (required) Path Parameters: - order_id (string, required): Order ID in the URL path Request Body Fields (only these are allowed): - weight (integer, optional): Updated package weight in grams - size (object, optional): Updated package dimensions - length (number, optional): Length in centimeters - width (number, optional): Width in centimeters - height (number, optional): Height in centimeters - status (string, optional): Updated package status (uses update_package_status RPC) Field Restrictions: - Only weight, size, and status fields are accepted - Any other fields will result in a validation error - Status updates are handled via the database RPC function for proper history tracking Business Logic: 1. Extract order_id from URL path 2. Validate only allowed fields are provided 3. Update weight and size directly in database 4. Update status via update_package_status RPC function 5. Return summary of updated fields Error Responses: 400 - Missing Order ID: 400 - Invalid Fields: 404 - Order Not Found: 500 - Update Failed:
1curl --request POST "$ONDI_BASE_URL/express/update-order/TREND-ORD-98765" \2 --header "Content-Type: application/json" \3 --header "X-API-Key: {{api_key}}" \4 --header "Content-Type: application/json" \5 --data '{6 "weight": 3000,7 "size": {8 "length": 35,9 "width": 25,10 "height": 1511 },12 "status": "executedByShipper"13}'1{2 "weight": 3000,3 "size": {4 "length": 35,5 "width": 25,6 "height": 157 },8 "status": "executedByShipper"9}Request body fields
weightExampleExample field from the request body.
sizeExampleExample field from the request body.
size.lengthExampleExample field from the request body.
size.widthExampleExample field from the request body.
size.heightExampleExample field from the request body.
statusExampleExample field from the request body.
Headers
Content-TypeOptionalapplication/json
X-API-KeyOptional{{api_key}}
API key authentication (required)
Responses
1{2 "success": true,3 "message": "Order updated successfully",4 "data": {5 "order_id": "TREND-ORD-98765",6 "updatedFields": {7 "weight": 3000,8 "size": {9 "length": 35,10 "width": 25,11 "height": 1512 },13 "status": "executedByShipper"14 },15 "timestamp": "2025-01-27T12:00:00Z"16 }17}1{2 "success": false,3 "error": "Invalid fields for update: products, customerEmail. Only weight, size, and status are allowed"4}1{2 "success": false,3 "error": "Order not found"4}1{2 "success": false,3 "error": "Order ID is required in URL path"4}1{2 "success": false,3 "error": "Failed to update package status"4}