Shiplee Internal API Documentation

Base URL: https://api4.shiplee.in

Version: 1.1 (Internal Release)

Table of Contents

1. Authentication (Login)

Authenticates a user and returns a JWT Bearer token required for all other endpoints.

POST/api/login

Request Body (JSON)

ParameterTypeRequiredDescription
mobilestringYesRegistered mobile number (e.g., "6393538851")
passwordstringYesUser password

Example Request

curl -X POST "https://api4.shiplee.in/api/login" \
-H "Content-Type: application/json" \
-d '{
    "mobile": "6393538851",
    "password": "Test@123"
}'

Success Response (200 OK)

Dev Note: You must store the access_token and send it in the headers of subsequent requests.
{
    "status": "success",
    "message": "Login successful",
    "redirect": "index",
    "token": "eyJ0eXAi...",         // Legacy support
    "access_token": "eyJ0eXAi...",  // Use this for Authorization
    "token_type": "Bearer",
    "expires_in": 10800,            // 3 Hours
    "email_verified": true
}

Error Responses

403 Forbidden: Account pending/blocked.

401 Unauthorized: Invalid credentials.

2. Home / User Profile

Fetches the initial app state, including user profile details, wallet balance, action alerts (like pending orders), and pickup schedules.

GET/api/home

Headers

KeyValueDescription
AuthorizationBearer <access_token>Token from Login API
Acceptapplication/jsonStandard accept header

Example Request

curl -X GET "https://api4.shiplee.in/api/home" \
-H "Authorization: Bearer eyJ0eXAiOiJK..." \
-H "Accept: application/json"

Success Response (200 OK)

{
    "status": "success",
    "data": {
        "user": {
            "fullname": "Ankit",
            "mobile": "6393538851",
            "email": "[email protected]",
            "account_status": "active",
            "wallet_balance": 5000
        },
        "steps": [],
        "actions": [
            { "label": "Unprocessable Orders", "value": 0 },
            { "label": "Weight Discrepancy Due", "value": 0 },
            { "label": "Shipment Delays", "value": 0 },
            { "label": "Pickup Delays", "value": 0 }
        ],
        "categories": [
            { "value": "all", "label": "All Categories" },
            { "value": "alerts", "label": "Alerts" }
        ],
        "pickups": {
            "today": "20 Jan 2026",
            "tomorrow": "21 Jan 2026",
            "has_pickups": false
        }
    }
}

3. Dashboard Analytics

Fetches detailed shipment statistics, earnings graphs, and courier performance for a specific date range.

GET/api/dashboard

Headers & Parameters

TypeKeyRequiredDescription
HeaderAuthorizationYesBearer <access_token>
Querystart_dateYesYYYY-MM-DD (e.g., 2023-01-01)
Queryend_dateYesYYYY-MM-DD (e.g., 2026-01-31)

Example Request

curl -X GET "https://api4.shiplee.in/api/dashboard?start_date=2023-01-01&end_date=2026-01-31" \
-H "Authorization: Bearer eyJ0eXAiOiJK..."

Success Response (200 OK)

{
    "status": "success",
    "filter": { "start": "2023-01-01", "end": "2026-01-31" },
    "data": {
        "tiles": {
            "total_shipments": 8734,
            "delivered": 556,
            "pending_orders": 1,
            "rto_count": 930
        },
        "wallet": 5000,
        "charts": {
            "courier_stats": [
                { "courier": "Bluedart- Surface", "total": 338, "delivered": 135, "rto": 195 }
            ],
            "channels": [
                { "name": "Shopify", "count": 8440 },
                { "name": "Custom", "count": 290 }
            ],
            "state_loads": [
                { "state": "Delhi", "count": 1110 },
                { "state": "Maharashtra", "count": 1480 }
            ],
            "monthly_cod_earnings": [
                { "label": "Sep 2024", "earnings": 1437144 },
                { "label": "Jan 2026", "earnings": 5976 }
            ]
        }
    }
}

4. Rates (Shipping Cost)

Returns available courier options and calculated shipping charges based on source/destination pincodes, weight, order value, and payment type (COD/Prepaid).

POST/api/rates

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format
Acceptapplication/jsonStandard accept header

Request Body (JSON)

ParameterTypeRequiredDescription
order_infoobjectYesMain payload wrapper
order_info.source_pincodestringYesPickup pincode (e.g., "110001")
order_info.destination_pincodestringYesDelivery pincode (e.g., "560001")
order_info.order_weightnumberYesWeight in grams (e.g., 1500 = 1.5 KG)
order_info.order_valuenumberYesOrder value in INR (used for COD rules/thresholds)
order_info.payment_typestringYescod or prepaid

Example Request (cURL)

curl -X POST "https://api4.shiplee.in/api/rates" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
  "order_info": {
    "source_pincode": "110001",
    "destination_pincode": "560001",
    "order_weight": 1500,
    "order_value": 1200,
    "payment_type": "cod"
  }
}'

Example Request (PowerShell)

$headers = @{
  "Authorization" = "Bearer <access_token>"
  "Content-Type"  = "application/json"
  "Accept"        = "application/json"
}

$body = @{
  order_info = @{
    source_pincode      = "110001"
    destination_pincode = "560001"
    order_weight        = 1500
    order_value         = 1200
    payment_type        = "cod"
  }
} | ConvertTo-Json -Depth 5

Invoke-RestMethod `
  -Uri "https://api4.shiplee.in/api/rates" `
  -Method POST `
  -Headers $headers `
  -Body $body

Success Response (200 OK)

Dev Note: Response contains carrier_info array (courier options). Usually, the UI should show the lowest cost first.
Formula: cost = freight_charges + cod_charges (for COD shipments).
{
  "status": 1,
  "code": 200,
  "message": "success",
  "data": {
    "carrier_info": [
      {
        "carrier_id": "delhivery_2kg_surface",
        "carrier_name": "Delhivery 2kg Surface",
        "ratecard_id": 60,
        "courier_id": "delhivery_surface",
        "zone": "D",
        "rate_type": "slab",
        "cost": 162,
        "freight_charges": 124,
        "cod_charges": 38,
        "slab": {
          "slab_id": 265,
          "weight_slab_grams": 2000,
          "pricing_type": "slab",
          "freight_amount": 124,
          "cod_charge": 38,
          "cod_percent": 2,
          "cod_threshold": 1700,
          "cod_apply_after_threshold": false,
          "includes_cod": false,
          "includes_rto": false
        }
      }
    ],
    "order_summary": {
      "source_pincode": "110001",
      "destination_pincode": "560001",
      "order_weight": 1500,
      "order_value": 1200,
      "payment_type": "cod"
    }
  }
}

Response Fields (carrier_info)

FieldTypeDescription
carrier_idstringInternal carrier/service identifier
carrier_namestringDisplay name for UI (e.g., "Delhivery Surface")
zonestringZone mapping between pincodes (A/B/C/D etc.)
rate_typestringPricing logic type (e.g., slab)
freight_chargesnumberBase freight amount
cod_chargesnumberCOD fee (0 for prepaid)
costnumberTotal payable shipping cost
slabobjectMatched slab details (weight slab, COD percent, thresholds, etc.)

Error Responses

401 Unauthorized: Missing/invalid token.

422 Unprocessable Entity: Validation error (missing pincode/weight/value).

404 Not Found: No ratecards/couriers available for given lane.

5. Account Settings

Fetch the authenticated user's profile and perform account actions: change password or send an email verification link.

5a. Get Profile

GET/api/account_settings

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Acceptapplication/jsonStandard accept header

Example Request

