Ecom Express

Ecom Express API: username and password in every form post, manifest, AWB fetch, pincode list, tracking and NDR. Hosts now dead after the Delhivery merger.

Ecom Express was, until recently, one of the three carriers an Indian D2C brand would name in the same breath as Delhivery and Xpressbees: a pure play e-commerce logistics company, strong on cash on delivery and reverse pickup, with a plain and long lived HTTP API. It is now part of Delhivery. The acquisition has already reached the public surfaces: ecomexpress.in serves a single "Delhivery X Ecom Express, Better Together" holding page on every path, api.ecomexpress.in no longer resolves in DNS, and plapi.ecomexpress.in answers with an expired TLS certificate and returns {"message":"Not Found"} for every documented path. This page therefore records what the API was, because integrations against it still exist in the wild and need to be migrated, and is explicit that it is no longer a target to build against.

At a glance

Warning

Do not build a new Ecom Express connector. Verified on 2026-09-22: api.ecomexpress.in returns NXDOMAIN, plapi.ecomexpress.in presents a wildcard certificate for *.ecomexpress.in that expired on 23 May 2026 and returns {"message":"Not Found"} for /apiv2/pincodes/, /apiv2/fetch_awb/, /apiv2/manifest_awb/, /apiv2/cancel_awb/, /apiv2/ndr_resolutions/ and /track_me/api/mawbd/ alike. The whole of ecomexpress.in serves one holding page pointing at Delhivery.

What it is

Ecom Express Limited was founded in 2012 by a team out of Blue Dart and First Flight, and built itself specifically around e-commerce parcels rather than documents or general freight. Its differentiators were cash on delivery handling, reverse logistics and deep reach into tier two and tier three pincodes, which made it the second or third carrier in most D2C brands' mix rather than the first. It never operated as a marketplace or a sales channel: purely a carrier, with an optional fulfilment arm.

The company filed for an initial public offering in 2024 and withdrew it, then ran into severe financial difficulty, and in 2025 Delhivery acquired it. By 2026 the consolidation is visible from the outside: the brand's own website now exists only to redirect customers to Delhivery, and the API hosts have been taken down rather than kept alive behind a redirect.

For a commerce database the practical consequence is a data continuity problem. Historical shipments that moved on Ecom Express AWBs are still in sellers' order histories, and the tracking API that would have backfilled their scan history no longer answers. Whatever scan data you already hold is all you will get. Going forward, those sellers are on Delhivery, and their shipments will carry Delhivery waybills.

API access

Access was never self serve. A seller signed a contract with Ecom Express, received a customer code, and was issued an API username and password by the account team along with a PDF integration document. There was no developer console, no key rotation UI and no scopes.

Historical base hosts:

Both production hosts served the same paths, and open source clients used them interchangeably, which is itself a sign of how informally the API was versioned. There was no version in the path beyond the literal string apiv2, and no changelog.

There were no official SDKs. The ecosystem was community built.

Authentication

There was nothing to exchange. username and password were ordinary form fields appended to the body of every request:

curl -X POST 'https://plapi.ecomexpress.in/apiv2/pincodes/' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'username=<api-username>' \
  --data-urlencode 'password=<api-password>'

An invalid credential produced a response body containing the string Unauthorised, which clients matched on rather than reading a status code. There was no token lifetime, no refresh and no scope model, so credential rotation meant asking the account manager and redeploying.

Multi account was one username and password per Ecom Express customer code. There was no concept of an application acting for several sellers.

Objects we can read

None of these respond today. They are recorded for the benefit of anyone reading an existing integration.

Shipments and tracking

POST /track_me/api/mawbd/ with awb set to one waybill or a comma separated list, plus the credentials.

The response was XML, not JSON, even though the rest of the API was JSON, and it used a generic object and field structure rather than named elements: a list of <object> elements, each containing <field name="...">value</field> entries, with the scan history nested inside a field named scans whose children were themselves field lists. Clients had to walk the tree and flatten it into a dictionary keyed by awb_number. There was no pagination and no "changed since" filter, so the only way to track was to poll by AWB.

