Shipyaari

Shipyaari seller API: email and password signIn returns a bearer JWT, with rates, order placement, AWB, label, manifest, tracking, NDR and RTO.

Shipyaari is an Indian shipping aggregator serving D2C brands, marketplace sellers and B2B shippers. It resells rate cards across roughly 25 courier partners (Blue Dart, DTDC, Delhivery, Ecom Express, XpressBees and others) and adds warehousing, a hyperlocal and same day product, and a working capital product ("Capital by Shipyaari"). Its seller API is published openly as a Postman collection at docs.shipyaari.com, covering rate shopping, order placement with AWB assignment, label and manifest generation, tracking, NDR actions and weight discrepancy reconciliation.

At a glance

What it is

Shipyaari (AVN Group, Mumbai) has been in logistics since the mid 2010s and repositioned as a technology aggregator with the current seller platform, which the collection labels "Blaze". It serves B2C ecommerce shipping, B2B and cargo, hyperlocal, international, and offers fulfilment centres. The seller panel is at app.shipyaari.com and the API host is api-seller.shipyaari.com.

For the unified model it is a source of shipments only. It is not a sales channel and holds no catalogue. One detail visible in the tracking response is worth noting: shipments carry a source field whose sample value is UNICOMMERCE, which means Shipyaari records which upstream system pushed the order. Orders arriving from an order management system will be tagged accordingly.