curl -X GET "https://api4.shiplee.in/api/account_settings" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "data": {
        "fullname": "Ankit",
        "email": "[email protected]",
        "mobile": "6393538851",
        "email_verified": true
    }
}

Error Responses

401 Unauthorized: Missing/invalid token.

404 Not Found: User not found.


5b. Update Account (Actions)

POST/api/account_settings

All POST actions share the same endpoint. Pass the action field in the JSON body to specify what to do.

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Action: change_password

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "change_password"
old_passwordstringYesThe user's current password
new_passwordstringYesNew password (min 8 characters)
confirm_passwordstringYesMust match new_password

Example Request

curl -X POST "https://api4.shiplee.in/api/account_settings" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "change_password",
    "old_password": "OldPass@123",
    "new_password": "NewPass@456",
    "confirm_password": "NewPass@456"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Password updated successfully."
}

Error Responses

401 Unauthorized: Current password is incorrect.

422 Unprocessable Entity: Missing fields / passwords don't match / new password too short.

Action: send_verification_email

Generates a secure one-time token and emails a verification link to the user's registered email. The link expires in 1 hour. Any previously issued tokens are invalidated.

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "send_verification_email"

Example Request

curl -X POST "https://api4.shiplee.in/api/account_settings" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "send_verification_email"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Verification email sent to [email protected]."
}
Note: If the email is already verified, the API returns 200 OK with "message": "Email is already verified." — no email is sent.

Error Responses

401 Unauthorized: Missing/invalid token.

500 Internal Server Error: Database error or email delivery failure.

6. Warehouse Management

List, add, and delete warehouses for the authenticated seller. New warehouses are automatically registered with SmartShip for both Express and Economy delivery types.

6a. List Warehouses

GET/api/warehouse

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API

Example Request

curl -X GET "https://api4.shiplee.in/api/warehouse" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "total": 2,
    "data": [
        {
            "id": 1,
            "nickname": "Delhi HQ",
            "address1": "123 Main Street",
            "address2": "Near Metro",
            "pincode": "110001",
            "city": "New Delhi",
            "state": "Delhi",
            "mobile_number": "9876543210",
            "address_type": "primary",
            "express_hub_id": "EXP_HUB_001",
            "economy_hub_id": "ECO_HUB_001",
            "created_at": "2026-01-15 10:30:00"
        },
        {
            "id": 2,
            "nickname": "Mumbai Warehouse",
            "address1": "456 Park Lane",
            "address2": "Shiplee-partner",
            "pincode": "400001",
            "city": "Mumbai",
            "state": "Maharashtra",
            "mobile_number": "9123456789",
            "address_type": "secondary",
            "express_hub_id": "EXP_HUB_002",
            "economy_hub_id": "ECO_HUB_002",
            "created_at": "2026-02-01 09:00:00"
        }
    ]
}

6b. Add / Delete Warehouse (Actions)

POST/api/warehouse

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Action: add_warehouse

Dev Note: The first warehouse added for a seller is automatically assigned address_type: "primary". All subsequent ones are "secondary". SmartShip hub registration runs in the same transaction — if it fails, nothing is saved.

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "add_warehouse"
nicknamestringYesDisplay name for the warehouse
mobilestringYes10-digit mobile number (no country code)
address1stringYesAddress line 1
address2stringNoAddress line 2 (defaults to "Shiplee-partner")
pincodestringYes6-digit Indian pincode
statestringYesState name
citystringYesCity name

Example Request

curl -X POST "https://api4.shiplee.in/api/warehouse" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "add_warehouse",
    "nickname": "Delhi HQ",
    "mobile": "9876543210",
    "address1": "123 Main Street",
    "address2": "Near Metro Station",
    "pincode": "110001",
    "state": "Delhi",
    "city": "New Delhi"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Warehouse added successfully.",
    "data": {
        "warehouse_id": 42,
        "address_type": "primary",
        "express_hub_id": "EXP_HUB_042",
        "economy_hub_id": "ECO_HUB_042"
    }
}

Error Responses

422 Unprocessable Entity: Missing/invalid fields (mobile not 10 digits, pincode not 6 digits).

500 Internal Server Error: SmartShip registration failure or DB error — transaction is rolled back.

Action: delete_warehouse

Performs a soft delete (is_deleted = 1). Primary warehouses cannot be deleted.

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "delete_warehouse"
warehouse_idintegerYesID of the warehouse to delete

Example Request

curl -X POST "https://api4.shiplee.in/api/warehouse" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "delete_warehouse",
    "warehouse_id": 42
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Warehouse deleted successfully."
}

Error Responses

404 Not Found: Warehouse not found or doesn't belong to the seller

Error Responses

404 Not Found: Warehouse not found or doesn't belong to the seller.

422 Unprocessable Entity: Attempting to delete a primary warehouse.

Action: make_primary

Promotes a warehouse to primary. All other seller warehouses are demoted to secondary in the same operation.

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "make_primary"
warehouse_idintegerYesID of the warehouse to promote

Example Request

curl -X POST "https://api4.shiplee.in/api/warehouse" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "action": "make_primary", "warehouse_id": 3 }'

Success Response

{ "status": "success", "message": "Primary warehouse updated successfully." }
Duplicate add guard: When adding a warehouse (add_warehouse), if a non-deleted warehouse with the same seller + mobile + pincode + city + state already has both SmartShip hub IDs, the API returns 200 success with "is_duplicate": true and the existing warehouse_id — no new row or SmartShip registration is created.

7. WooCommerce Stores

List, connect, and remove WooCommerce stores for the authenticated seller. Each store gets a unique API key and internal name used to sync orders.

7a. List Connected Stores

GET/api/woocommerce

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API

Example Request

curl -X GET "https://api4.shiplee.in/api/woocommerce" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "total": 1,
    "data": [
        {
            "id": 5,
            "store_url": "https://myshop.com",
            "api_key": "a3f8e1c2d94b...",
            "woocommerce_name": "wc_a1b2c3d4",
            "status": "active",
            "created_at": "2026-01-10 11:00:00"
        }
    ]
}

7b. Add / Remove Store (Actions)

POST/api/woocommerce

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Action: add_store

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "add_store"
store_urlstringYesFull URL of the WooCommerce store (e.g., https://myshop.com)

Example Request

curl -X POST "https://api4.shiplee.in/api/woocommerce" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "add_store",
    "store_url": "https://myshop.com"
}'

Success Response (200 OK)

Dev Note: Store the returned api_key and woocommerce_name — these are used to configure the Shiplee plugin on the WooCommerce side.
{
    "status": "success",
    "message": "WooCommerce store added successfully.",
    "data": {
        "id": 5,
        "store_url": "https://myshop.com",
        "api_key": "a3f8e1c2d94b...",
        "woocommerce_name": "wc_a1b2c3d4",
        "status": "active"
    }
}

Error Responses

409 Conflict: This store URL is already linked to the seller's account.

422 Unprocessable Entity: Missing or invalid store_url.

Action: delete_store

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "delete_store"
store_idintegerYesID of the store to remove (from list response)

Example Request

curl -X POST "https://api4.shiplee.in/api/woocommerce" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "delete_store",
    "store_id": 5
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Store removed successfully."
}

Error Responses

404 Not Found: Store not found or doesn't belong to the seller.

422 Unprocessable Entity: Missing store_id.

8. Agreement (Terms & Conditions)

⚠️ Enforcement: Every protected API endpoint checks for agreement acceptance via auth_middleware.php. If the user has not accepted the current active agreement, all API calls (except GET /api/agreement and POST /api/agreement) return:
HTTP 403 Forbidden
{
    "status": "error",
    "error_code": "AGREEMENT_REQUIRED",
    "message": "You must accept the Terms and Conditions before continuing."
}
The frontend should intercept this error_code globally and redirect the user to the agreement screen.

