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..." \
  -d '{
    "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,
      "delivery_cost": 50,
      "cod": 300,
      "shipping_cost_type": 1
    }
  }'
🐘 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...',
        'Accept'       => 'application/json',
    ],
    'json' => [
        'shipping_service' => 'srv8gJ',
        'shipment_info' => [
            'pieces' => 1,
            'description' => 'Electronics package',
            'order_type' => 1,
            'delivery_type' => 1
        ],
        'recipient' => [
            'name' => 'Ahmed Hassan',
            'phone' => '0910000000',
            'to_city' => 'lejRej',
            'to_place' => 'mep2bM'
        ],
        'financial_info' => [
            'amount' => 250,
            'amount_type' => 1
        ]
    ]
]);

$data = json_decode($response->getBody(), true);
📦 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...',
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify({
            shipping_service: 'srv8gJ',
            shipment_info: { pieces: 1, order_type: 1 },
            recipient: { name: 'Ahmed Hassan', phone: '0910000000', to_city: 'lejRej' },
            financial_info: { amount: 250, amount_type: 1 }
        })
    });
    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 New Order created but not yet processed Merchant Office
2 Processing Order confirmed and being prepared Warehouse
10 Picked Up Package collected from merchant In Transit
20 At Branch Package arrived at destination branch Local Sorting
22 Out for Delivery Delegate is delivering to customer Final Mile
30 Delivered Package delivered and paid Completed
40 Returned Order rejected/returned to merchant Closed
50 Cancelled Order cancelled before pickup Closed

🔢 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
How Authentication Works

Unlike the mobile app API that uses Bearer tokens (login + password), the Public API uses 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://api.shippingeyes.com/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://api.shippingeyes.com/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://api.shippingeyes.com/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://api.shippingeyes.com/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.created

Sync inventory the moment an order hits our system.

🚚
order.dispatched

Notify your customers immediately when the courier leaves.

order.delivered

Trigger automated reviews or loyalty points instantly.

🔄
order.updated

Real-time tracking for every step of the journey.

🚀 Marketing Edge: Why 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.

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

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

🛠️ Webhook Delivery Architecture

Our webhook engine is built for reliability and high performance:

  • Queue-Based: Events are dispatched to a background queue to ensure instant response times.
  • Retry Policy: If your server is down or returns a non-2xx status, we automatically retry the delivery multiple times using an exponential backoff strategy.
  • Auto-Disable: To protect our system, webhooks that repeatedly fail are automatically disabled. Ensure your endpoint is stable and returns a 2xx status promptly.

🔐 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'] ?? '';
$secret = 'your_webhook_secret_here';

$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (hash_equals($expected, $signature)) {
    // ✅ Valid request
    $data = json_decode($payload, true);
} else {
    // ❌ Invalid signature
    http_response_code(401);
}
📦 Node.js (Express)
const crypto = require('crypto');

app.post('/webhook', (req, res) => {
    const signature = req.headers['shippingeyes-webhook-signature'];
    const secret = 'your_webhook_secret_here';
    const payload = JSON.stringify(req.body);

    const expected = 'sha256=' + crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');

    // Timing-safe comparison
    const signatureBuffer = Buffer.from(signature || '', 'utf8');
    const expectedBuffer = Buffer.from(expected, 'utf8');

    if (signatureBuffer.length === expectedBuffer.length && 
        crypto.timingSafeEqual(signatureBuffer, expectedBuffer)) {
        res.status(200).send('OK');
    } else {
        res.status(401).send('Unauthorized');
    }
});

📅 Event Catalog

The following events are currently supported by the ShippingEyes platform:

🔔 order.status_updated

Triggered whenever an order's status changes (e.g., from "New" to "Out for Delivery").

📦 Payload Example
{
  "event": "order.status_updated",
  "timestamp": 1714838400,
  "uuid": "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"
  }
}

💬 order.followup_recorded

Triggered when a new followup or note is added to an order by the delivery agent or customer service.

📦 Payload Example
{
  "event": "order.followup_recorded",
  "timestamp": 1714838400,
  "uuid": "660f9500-f39c-52d5-b817-557766551111",
  "data": {
    "order_snum": 10042,
    "followup_type": "followup",
    "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
{
  "event": "catalog.shipping_pricing_updated",
  "timestamp": 1714838400,
  "uuid": "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
{
  "event": "platform.configuration_updated",
  "timestamp": 1714838400,
  "uuid": "880h1700-h51e-74f7-d039-779988773333",
  "data": {
    "message": "Orders creation settings have been updated",
    "updated_at": "2026-05-04T16:30:00Z"
  }
}