Shiplee
API Reference
Full logistics integration — authenticate, create orders, fetch rates, book, cancel and track shipments.https://apiv1.shiplee.app
Overview
The Shiplee API is a RESTful JSON interface for programmatic logistics management. All requests and responses use application/json unless noted.
- JWT authentication with per-seller IP and domain whitelisting
- Forward order creation with same or separate billing / shipping addresses
- Reverse order creation for customer returns and exchange pickups
- Live courier rate fetching with zone, weight-slab, and COD pricing
- Forward and reverse shipment booking across all major couriers
- Shipment cancellation with automatic wallet refund and re-booking support
- AWB-based shipment tracking with full scan event timeline
- Shipping label PDF generation with AWB barcode and branding
- Warehouse management for pickup and return destinations
All protected endpoints require Authorization: Bearer <token>. Tokens expire after 1 hour — re-authenticate via /login to refresh.
Authentication
Shiplee uses signed JWT tokens bound to your seller account. Every token encodes your user ID, email, and Shiplee ID.
- Register at app.shiplee.ai and generate an API key in API Settings.
- Whitelist your server IP address and request domain in API Settings.
- POST credentials to
/login— receive a JWT valid for 1 hour. - Pass
Authorization: Bearer <token>on every subsequent request.
Both IP and domain must be whitelisted. Requests from unknown origins return 403 Forbidden.
Login
Authenticates your credentials and returns a JWT token.
{
"username": "you@example.com",
"apikey": "your-api-key"
}curl -X POST https://apiv1.shiplee.app/login \
-H "Content-Type: application/json" \
-H "Origin: http://localhost" \
-d '{"username":"you@example.com","apikey":"your-api-key"}'$body = @{ username = "you@example.com"; apikey = "your-api-key" } | ConvertTo-Json
$headers = @{ "Content-Type" = "application/json"; "Origin" = "http://localhost" }
Invoke-RestMethod -Uri "https://apiv1.shiplee.app/login" -Method Post -Body $body -Headers $headers<?php
$ch = curl_init('https://apiv1.shiplee.app/login');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json','Origin: http://localhost'],
CURLOPT_POSTFIELDS => json_encode(['username'=>'you@example.com','apikey'=>'your-api-key']),
]);
echo curl_exec($ch); curl_close($ch);import requests
r = requests.post('https://apiv1.shiplee.app/login',
json={'username': 'you@example.com', 'apikey': 'your-api-key'},
headers={'Origin': 'http://localhost'})
token = r.json()['token']const { token } = await fetch('https://apiv1.shiplee.app/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'you@example.com', apikey: 'your-api-key' })
}).then(r => r.json());{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": { "id": 62, "email": "you@example.com", "shiplee_id": "d10701280b9798033c6917e9415b03c3" }
}Add Order
Creates a new forward order. Returns a numeric order_id used across all shipping endpoints.
{
"pincode": "560098", "city": "Bangalore", "state": "Karnataka",
"name": "John Doe", "email": "customer@example.com", "mobileNumber": "9000000001",
"addressLine1": "123 Sample Street, Apt 4B", "sameAddressCheckbox": 1,
"orderID": "ORD-123456", "paymentType": "prepaid",
"products": [{ "productName": "Sample Product", "quantity": 2, "productPrice": 500.00, "sku": "SKU123" }],
"parcels": [{ "length": 10, "breadth": 10, "height": 10, "physicalWeight": 1.5 }]
}Set sameAddressCheckbox to 0 and add billingPincode, billingName, etc. for separate billing addresses.
{ "success": true, "message": "Order added successfully", "order_id": 484900 }Reverse Order
Creates a reverse pickup order for a customer return or exchange.
Critical: orderId must be the numeric integer from /order (e.g. 484900). The warehouseId must belong to your account.
{
"orderId": 484900, "awbNumber": "XB1234567890", "reason": "Customer return — wrong size",
"warehouseId": 2147483833, "paymentType": "prepaid", "insurance": false,
"customer": { "name": "John Doe", "mobile": "9000000001", "address1": "123 Sample Street, Apt 4B",
"pincode": "560098", "city": "Bangalore", "state": "Karnataka" },
"products": [{ "productName": "Sample Product", "quantity": 1, "productPrice": 500.00, "sku": "SKU123" }],
"parcel": { "length": 10, "breadth": 10, "height": 10, "physicalWeight": 1.5 }
}{ "success": true, "message": "Reverse order created successfully", "reverse_order_id": "RO-7A685" }Get Rates
Returns available courier options with freight and COD charges for an existing order.
{ "orderId": 484900, "warehouseId": 2147483833, "shipmentType": "forward" }{
"success": true, "message": "Rates fetched successfully",
"data": { "carrier_info": [
{ "carrier_id": "delhivery_e_prepaid", "carrier_name": "Delhivery Express", "cost": 138, "freight_charges": 138, "cod_charges": 0, "tat": "2-3 days" },
{ "carrier_id": "delhivery_s_prepaid", "carrier_name": "Delhivery Surface", "cost": 104, "freight_charges": 104, "cod_charges": 0, "tat": "4-6 days" }
]}
}Create Shipment
Books a forward shipment for an existing order. Deducts charges from your wallet and returns the AWB number.
Minimum wallet balance of ₹500 required. Duplicate bookings for the same orderId are rejected automatically.
{
"orderId": 484900, "warehouseId": 2147483833, "action": "book_shipment",
"carrierId": "delhivery_e_prepaid", "carrierName": "Delhivery Express", "shipmentType": "forward"
}{ "success": true, "message": "Shipment booked", "awb_number": "XB1234567890", "shipment_id": "SHPL-54321" }Cancel Shipment
Cancels one or more booked shipments by AWB. Calls the courier's own cancellation API, deletes the booking record, credits the full shipping charge back to your wallet, and either resets the order for re-booking or marks it permanently cancelled.
Only cancellable statuses: Orders must be in booked or manifested state. Already delivered, RTO, or new orders will be rejected. If any AWB in a batch fails the ownership or status check the entire request is rejected.
The cancel is atomic — if the courier API call succeeds but any DB step fails, the entire transaction is rolled back and the courier cancellation is logged for manual review.
{
"awb": "XB1234567890",
"action": "cancel"
}{
"awbs": ["XB1234567890", "37574910074362"],
"action": "delete"
}| Field | Type | Required | Description |
|---|---|---|---|
awb | string | optional* | Single AWB to cancel. Alphanumeric + _-, max 50 chars. |
awbs | array | optional* | Array of AWB strings. Max 50 per request. |
action | string | optional | cancel (default) or delete — see table below. |
* Provide either awb or awbs — at least one is required.
| action | Order status after cancel | Can re-book? | Use case |
|---|---|---|---|
cancel | new | ✅ Yes | Wrong courier / address — want to re-book immediately |
delete | cancelled | ❌ No | Order genuinely cancelled by customer |
- JWT + IP whitelist verified
- Every AWB checked — must belong to your account and be in
booked/manifestedstate - Courier cancel API called (auto-detected: Delhivery → XpressBees → Amazon → SmartShip)
- Row deleted from
orderstable customer_info.statusupdated toneworcancelled- Full shipping charge credited back to your wallet
- Entry added to
RechargeLogs(Credit) andShippingCharges(status = cancelled) - Full audit trail written to
CancelDeleteLogs - Entire batch rolled back if any step fails
# Cancel single — reset to new (re-bookable)
curl -X POST https://apiv1.shiplee.app/cancel_shipment \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"awb":"XB1234567890","action":"cancel"}'
# Delete bulk — permanently cancelled
curl -X POST https://apiv1.shiplee.app/cancel_shipment \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"awbs":["XB1234567890","37574910074362"],"action":"delete"}'<?php
// Cancel single AWB — reset to new so you can re-book
$ch = curl_init('https://apiv1.shiplee.app/cancel_shipment');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer YOUR_JWT_TOKEN',
],
CURLOPT_POSTFIELDS => json_encode([
'awb' => 'XB1234567890',
'action' => 'cancel', // resets to 'new' — re-bookable
]),
]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($res['success']) {
echo "Cancelled. Refunded: " . $res['refunded_count'] . " shipment(s).";
// Order is now 'new' — call /rates then /create_shipment to re-book
} else {
echo "Error: " . $res['message'];
}import requests
headers = {'Authorization': 'Bearer YOUR_JWT_TOKEN'}
# Cancel single — re-bookable
r = requests.post('https://apiv1.shiplee.app/cancel_shipment',
json={'awb': 'XB1234567890', 'action': 'cancel'},
headers=headers)
print(r.json())
# {'success': True, 'message': 'Shipment(s) cancelled and reset to new...', 'refunded_count': 1}
# Cancel bulk — permanently deleted
r2 = requests.post('https://apiv1.shiplee.app/cancel_shipment',
json={'awbs': ['XB1234567890', '37574910074362'], 'action': 'delete'},
headers=headers)
print(r2.json())// Cancel and re-book flow
async function cancelAndRebook(awb, orderId, warehouseId) {
// Step 1 — cancel
const cancel = await fetch('https://apiv1.shiplee.app/cancel_shipment', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_JWT_TOKEN' },
body: JSON.stringify({ awb, action: 'cancel' }),
}).then(r => r.json());
if (!cancel.success) throw new Error(cancel.message);
// Step 2 — get new rates
const rates = await fetch('https://apiv1.shiplee.app/rates', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_JWT_TOKEN' },
body: JSON.stringify({ orderId, warehouseId, shipmentType: 'forward' }),
}).then(r => r.json());
const carrier = rates.data.carrier_info[0]; // pick cheapest
// Step 3 — re-book with new carrier
const booking = await fetch('https://apiv1.shiplee.app/create_shipment', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_JWT_TOKEN' },
body: JSON.stringify({
orderId, warehouseId, action: 'book_shipment',
carrierId: carrier.carrier_id, carrierName: carrier.carrier_name,
shipmentType: 'forward',
}),
}).then(r => r.json());
return booking; // { success: true, awb_number: 'NEW_AWB', ... }
}{
"success": true,
"message": "Shipment(s) cancelled and reset to new. You can re-book them.",
"refunded_count": 1
}{ "success": false, "message": "Missing Authorization header" }
{ "success": false, "message": "Invalid JWT token" }
{ "success": false, "message": "User account not active" }
{ "success": false, "message": "The IP '1.2.3.4' is not whitelisted" }
{ "success": false, "message": "Provide \"awb\" (string) or \"awbs\" (array)" }
{ "success": false, "message": "Invalid action: must be \"cancel\" or \"delete\"" }
{ "success": false, "message": "Maximum 50 AWBs per request" }
{ "success": false, "message": "One or more AWBs not found, do not belong to your account, or are not in a cancellable state (must be booked/manifested)" }
{ "success": false, "message": "Delhivery cancel failed for AWB XB1234567890: ..." }
{ "success": false, "message": "Internal server error" }Re-booking flow: After a successful action: "cancel", the order is back in new state. Call /rates with the same orderId + warehouseId, pick a carrier, then call /create_shipment to get a fresh AWB — no need to recreate the order.
Reverse Shipment
Books a Delhivery pickup for an existing reverse order. Request body is application/x-www-form-urlencoded.
order_id=1042&warehouse_id=2147483833&carrierId=delhivery_e_prepaid&carrierName=Delhivery+Express{ "success": true, "message": "Reverse shipment booked", "awb_number": "1234567890123", "shipment_id": "UPLOAD_WBN_ABC" }Track Shipment
Returns the full tracking timeline for a shipment by AWB number. Sellers can only query AWBs belonging to their own account.
{
"data": {
"orderNumber": "122", "orderStatus": "Manifested", "orderStatusCode": "manifested",
"trackingNumber": "80905112190", "carrierName": "Blue Dart- Apex",
"paymentType": "cod", "orderValue": 1450, "weightGrams": 500,
"trackingDetails": [
{ "scanStatus": "SHIPMENT DELIVERED", "scanLocation": "KATARGAM OFFICE", "scanDateTime": "2025-09-27 16:31:00", "message": "delivered" }
]
}, "errorMessage": null
}Generate Label
Generates a shipping label PDF for one or more AWBs. Returns a binary PDF stream (application/pdf) ready for download or direct printing.
Security: Every AWB is verified against your seller account. If any AWB belongs to another seller the entire request is rejected with 403.
Response Content-Type is application/pdf on success and application/json on error — check the header before parsing.
{ "awb": "80905112190" }{ "awbs": ["80905112190", "XB1234567890", "1234567890123"] }curl -X POST https://apiv1.shiplee.app/label \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"awb":"80905112190"}' --output label.pdf<?php
$ch = curl_init('https://apiv1.shiplee.app/label');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,
CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer YOUR_JWT_TOKEN'],
CURLOPT_POSTFIELDS=>json_encode(['awb'=>'80905112190'])]);
$res = curl_exec($ch);
$ct = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch);
if (str_contains($ct,'application/pdf')) { file_put_contents('label.pdf',$res); echo "Saved."; }
else { echo json_decode($res,true)['message']; }import requests
r = requests.post('https://apiv1.shiplee.app/label',
json={'awb': '80905112190'},
headers={'Authorization': 'Bearer YOUR_JWT_TOKEN'})
if r.headers.get('Content-Type','').startswith('application/pdf'):
open('label.pdf','wb').write(r.content)
else: print(r.json()['message'])const res = await fetch('https://apiv1.shiplee.app/label', {
method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer YOUR_JWT_TOKEN'},
body: JSON.stringify({ awb: '80905112190' })
});
if (res.headers.get('Content-Type')?.includes('application/pdf')) {
const a = Object.assign(document.createElement('a'),
{href: URL.createObjectURL(await res.blob()), download:'label.pdf'});
a.click();
}| Setting | Effect when enabled |
|---|---|
hide_cust_name | Removes consignee name |
hide_cust_mobile | Removes consignee phone |
hide_wh_name | Removes warehouse name |
hide_wh_address | Removes warehouse address |
hide_wh_mobile | Removes warehouse phone |
hide_product | Removes product list |
hide_sku | Removes SKU from products |
hide_quantity | Removes quantity from products |
hide_order_amount | Hides ₹ amount (COD/PREPAID still shown) |
{ "success": false, "message": "Forbidden: one or more AWBs do not belong to your account" }
{ "success": false, "message": "No valid orders found for the provided AWB(s)" }
{ "success": false, "message": "Maximum 50 AWBs per request" }Warehouse Management
Warehouses are your pickup and return destinations. Register new locations or list existing ones.
{
"nickname": "Main Warehouse", "mobileNumber": "9000000001",
"address1": "123 Logistics Road", "pincode": "110076",
"city": "New Delhi", "state": "Delhi", "addressType": "primary"
}Returns all active warehouses for the authenticated seller.
{
"success": true, "message": "Warehouses retrieved successfully",
"data": [{ "id": 2147483833, "nickname": "Main Warehouse", "address1": "123 Logistics Road",
"pincode": "110076", "city": "New Delhi", "state": "Delhi", "addressType": "primary" }]
}Support
Reach the Shiplee technical team through any of these channels:
| Channel | Contact |
|---|---|
| support@shiplee.app | |
| +91 86453 22815 | |
| Dashboard | app.shiplee.ai |