ShipPilot API Documentation
Integrate your store, ERP, or custom system with ShipPilot. Push orders programmatically, and fetch live courier tracking for any AWB shipped through ShipPilot.
https://app.shippilot.inThe Order Ingest API authenticates with two headers. Your Vendor ID (e.g. SKY123) and Shared Secret are generated when you enable the Custom Webhook / API channel in Settings → Channel Integrations.
| Field | Type | Notes |
|---|---|---|
| X-Shippilot-Vendor | header (string) | Your vendor ID, e.g. SKY123 |
| X-Shippilot-Signature | header (string) | Hex HMAC-SHA256 of the exact raw request body, keyed with your shared secret |
The signature must be computed over the exact bytes you send — compute it before sending, as shown below.
import crypto from "crypto";
const body = JSON.stringify(orderPayload); // exact string you send
const signature = crypto
.createHmac("sha256", SHARED_SECRET) // from Settings → Channel Integrations → Custom
.update(body)
.digest("hex");
await fetch("https://app.shippilot.in/api/public/orders/ingest", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Shippilot-Vendor": "SKY123",
"X-Shippilot-Signature": signature,
},
body,
});/api/public/orders/ingestCreates an order in the seller's ShipPilot account (status new → ready to dispatch). The call is idempotent: re-sending the same order_number returns the existing order instead of duplicating it.
| Field | Type | Notes |
|---|---|---|
| order_number * | string (≤64) | Unique per seller; used for idempotency |
| customer_name * | string (≤120) | Consignee full name |
| customer_phone * | string (6–20) | Delivery contact number |
| customer_email | string (email) | Optional |
| address1 * | string (≤255) | Street address line 1 |
| address2 | string (≤255) | Optional landmark / line 2 |
| city * | string (≤80) | Delivery city |
| state * | string (≤80) | Delivery state |
| pincode * | string (4–10) | 6-digit Indian pincode |
| payment_mode * | prepaid | cod | COD orders need cod_amount |
| cod_amount | number | Defaults to items total for COD |
| items * | array (1–50) | { sku?, name*, qty*, price* } per line item |
| weight_g | number (1–50000) | Default 500 |
| length_cm / breadth_cm / height_cm | number (1–200) | Default 10 each |
curl -X POST https://app.shippilot.in/api/public/orders/ingest \
-H "Content-Type: application/json" \
-H "X-Shippilot-Vendor: SKY123" \
-H "X-Shippilot-Signature: <hmac-sha256-hex>" \
-d '{
"order_number": "ORD-1001",
"customer_name": "Rahul Sharma",
"customer_phone": "9876543210",
"customer_email": "rahul@example.com",
"address1": "12, MG Road",
"address2": "Near Metro Station",
"city": "Bengaluru",
"state": "Karnataka",
"pincode": "560001",
"payment_mode": "cod",
"cod_amount": 1499,
"items": [
{ "sku": "TSHIRT-BLK-M", "name": "Cotton T-Shirt Black M", "qty": 1, "price": 1499 }
],
"weight_g": 400,
"length_cm": 30,
"breadth_cm": 25,
"height_cm": 4
}'{
"ok": true,
"order": { "id": "uuid", "order_number": "ORD-1001", "status": "new" }
}/api/public/trackPublic — no authentication required. Returns the current status, live scan timeline, and estimated delivery date for any AWB booked through ShipPilot. Status is synced from the courier (Delhivery, XpressBees, Shadowfax, Pikndel) on every call and cached in the background.
curl "https://app.shippilot.in/api/public/track?awb=57461410000210"
curl -X POST https://app.shippilot.in/api/public/track \
-H "Content-Type: application/json" \
-d '{ "awb": "57461410000210" }'{
"awb": "57461410000210",
"courier": "Delhivery",
"status": "delivered",
"edd": "2026-09-14T00:00:00.000Z",
"events": [
{
"status": "delivered",
"location": "Ludhiana",
"message": "Delivered to consignee",
"event_time": "2026-09-10T07:05:00.000Z"
}
]
}| Field | Type | Notes |
|---|---|---|
| status | string | new, ready_to_ship, manifested, in_transit, out_for_delivery, delivered, rto, ndr, cancelled |
| events[] | array | Newest first: status, location, message, event_time (ISO 8601 UTC) |
| edd | string | null | Estimated delivery date when provided by the courier |
404 — unknown AWB. Prefer embedding the customer-facing page instead: https://shippilot.in/track?awb={AWB}
When you connect the Custom Webhook / API channel you can optionally set a Status Webhook URL. ShipPilot pushes shipment status changes to that URL as they are received from couriers, so your system stays in sync without polling.
POST https://yourstore.com/webhooks/shippilot
Content-Type: application/json
{
"awb": "57461410000210",
"order_number": "ORD-1001",
"status": "delivered",
"courier": "Delhivery",
"event_time": "2026-09-10T07:05:00.000Z"
}ShipPilot also exposes a signed-in Model Context Protocol server at https://app.shippilot.in/mcp with tools to list orders & shipments, track any AWB, view wallet balance, and manage support tickets — usable from Claude, ChatGPT and other MCP clients after OAuth sign-in.
Need higher rate limits or a custom integration? Contact us.