8a. Fetch Active Agreement

GET/api/agreement

Note: This endpoint uses skip_agreement_check: true — it is always accessible even if the agreement hasn't been accepted yet.

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API

Example Request

curl -X GET "https://api4.shiplee.in/api/agreement" \
-H "Authorization: Bearer <access_token>"

Response: Agreement required (200 OK)

{
    "status": "success",
    "agreement_required": true,
    "data": {
        "id": 3,
        "title": "Shiplee Terms and Conditions v2",
        "content": "<p>Full HTML agreement content...</p>"
    }
}

Response: Already accepted / No active agreement (200 OK)

{
    "status": "success",
    "agreement_required": false
}

Error Responses

403 Forbidden with "error_code": "EMAIL_NOT_VERIFIED" — user must verify email before they can view or accept agreements.


8b. Accept Agreement

POST/api/agreement

Note: Also uses skip_agreement_check: true — the user needs to be able to POST acceptance before the gate is lifted. After a successful acceptance, all subsequent API calls will pass the middleware check.

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "accept"
agreement_idintegerYesThe id from the GET response

Example Request

curl -X POST "https://api4.shiplee.in/api/agreement" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "accept",
    "agreement_id": 3
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Agreement accepted successfully.",
    "email_sent": true
}
What happens on acceptance:
  • A row is inserted into user_agreements with the user's IP and timestamp.
  • users2.agreement_accepted is set to 1.
  • A branded confirmation email (including the full agreement HTML) is sent via ZeptoMail.
  • All subsequent API calls now pass the middleware gate.

Error Responses

404 Not Found: Agreement ID is invalid or no longer active.

422 Unprocessable Entity: Missing agreement_id or unknown action.


Frontend Integration Flow

StepAction
1After login, call GET /api/agreement
2If agreement_required: true → show agreement screen with content
3User checks the box and taps Accept → call POST /api/agreement
4On success → navigate to the app normally
5On any API call returning "error_code": "AGREEMENT_REQUIRED" → redirect back to agreement screen (handles edge case of agreement being updated)

9. Reverse Orders

Three endpoints power the Reverse Orders page: listing orders with date/product filters, a live search bar, and a product-name dropdown loader.

9a. List Reverse Orders

GET/api/reverse_orders

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API

Query Parameters

ParameterTypeRequiredDescription
start_datestringNoYYYY-MM-DD. Defaults to 90 days ago.
end_datestringNoYYYY-MM-DD. Defaults to tomorrow.
product_namestringNoExact product name to filter by.

Example Request

curl -X GET "https://api4.shiplee.in/api/reverse_orders?start_date=2026-01-01&end_date=2026-03-18&product_name=Shoes" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "filter": {
        "start": "2026-01-01",
        "end": "2026-03-18",
        "product_name": "Shoes"
    },
    "total": 2,
    "data": [
        {
            "id": 101,
            "reverse_order_id": "REV-10001",
            "awb_number": "143900012345",
            "customer_name": "Rahul Sharma",
            "customer_mobile": "9876543210",
            "customer_address1": "12 MG Road",
            "customer_address2": "Apt 4B",
            "customer_city": "Bengaluru",
            "customer_state": "Karnataka",
            "customer_pincode": "560001",
            "product_names": "Shoes",
            "total_price": 1299.00,
            "payment_type": "prepaid",
            "charge_weight": 0.5,
            "length": 30,
            "breadth": 20,
            "height": 15,
            "reason": "Wrong size",
            "status": "pending",
            "warehouse_id": 3,
            "wh_nickname": "Delhi HQ",
            "wh_addr1": "123 Main Street",
            "wh_addr2": "Near Metro",
            "wh_city": "New Delhi",
            "wh_state": "Delhi",
            "wh_pincode": "110001",
            "wh_type": "primary",
            "created_at": "10 Mar 2026"
        }
    ]
}
Dev Note: charge_weight is in KG. Multiply by 1000 for grams (as the UI does). If warehouse_id is null, the order has no warehouse assigned and cannot be booked.

9b. Search Reverse Orders

GET/api/search_reverse_orders

Searches across AWB number, customer name, and customer mobile. Used by the topbar search box.

Query Parameters

ParameterTypeRequiredDescription
qstringYesSearch term — minimum 3 characters.

Example Request

curl -X GET "https://api4.shiplee.in/api/search_reverse_orders?q=Rahul" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "total": 1,
    "data": [
        {
            "id": 101,
            "reverse_order_id": "REV-10001",
            "awb_number": "143900012345",
            "customer_name": "Rahul Sharma",
            "customer_mobile": "9876543210",
            "status": "pending",
            "created_at": "10 Mar 2026"
        }
    ]
}

Error Responses

422 Unprocessable Entity: Search term is fewer than 3 characters.


9c. Product Names (Filter Dropdown)

GET/api/reverse_order_products

Returns all distinct product names for the seller — used to populate the Filter dropdown.

Example Request

curl -X GET "https://api4.shiplee.in/api/reverse_order_products" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "total": 3,
    "data": ["Shoes", "T-Shirt", "Watch"]
}

10. Shopify App

Entry point for the Shiplee Shopify app. Checks whether a given shop is connected and either returns a session JWT or the OAuth redirect URL to begin the connection flow.

GET/api/shopify_app

Note: This endpoint does not require a Shiplee Authorization header — it is public-facing and called by the Shopify app iframe on load.

Query Parameters

ParameterTypeRequiredDescription
shopstringYesThe Shopify store domain (e.g. mystore.myshopify.com)

Example Request

curl -X GET "https://api4.shiplee.in/api/shopify_app?shop=mystore.myshopify.com"

Response: Store Connected (200 OK)

Dev Note: Store the access_token and use it as a Bearer token for any subsequent Shiplee API calls made from within the Shopify app context. It expires in 24 hours.
{
    "status": "success",
    "connected": true,
    "shop": "mystore.myshopify.com",
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "token_type": "Bearer",
    "expires_in": 86400,
    "dashboard_url": "https://app.shiplee.ai"
}

Response: Store Not Connected (200 OK)

Dev Note: When connected: false, redirect the user (or open a popup) to the oauth_redirect URL to begin the Shopify OAuth flow. After OAuth completes, call this endpoint again — it will return a JWT.
{
    "status": "success",
    "connected": false,
    "oauth_redirect": "https://app.shiplee.ai/shopify/connect?shop=mystore.myshopify.com",
    "message": "Store not connected. Redirect user to oauth_redirect to begin OAuth."
}

Frontend Integration Flow

StepAction
1Shopify app loads → call GET /api/shopify_app?shop=<shop>
2If connected: false → redirect to oauth_redirect
3OAuth completes → call endpoint again → receive JWT
4If connected: true → store JWT, show dashboard button

Error Responses

422 Unprocessable Entity: Missing or invalid shop parameter (must be a .myshopify.com domain).

11. Billing Ticket

Raises a billing support ticket, creates escalation rows (one per AWB), and fires an in-app notification — all in a single transaction.

POST/api/billing_ticket

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
issuestringYesMust be one of the allowed issue types (see below)
remarksstringYesQuery description — max 300 characters, alphanumeric only
awb_numbersstringNoComma-separated AWB numbers (e.g. "AWB001, AWB002"). Defaults to "NA" if omitted.

Allowed Issue Types

Value
Billing Invoice
Billing Credit
Billing Debit
Wallet Recharge
COD Transaction
Service Fee
GST Issue

Example Request