An alternate path, /track_me/api/mawb/, was used as the public human facing tracking URL.

Pincode serviceability

POST /apiv2/pincodes/ with credentials only, returning the entire serviceable pincode list as JSON. There was no single pincode lookup on this endpoint: you pulled the whole list and cached it. A separate serviceability path, /services/expp/expppincode/, appears in multi carrier aggregator code as an Ecom Express pincode check.

AWB inventory

POST /apiv2/fetch_awb/ with count and type, where type was COD or PPD (prepaid). It returned a block of waybill numbers to be consumed by the manifest call. Unlike Delhivery, waybills had to be fetched before manifesting: AWB_NUMBER was a required field in the manifest request, not something the carrier assigned for you.

Orders, listings, inventory, returns, settlements

None existed. A reverse pickup was a manifest with the addresses reversed, not a separate object. COD remittance and freight invoicing were handled outside the API.

Writing back: listings, price and stock

Not applicable, this is a carrier. There were no listings, no prices and no stock. The write path was manifest, cancel and NDR.

Create a shipment (manifest)

POST /apiv2/manifest_awb/ with username, password, awb and json_input, where json_input was a URL encoded JSON array of shipment objects. Field names were upper case with underscores, unusually for a JSON API:

[
  {
    "AWB_NUMBER": "1234567890",
    "ORDER_NUMBER": "ORD-10231",
    "PRODUCT": "COD",
    "CONSIGNEE": "Ramesh Kumar",
    "CONSIGNEE_ADDRESS1": "12, MG Road",
    "CONSIGNEE_ADDRESS2": "",
    "CONSIGNEE_ADDRESS3": "",
    "DESTINATION_CITY": "Pune",
    "STATE": "Maharashtra",
    "PINCODE": "411001",
    "MOBILE": "9876543210",
    "TELEPHONE": "",
    "ITEM_DESCRIPTION": "Cotton shirt",
    "PIECES": "1",
    "COLLECTABLE_VALUE": "999",
    "DECLARED_VALUE": "999",
    "ACTUAL_WEIGHT": "0.4",
    "VOLUMETRIC_WEIGHT": "0.4",
    "LENGTH": "15",
    "BREADTH": "14",
    "HEIGHT": "11",
    "PICKUP_NAME": "Main Warehouse",
    "PICKUP_ADDRESS_LINE1": "Plot 7, Industrial Area",
    "PICKUP_ADDRESS_LINE2": "",
    "PICKUP_PINCODE": "110030",
    "PICKUP_MOBILE": "9811111111",
    "PICKUP_PHONE": "",
    "RETURN_NAME": "Main Warehouse",
    "RETURN_ADDRESS_LINE1": "Plot 7, Industrial Area",
    "RETURN_ADDRESS_LINE2": "",
    "RETURN_PINCODE": "110030",
    "RETURN_MOBILE": "9811111111",
    "RETURN_PHONE": "",
    "ROUTE": ""
  }
]

PRODUCT was COD or PPD and was the single field that decided prepaid versus cash on delivery. COLLECTABLE_VALUE was the cash to collect, zero for prepaid. ORDER_NUMBER was the only join key back to a seller's order.

Cancel a shipment

POST /apiv2/cancel_awb/ with awbs (comma separated), username and password. The response was a JSON array with one entry per AWB carrying a success boolean and, on failure, a reason string. HTTP status was not a reliable signal; clients branched on success.

Act on a failed delivery (NDR)

POST /apiv2/ndr_resolutions/ as multipart/form-data with username, password and json_input, the last being a JSON array of action objects:

[
  {
    "awb": "1234567890",
    "instruction": "RAD",
    "comments": "Reattempt requested",
    "scheduled_delivery_date": "2026-09-23",
    "scheduled_delivery_slot": "1",
    "mobile": "9876543210",
    "consignee_address": { "CA1": "12, MG Road", "CA2": "", "CA3": "", "CA4": "" }
  }
]

