Public API V1 — Developer Guide
Unified Integration Gateway for the ShippingEyes Ecosystem
Data Integration Lifecycle
🛠️ Developer Sandbox Settings
(All cURL, PHP, and JS examples update in real-time)
📋 Public API V1 — Endpoints Summary (23 endpoints)
| Method | Endpoint | Scope | Description |
|---|---|---|---|
| GET | /api/v1/public/locations/countries | shipping:read | List delivery countries |
| GET | /api/v1/public/locations/routes | shipping:read | List all delivery routes |
| GET | /api/v1/public/locations/routes/country/{id} | shipping:read | List routes by country |
| GET | /api/v1/public/locations/cities | shipping:read | List all delivery cities |
| GET | /api/v1/public/locations/cities/country/{id} | shipping:read | List cities by country |
| GET | /api/v1/public/locations/cities/route/{id} | shipping:read | List cities by route |
| GET | /api/v1/public/locations/places | shipping:read | List all delivery places |
| GET | /api/v1/public/locations/places/city/{id} | shipping:read | List places by city |
| GET | /api/v1/public/locations/districts | shipping:read | List all delivery districts |
| GET | /api/v1/public/locations/districts/place/{id} | shipping:read | List districts by place |
| GET | /api/v1/public/shipping/prices | shipping:read | Get shipping prices |
| GET | /api/v1/public/shipping/services | shipping:read | Get shipping services |
| GET | /api/v1/public/shipping/config | shipping:read | Get configuration for order creation |
| GET | /api/v1/public/shipping/config/statuses | shipping:read | Get available order statuses |
| POST | /api/v1/public/orders/create | orders:create | Create new order |
| POST | /api/v1/public/orders/update | orders:create | Update existing order |
| DELETE | /api/v1/public/orders/delete/{order_id} | orders:create | Delete order |
| GET | /api/v1/public/orders/list/{status} | orders:read | List orders by status |
| GET | /api/v1/public/orders/info/{order_id} | orders:read | Get order details |
| POST | /api/v1/public/orders/search | orders:read | Search and Query orders (Ultra High Performance) |
| GET | /api/v1/public/orders/tracking/{order_id} | tracking:read | Get order tracking |
| POST | /api/v1/public/orders/tracking/bulk | tracking:read | Bulk order tracking |
| POST | /api/v1/public/orders/followups/bulk | orders:read | Bulk order followups and history |
🚀 Quick Start Guide
🌐 Base URL
Production: https://your-domain.com/api/v1/public
Development: {APP_URL}/api/v1/public
🔑 Authentication — API Key + Secret
Every request must include two custom headers:
| Header | Type | Required | Description |
|---|---|---|---|
| ShippingEyes-Api-Key | string | ✅ Yes | Your public API key (starts with se_live_ or se_test_)
|
| ShippingEyes-Api-Secret | string | ✅ Yes | Your private API secret (64 characters). Never expose publicly. |
| ShippingEyes-Api-Nonce | string | ⚠️ Conditional | Mandatory for POST, PUT, DELETE. Optional for GET. A unique per-request UUID to prevent replay attacks. |
📝 Complete Example — Create Order
curl -X POST https://your-domain.com/api/v1/public/orders/create \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "ShippingEyes-Api-Key: se_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678" \
-H "ShippingEyes-Api-Secret: your_64_char_secret_here..." \
-H "ShippingEyes-Api-Nonce: 123e4567-e89b-12d3-a456-426614174000" \
-d '{
"ref_num": "ORD-10055",
"shipping_service": "srv8gJ",
"shipment_info": {
"pieces": 1,
"description": "Electronics package",
"order_type": 1,
"delivery_type": 1,
"allow_opening": 0,
"breakable": 0
},
"recipient": {
"name": "Ahmed Hassan",
"phone": "0910000000",
"to_city": "lejRej",
"to_place": "mep2bM",
"address": "123 Main Street"
},
"financial_info": {
"amount": 250,
"amount_type": 1,
"shipping_cost_type": 1,
"payment_type": "cash"
}
}'
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('https://your-domain.com/api/v1/public/orders/create', [
'headers' => [
'ShippingEyes-Api-Key' => 'se_live_...',
'ShippingEyes-Api-Secret' => 'your_secret...',
'ShippingEyes-Api-Nonce' => uniqid('nonce_'),
'Accept' => 'application/json',
],
'json' => [
'ref_num' => 'ORD-10055', // 🛡️ Prevent duplicate orders
'shipping_service' => 'srv8gJ',
'shipment_info' => [
'pieces' => 1,
'description' => 'Electronics package',
'order_type' => 1,
'delivery_type' => 1,
'allow_opening' => 0,
'breakable' => 0
],
'recipient' => [
'name' => 'Ahmed Hassan',
'phone' => '0910000000',
'to_city' => 'lejRej',
'to_place' => 'mep2bM',
'address' => '123 Main Street'
],
'financial_info' => [
'amount' => 250,
'amount_type' => 1,
'shipping_cost_type' => 1,
'payment_type' => 'cash'
]
]
]);
$data = json_decode($response->getBody(), true);
<?php
$payload = [
'ref_num' => 'ORD-10055', // 🛡️ Prevent duplicate orders
'shipping_service' => 'srv8gJ',
'shipment_info' => [
'pieces' => 1,
'description' => 'Electronics package',
'order_type' => 1,
'delivery_type' => 1,
'allow_opening' => 0,
'breakable' => 0
],
'recipient' => [
'name' => 'Ahmed Hassan',
'phone' => '0910000000',
'to_city' => 'lejRej',
'to_place' => 'mep2bM',
'address' => '123 Main Street'
],
'financial_info' => [
'amount' => 250,
'amount_type' => 1,
'shipping_cost_type' => 1,
'payment_type' => 'cash'
]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://your-domain.com/api/v1/public/orders/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$nonce = uniqid('nonce_');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"ShippingEyes-Api-Key: se_live_...",
"ShippingEyes-Api-Secret: your_secret...",
"ShippingEyes-Api-Nonce: $nonce",
"Content-Type: application/json",
"Accept: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
print_r($data);
?>
const fetch = require('node-fetch');
const createOrder = async () => {
const response = await fetch('https://your-domain.com/api/v1/public/orders/create', {
method: 'POST',
headers: {
'ShippingEyes-Api-Key': 'se_live_...',
'ShippingEyes-Api-Secret': 'your_secret...',
'ShippingEyes-Api-Nonce': require('crypto').randomUUID(),
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
ref_num: 'ORD-10055', // 🛡️ Prevent duplicate orders
shipping_service: 'srv8gJ',
shipment_info: { pieces: 1, description: 'Electronics package', order_type: 1, delivery_type: 1, allow_opening: 0, breakable: 0 },
recipient: { name: 'Ahmed Hassan', phone: '0910000000', to_city: 'lejRej', to_place: 'mep2bM', address: '123 Main Street' },
financial_info: { amount: 250, amount_type: 1, shipping_cost_type: 1, payment_type: 'cash' }
})
});
const data = await response.json();
console.log(data);
};
{
"status": 200,
"message": "success",
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"request_id": "uuid-string",
"rate_limit": {
"limit": 30,
"unit": "requests per minute",
"note": "Standard creation quota."
}
},
"order_id": "ord4cN",
"order_snum": 10042
}
📱 Required Headers for All Requests
| Header | Value | Required |
|---|---|---|
| Content-Type | application/json |
POST requests |
| Accept | application/json |
All requests |
| ShippingEyes-Api-Key | Your API key | ✅ Always |
| ShippingEyes-Api-Secret | Your API secret | ✅ Always |
📌 ID Format Convention
"lejRej",
"mep2bM"). Never assume IDs are numeric or sequential. Treat them as opaque
strings.
🔒 Security Layers (6-Layer Middleware Stack)
| # | Layer | Purpose |
|---|---|---|
| 1 | HTTPS Enforcement | Blocks all non-HTTPS requests |
| 2 | Rate Limiting | Dynamic quotas (3/5min to 60/min) based on endpoint sensitivity |
| 3 | API Key Auth | Validates key + secret + IP whitelist |
| 4 | Scope Check | Verifies endpoint permission |
| 5 | Response Filter | Strips sensitive internal fields |
| 6 | Audit Log | Logs every request for forensics |
📌 Order Status Reference
Use these status keys to interpret the status_key field in responses and to filter
the view-orders-list endpoint.
| Key | Status Name | Description | Workflow Stage |
|---|---|---|---|
| 1 | Order Creation |
Order successfully created by the
merchant.
Code: OC
|
Creation |
| 5 | Pickup Collected |
Package has been collected from
the merchant.
Code: PUC
|
Pickup Operations |
| 12 | Receive In Branch |
Package arrived and received at
the destination branch.
Code: RIB
|
Branch Transfer |
| 14 | Cancel |
Order has been cancelled before
final processing.
Code: C
|
Exceptions |
| 19 | IN Preparation |
Order is being prepared and
packed for dispatch.
Code: INP
|
Delivery Preparation |
| 22 | Out for delivery |
Delegate is currently out
delivering the package to the customer.
Code: OFD
|
Final Mile |
| 30 | Delivered |
Package successfully delivered to
the customer.
Code: D
|
Final Delivery Status |
| 35 | Returned |
Order could not be delivered and
has been returned.
Code: RD
|
Returns Workflow |
🔢 Pagination Standard
All list endpoints use a standard metadata object to handle large data sets:
{
"data": [...],
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"rate_limit": {
"limit": 60,
"unit": "requests per minute",
"note": "Real-time monitoring quota. No-cache enforced."
},
"current_page": 1,
"last_page": 12,
"per_page": 20,
"total": 235,
"next_page_url": "...?page=2",
"prev_page_url": null
}
}
🔑 Authentication
🚨 Security & Abuse Policy
Shipping Eyes employs advanced Web Application Firewalls (WAF) and AI-driven anomaly detection to safeguard logistics integrity. Automated data scraping, payload fuzzing, or any deliberate attempts to circumvent API limitations are strictly prohibited.
Consequences of Abuse: Any detection of malicious behavior, suspicious traffic patterns, or systemic abuse will trigger an immediate, automated, and permanent IP ban, along with the permanent revocation of your API credentials without prior notice.
The Public API utilizes Server-to-Server authentication using pre-generated API credentials:
1. Obtain Your Credentials
Your API Key and Secret are generated by the system administrator. You receive them once:
{
"ShippingEyes-Api-Key": "se_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678",
"ShippingEyes-Api-Secret": "x9K2mP7qR4tL8wN3vB6jH1dF5gY0sA..."
}
2. Include in Every Request
ShippingEyes-Api-Key: se_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678 ShippingEyes-Api-Secret: x9K2mP7qR4tL8wN3vB6jH1dF5gY0sA...
3. Authentication Errors
{
"status": "error",
"message": "authentication_required",
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"request_id": "uuid-string",
"rate_limit": {
"limit": 60,
"unit": "requests per minute",
"note": "Standard authentication quota."
}
}
}
{
"status": "error",
"message": "invalid_credentials",
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"request_id": "uuid-string",
"rate_limit": {
"limit": 60,
"unit": "requests per minute",
"note": "Standard authentication quota."
}
}
}
4. Implementation Examples
Integrate ShippingEyes into your stack using these boilerplate examples:
curl -X GET "https://your-domain.com/api/v1/orders" \
-H "ShippingEyes-Api-Key: YOUR_API_KEY" \
-H "ShippingEyes-Api-Secret: YOUR_API_SECRET" \
-H "Accept: application/json"
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://your-domain.com/api/v1/orders");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"ShippingEyes-Api-Key: YOUR_API_KEY",
"ShippingEyes-Api-Secret: YOUR_API_SECRET",
"Accept: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
const axios = require('axios');
axios.get('https://your-domain.com/api/v1/orders', {
headers: {
'ShippingEyes-Api-Key': 'YOUR_API_KEY',
'ShippingEyes-Api-Secret': 'YOUR_API_SECRET',
'Accept': 'application/json'
}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests
url = "https://your-domain.com/api/v1/orders"
headers = {
"ShippingEyes-Api-Key": "YOUR_API_KEY",
"ShippingEyes-Api-Secret": "YOUR_API_SECRET",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())
{
"status": "error",
"message": "ip_forbidden",
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"request_id": "uuid-string",
"rate_limit": {
"limit": 60,
"unit": "requests per minute",
"note": "Standard authentication quota."
}
}
}
{
"status": "error",
"message": "too_many_requests",
"meta": {
"api_version": "1.0.0",
"timestamp": "2026-04-30T10:45:00Z",
"request_id": "uuid-string",
"rate_limit": {
"limit": 60,
"unit": "requests per minute",
"note": "Quota exceeded. Check headers for retry time."
}
}
}
- Never expose your API Secret in client-side code, Git repos, or public URLs
- IP Whitelist: If configured, only requests from allowed IPs will be accepted
- Auto-Disable: After multiple consecutive failed secret attempts, the key is automatically disabled
- Rotation: Keys should be rotated periodically as a security best practice
🧪 Test Environment (Test Mode)
We provide a safe sandbox environment to test your integration without affecting live data or real balances.
- Request a Test API Key from the system administrator (keys starting
with
se_test_). - Use the exact same endpoints and URLs as production.
- When using a
se_test_key, orders are fully validated and saved, but they are flagged internally as test orders. They will not trigger dispatchers, billing, or real logistics workflows.
⚡ Webhooks & Real-time Notifications
Webhooks allow your application to receive real-time notifications about events in the ShippingEyes ecosystem. Instead of polling the API, we push data to your server as soon as an event occurs.
order.status_updated
Real-time tracking for every step of the journey.
order.status_bulk_updated
Sync mass updates instantly when multiple orders change statuses.
order.followup_recorded
Stay informed when drivers or agents add notes.
catalog.shipping_pricing_updated
Automatically sync prices when your shipping package updates.
platform.configuration_updated
Instantly adapt to global platform setting changes.
webhook.test_ping
Test your endpoint integration directly from the dashboard.
🚀 Why Shipping Eyes Webhooks?
Webhooks transform your integration from a "pull" system to an Active Intelligence Engine. Instead of wasting server resources asking "Is it delivered yet?", ShippingEyes shouts "It's delivered!" the millisecond it happens. This enables you to provide an Amazon-like experience to your customers with zero latency.
Lightning Fast Delivery Guarantee
Notifications arrive instantly in real-time. In the absolute worst-case network scenario, the maximum delay is strictly guaranteed to be under 60 seconds.
Authorization or x-api-key) to allow incoming traffic, you can define
up to 3 Custom Headers directly from your webhook settings in the dashboard. We
will automatically attach them to every webhook request sent to your endpoint.
User-Agent, Content-Type,
Accept, or any ShippingEyes-* headers). Any custom header matching
a reserved name will be silently ignored to preserve payload integrity.
📑 HTTP Headers
Every webhook POST request includes the following headers for identification and security:
| Header | Value Example | Description |
|---|---|---|
| ShippingEyes-Webhook-Signature | sha256=a1b2c3... | HMAC-SHA256 signature for payload verification. |
| ShippingEyes-Webhook-Event | order.status_updated | The type of event being sent. |
| ShippingEyes-Webhook-ID | uuid-string | Unique identifier for this specific delivery attempt. |
| ShippingEyes-Webhook-Timestamp | 1714838400 | Unix timestamp of when the event was generated. |
| ShippingEyes-Webhook-Version | 1.0.0 | The current version of the Webhook API. |
| User-Agent | ShippingEyes-Webhook/1.0(or ShippingEyes-Webhook-Tester/1.0 for test events) |
Identifies the webhook dispatcher client. Ensure your firewall allows both if restricted by User-Agent. |
| Content-Type | application/json | The media type of the payload format. |
| Accept | application/json | The media type expected in response (if any). |
🛠️ Webhook Delivery Architecture
Our webhook engine is built for reliability and high performance:
- Asynchronous Delivery & SLA: Events are processed asynchronously to
ensure our core API remains fast.
• Transactional Events (e.g., order updates) are delivered instantly.
• Bulk Fan-out Events (e.g., catalog or configuration updates sent to many merchants) may take a few minutes to arrive during mass updates. - Retry Policy: If your server is down or returns a non-2xx status, we
automatically retry the delivery up to 5 times using a strict exponential
backoff strategy.
⏱️ Exact Retry Schedule:
Attempt 1: Immediately ➔ Attempt 2: After 1 minute ➔ Attempt 3: After 5 minutes ➔ Attempt 4: After 15 minutes ➔ Attempt 5: After 60 minutes - Auto-Disable & Re-enabling: To protect our system, webhooks that fail for 10 consecutive attempts are automatically disabled. If disabled, you must resolve the issue on your endpoint and manually re-enable the webhook from your Merchant Dashboard. Ensure your endpoint is stable and returns a 2xx status promptly.
- Idempotency (Crucial): Because of network
retries, your endpoint might occasionally receive the exact same webhook payload more than
once. You MUST use the
request_idprovided in themetaobject as an idempotency key to ensure you do not process the same event twice in your system.
⚡ Customizable Rate Limiting (Throttling)
By default, we limit webhook dispatches to a maximum of 30 requests per minute to protect your server from traffic spikes. If the volume of generated events exceeds this limit, the excess events will be safely paused and queued (without failing) and delivered as soon as your rate limit window resets.
Your server MUST process the request and return an HTTP 2xx response within 5 seconds. If it takes longer, we will drop the connection, consider it a failure, and initiate a retry.
To successfully acknowledge the receipt of the webhook, your server MUST return a JSON response containing
{"success": true} along with an HTTP 200 (OK) status
code. If this exact JSON payload is not returned, our system will consider the delivery as
failed and will automatically initiate the retry sequence.
For security and data integrity reasons, our dispatcher will NOT follow HTTP redirects (e.g., 301, 302). You must provide the absolute, final destination URL. If your server redirects the request, the delivery will fail.
- Your webhook URL MUST start with
https://. - Localhost, private network IPs (e.g.,
127.0.0.1), and unresolvable domains are strictly blocked. For local testing during development, please use a secure public tunnel service like Ngrok.
If your server uses a strict firewall, ensure you whitelist our static IP addresses to allow incoming webhooks. Please contact our technical support to obtain the list of our current outbound IP addresses.
🔐 Verifying the Signature
Every webhook request includes a ShippingEyes-Webhook-Signature header. This is a
sha256 hash of the raw JSON body signed with your Webhook Secret.
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_SHIPPINGEYES_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = (int) ($_SERVER['HTTP_SHIPPINGEYES_WEBHOOK_TIMESTAMP'] ?? 0);
// Prevent Replay Attacks
if (time() - $timestamp > 300) {
http_response_code(400);
die('Expired');
}
$secret = 'your_webhook_secret_here';
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (hash_equals($expected, $signature)) {
// ✅ Valid request
$data = json_decode($payload, true);
// Process your event here...
// 🚀 Acknowledge Receipt
header('Content-Type: application/json');
http_response_code(200);
echo json_encode(['success' => true]);
exit;
} else {
// ❌ Invalid signature
http_response_code(401);
}
// ⚠️ IMPORTANT: This route must be placed BEFORE any global app.use(express.json())
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['shippingeyes-webhook-signature'] || '';
const timestamp = parseInt(req.headers['shippingeyes-webhook-timestamp'] || '0', 10);
const secret = 'your_webhook_secret_here';
// Prevent Replay Attacks
if (Date.now() / 1000 - timestamp > 300) {
return res.status(400).send('Expired');
}
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(req.body)
.digest('hex');
try {
const calculatedBuffer = Buffer.from(expected, 'hex');
const providedBuffer = Buffer.from(signature.replace('sha256=', ''), 'hex');
// MUST check length before timingSafeEqual to prevent Node.js crashes!
if (calculatedBuffer.length !== providedBuffer.length ||
!crypto.timingSafeEqual(calculatedBuffer, providedBuffer)) {
throw new Error('Invalid signature');
}
} catch (error) {
return res.status(401).send('Unauthorized');
}
// ✅ Valid request. Safely parse the Buffer to JSON.
const payload = JSON.parse(req.body.toString());
console.log('Event:', payload.meta.event);
// Process your event here...
// 🚀 Acknowledge Receipt
res.status(200).json({ success: true });
});
📅 Event Catalog
The following events are currently supported by the ShippingEyes platform:
🏓 ping
A system event sent when you test your webhook endpoint from the Merchant Dashboard. Use this to verify your signature validation logic.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "ping",
"timestamp": "2026-05-04T15:30:00Z",
"request_id": "990i2800-i62f-8508-e14a-880099884444"
},
"data": {
"message": "This is a test ping from ShippingEyes Webhook Tester.",
"test": true
}
}
🔔 order.status_updated
Triggered whenever an order's status changes (e.g., from "New" to "Out for Delivery").
Note: The delegate object is only included in the payload when
the order status is 21 (To Delegate), 22 (Out for delivery),
23 (Postponed with delegate), or 34 (Returned With Delegate).
Always check if it exists before accessing
its properties to avoid Null Reference errors.
💡 Pro Tip (Data Types &
Mapping): order_snum can be a String or Integer.
order_status is always an Integer. We highly recommend using the integer
order_status (e.g., 22) to map statuses in your database instead of relying
on the localized status_name string.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "order.status_updated",
"timestamp": "2026-05-04T15:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
},
"data": {
"order_snum": 10042,
"order_status": 22,
"status_name": "Out for Delivery",
"updated_at": "2026-05-04 15:30:00",
"delegate": {
"name": "Adam",
"phone": "0900000000"
}
}
}
📦 order.status_bulk_updated
Triggered whenever multiple orders' statuses are updated simultaneously in bulk.
Note: The delegate object is only included in the payload when
the order status is 21 (To Delegate), 22 (Out for delivery),
23 (Postponed with delegate), or 34 (Returned With Delegate).
Always check if it exists before accessing
its properties to avoid Null Reference errors.
💡 Pro Tip (Data Types):
orders_snums is an Array of Strings/Integers. order_status is
always an Integer.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "order.status_bulk_updated",
"timestamp": "2026-05-04T15:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440001"
},
"data": {
"order_status": 22,
"status_name": "Out for delivery",
"orders_snums": [
"SHP-10042",
"SHP-10043"
],
"updated_at": "2026-05-04 15:30:00",
"delegate": {
"name": "Adam",
"phone": "0900000000"
}
}
}
💬 order.followup_recorded
Triggered when a new followup or note is added to an order by the delivery agent or customer service.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "order.followup_recorded",
"timestamp": "2026-05-04T16:00:00Z",
"request_id": "660f9500-f39c-52d5-b817-557766551111"
},
"data": {
"order_snum": 10042,
"followup_type": "followup",
"reason_name": "Customer request",
"notes": "Customer requested delivery after 4 PM",
"created_at": "2026-05-04 16:00:00"
}
}
💰 catalog.shipping_pricing_updated
Triggered when shipping prices in your assigned price package are updated. Useful for syncing prices with your ecommerce store.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "catalog.shipping_pricing_updated",
"timestamp": "2026-05-04T16:30:00Z",
"request_id": "770g0600-g40d-63e6-c928-668877662222"
},
"data": {
"price_package_id": "pkg9jL",
"message": "Shipping prices have been updated",
"updated_at": "2026-05-04T16:30:00Z"
}
}
⚙️ platform.configuration_updated
Triggered when global shipment settings (e.g., allowed order types, closing times) are modified by the system.
{
"status": 200,
"message": "webhook_event",
"meta": {
"api_version": "1.0.0",
"event": "platform.configuration_updated",
"timestamp": "2026-05-04T16:30:00Z",
"request_id": "880h1700-h51e-74f7-d039-779988773333"
},
"data": {
"message": "Orders creation settings have been updated",
"updated_at": "2026-05-04T16:30:00Z"
}
}
👤 Delegate Webhook Statuses
The delegate object (containing the driver's name and phone number) is only
included in the webhook payload when the order's status matches one of the following integer
codes:
| Integer Code | Status Name (English) |
|---|---|
| 21 | To Delegate 👤 Includes Delegate Info |
| 22 | Out for delivery 👤 Includes Delegate Info |
| 23 | postponed with delegate 👤 Includes Delegate Info |
| 34 | Returned With Delegate 👤 Includes Delegate Info |