curl -X POST "https://api4.shiplee.in/api/billing_ticket" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "issue": "Billing Invoice",
    "remarks": "Invoice amount looks incorrect for last month",
    "awb_numbers": "AWB1234, AWB5678"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Billing ticket raised successfully. Our billing team will contact you shortly.",
    "ticket_id": 42
}
What happens on submission:
  • One row inserted into tickets with status Open.
  • One escalations row per AWB number, assigned to Billing Team.
  • One notifications row created for the seller.
  • All three inserts run inside a single transaction — if any step fails, everything is rolled back.

Error Responses

422 Unprocessable Entity: Missing fields, invalid issue type, or remarks exceeding 300 characters. When the issue type is invalid, the response also includes an allowed array of valid values.

401 Unauthorized: Missing or invalid token.

500 Internal Server Error: DB failure — transaction rolled back, nothing is saved.

12. Book Shipment

Books a forward shipment for an order. Resolves the seller's plan ratecard, checks serviceability, calculates charges, calls the courier API, saves the booking, and records cost snapshots — all in one call.

POST/api/book_shipment

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
carrier_idstringYesThe carrier_id (booking key) returned by the Rates API
carrier_namestringNoDisplay name of the carrier (used as fallback for service matching)
order_idintegerYesThe Shiplee customer_info.id of the order to book
warehouse_idintegerYesThe warehouse to ship from (must belong to the seller)

Example Request

curl -X POST "https://api4.shiplee.in/api/book_shipment" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "carrier_id": "delhivery_2kg_surface",
    "carrier_name": "Delhivery 2kg Surface",
    "order_id": 10042,
    "warehouse_id": 3
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Shipment booked successfully.",
    "awb_number": "1234567890123",
    "carrier": "Delhivery 2kg Surface",
    "zone": "D",
    "charges": {
        "freight_charges": 124,
        "cod_charges": 38,
        "cost": 162
    }
}
What happens on a successful booking:
  • Ratecard resolved from the seller's assigned plan.
  • Destination pincode checked for serviceability (prepaid/COD).
  • Zone determined by zone_rules table (city → state → metro → fallback D).
  • Charge calculated: freight × weight multiplier + COD (threshold-aware).
  • Courier API called via the matching service class (Delhivery, SmartShip, XpressBees, etc.).
  • Booking saved: customer_info.status updated, row inserted in orders, wallet debited, ShippingCharges recorded.
  • Two cost snapshots saved to courier_cost_snapshots: our calculated rate (source: "booking") and the live rate from the courier API (source: "live_rate") for reconciliation.

Booking Pipeline

StepCheckFailure Response
1JWT auth + agreement gate401 / 403
2Duplicate booking guard (orders.linkid)409 ALREADY_BOOKED
3Order exists and belongs to seller404
4Warehouse exists and belongs to seller404
5Wallet balance ≥ ₹500402 INSUFFICIENT_BALANCE
6Ratecard found in seller's plan422
7Destination serviceable for payment type422 NOT_SERVICEABLE
8Rate slab found for zone + weight422
9Courier API returns AWB500

COD Charge Formula

order_value ≤ cod_threshold → COD = ₹0 (included in freight)
order_value > cod_threshold → COD = max(cod_charge, order_value × cod_percent / 100)

Error Responses

402 Payment RequiredINSUFFICIENT_BALANCE: Wallet below ₹500.

404 Not Found: Order or warehouse not found / doesn't belong to seller.

409 ConflictALREADY_BOOKED: Order already has an AWB. Response includes existing awb_number.

422 Unprocessable Entity: Missing fields, ratecard not found, destination not serviceable, slab not found, or unsupported courier.

500 Internal Server Error: Courier API failure or DB error.

13. Bulk Booking Queue

Queues multiple orders for shipment booking. Orders are processed asynchronously by a cron job — this endpoint only enqueues them. Use Book Shipment for single, immediate bookings.

POST/api/bulk_booking

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
order_idsinteger[]YesArray of customer_info.id values to queue
warehouse_idintegerYesWarehouse to ship from (must belong to the seller)

Example Request

curl -X POST "https://api4.shiplee.in/api/bulk_booking" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "order_ids": [1001, 1002, 1003],
    "warehouse_id": 3
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "2 order(s) queued for booking (1 skipped — already pending or booked)",
    "queued_count": 2,
    "queued_orders": [1001, 1002],
    "skipped_count": 1,
    "skipped_orders": [1003],
    "skipped_reasons": {
        "1003": "already_booked"
    }
}
What happens per order:
  • Ownership verified: order must belong to the authenticated seller.
  • Skipped if bulk_booking_logs shows status pending or processing.
  • Skipped if already booked in the orders table.
  • Stale failed or new rows are deleted before inserting a fresh pending row.
  • customer_info.status is set to 'pending' (only if currently 'new').
  • The cron job picks up all pending rows and calls the booking logic.

Skipped Reason Codes

CodeMeaning
already_queuedOrder is already in pending or processing state in the queue
already_bookedOrder already has an AWB in the orders table
db_errorInsert failed — check server logs

Error Responses

404 Not Found: Warehouse not found or no valid orders found for this account.

422 Unprocessable Entity: Missing order_ids or warehouse_id.

14. Cancel Orders

Cancels one or more orders. Only orders with status new can be cancelled. Also soft-deletes any linked Shopify import rows.

POST/api/cancel_orders

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
order_idsinteger[]YesArray of customer_info.id values to cancel

Example Request

curl -X POST "https://api4.shiplee.in/api/cancel_orders" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "order_ids": [1001, 1002, 1003]
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "2 order(s) cancelled successfully.",
    "cancelled": [1001, 1002],
    "skipped": {
        "not_found": [],
        "non_cancellable": {
            "1003": "manifested"
        }
    }
}
Behaviour:
  • Only orders with status new are cancelled — already booked/manifested orders are reported in non_cancellable with their current status.
  • Orders not belonging to the seller are reported in not_found.
  • If any cancellable order fails due to a race condition, the entire transaction is rolled back — nothing is cancelled.
  • If a cancelled order has a linked row in shopify_implink, it is soft-deleted (is_deleted = 1) in the same transaction.

Error Responses

409 Conflict: A race condition prevented one or more orders from being cancelled. No changes saved — retry the request.

422 Unprocessable Entity: No cancellable orders found (all orders are already booked, not found, or wrong status).

15. Cancel Shipments (Booked)

Cancels already-booked or manifested shipments. Calls the courier's cancellation API, reverts the order status, deletes the booking record, refunds the wallet, and writes a full audit log — all in one transaction.

Note: This endpoint is for booked/manifested orders only. To cancel unbooked (new) orders, use Cancel Orders instead.

POST/api/cancel_shipments

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
order_idsinteger[]YesArray of customer_info.id values to cancel
actionstringNo"cancel" — reset to new (rebookable)  |  "delete" — set to cancelled (default)

Example Request

curl -X POST "https://api4.shiplee.in/api/cancel_shipments" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "order_ids": [1001, 1002],
    "action": "cancel"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Shipment(s) cancelled and reset to new. You can rebook these orders.",
    "cancelled_count": 2,
    "new_status": "new",
    "wallet_balance": 4836.50
}
What happens per shipment (in one transaction):
  • Courier API called (Delhivery / XpressBees / Amazon / SmartShip — auto-detected from courier_name).
  • customer_info.status set to new (action=cancel) or cancelled (action=delete).
  • Row deleted from orders table.
  • Refund credited to seller wallet (userwallet) and logged to RechargeLogs.
  • ShippingCharges.Status set to cancelled.
  • Full audit row written to CancelDeleteLogs (success or failure).
  • If any step fails, the entire transaction is rolled back.

