Skip to main content

Express

4 API calls in this section.

Package Entry

Express Shipping / Express
POST/express/package-entry

API: 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:

Send the tenant API key in X-APIKey or X-API-Key after the key is created and approved.
Request
curl
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}'
Request body
json
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

weightExample
number

Example field from the request body.

customer_idExample
string

Example field from the request body.

order_idExample
string

Example field from the request body.

cargo_tracking_codeExample
string

Example field from the request body.

cargo_infoExample
array<string>

Example field from the request body.

label_dataExample
object

Example field from the request body.

Headers

Content-TypeOptional
header string

application/json

X-API-KeyOptional
header string

{{api_key}}

API key authentication (required)

Responses

Success Response - Claimed Package200OK
Response body
json
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}
Success Response - Unclaimed Package200OK
Response body
json
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}
Error - Missing Required Fields400Bad Request
Response body
json
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}
Error - Customer Not Found404Not Found
Response body
json
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}
Error - Internal Server Error500Internal Server Error
Response body
json
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}
400 - Missing Required Fields400
Response body
json
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}
404 - Customer Not Found404
Response body
json
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}
500 - Service Unavailable500
Response body
json
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 Shipping / Express
POST/express/package-update

API: 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

Send the tenant API key in X-APIKey or X-API-Key after the key is created and approved.
Request
curl
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}'
Request body
json
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_idExample
string

Example field from the request body.

weightExample
number

Example field from the request body.

cargo_tracking_codeExample
string

Example field from the request body.

cargo_infoExample
array<string>

Example field from the request body.

Headers

Content-TypeOptional
header string

application/json

X-API-KeyOptional
header string

{{api_key}}

API key authentication (required)

Responses

Success Response200OK
Response body
json
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}
Success Response (200)200
Response body
json
1{2  "success": true,3  "data": { /* updated express_shipping_packages row */ }4}

Webhook Status Update

Express Shipping / Express
POST/express/webhook-status-update

API: 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

Send the tenant API key in X-APIKey or X-API-Key after the key is created and approved.
Request
curl
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}'
Request body
json
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_idExample
string

Example field from the request body.

statusExample
string

Example field from the request body.

timestampExample
string

Example field from the request body.

detailsExample
string

Example field from the request body.

Headers

Content-TypeOptional
header string

application/json

X-API-KeyOptional
header string

{{api_key}}

API key authentication (required)

Responses

Success Response - Status Updated200OK
Response body
json
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}
Success Response - Package Not Found200OK
Response body
json
1{2  "success": true,3  "data": {4    "order_id": "NON-EXISTENT-ORDER",5    "processed": false6  },7  "message": "Webhook received but package not found"8}
Error - Missing Required Fields500Internal Server Error
Response body
json
1{2  "success": false,3  "error_code": "MISSING_REQUIRED_FIELDS",4  "message": "Missing required fields",5  "details": "Missing fields: timestamp, details"6}
Success Response (Package Not Found)200
Response body
json
1{2  "success": true,3  "data": {4    "order_id": "TREND-ORD-98765",5    "processed": false6  },7  "message": "Webhook received but package not found"8}
Success Response (Update Failed)200
Response body
json
1{2  "success": true,3  "data": {4    "order_id": "TREND-ORD-98765",5    "processed": false6  },7  "message": "Webhook received but status update failed"8}
Error Response (500 - Only for severe errors)500
Response body
json
1{2  "success": false,3  "error_code": "INTERNAL_SERVER_ERROR",4  "message": "Internal server error",5  "details": "JSON parsing failed"6}

Update Order

Express Shipping / Express
POST/express/update-order/TREND-ORD-98765

API: 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:

Send the tenant API key in X-APIKey or X-API-Key after the key is created and approved.
Request
curl
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}'
Request body
json
1{2  "weight": 3000,3  "size": {4    "length": 35,5    "width": 25,6    "height": 157  },8  "status": "executedByShipper"9}

Request body fields

weightExample
number

Example field from the request body.

sizeExample
object

Example field from the request body.

size.lengthExample
number

Example field from the request body.

size.widthExample
number

Example field from the request body.

size.heightExample
number

Example field from the request body.

statusExample
string

Example field from the request body.

Headers

Content-TypeOptional
header string

application/json

X-API-KeyOptional
header string

{{api_key}}

API key authentication (required)

Responses

Success Response200OK
Response body
json
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}
Error - Invalid Fields400Bad Request
Response body
json
1{2  "success": false,3  "error": "Invalid fields for update: products, customerEmail. Only weight, size, and status are allowed"4}
Error - Order Not Found404Not Found
Response body
json
1{2  "success": false,3  "error": "Order not found"4}
400 - Missing Order ID400
Response body
json
1{2  "success": false,3  "error": "Order ID is required in URL path"4}
500 - Update Failed500
Response body
json
1{2  "success": false,3  "error": "Failed to update package status"4}