instruction was RAD to re-attempt delivery and RTO to send the shipment back. The four CA1 through CA4 fields were the corrected address lines, used when the failure reason was a bad address. Only the re-attempt path accepted a scheduled date and slot.

Pickup

No pickup request endpoint appears in any open source client. Pickups were scheduled through the Ecom Express client panel or by standing arrangement with the local hub, not over the API. This is a gap worth stating plainly rather than guessing at.

Webhooks and notifications

None published, and none found in any integration. Every client polled /track_me/api/mawbd/, batching AWBs into the comma separated awb parameter. No rate limit was ever published, and a typical integration polled in flight shipments a few times a day.

Rate limits and pagination

Neither was published. There is no pagination anywhere: tracking is a lookup by key, the pincode endpoint returns everything, and AWB fetch takes a count. Assume nothing, because there is nothing left to measure.

Mapping to the unified model

Historical only. Ecom Express contributed shipments and nothing else.

ship_to_address on an order maps to the CONSIGNEE*, DESTINATION_CITY, STATE and PINCODE fields you sent, all PII. locations maps to the PICKUP_* and RETURN_* blocks, which were sent per shipment rather than registered once, so there was no warehouse registry to read.

Gaps and open questions

  • The API is gone. Every documented host and path was probed on 2026-09-22 and none responds usefully. Treat any Ecom Express connector as a migration task, not a maintenance task.
  • No migration path is published. Neither the Ecom Express holding page nor Delhivery's developer portal describes how an existing Ecom Express client maps onto Delhivery credentials, waybill ranges or the Token header. That conversation is with the Delhivery account team.
  • Historical scan data cannot be backfilled. If you did not capture the scans while the API was live, they are not retrievable.
  • The documentation was never public, so every field name and behaviour on this page comes from open source clients. Where clients disagreed, the shape used by the two most production-looking integrations is the one shown.
  • No pickup API was ever found. It may have existed in the client documentation pack; no public integration uses one.
  • The staging host ecomm.prtouch.com carries shared credentials committed to open source repositories. If you are auditing an inherited integration, check whether it is still pointed at that host and still carrying those credentials.

Sources

Verified live on 2026-09-22:

  • DNS: api.ecomexpress.in returns NXDOMAIN. plapi.ecomexpress.in resolves to 13.234.171.133 and 35.154.218.47
  • TLS: plapi.ecomexpress.in presents CN=*.ecomexpress.in, issued by Amazon RSA 2048 M03, valid 23 Apr 2025 to 23 May 2026, therefore expired
  • HTTP: POST to /apiv2/pincodes/, /apiv2/fetch_awb/, /apiv2/manifest_awb/, /apiv2/cancel_awb/, /apiv2/ndr_resolutions/, /track_me/api/mawbd/ on plapi.ecomexpress.in all return HTTP 404 with {"message":"Not Found"}
  • ecomexpress.in and ecomexpress.in/apis: both serve the same "Delhivery X Ecom Express, Better Together" holding page with a "Continue to Delhivery" call to action
  • developer.ecomexpress.in: does not resolve

Secondary, open source clients read for the historical API shape:

  • Unkodero/ecom-express-api, a PHP client: the base hosts, the credentials in the request body, /apiv2/pincodes/, /apiv2/fetch_awb/ with count and type, /apiv2/manifest_awb/ with json_input, /track_me/api/mawbd/ with awb, the XML object and field response shape, and the Unauthorised error string
  • elanic-tech/angarum, Partners/ecomexpress.js, a production multi carrier integration: the full upper case manifest field list, /apiv2/cancel_awb/ with awbs and the success and reason response, and the /track_me/api/mawb/ public tracking path
  • Avry123/node-worker, src/actions/deliveryPartner/ecom.ts: /apiv2/ndr_resolutions/ as multipart form data, the instruction values RAD and RTO, and the CA1 through CA4 address correction fields