Action Values

ActionResulting StatusUse Case
cancelnewCancel and rebook with a different courier
deletecancelledPermanently cancel the order

Error Responses

422 Unprocessable Entity: No orders found in booked or manifested status for this seller.

503 Service Unavailable: Could not obtain courier API tokens — retry after a short delay.

500 Internal Server Error: Courier API rejected the cancellation, or a DB step failed. Transaction rolled back. Failure logged to CancelDeleteLogs.

16. Channels

Manage connected sales channels across Shopify, WooCommerce, and QuickSell. Shopify and WooCommerce stores are connected via their own OAuth flows — this API only handles listing and deleting them. QuickSell is connected directly via API key.

16a. List Channels

GET/api/channels

Example Request

curl -X GET "https://api4.shiplee.in/api/channels" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "total": 3,
    "data": [
        {
            "id": 1,
            "store_name": "my-store",
            "store_url": "https://my-store.myshopify.com",
            "platform": "shopify",
            "status": "active"
        },
        {
            "id": 4,
            "store_name": "myshop.com",
            "store_url": "https://myshop.com",
            "platform": "woocommerce",
            "status": "active"
        },
        {
            "id": 7,
            "store_name": "https://quicksell.co/s/abc123",
            "store_url": "https://quicksell.co/s/abc123",
            "platform": "quicksell",
            "status": "active"
        }
    ]
}

16b. Add / Delete Channel (Actions)

POST/api/channels

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Action: add_quicksell

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "add_quicksell"
api_keystringYesQuickSell API key from Account Settings → Developer API
catalogue_urlstringNoQuickSell catalogue URL for share links
lengthnumberNoDefault parcel length in cm (default: 10)
breadthnumberNoDefault parcel breadth in cm (default: 10)
heightnumberNoDefault parcel height in cm (default: 10)
weightnumberNoDefault parcel weight in kg (default: 0.5)

Example Request

curl -X POST "https://api4.shiplee.in/api/channels" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "add_quicksell",
    "api_key": "qs_live_abc123xyz",
    "catalogue_url": "https://quicksell.co/s/mystore",
    "length": 20,
    "breadth": 15,
    "height": 10,
    "weight": 0.8
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "QuickSell connected successfully.",
    "data": {
        "id": 7,
        "platform": "quicksell"
    }
}

Error Responses

409 ConflictDUPLICATE: This API key is already connected.

422 Unprocessable Entity: Missing api_key or invalid dimensions.

Action: delete_channel

Delete behaviour by platform:
  • Shopify — hard delete (no status column in the table).
  • WooCommerce / QuickSell — soft delete (status = 'delete') if the column exists, otherwise hard delete.

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "delete_channel"
channel_idintegerYesThe id of the channel from the list response
platformstringYesshopify, woocommerce, or quicksell

Example Request

curl -X POST "https://api4.shiplee.in/api/channels" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "action": "delete_channel",
    "channel_id": 7,
    "platform": "quicksell"
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Channel deleted successfully."
}

Error Responses

404 Not Found: Channel not found or doesn't belong to the seller.

422 Unprocessable Entity: Missing fields or invalid platform.

17. COD Remittance

Returns the seller's COD remittance summary, all grouped remittance rows, available plans, current plan, and COD→Wallet eligibility status.

17a. Get Remittance Data

GET/api/cod_remittance

Example Request

curl -X GET "https://api4.shiplee.in/api/cod_remittance" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "data": {
        "summary": {
            "remitted_till_date": 45230.00,
            "total_pending": 8750.00,
            "total_adjustment": 120.00,
            "total_cancelled": 300.00,
            "last_remittance_date": "2026-03-01"
        },
        "current_plan": { "id": 4, "name": "Standard D+7" },
        "plans": [
            { "id": 3, "plan_name": "Express D+3", "tat_days": 3, "fee_percentage": 1.5, "is_current": false },
            { "id": 4, "plan_name": "Standard D+7", "tat_days": 7, "fee_percentage": 0.5, "is_current": true }
        ],
        "wallet_eligible": true,
        "open_disputes": 0,
        "remittances": [
            {
                "remittance_ids": "201,202",
                "awbs": "AWB001,AWB002",
                "total_cod_amount": 3500.00,
                "total_net_remittance": 3482.50,
                "total_base_charge": 15.00,
                "total_gst_component": 2.50,
                "remittance_status": "pending",
                "remittance_date": "2026-03-18",
                "tat_days": 7,
                "fee_percentage": 0.5,
                "utr_number": null,
                "wallet_convertible": true,
                "days_until_eligible": null
            }
        ]
    }
}
wallet_convertible is true only when: status is pending, open_disputes === 0, and remittance_date ≤ today. Use this field to decide whether to show the COD→Wallet button per row.

days_until_eligible is the number of days until the remittance_date is reached (for future-dated pending rows).

17b. Activate Remittance Plan

POST/api/cod_remittance

Request Body

ParameterTypeRequiredDescription
actionstringYesMust be "activate_plan"
plan_idintegerYesID of the plan to activate (from the plans array)

Example Request

curl -X POST "https://api4.shiplee.in/api/cod_remittance" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "action": "activate_plan", "plan_id": 3 }'

Success Response

{ "status": "success", "message": "Remittance plan activated successfully." }

Error Responses

404 Not Found: Plan not found or inactive.

422 Unprocessable Entity: Missing plan_id.

18. COD → Wallet Conversion

Converts pending COD remittances directly to the seller's main shipping wallet. Runs as a fully atomic 5-step transaction — all or nothing.

POST/api/cod_to_wallet

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
remittance_idsstring or integer[]YesComma-separated string or array of cod_remittance.id values. Max 100.

Example Request

curl -X POST "https://api4.shiplee.in/api/cod_to_wallet" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "remittance_ids": [201, 202] }'

Success Response (200 OK)

{
    "status": "success",
    "message": "₹3,500.00 credited to your wallet from 2 remittance(s).",
    "total_credited": 3500.00,
    "new_balance": 8500.00,
    "rows_converted": 2,
    "recharge_log_id": 9142,
    "utr_reference": "WALLET-CREDIT-9142"
}
Transaction steps (all-or-nothing):
  1. Rows locked with FOR UPDATE and validated (seller ownership + pending status + date ≤ today).
  2. userwallet.balance credited atomically.
  3. Credit row inserted into RechargeLogs.
  4. All remittance rows flipped to completed, utr_number set to WALLET-CREDIT-{recharge_log_id}.
  5. Audit row written to cod_wallet_conversions.
Warning: Once confirmed, these remittances will NOT be paid to the seller's bank account.

Error Responses

403 ForbiddenDISPUTES_OPEN: Seller has open weight disputes that must be resolved first.

409 Conflict: A row's status changed between validation and update (race condition) — transaction rolled back, retry.

422 Unprocessable Entity: Missing IDs, more than 100 IDs, or rows not eligible (future date or wrong status).

19. COD Confirmation Calls

Manages the COD Order Confirmation Call Service — trained agents call COD customers to confirm orders and verify delivery addresses before dispatch.

Pricing: ₹5 per successfully connected & confirmed call, deducted from the seller's Shiplee wallet. Zero charge if the customer is unreachable.

19a. Get Service Status, Stats & Orders

GET/api/cod_confirmation

Query Parameters

ParameterTypeRequiredDescription
statusstringNoFilter orders by call status (see table below). queued returns orders with no call record yet.
limitintegerNoMax orders to return. Default 200, max 500.

Call Status Values

