Introduction
The Parcel Uncle Merchant API provides programmatic access to manage your logistics operations. Build directly into your storefront, ERP, or custom dashboard.
Base URL: https://parceluncle.com/carrier/v1/merchant/
All requests must be made over HTTPS. Responses are served in JSON format. We provide both Sandbox (TEST) and Production (LIVE) environments accessible through different API keys.
Authentication
Authenticate your API requests by including your API key in the X-API-Key header. You can manage your API keys in the Developer section of your Seller Dashboard.
Sandbox Mode
Keys prefixed with pu_test_. Actions are simulated and no real wallet deductions occur. COD is forced.
Live Mode
Keys prefixed with pu_live_. Actions are real and shipments will be dispatched. Wallet/Credit deductions apply.
curl -X GET https://parceluncle.com/carrier/v1/merchant/shipments/ \
-H "X-API-Key: pu_live_1234567890abcdef1234567890abcdef1234567890abcdef"
Rate Limits
To ensure service stability, API requests are rate-limited per API key on a 1-minute sliding window. If you exceed the limit, you will receive a 429 Too Many Requests response.
| Key Type | General Endpoints | Tracking Endpoint |
|---|---|---|
| Live (Production) | 500 req / min | 120 req / min |
| Test (Sandbox) | 60 req / min | 120 req / min |
Serviceability Check
/carrier/v1/merchant/serviceability/?pincode={pincode}
Check if Parcel Uncle provides delivery services to a specific pincode. Unauthenticated requests are allowed for this endpoint if you provide a valid API key.
Query Parameters
pincodeRequired — The 6-digit postal code to check.
curl -X GET "https://parceluncle.com/carrier/v1/merchant/serviceability/?pincode=110014" \
-H "X-API-Key: pu_live_..."
{
"success": true,
"data": {
"pincode": "110014",
"is_serviceable": true,
"city": "South Delhi"
}
}
Rate Quote
/carrier/v1/merchant/rates/
Calculate estimated shipping costs before creating a shipment. Prices vary based on service type, weight, and distance.
Payload Details
service_type: "SAME_DAY" | "NEXT_DAY" | "EXPRESS_4H"weight_kg: floatpickup_pincode: stringdelivery_pincode: stringis_cod: boolean (optional)distance_km: float (optional)length_cm,width_cm,height_cm: float (optional)
{
"success": true,
"data": {
"service_type": "EXPRESS_4H",
"currency": "INR",
"total": "145.50",
"breakdown": {
"distance_charge": 100,
"weight_charge": 25,
"gst_amount": 20.50
},
"sandbox": false
}
}
Create Shipment
/carrier/v1/merchant/shipments/
Create a new shipment request. This will instantly deduct funds from your Wallet or Credit Line if in LIVE mode.
payment_mode, order_number, and total_amount for a cleaner integration. These fields are optional and fully backward-compatible — existing integrations continue to work without changes.
New Optional Fields
| Field | Type | Required | Description |
|---|---|---|---|
order_number |
string | Optional | Your own order reference number (e.g., Shopify order ID) |
payment_mode |
"COD" | "Prepaid" | Optional | Controls whether the recipient pays on delivery (COD) or the order is already paid (Prepaid) |
total_amount |
number | Required if payment_mode | Complete order value (must be > 0) |
cod_amount |
number | Required if COD | Amount to collect from recipient. Must be > 0 for COD, must be 0 for Prepaid. |
- If
payment_modeis"COD":cod_amountis mandatory and must be > 0. The rider will collect this amount from the recipient. - If
payment_modeis"Prepaid":cod_amountmust be 0. The order is already paid by the customer. total_amountshould always contain the complete order value.payment_method(WALLET/CREDIT/COD) controls how you pay Parcel Uncle for shipping.
Example: COD Order
{
"service_type": "SAME_DAY",
"payment_method": "COD",
"payment_mode": "COD",
"order_number": "ORD-2024-001",
"total_amount": 800,
"cod_amount": 800,
"pickup_address": "114/7, Second Floor, Hari Nagar Ashram",
"pickup_city": "New Delhi",
"pickup_state": "Delhi",
"pickup_pincode": "110014",
"delivery_address": "A-42, Sector 4",
"delivery_city": "Noida",
"delivery_state": "UP",
"delivery_pincode": "201301",
"sender_name": "Lekya Store",
"sender_phone": "9876543210",
"recipient_name": "John Doe",
"recipient_phone": "9998887776",
"weight_kg": 1.5,
"parcel_type": "PACKAGE"
}
Example: Prepaid Order
{
"service_type": "SAME_DAY",
"payment_method": "WALLET",
"payment_mode": "Prepaid",
"order_number": "ORD-2024-002",
"total_amount": 800,
"cod_amount": 0,
"pickup_address": "114/7, Second Floor, Hari Nagar Ashram",
"pickup_city": "New Delhi",
"pickup_state": "Delhi",
"pickup_pincode": "110014",
"delivery_address": "A-42, Sector 4",
"delivery_city": "Noida",
"delivery_state": "UP",
"delivery_pincode": "201301",
"sender_name": "Lekya Store",
"sender_phone": "9876543210",
"recipient_name": "John Doe",
"recipient_phone": "9998887776",
"weight_kg": 1.5,
"parcel_type": "PACKAGE"
}
WALLET to debit from prepaid balance, CREDIT for post-paid credit line, or COD for Cash on Delivery. If COD is selected, you must also provide cod_amount.
Success Response (201 Created)
{
"success": true,
"sandbox": false,
"message": "Shipment created successfully",
"data": {
"tracking_number": "AWB987654321",
"status": "PAID",
"service_type": "SAME_DAY",
"payment_method": "WALLET",
"is_cod": false,
"cod_amount": "0.00",
"shipment_amount": "145.50",
"order_number": "ORD-2024-002",
"payment_mode": "Prepaid",
"total_amount": "800.00",
"pickup": {
"address": "114/7, Second Floor, Hari Nagar Ashram",
"city": "New Delhi",
"state": "Delhi",
"pincode": "110014",
"landmark": ""
},
"delivery": {
"address": "A-42, Sector 4",
"city": "Noida",
"state": "UP",
"pincode": "201301",
"landmark": ""
},
"sender": {
"name": "Lekya Store",
"phone": "9876543210",
"email": ""
},
"recipient": {
"name": "John Doe",
"phone": "9998887776",
"email": ""
},
"parcel": {
"type": "PACKAGE",
"weight_kg": "1.50",
"length_cm": null,
"width_cm": null,
"height_cm": null
},
"cost_breakdown": {
"distance_charge": 100,
"weight_charge": 25,
"gst_amount": 20.50
},
"assigned_rider": null,
"special_instructions": "",
"created_at": "2024-05-10T10:00:00Z",
"updated_at": "2024-05-10T10:00:00Z",
"delivered_at": null
}
}
order_number, payment_mode ("COD" or "Prepaid"), and total_amount. These are returned for all shipments, even those created without these fields (they will default to empty/null/derived values).
List Shipments
/carrier/v1/merchant/shipments/
Retrieve a paginated list of shipments associated with your account.
Query Parameters
page: Page number (default: 1)limit: Items per page (default: 20, max: 100)status: Filter by status (e.g.DELIVERED)date_from/date_to: Filter by creation date (YYYY-MM-DD)
{
"success": true,
"pagination": {
"total": 142,
"page": 1,
"page_size": 20,
"total_pages": 8,
"has_next": true,
"has_previous": false
},
"data": [
{
"tracking_number": "AWB123456789",
"status": "DELIVERED",
"service_type": "SAME_DAY",
"payment_method": "WALLET",
"is_cod": false,
"cod_amount": "0.00",
"shipment_amount": "145.50",
"order_number": "ORD-2024-001",
"payment_mode": "Prepaid",
"total_amount": "800.00",
"created_at": "2024-05-10T10:00:00Z"
}
]
}
Get Shipment
/carrier/v1/merchant/shipments/{tracking_number}/
Retrieve the full details of a specific shipment using its tracking number.
Path Parameters
tracking_numberRequired — The unique AWB/tracking number of the shipment.
{
"success": true,
"data": {
"tracking_number": "AWB123456789",
"status": "DELIVERED",
"service_type": "SAME_DAY",
"payment_method": "COD",
"is_cod": true,
"cod_amount": "800.00",
"shipment_amount": "145.50",
"order_number": "ORD-2024-001",
"payment_mode": "COD",
"total_amount": "800.00",
"pickup": {
"address": "114/7, Second Floor, Hari Nagar Ashram",
"city": "New Delhi",
"state": "Delhi",
"pincode": "110014",
"landmark": ""
},
"delivery": {
"address": "A-42, Sector 4",
"city": "Noida",
"state": "UP",
"pincode": "201301",
"landmark": ""
},
"sender": {
"name": "Lekya Store",
"phone": "9876543210",
"email": ""
},
"recipient": {
"name": "John Doe",
"phone": "9998887776",
"email": ""
},
"parcel": {
"type": "PACKAGE",
"weight_kg": "1.50",
"length_cm": null,
"width_cm": null,
"height_cm": null
},
"cost_breakdown": {
"distance_charge": 100,
"weight_charge": 25,
"gst_amount": 20.50
},
"assigned_rider": "Ramesh Kumar",
"special_instructions": "",
"delivery_proofs": [
{
"url": "https://parceluncle.com/media/shipments/proofs/proof_001.jpg",
"uploaded_at": "2024-05-10T16:30:00Z"
}
],
"created_at": "2024-05-10T10:00:00Z",
"updated_at": "2024-05-10T16:45:00Z",
"delivered_at": "2024-05-10T16:30:00Z"
}
}
Track Shipment
/carrier/v1/merchant/shipments/{tracking_number}/track/
Retrieve the real-time tracking timeline and current status of a specific shipment. Perfect for embedding tracking directly into your frontend.
{
"success": true,
"data": {
"tracking_number": "AWB123456789",
"current_status": "OUT_FOR_DELIVERY",
"description": "Out for delivery",
"is_delivered": false,
"rider": {
"name": "Ramesh Kumar"
},
"delivery_proofs": [
{
"url": "https://parceluncle.com/media/shipments/proofs/proof_001.jpg",
"uploaded_at": "2024-05-10T16:30:00Z"
}
],
"timeline": [
{
"status": "CREATED",
"description": "Order created and awaiting processing",
"timestamp": "2024-05-10T10:00:00Z",
"note": "Created via Merchant API v1 [LIVE]"
},
{
"status": "PICKED_UP",
"description": "Parcel picked up by rider",
"timestamp": "2024-05-10T12:30:00Z",
"note": ""
}
]
}
}
Tracking Status Codes
Every shipment moves through the following statuses. Use these codes to map your internal tracking system with Parcel Uncle's tracking updates.
| Status Code | Display Name | Description | Terminal? |
|---|---|---|---|
| First Mile | |||
CREATED |
Created | Order created and awaiting processing. | — |
PENDING |
Pending Payment | Awaiting payment confirmation. | — |
PAID |
Payment Confirmed | Payment received. Shipment queued for processing. | — |
READY_TO_SHIP |
Ready to Ship | Seller has packed the order, awaiting pickup. | — |
ASSIGNED |
Assigned to Rider | A rider has been assigned for pickup. | — |
ACCEPTED |
Accepted by Rider | Rider accepted and is heading to pickup location. | — |
WAITING_PICKUP |
Waiting for Pickup | Rider arrived at pickup location, waiting for parcel. | — |
PICKUP_ATTEMPTED |
Pickup Attempted | Rider tried to collect but couldn't (seller absent, not ready). | — |
PICKED_UP |
Picked Up | Parcel collected by rider from pickup location. | — |
| Mid Mile | |||
ARRIVED_AT_HUB |
Arrived at Hub | Parcel scanned at sorting hub. Hub name shown in timeline notes. | — |
SORTING |
Sorting in Progress | Parcel is being sorted at hub for next destination. | — |
IN_TRANSIT |
In Transit | Parcel moving between hubs. May repeat for multi-hub routes. | — |
| Last Mile | |||
OUT_FOR_DELIVERY |
Out for Delivery | Delivery rider heading to recipient address. | — |
DELIVERY_ATTEMPTED |
Delivery Attempted | Delivery tried but recipient unavailable. Creates NDR entry. | — |
DELIVERED |
Delivered | Successfully delivered to recipient. | ✓ Final |
| Returns (RTO) | |||
RTO_INITIATED |
RTO Initiated | Return to origin process started. | — |
RTO_IN_TRANSIT |
RTO In Transit | Return shipment is moving back to seller. | — |
RETURNED |
Returned | Parcel returned to seller. | ✓ Final |
| Exceptions | |||
FAILED |
Delivery Failed | All delivery attempts exhausted. Can be reattempted or RTO'd. | — |
ON_HOLD |
On Hold | Shipment paused by operations. Contact support. | — |
DAMAGED |
Damaged | Parcel reported as damaged during transit or handling. | — |
LOST |
Lost | Shipment lost — investigation in progress. | ✓ Final |
CANCELLED |
Cancelled | Shipment cancelled before delivery. | ✓ Final |
Direct Delivery Flow
Hub-Based / Multi-Hub Flow
ARRIVED_AT_HUB ↔ IN_TRANSIT can repeat for multi-hub routes. Hub name is in the timeline note.
RTO (Return) Flow
timeline array from the Track endpoint for the actual sequence of events.
DELIVERED, RETURNED, CANCELLED, or LOST, no further transitions occur.
NDR List
NEW/carrier/v1/merchant/ndr/
Retrieve all Non-Delivery Report (NDR) entries for your shipments. NDR entries are created when a delivery attempt fails.
Query Parameters
status: Filter by NDR status —OPEN,ACTION_TAKEN,RESOLVED,ESCALATEDaction: Filter by action taken —PENDING,REATTEMPT,RTO,ADDRESS_UPDATE,HOLD
curl -X GET "https://parceluncle.com/carrier/v1/merchant/ndr/?status=OPEN" \
-H "X-API-Key: pu_live_..."
{
"success": true,
"data": [
{
"ndr_id": "a1b2c3d4-...",
"tracking_number": "PU1234567890",
"attempt_number": 1,
"reason": "RECIPIENT_UNAVAILABLE",
"reason_detail": "Customer not at home",
"rider_remarks": "Called twice, no answer",
"status": "OPEN",
"action": "PENDING",
"action_taken_at": null,
"reattempt_date": null,
"reattempt_slot": "",
"updated_address": "",
"updated_phone": "",
"created_at": "2024-05-10T16:45:00Z"
}
]
}
NDR Reason Codes
| Code | Description |
|---|---|
RECIPIENT_UNAVAILABLE | Recipient not available at delivery address |
ADDRESS_INCORRECT | Incorrect delivery address |
ADDRESS_INCOMPLETE | Incomplete address details |
REFUSED | Delivery refused by recipient |
DOOR_LOCKED | Door locked / no response |
COD_NOT_READY | COD amount not ready with recipient |
RESCHEDULE_REQUESTED | Customer requested reschedule |
WEATHER | Weather conditions prevented delivery |
SECURITY_ISSUE | Security restriction at location |
OTHER | Other reason (see reason_detail) |
NDR Action
NEW/carrier/v1/merchant/ndr/{tracking_number}/action/
Take action on an open NDR case. You can reattempt delivery, update the address, or initiate a Return to Origin (RTO).
Available Actions
| Action | Required Fields | Description |
|---|---|---|
REATTEMPT |
reattempt_date (YYYY-MM-DD), reattempt_slot (optional) |
Schedule a re-delivery attempt on the specified date |
ADDRESS_UPDATE |
updated_address (required), updated_phone (optional) |
Update the delivery address and reattempt |
RTO |
remarks (optional) |
Return the parcel to the sender (Return to Origin) |
Example: Reattempt Delivery
curl -X POST "https://parceluncle.com/carrier/v1/merchant/ndr/PU1234567890/action/" \
-H "X-API-Key: pu_live_..." \
-H "Content-Type: application/json" \
-d '{
"action": "REATTEMPT",
"reattempt_date": "2024-05-12",
"reattempt_slot": "10AM-1PM"
}'
{
"success": true,
"message": "NDR action REATTEMPT applied successfully",
"data": {
"ndr_id": "a1b2c3d4-...",
"tracking_number": "PU1234567890",
"attempt_number": 1,
"reason": "RECIPIENT_UNAVAILABLE",
"status": "ACTION_TAKEN",
"action": "REATTEMPT",
"action_taken_at": "2024-05-11T08:30:00Z",
"reattempt_date": "2024-05-12",
"reattempt_slot": "10AM-1PM"
}
}
Example: Update Address
{
"action": "ADDRESS_UPDATE",
"updated_address": "B-15, Block C, Sector 62, Noida, UP 201309",
"updated_phone": "9876543210"
}
Example: Return to Origin
{
"action": "RTO",
"remarks": "Customer refused delivery"
}
OPEN NDR cases can have actions taken on them. If no open NDR exists for the shipment, the API will return a 404 error.
Cancel Shipment
/carrier/v1/merchant/shipments/{tracking_number}/cancel/
Cancel a shipment and receive a wallet refund. The behavior depends on whether a rider has been assigned:
No Rider Assigned
- Instant cancellation
- Full wallet refund (auto-approved)
- Returns
200 OK
Rider Assigned
- Cancellation request created
- Admin reviews & decides refund (full/partial/none)
- Returns
202 Accepted
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
reason |
string | Yes | Reason for cancelling the shipment |
Cancellable Statuses
CREATED
PENDING
PAID
ASSIGNED
ACCEPTED
Example: Instant Cancel (No Rider)
curl -X POST "https://parceluncle.com/carrier/v1/merchant/shipments/PU1234567890/cancel/" \
-H "X-API-Key: pu_live_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Customer changed delivery address"
}'
{
"success": true,
"data": {
"tracking_number": "PU1234567890",
"status": "CANCELLED",
"cancellation_status": "AUTO_APPROVED",
"refund_type": "FULL",
"refund_amount": "149.00",
"message": "Shipment cancelled successfully. Full refund processed.",
"sandbox": false
}
}
Example: Pending Review (Rider Assigned)
curl -X POST "https://parceluncle.com/carrier/v1/merchant/shipments/PU9876543210/cancel/" \
-H "X-API-Key: pu_live_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Order cancelled by buyer"
}'
{
"success": true,
"data": {
"tracking_number": "PU9876543210",
"status": "ASSIGNED",
"cancellation_status": "PENDING",
"rider_assigned": "Rahul Sharma",
"message": "Rider \"Rahul Sharma\" is assigned. Cancellation request submitted for admin review.",
"sandbox": false
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
tracking_number |
string | Tracking number of the shipment |
status |
string | CANCELLED (instant) or the current status (pending review) |
cancellation_status |
string | AUTO_APPROVED (no rider) or PENDING (rider assigned, awaiting admin) |
refund_type |
string | FULL, PARTIAL, or NONE. Only present for auto-approved. |
refund_amount |
string | Refund amount credited to wallet. Only present for auto-approved. |
rider_assigned |
string | Name of assigned rider. Only present when status is PENDING. |
PICKED_UP, IN_TRANSIT, OUT_FOR_DELIVERY, DELIVERED, FAILED, RETURNED, or CANCELLED cannot be cancelled via this endpoint. The API will return 400 Bad Request.
Get Shipping Label
/carrier/v1/merchant/shipments/{tracking_number}/label/
Download a print-ready 4×6 inch PDF shipping label for any shipment. The label includes sender/recipient addresses, QR code for tracking, barcode, weight, dimensions, COD badge, and SKU details if available.
Path Parameters
tracking_numberRequired — The AWB/tracking number of the shipment.
Content-Type header will be application/pdf.
curl -X GET "https://parceluncle.com/carrier/v1/merchant/shipments/PU1234567890/label/" \
-H "X-API-Key: pu_live_..." \
--output Label-PU1234567890.pdf
Label Contents
- Header: Parcel Uncle logo + QR code for live tracking
- Tracking ID: Bold tracking number
- From / To: Full sender and recipient addresses with phone numbers
- Parcel Info: Weight, dimensions, service type
- SKU Items: Item table with SKU, quantity, price (if available)
- Payment: Payment method + COD amount badge
- Barcode: Scannable barcode of the tracking number
| Status Code | Meaning |
|---|---|
200 OK |
PDF label returned as binary download |
404 Not Found |
Shipment not found or doesn't belong to your account |
500 Error |
PDF generation failed (rare) |
Webhooks
Receive real-time notifications when shipment events occur. Register a webhook URL and we'll POST event payloads to it automatically.
Configure Webhook URL
PUT /carrier/v1/merchant/webhook/
curl -X PUT "https://parceluncle.com/carrier/v1/merchant/webhook/" \
-H "X-API-Key: pu_live_..." \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://yoursite.com/parceluncle-webhook"}'
{
"success": true,
"message": "Webhook URL configured successfully",
"data": {
"webhook_url": "https://yoursite.com/parceluncle-webhook",
"events": [
"shipment.status_updated",
"shipment.ndr_created",
"shipment.ndr_updated",
"shipment.pod_uploaded"
]
}
}
Supported Events
| Event | Triggered When |
|---|---|
shipment.status_updated |
Any status change — CREATED, ASSIGNED, PICKED_UP, OUT_FOR_DELIVERY, DELIVERED, CANCELLED, RETURNED, etc. |
shipment.ndr_created |
A Non-Delivery Report is filed (delivery attempt failed) |
shipment.ndr_updated |
NDR action taken — reattempt, RTO, address update, etc. |
shipment.pod_uploaded |
Proof of delivery image uploaded by the rider |
Example Webhook Payloads
{
"event": "shipment.status_updated",
"timestamp": "2024-06-01T16:30:00Z",
"data": {
"tracking_number": "PU1234567890",
"status": "DELIVERED",
"previous_status": "OUT_FOR_DELIVERY",
"delivered_at": "2024-06-01T16:30:00Z",
"updated_at": "2024-06-01T16:30:00Z"
}
}
{
"event": "shipment.ndr_created",
"timestamp": "2024-06-01T14:00:00Z",
"data": {
"tracking_number": "PU1234567890",
"shipment_status": "FAILED",
"ndr": {
"attempt_number": 1,
"reason": "RECIPIENT_UNAVAILABLE",
"reason_detail": "Customer not at home",
"action": "PENDING",
"status": "OPEN",
"reattempt_date": null
}
}
}
{
"event": "shipment.pod_uploaded",
"timestamp": "2024-06-01T16:35:00Z",
"data": {
"tracking_number": "PU1234567890",
"shipment_status": "DELIVERED",
"pod": {
"image_url": "/media/shipments/proofs/proof_001.jpg",
"uploaded_at": "2024-06-01T16:35:00Z"
}
}
}
Other Endpoints
GET/carrier/v1/merchant/webhook/— View current webhook configPUT/carrier/v1/merchant/webhook/— Set/update webhook URLDELETE/carrier/v1/merchant/webhook/— Remove webhook URL
2xx status code to acknowledge receipt.
Error Codes
All error responses follow a standard format. Use the error field for programmatic handling and the message field for user-friendly display.
{
"success": false,
"error": "ERROR_CODE",
"message": "Human-readable description of what went wrong",
"details": {}
}
HTTP Status Codes
| Code | Status | Meaning | How to Fix |
|---|---|---|---|
200 |
OK | Request succeeded | — |
201 |
Created | Resource created successfully (shipment, etc.) | — |
202 |
Accepted | Request accepted for processing (e.g., cancellation pending admin review) | — |
400 |
Bad Request | Invalid or missing request parameters. The request body failed validation. | Check the message field for which parameter is invalid. Verify all required fields are present and correctly formatted. |
401 |
Unauthorized | Missing, invalid, expired, or revoked API key. | Verify your X-API-Key header is present and the key is active in your dashboard. |
403 |
Forbidden | API key is paused, or your IP is not in the whitelist, or you lack permission for this action. | Check key status in dashboard. If using IP whitelisting, add your IP. Ensure the key type matches (TEST vs LIVE). |
404 |
Not Found | The requested resource (shipment, NDR, etc.) was not found or does not belong to your account. | Verify the tracking number or resource ID. Ensure the shipment was created with the same API key / seller account. |
409 |
Conflict | Duplicate request or conflicting state. E.g., creating a shipment with an already-used order number, or cancelling an already-cancelled shipment. | Check if the resource already exists. Use idempotency keys for retries. |
422 |
Unprocessable Entity | Request is well-formed but logically invalid. E.g., insufficient wallet balance, pincode not serviceable, COD amount mismatch. | Check the message for the specific business logic failure. Top up wallet, verify serviceability, or fix COD/Prepaid amounts. |
429 |
Too Many Requests | You have exceeded the rate limit for your API key. Current limits: 500 req/min (Live), 60 req/min (Test). | Implement exponential backoff. Batch your requests. Use webhooks instead of polling for tracking updates. |
500 |
Internal Server Error | An unexpected error occurred on our server. These are rare and logged automatically. | Retry with exponential backoff. If persistent, contact support with the request_id from the response. |
503 |
Service Unavailable | Server is temporarily overloaded or under maintenance. | Wait and retry after a few seconds. Check our status page for scheduled maintenance. |
Example Error Responses
{
"success": false,
"error": "VALIDATION_ERROR",
"message": "recipient_phone is required",
"details": {
"field": "recipient_phone",
"reason": "missing"
}
}
{
"success": false,
"error": "INVALID_API_KEY",
"message": "API key is invalid or has been revoked"
}
{
"success": false,
"error": "INSUFFICIENT_BALANCE",
"message": "Wallet balance ₹45.00 is insufficient. Required: ₹149.00",
"details": {
"wallet_balance": "45.00",
"required": "149.00"
}
}
{
"detail": "Request was throttled. Expected available in 23 seconds."
}
{
"success": false,
"error": "NOT_FOUND",
"message": "Shipment PU0000000000 not found"
}
{
"success": false,
"error": "NOT_SERVICEABLE",
"message": "Pincode 999999 is not serviceable"
}
success field first. If false, read the error code for programmatic handling and message for human-readable context. Implement retry logic with exponential backoff for 429, 500, and 503 errors.
Response Fields Reference
Complete reference of all fields returned in shipment responses across Create, List, and Get endpoints.
| Field | Type | Description |
|---|---|---|
tracking_number |
string | Unique AWB number for the shipment |
status |
string | Current status: CREATED, PAID, ASSIGNED, PICKED_UP, IN_TRANSIT, OUT_FOR_DELIVERY, DELIVERED, FAILED, CANCELLED |
service_type |
string | SAME_DAY, NEXT_DAY, or EXPRESS_4H |
payment_method |
string | How the merchant pays: WALLET, CREDIT, or COD |
payment_mode 🆕 |
string | Recipient-side payment: "COD" or "Prepaid". Derived from is_cod. |
order_number 🆕 |
string | Merchant's own order reference. Empty string if not provided. |
total_amount 🆕 |
string | null | Complete order value. Null for shipments created before this feature. |
is_cod |
boolean | Whether this is a Cash on Delivery order |
cod_amount |
string | Amount to collect from recipient ("0.00" if not COD) |
shipment_amount |
string | Shipping cost charged to the merchant |
pickup |
object | Pickup address details (address, city, state, pincode, landmark) |
delivery |
object | Delivery address details (address, city, state, pincode, landmark) |
sender |
object | Sender contact info (name, phone, email) |
recipient |
object | Recipient contact info (name, phone, email) |
parcel |
object | Parcel details (type, weight_kg, length_cm, width_cm, height_cm) |
cost_breakdown |
object | Itemized pricing (distance_charge, weight_charge, gst_amount, etc.) |
assigned_rider |
string | null | Name of the assigned rider, or null if not yet assigned |
created_at |
string (ISO 8601) | Timestamp when the shipment was created |
delivered_at |
string | null | Timestamp when delivered, null if not yet delivered |
delivery_proofs |
array | Proof of delivery images. Each entry has url (absolute image URL) and uploaded_at (ISO 8601 timestamp). Empty array if no proofs uploaded. |