Public API V1 — Developer Guide

Unified Integration Gateway for the ShippingEyes Ecosystem

Version 1.0 — Secure Server-to-Server Authentication — 23 Endpoints

99.9%
Platform Uptime
<120ms
Avg Response
1M+
Monthly Req
🔄 Integration Architecture

Data Integration Lifecycle

1
🛒
Your Ecommerce
Your store or custom integration platform
WooCommerce Shopify EasyOrders Salla Zid
2
🔌
Public API V1
Secure gateway with multi-layer middleware
Auth Validation Rate Limit
3
👁️
Shipping Eyes Technology
Enterprise-Grade Logistics ERP & Financial Intelligence Engine
Neural Routing Deep Logistics ERP Ai Engine

🛠️ Developer Sandbox Settings

(All cURL, PHP, and JS examples update in real-time)

📡 Live Endpoint Preview:
https://your-domain.com/api/v1/public/...

📋 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

Postman Download Postman Collection

🌐 Base URL

Production: https://your-domain.com/api/v1/public

Development: {APP_URL}/api/v1/public

⚠️ Important: This API is for public integrations only (WooCommerce, Shopify, Custom CRMs/ERPs). It uses API Key + Secret authentication — NOT Bearer tokens. All requests must be over HTTPS.

🔑 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 Example
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"
    }
  }'
🐘 PHP (Guzzle)
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 (Native cURL)
<?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);
?>
📦 Node.js (Fetch)
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);
};
✅ Success Response
{
  "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

ℹ️ All IDs are encoded strings (e.g. "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

Headers: ShippingEyes-Api-Key + ShippingEyes-Api-Secret

🚨 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.

How Authentication Works

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:

🔑 Your Credentials (shown only once)
{
  "ShippingEyes-Api-Key":    "se_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678",
  "ShippingEyes-Api-Secret": "x9K2mP7qR4tL8wN3vB6jH1dF5gY0sA..."
}

2. Include in Every Request

📝 Headers
ShippingEyes-Api-Key: se_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678
ShippingEyes-Api-Secret: x9K2mP7qR4tL8wN3vB6jH1dF5gY0sA...

3. Authentication Errors

❌ 401 — Missing Credentials
{
  "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."
    }
  }
}
❌ 401 — Invalid Credentials
{
  "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
PHP
Node.js
Python
Shell / cURL
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 (cURL)
<?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;
?>
Node.js (axios)
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));
Python (requests)
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())
❌ 403 — IP Not Allowed
{
  "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."
    }
  }
}
❌ 429 — Quota Exceeded
{
  "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."
    }
  }
}
🔐 Security Notes:
  • 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.

How to use Test Mode:
  • 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

Asynchronous Push

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.

🔐 Security & Integrity: All webhook requests are signed with an HMAC-SHA256 signature based on your Webhook Secret. You must verify this signature to ensure the request originated from ShippingEyes.
🛡️ Custom Security Headers: If your server (Firewall / API Gateway) requires specific security headers (like 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.
⚠️ Note: You cannot override reserved system headers (e.g., 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: ImmediatelyAttempt 2: After 1 minuteAttempt 3: After 5 minutesAttempt 4: After 15 minutesAttempt 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_id provided in the meta object as an idempotency key to ensure you do not process the same event twice in your system.
🚀
🔥 Hot Feature

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.

💡
Pro Tip for Merchants: You can fully control and customize this Rate Limit (from 10 up to 1000 requests/minute) directly from your Merchant Panel ➔ Webhook Settings to perfectly match your server's capacity!
⚠️ Strict Timeout:
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.
✅ Acknowledging Receipt (Required):
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.
⛔ No Redirects Followed:
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.
🌐 URL Security Requirements (SSRF Protection):
  • 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.
🌍 IP Whitelisting:
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.

🐘 PHP Verification
$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);
}
📦 Node.js (Express)
// ⚠️ 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.

📦 Payload Example
{
  "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.

📦 Payload Example
{
  "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.

📦 Payload Example
{
  "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.

📦 Payload Example
{
  "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.

📦 Payload Example
{
  "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.

📦 Payload Example
{
  "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