API access

  • Seller account required. There is no separate developer registration, app id or approval step documented: the panel login is the API login.
  • Hosts in use: https://api-seller.shipyaari.com/api/v1/ for almost everything, and https://tracking.shipyaari.com/api/v1/ for weight discrepancy reconciliation. Both are v1.
  • No official SDK in any language. Two Shipyaari WooCommerce plugins exist on WordPress.org (shipyaari-shipping-managment and manage-shipyaari-shipping), but they were last touched around 2019 and call an older generation of endpoints at seller.shipyaari.com/logistic/webservice/*.php. Those legacy PHP routes are unrelated to the current REST API and should not be used as a reference.
  • No published sandbox, pricing for API access, or partner tiering.

Authentication

  1. POST the seller panel email and password to seller/signIn.
  2. Read data[0].token, along with sellerId, companyId and privateCompanyId, which identify the account.
  3. Send the token as Authorization: Bearer on every subsequent call, with Content-Type: application/json.
  4. Re-sign in when the token expires. There is no refresh token.
POST /api/v1/seller/signIn HTTP/1.1
Host: api-seller.shipyaari.com
Content-Type: application/json

{
  "email": "seller@example.com",
  "password": "Test@123"
}
{
  "success": true,
  "data": [
    {
      "name": "test Example",
      "email": "seller@example.com",
      "sellerId": 1010,
      "companyId": "00a8dd6f-9a70-497e-b7bd-2c149521fdad",
      "privateCompanyId": 100018,
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "nextStep": { "qna": true, "kyc": true, "bank": true },
      "isReturningUser": true
    }
  ],
  "message": "Seller Signed In Successfully."
}

The JWT carries email, sellerId, companyId, privateCompanyId, iat and exp. Token lifetime is not stated in prose and the published samples disagree: the sign in sample spans 86,400 seconds (24 hours), while a token captured on the weight reconciliation call spans 604,800 seconds (7 days). Do not hard code a lifetime. Read exp from the token itself and refresh on expiry or on the first 401.

curl -X POST "https://api-seller.shipyaari.com/api/v1/order/checkServiceabilityV2" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pickupPincode":400018,"deliveryPincode":202002,"invoiceValue":10,"paymentMode":"PREPAID","weight":10,"orderType":"B2C","dimension":{"length":1,"width":1,"height":1}}'

Multi seller support means one email, password and token per Shipyaari seller account. The companyId is a shared UUID across the samples while privateCompanyId and sellerId differ, which suggests a company and seller hierarchy, but sub account scoping is not documented.

Every response uses the same envelope: success (boolean), data (always an array, even for a single result), and message. Note that logical failures such as "no tracking info found" are returned with HTTP 500 and success: false, not a 4xx, so the status code cannot be trusted on its own.

Objects we can read

Orders

There is no order list or order detail read in the published collection. Orders can be created and cancelled but not enumerated. The only order shaped read is the AWB lookup for asynchronous B2B bookings:

GET /api/v1/order/delhiveryB2B/jobId/{jobId}

{
  "success": "success",
  "code": 200,
  "data": { "job_id": "5a4443e3-41a1-4044-b182-c14a6a21bd9a", "awb": "295549886" },
  "message": "AWB retrieved successfully."
}

Note the envelope differs here (success is the string "success" and a code field appears), so this endpoint was built separately from the rest.

Shipments and tracking

GET /api/v1/tracking/getTracking?trackingNo={awb}

{
  "success": true,
  "data": [
    {
      "trackingInfo": [
        {
          "isRTO": false,
          "tempOrderId": "17332975595044120",
          "orderType": "B2C",
          "orderId": "5940054360292",
          "awb": "77695249144",
          "courierPartnerName": "BLUEDART",
          "currentStatus": "BOOKED",
          "source": "UNICOMMERCE",
          "zone": "ZONE 4",
          "shipmentStatus": {
            "rtoAwb": "",
            "outForDelivery": [],
            "attemptsReasons": [],
            "rtoInitiDate": "",
            "deliveryDate": "",
            "rtoDeliveryDate": "",
            "lastScanDatePartner": 1733297520000,
            "EDD": null,
            "pickUpDate": null
          },
          "processedLog": [
            {
              "Scans": [
                {
                  "status": "BOOKED",
                  "message": "ONLINE SHIPMENT BOOKED",
                  "location": "RAMA ROAD"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

The shipmentStatus object is the useful part: it carries the RTO waybill, the out for delivery attempts, the NDR attemptsReasons array, the RTO initiation and delivery dates, the last carrier scan timestamp as epoch milliseconds, the expected delivery date and the pickup date, all on one record. processedLog[].Scans[] is the event history.

The query parameter is singular (trackingNo). Whether comma separated AWBs are accepted is not documented, so assume one AWB per call until tested.

Serviceability and rates

POST /api/v1/order/checkServiceabilityV2 with pickupPincode, deliveryPincode, invoiceValue, paymentMode (PREPAID in the sample), weight, orderType (B2C), and a dimension object.

{
  "success": true,
  "data": [
    {
      "partnerServiceId": "8a6cec14",
      "partnerServiceName": "DTDC-B2C_AIR",
      "companyServiceId": "f9943462",
      "companyServiceName": "STANDARD",
      "partnerName": "DTDC",
      "serviceMode": "AIR",
      "appliedWeight": 1,
      "invoiceValue": 10,
      "collectableAmount": 0,
      "insurance": 0,
      "base": 10,
      "cod": 0,
      "tax": 1.8,
      "total": 11.8,
      "zoneName": "ZONE 3",
      "EDT": 3,
      "sortType": "priority",
      "priorityRank": 1,
      "cheapestRank": 1
    }
  ]
}

This is the rate card and the serviceability check in one call. EDT is the expected days in transit, zoneName the rate zone, and priorityRank and cheapestRank are Shipyaari's own orderings. The partnerServiceId returned here is what gets passed back on order placement to pin a carrier service.

Weight reconciliation

POST https://tracking.shipyaari.com/api/v1/tracking/weight-discrepancy-recon with {"orderId": "3627"}. This is the billed weight dispute surface, which most Indian aggregators expose only in the panel. Response shape is not published in the collection.

Not available

No order list, no products or listings, no inventory, no customers, no settlements or COD remittance, no proof of delivery endpoint, no pickup request endpoint (pickup is implied by order placement), and no returns or reverse pickup endpoint in the published collection despite reverse shipping being a marketed feature.

Writing back: listings, price and stock

Not applicable, this is a carrier aggregator. Shipyaari holds no catalogue, price or stock. The write path is the shipment lifecycle.

Place an order

POST /api/v1/order/placeOrderApiV3

The request body is three blocks: pickupDetails, deliveryDetails and boxInfo[]. Both address blocks take addressType, fullAddress, pincode, a pickup or delivery window as startTime and endTime (hours as strings), latitude, longitude, and a contact object with name, mobileNo and alternateMobileNo. deliveryDetails also accepts gstNumber.

boxInfo[] is per package: name, type (parcel), weightUnit, deadWeight, length, breadth, height, qty, discount, measureUnit (cm) and a products[] array carrying name, category, sku, hsnCode, qty, unitPrice, discount, unitTax, sellingPrice, totalDiscount, totalPrice, weightUnit and deadWeight. Multi box shipments are native: the box is the unit, not the order.

The response echoes a resolved pickupAddress object (with a generated pickupAddressId, normalised city and state, working days and working hours) alongside orderId, shipyaariId, orderType, sellerId and privateCompanyId. Shipyaari creates the pickup address record from the free text address on first use, so addresses are deduplicated server side rather than registered in advance.

POST /api/v1/order/placeDraftOrderApi takes the same request body and creates a draft, which returns only a message and an empty data array.

Label, manifest and invoice

All three take an array of AWBs and a source field, and all three cap the batch at 10:

  • POST /api/v1/labels/fetchLabels with {"awbs": ["343669666744"], "source": "API"}. An AWB must already be assigned.
  • POST /api/v1/order/fetchManifest. The AWB must be assigned and a pickup requested.
  • POST /api/v1/labels/fetchTaxInvoices.

Each returns a download URL for the generated PDF.

Cancel

POST /api/v1/order/cancelAWBs with {"awbs": ["76947842882"]}. The response is "AWB Cancel Process Started", so cancellation is asynchronous: a 200 here means accepted, not cancelled. Confirm through tracking.

NDR, RTO and reattempt

POST /api/v1/order/ndr-rto-remarks with awb, requestType (RTO in the sample), comments and an optional preferredDate for a reattempt. One AWB per call.

Change buyer details

POST /api/v1/order/updateBuyerInfo with airwaybillno, buyer_name, buyer_last_name and buyer_contact. Note the field naming here is snake case and the AWB parameter is airwaybillno, unlike every other endpoint, which is a sign this route came from the older system.

Webhooks and notifications

None published. The collection has no callback registration, no event catalogue and no signature scheme. Shipyaari markets branded tracking and buyer notifications, but those are sent to the buyer, not to the seller's server.

Poll instead:

  • Tracking: read getTracking for each open AWB. Because the endpoint appears to take a single trackingNo, budget one request per open shipment, which caps how tight the cadence can be. Every 30 to 60 minutes for the open set, tighter only for shipments whose shipmentStatus.outForDelivery is populated.
  • NDR: there is no NDR list endpoint, so exceptions must be detected from shipmentStatus.attemptsReasons on the tracking read.
  • Rates and serviceability: call per order at checkout, there is no bulk pincode dump.

Rate limits and pagination

No rate limits, quota headers or 429 semantics are published. The only documented volume limits are the batch caps stated on the label, manifest and invoice endpoints: a maximum of 10 per call.

There is no pagination anywhere in the published collection, because there are no list endpoints. Tracking is by identifier, rate shopping is per lane, and label generation is by batch of up to 10. Any bulk read therefore has to be driven from the connector's own set of AWBs.

Given single AWB tracking and no webhooks, a large seller will be request bound. Keep concurrency low, cache serviceability results per lane and weight slab, and treat the tracking poll as the dominant cost.

Mapping to the unified model

Gaps and open questions

  • There is no way to list orders or shipments. Without an order list endpoint, the connector must be the system of record for every AWB it creates, and any shipment created in the panel is invisible to it.
  • No webhooks, so status is pull only, and tracking appears to be one AWB per request.
  • Token lifetime is contradictory between published samples (24 hours versus 7 days). Read exp from the token.
  • Logical errors return HTTP 500 with success: false. Whether real server faults are distinguishable from "not found" is unclear.
  • No returns or reverse pickup endpoint, no pickup request endpoint, and no proof of delivery endpoint, despite all three being marketed features. They are presumably panel only or available on request.
  • The weight discrepancy reconciliation endpoint sits on a different host and its response shape is not published.
  • updateBuyerInfo uses a different naming convention (airwaybillno, snake case) from the rest of the API, suggesting mixed generations behind one gateway. Expect inconsistency.
  • No rate limits, changelog, versioning or deprecation policy.
  • Two abandoned WooCommerce plugins on WordPress.org reference an entirely different legacy endpoint family. If a seller is on one of those, they are not on this API.

Sources