ValueMeaning
queuedCOD order placed, not yet called
pendingIn the calling queue
calledCall attempted
connectedCall connected
not_reachableCustomer unreachable after 3 attempts
callback_requestedCustomer requested a callback
confirmedOrder confirmed by customer — ₹5 charged
address_updatedAddress corrected during call — ₹5 charged
cancelledCustomer cancelled the order on call

Example Request

curl -X GET "https://api4.shiplee.in/api/cod_confirmation?status=confirmed&limit=50" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK) — Service active

{
    "status": "success",
    "data": {
        "service_enabled": true,
        "activated_since": "2026-01-15 10:30:00",
        "stats": {
            "total_cod": 342,
            "calls_done": 280,
            "confirmed": 241,
            "cancelled": 18,
            "address_updated": 21,
            "pending": 62,
            "total_charged": 1310.00,
            "total_confirmed_value": 485200.00
        },
        "orders": [
            {
                "awb": "ORD-10042",
                "customer_name": "Rahul Sharma",
                "customer_phone": "9876543210",
                "address": "12 MG Road, Bengaluru, Karnataka, 560001",
                "order_value": 1299.00,
                "order_date": "2026-03-17",
                "call_status": "confirmed",
                "call_outcome": null,
                "agent_name": "Priya",
                "call_time": "2026-03-17 14:22:00",
                "charge_amount": 5.00,
                "charged": true,
                "address_confirmed": true,
                "address_remarks": null,
                "call_remarks": "Customer confirmed order and address"
            }
        ],
        "total_orders": 1
    }
}

Success Response — Service never activated

{
    "status": "success",
    "data": {
        "service_enabled": false,
        "activated_since": null,
        "stats": null,
        "orders": []
    }
}

19b. Enable / Disable Service

POST/api/cod_confirmation

Request Body

ParameterTypeRequiredDescription
actionstringYes"enable" or "disable"

Example — Enable

curl -X POST "https://api4.shiplee.in/api/cod_confirmation" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "action": "enable" }'

Success Response

{
    "status": "success",
    "message": "COD Confirmation Call service enabled. New COD orders will be queued for calling within a few hours.",
    "service_enabled": true
}
Enable behaviour: Uses INSERT ... ON DUPLICATE KEY UPDATEactivated_at is set only on first activation and preserved on re-enables.
Disable behaviour: Orders already in the calling queue continue to be processed. No new orders are queued after disabling.

Error Responses

422 Unprocessable Entity: action is missing or not "enable"/"disable".

19. COD Confirmation Call Service

Enables or disables the COD Confirmation Call Service. When active, the cron automatically picks up new COD orders and queues confirmation calls within 24 hours.

19a. Get Service Status

GET/api/cod_confirmation_service

Example Request

curl -X GET "https://api4.shiplee.in/api/cod_confirmation_service" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "data": {
        "is_active": true,
        "activated_at": "2026-03-10 14:22:00",
        "updated_at": "2026-03-10 14:22:00"
    }
}

19b. Enable / Disable Service

POST/api/cod_confirmation_service

Request Body

ParameterTypeRequiredDescription
actionstringYes"enable" or "disable"

Example Requests

// Enable
curl -X POST "https://api4.shiplee.in/api/cod_confirmation_service" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "action": "enable" }'

// Disable
curl -X POST "https://api4.shiplee.in/api/cod_confirmation_service" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "action": "disable" }'

Success Responses

// Enabled
{
    "status": "success",
    "message": "COD Confirmation Call Service activated. New COD orders from today will be called within 24 hours.",
    "is_active": true
}

// Disabled
{
    "status": "success",
    "message": "COD Confirmation Call Service disabled. Orders already in queue will still be processed.",
    "is_active": false
}
Calling enable when already enabled (or disable when already disabled) returns 200 OK with the current state — no error, idempotent.

Error Responses

422 Unprocessable Entity: Invalid action value.

20. Courier Preferences

Manages per-seller courier enable/disable toggles and booking priority mode (Cheapest / Fastest / Custom drag order). Services are dynamically loaded from the seller's assigned shipping plan.

20a. Get Preferences

GET/api/courier_preferences

Example Request

curl -X GET "https://api4.shiplee.in/api/courier_preferences" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "no_plan": false,
    "data": {
        "mode": "custom",
        "custom_order": ["delhivery_2kg_surface", "xpressbees_air"],
        "groups": [
            {
                "group_key": "delhivery",
                "group_label": "Delhivery",
                "logo": "https://cdn.shiplee.ai/fet.png",
                "services": [
                    {
                        "toggle_key": "delhivery_2kg_surface",
                        "label": "Delhivery 2kg Surface",
                        "logo": "https://cdn.shiplee.ai/fet.png",
                        "enabled": true
                    }
                ]
            },
            {
                "group_key": "xpressbees",
                "group_label": "Xpressbees",
                "logo": "https://old-xpressbees.xbees.in/images/logo.png",
                "services": [
                    {
                        "toggle_key": "xpressbees_air",
                        "label": "Xpressbees Air",
                        "logo": "https://old-xpressbees.xbees.in/images/logo.png",
                        "enabled": true
                    }
                ]
            }
        ]
    }
}
If the seller has no plan assigned, no_plan: true is returned with data: null.

Default state (before the seller saves any preferences): all services ON except any Ekart key which defaults to OFF.

20b. Save Preferences

POST/api/courier_preferences

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
modestringYes"cheapest", "fastest", or "custom"
servicesobjectYesMap of toggle_key → boolean. Keys not in seller's plan are silently ignored.
custom_orderstring[]NoOrdered array of toggle_key values. Only used when mode = "custom". Only enabled keys are stored.

Example Request

curl -X POST "https://api4.shiplee.in/api/courier_preferences" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "mode": "custom",
    "services": {
        "delhivery_2kg_surface": true,
        "xpressbees_air": true,
        "ekart_standard": false
    },
    "custom_order": ["delhivery_2kg_surface", "xpressbees_air"]
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Courier preferences saved successfully.",
    "data": {
        "mode": "custom",
        "custom_order": ["delhivery_2kg_surface", "xpressbees_air"]
    }
}

Priority Mode Reference

ModeBehaviour
cheapestAlways picks the lowest-cost serviceable courier for each order
fastestPrefers air services — Blue Dart Apex first, then Air Xpressbees
customUses the custom_order array. First serviceable courier in the list is booked

Error Responses

422 Unprocessable Entity: services is not an object, or seller has no plan assigned.

21. Edit Order

Fetch or update a new status order. Once an order is booked/manifested it can no longer be edited.

21a. Get Order for Editing

GET/api/edit_order?order_id=123

Query Parameters

ParameterTypeRequiredDescription
order_idintegerYescustomer_info.id

Example Request

curl -X GET "https://api4.shiplee.in/api/edit_order?order_id=1042" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "data": {
        "order": {
            "id": 1042,
            "order_id": "ORD-001",
            "pincode": "110001",
            "city": "New Delhi",
            "state": "Delhi",
            "name": "Rahul Sharma",
            "mobile": "9876543210",
            "address1": "12 MG Road",
            "payment_type": "cod",
            "same_billing_address": true,
            "total_price": 1299.00
        },
        "products": [
            { "product_name": "Shoes", "quantity": 1, "product_price": 1299.00, "sku": "SKU001" }
        ],
        "parcels": [
            { "length": 30, "breadth": 20, "height": 15, "physical_weight": 0.5, "charge_weight_grams": 500 }
        ]
    }
}

21b. Update Order

POST/api/edit_order

Products and parcels are replaced entirely — send the full updated list each time.

Request Body (key fields)

