Developers

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.

Base URL: https://app.shippilot.in
Authentication

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

FieldTypeNotes
X-Shippilot-Vendorheader (string)Your vendor ID, e.g. SKY123
X-Shippilot-Signatureheader (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.

signing example (Node.js)
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,
});
Create an order
POST
/api/public/orders/ingest

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

FieldTypeNotes
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_emailstring (email)Optional
address1 *string (≤255)Street address line 1
address2string (≤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 | codCOD orders need cod_amount
cod_amountnumberDefaults to items total for COD
items *array (1–50){ sku?, name*, qty*, price* } per line item
weight_gnumber (1–50000)Default 500
length_cm / breadth_cm / height_cmnumber (1–200)Default 10 each
example request
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
  }'
success 201
{
  "ok": true,
  "order": { "id": "uuid", "order_number": "ORD-1001", "status": "new" }
}
200 + duplicate — order_number already exists; existing order returned.
400 — missing vendor header or payload validation failed (details included).
401 — bad signature. 403 — custom channel not enabled. 404 — unknown vendor.
Track a shipment
GET
POST
/api/public/track

Public — 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.

GET
curl "https://app.shippilot.in/api/public/track?awb=57461410000210"
POST
curl -X POST https://app.shippilot.in/api/public/track \
  -H "Content-Type: application/json" \
  -d '{ "awb": "57461410000210" }'
success 200
{
  "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"
    }
  ]
}
FieldTypeNotes
statusstringnew, ready_to_ship, manifested, in_transit, out_for_delivery, delivered, rto, ndr, cancelled
events[]arrayNewest first: status, location, message, event_time (ISO 8601 UTC)
eddstring | nullEstimated delivery date when provided by the courier

404 — unknown AWB. Prefer embedding the customer-facing page instead: https://shippilot.in/track?awb={AWB}

Status callbacks (webhook)

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.

example payload
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"
}
AI agent integration (MCP)

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.