ParameterTypeRequiredDescription
order_idintegerYesThe order to update
pincodestringYesDelivery pincode
citystringYesDelivery city
statestringYesDelivery state
namestringYesCustomer name
mobilestringYesCustomer mobile
address1stringYesAddress line 1
same_billing_addressbooleanNoIf true, billing fields are copied from shipping
payment_typestringNocod or prd (default: cod)
pickup_typestringNofwd or rvrs (default: fwd)
productsobject[]YesArray of { product_name, quantity, product_price, sku }
parcelsobject[]YesArray of { length, breadth, height, physical_weight } in cm/kg. Volumetric weight is calculated server-side.

Example Request

curl -X POST "https://api4.shiplee.in/api/edit_order" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "order_id": 1042,
    "pincode": "110001",
    "city": "New Delhi",
    "state": "Delhi",
    "name": "Rahul Sharma",
    "mobile": "9876543210",
    "address1": "12 MG Road",
    "payment_type": "cod",
    "same_billing_address": true,
    "products": [
        { "product_name": "Shoes", "quantity": 1, "product_price": 1299, "sku": "SKU001" }
    ],
    "parcels": [
        { "length": 30, "breadth": 20, "height": 15, "physical_weight": 0.5 }
    ]
}'

Success Response (200 OK)

{
    "status": "success",
    "message": "Order updated successfully.",
    "data": {
        "order_id": 1042,
        "total_price": 1299.00
    }
}

Error Responses

404 Not Found: Order not found, doesn't belong to seller, or is not in new status.

422 Unprocessable Entity: Missing required fields, no products, or no parcels.

22. Wallet Transactions

Returns wallet transaction history from RechargeLogs. Supports date-range filtering for the full list, or AWB-specific lookup for a single shipment's charges/refunds.

GET/api/wallet_transactions

Query Parameters

ParameterTypeRequiredDescription
start_datestringNoYYYY-MM-DD. Defaults to 90 days ago.
end_datestringNoYYYY-MM-DD. Defaults to tomorrow.
awbstringNoAWB number — returns all transactions for this shipment only. When present, date filters are ignored.

Example: Date Range

curl -X GET "https://api4.shiplee.in/api/wallet_transactions?start_date=2026-03-01&end_date=2026-03-18" \
-H "Authorization: Bearer <access_token>"

Example: AWB Lookup

curl -X GET "https://api4.shiplee.in/api/wallet_transactions?awb=143900012345" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "filter": { "start": "2026-03-01", "end": "2026-03-18" },
    "total": 2,
    "data": [
        {
            "transaction_id": 9142,
            "date": "2026-03-15 14:22:00",
            "awb_number": "143900012345",
            "credit": 0.00,
            "debit": 162.00,
            "closing_balance": 4838.00,
            "description": "Shipping charges for AWB: 143900012345"
        },
        {
            "transaction_id": 9100,
            "date": "2026-03-10 09:00:00",
            "awb_number": null,
            "credit": 5000.00,
            "debit": 0.00,
            "closing_balance": 5000.00,
            "description": "Wallet recharge via PhonePe"
        }
    ]
}
For AWB lookups the response includes "awb" instead of "filter". All other fields are identical.

23. Weight Disputes

Fetch weight disputes raised by Shiplee against the seller's shipments, and submit seller responses with evidence images.

On every request, disputes older than 4 days with status = 'DISPUTE' are automatically closed (auto_accepted = true). This mirrors the original page-load behaviour.

23a. List Disputes

GET/api/weight_disputes?start_date=2026-03-01&end_date=2026-03-18

Query Parameters

ParameterTypeRequiredDescription
start_datestringNoYYYY-MM-DD. Defaults to 7 days ago.
end_datestringNoYYYY-MM-DD. Defaults to today.

Success Response (200 OK)

{
    "status": "success",
    "filter": { "start": "2026-03-01", "end": "2026-03-18" },
    "total": 1,
    "disputes": [
        {
            "id": 42,
            "order_id": "ORD-001",
            "awb_number": "143900012345",
            "carrier": "Delhivery",
            "chargeable_booked_weight": 500,
            "chargeable_applied_weight": 1000,
            "difference": 500,
            "upcoming_charges": 41.00,
            "status": "DISPUTE",
            "image_url": "https://...",
            "seller_response": null,
            "new_weight": null,
            "auto_accepted": false,
            "created_at": "2026-03-15 10:00:00"
        }
    ]
}

23b. Submit Dispute Response

POST/api/weight_disputes

This endpoint uses multipart/form-data (not JSON) because it includes file uploads.

Form Fields

FieldTypeRequiredDescription
dispute_idintegerYesID of the open dispute to respond to
new_weightfloatYesSeller's actual package weight in grams
responsestringYesSeller's written explanation
weighing_scale_imagefileYesPackage on weighing scale
length_imagefileYesLength measurement
breadth_imagefileYesBreadth measurement
height_imagefileYesHeight measurement

Example Request

curl -X POST "https://api4.shiplee.in/api/weight_disputes" \
-H "Authorization: Bearer <access_token>" \
-F "dispute_id=42" \
-F "new_weight=480" \
-F "response=Package weighs 480g, not 1000g as claimed." \
-F "weighing_scale_image=@/path/to/scale.jpg" \
-F "length_image=@/path/to/length.jpg" \
-F "breadth_image=@/path/to/breadth.jpg" \
-F "height_image=@/path/to/height.jpg"

Success Response (200 OK)

{
    "status": "success",
    "message": "Response and ticket submitted successfully.",
    "ticket_id": 88
}

Error Responses

404 Not Found: Dispute not found, doesn't belong to seller, or already responded to.

422 Unprocessable Entity: Missing required fields or one or more image uploads failed.

24. Dispute Tickets

Returns the seller's submitted dispute tickets with their images, seller response, resolution notes, and current status. Supports date range, status, order ID, and AWB filters with server-side pagination.

GET/api/dispute_tickets

Query Parameters

ParameterTypeRequiredDescription
start_datestringNoYYYY-MM-DD. Defaults to 14 days ago.
end_datestringNoYYYY-MM-DD. Defaults to today.
statusstringNoOPEN, IN_REVIEW, RESOLVED, or CLOSED
order_idstringNoPartial match
awb_numberstringNoPartial match
pageintegerNoDefault 1
page_sizeintegerNoDefault 10, max 100

Example Request

curl -X GET "https://api4.shiplee.in/api/dispute_tickets?status=OPEN&page=1&page_size=10" \
-H "Authorization: Bearer <access_token>"

Success Response (200 OK)

{
    "status": "success",
    "filter": { "start": "2026-03-04", "end": "2026-03-18", "status": "OPEN" },
    "pagination": { "page": 1, "page_size": 10, "total": 3, "total_pages": 1 },
    "tickets": [
        {
            "id": 88,
            "dispute_id": 42,
            "awb_number": "143900012345",
            "order_id": "ORD-001",
            "booked_weight_g": 500,
            "applied_weight_g": 1000,
            "new_weight_g": 480,
            "status": "OPEN",
            "seller_response": "Package weighs 480g...",
            "resolution_notes": null,
            "dispute_image": "https://...",
            "weighing_scale_image": "https://...",
            "resolved_at": null,
            "created_at": "2026-03-15 14:00:00"
        }
    ]
}

25. Manifest PDF

Generates and streams a TCPDF manifest PDF for a set of manifested orders, grouped by courier. Each courier gets its own page. Returns application/pdf on success and application/json on error.

GET/api/manifest?order_ids=1,2,3&warehouse_id=5

Query Parameters

ParameterTypeRequiredDescription
order_idsstringYesComma-separated customer_info.id values. Orders must have status = 'manifested' and belong to the seller. Max 500.
warehouse_idintegerNoWarehouse to show as pickup address. If omitted, falls back to the first order's warehouse.

Example Request

curl -X GET "https://api4.shiplee.in/api/manifest?order_ids=1042,1043,1044&warehouse_id=3" \
-H "Authorization: Bearer <access_token>" \
--output Shiplee_Manifest.pdf

Success Response

200 OKContent-Type: application/pdf with Content-Disposition: attachment; filename="Shiplee_Manifest_YYYYMMDD_HHMMSS.pdf"

The PDF is grouped by courier — if orders span Delhivery and Xpressbees, the manifest will have two pages. The pickup address is cleaned of SmartShip's _TS timestamp suffixes before being printed.

Error Responses (JSON)

404 Not Found: No manifested orders found for the given IDs (wrong status, wrong seller, or invalid IDs).

422 Unprocessable Entity: order_ids missing, empty, or more than 500 IDs.

26. Get Orders

Returns all new status orders for the seller with date range and optional product name filter. Used to populate the All Orders table.

POST/api/get_orders

Request Body (form-data or JSON)

FieldTypeRequiredDescription
start_datestringNoYYYY-MM-DD. Defaults to 90 days ago.
end_datestringNoYYYY-MM-DD. Defaults to tomorrow.
product_namestringNoPartial match on product name.

Example Request

curl -X POST "https://api4.shiplee.in/api/get_orders" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "start_date": "2026-03-01", "end_date": "2026-03-21" }'

Success Response (200 OK)

{
    "success": true,
    "count": 2,
    "data": [
        {
            "id": 1042,
            "customer_order_id": "ORD-001",
            "name": "Rahul Sharma",
            "mobile1": "9876543210",
            "pincode": "110001",
            "ptype": "cod",
            "total_price": 1299.00,
            "status": "new",
            "order_date": "2026-03-15 10:00:00",
            "whatsapp_status": "pending",
            "wa_confirm_status": "",
            "type": "quick",
            "product_names": "Shoes",
            "chargeweightgram": 500,
            "length": 30, "breadth": 20, "height": 15,
            "rto_score": 42,
            "rto_score_reasons": "New address, first order"
        }
    ]
}

27. Search Orders

Searches booked/manifested orders by AWB number, customer name, or mobile number. Powers the topbar search across all pages. Returns a maximum of 20 results.

POST/api/search_orders

Request Body

FieldTypeRequiredDescription
searchstringYesMinimum 3 characters. Matched against AWB, name, and mobile.

Example Request

curl -X POST "https://api4.shiplee.in/api/search_orders" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "search": "98765" }'

Success Response (200 OK)

{
    "orders": [
        {
            "customer_info_id": 1042,
            "awb_number": "143900012345",
            "customer_name": "Rahul Sharma",
            "customer_mobile": "9876543210",
            "status": "manifested",
            "order_date": "2026-03-15 10:00:00"
        }
    ]
}
Returns { "orders": [] } (not an error) if the query is under 3 characters or no results are found.

28. Bulk Update Dimensions

Updates parcel dimensions and recalculates volumetric and charge weight for multiple orders in one call. Only affects orders with status = 'new' that belong to the seller. Leave any field null/omitted to keep the existing value.

POST/api/bulk_update_dimensions

Request Body

FieldTypeRequiredDescription
orderIdsinteger[]Yescustomer_info.id values. Max 500.
lengthfloatNo*Length in cm
breadthfloatNo*Breadth in cm
heightfloatNo*Height in cm
weightfloatNo*Physical weight in grams

* At least one of these fields must be provided.

Example Request

curl -X POST "https://api4.shiplee.in/api/bulk_update_dimensions" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "orderIds": [1042, 1043, 1044],
    "length": 30,
    "breadth": 20,
    "height": 15,
    "weight": 500
}'

Success Response (200 OK)

{
    "success": true,
    "message": "3 order(s) updated successfully.",
    "updated": 3,
    "failed": 0,
    "errors": [],
    "skipped_ids": []
}
Charge weight is recalculated server-side as max(physical_weight, volumetric_weight) where volumetric = (L × B × H) / 5000. Orders not in new status or belonging to a different seller are silently skipped and returned in skipped_ids.

Error Responses

404 Not Found: No eligible orders found for the given IDs.

422 Unprocessable Entity: No orderIds provided, more than 500 IDs, or no dimension fields provided.

29. Create Order

Creates a new quick (manual) order with full customer details, one or more products, and parcel dimensions. Insertions to customer_info, products_q, and parcels are all committed atomically.

POST/api/create_order

Headers

KeyValueDescription
AuthorizationBearer <access_token>JWT token from Login API
Content-Typeapplication/jsonRequest body JSON format

Request Body

ParameterTypeRequiredDescription
pincodestringYes6-digit delivery pincode
citystringYesDelivery city
statestringYesDelivery state
namestringYesCustomer name
mobilestringYes10-digit mobile (starts 6–9)
address1stringYesAddress line 1 (max 100 chars)
address2stringNoAddress line 2 (max 110 chars)
emailstringNoCustomer email. Defaults to [email protected]
order_idstringYesSeller's own reference ID (e.g. "ORD-001")
pickup_typestringNofwd (default) or rvrs
payment_typestringNocod (default) or prd
same_billing_addressbooleanNoIf true (default), billing fields are copied from shipping
reseller_namestringNoOptional reseller name
gstin_numberstringNoOptional GSTIN
productsobject[]YesAt least one product (see below)
parcelsobject[]YesAt least one parcel (see below)

Product Object

FieldTypeRequiredDescription
product_namestringYesProduct name
quantityintegerYesQuantity
product_pricefloatYesUnit price in INR
skustringNoSKU code. Auto-generated if blank.
gst_percentagefloatNoGST % (default 0)
hsn_codestringNoHSN code

Parcel Object

FieldTypeRequiredDescription
lengthfloatYesLength in cm
breadthfloatYesBreadth in cm
heightfloatYesHeight in cm
physical_weightfloatYesPhysical weight in kg. Volumetric weight is calculated server-side.

Example Request

curl -X POST "https://api4.shiplee.in/api/create_order" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "pincode": "110001",
    "city": "New Delhi",
    "state": "Delhi",
    "name": "Rahul Sharma",
    "mobile": "9876543210",
    "address1": "123 Main Street",
    "order_id": "ORD-TEST-001",
    "pickup_type": "fwd",
    "payment_type": "cod",
    "same_billing_address": true,
    "products": [
        { "product_name": "Shoes", "quantity": 1, "product_price": 1299 }
    ],
    "parcels": [
        { "length": 30, "breadth": 20, "height": 15, "physical_weight": 0.5 }
    ]
}'

Success Response (200 OK)

{
    "success": true,
    "message": "Order created successfully.",
    "order_id": 1085,
    "data": {
        "id": 1085,
        "order_id": "ORD-TEST-001",
        "total_price": 1299.00,
        "status": "new",
        "type": "quick"
    }
}
What happens on success:
  • Row inserted into customer_info with type = 'quick', status = 'new'.
  • One row per product inserted into products_q (with GST calculation).
  • One row per parcel inserted into parcels (volumetric weight = L×B×H/5000, charge weight = max(physical, volumetric)).
  • All inserts are in a single transaction — if any step fails, nothing is saved.
  • The returned order_id (integer) is the customer_info.id — this is what you pass to book_shipment.

Error Responses

422 Unprocessable Entity: Missing required fields, invalid pincode/mobile format, invalid pickup_type/payment_type, no products, or no parcels.

500 Internal Server Error: DB failure — transaction rolled back, nothing saved.