Ekart

Ekart Logistics, Flipkart's carrier arm: a live merchant API with an Authorization token plus merchant code header, shipment create, track, update and RTO.

Ekart Logistics is Flipkart's in house supply chain arm, and the largest captive logistics network in India. It moves the overwhelming majority of Flipkart's own parcels, and it also sells capacity to third party sellers and aggregators as a standalone carrier. For a commerce database it is a carrier connector: no orders, no listings, no stock. What it gives us is a tracking id and a label when we book, a tracking history, a shipment update mechanism that doubles as the NDR action path, and return to origin and reverse pickup flows. Ekart publishes nothing about its API. The API itself, however, is live, self describing at the edge and can be mapped precisely by probing, which is what this page does.

At a glance

Note

HTTP_X_MERCHANT_CODE is a real header name, not a transcription error. It looks like a PHP $_SERVER superglobal key (HTTP_ prefix plus the uppercased header name) that was adopted as the literal header, which is a fingerprint of an older PHP gateway somewhere in Ekart's stack. Send it exactly as written.

What it is

Ekart was founded in 2009 as Flipkart's internal delivery arm, at a point when no Indian third party carrier could reliably do cash on delivery at e-commerce scale. It grew into the country's largest logistics network by parcel volume, with its own sortation hubs, line haul, last mile fleet and a large kirana and franchise based delivery layer. It is owned by Flipkart, which is majority owned by Walmart.

Two things follow for anyone building a connector. First, Ekart is not a neutral carrier: its first duty is Flipkart's own volume, and third party capacity is sold selectively. A D2C brand does not simply sign up. Second, most sellers meet Ekart through an intermediary rather than directly, either as the carrier assigned to a Flipkart marketplace order under Flipkart Advantage, or as a courier option inside an aggregator. Shiprocket exposes it as courier_company_id 48 (Ekart Logistics) and 54 (Ekart Logistics Surface), for example. In both of those cases the connector you want is the Flipkart one or the aggregator one, not this one.

A direct Ekart integration means a contracted third party shipper relationship with a merchant code.

API access

There is no console, no documentation portal and no signup. Access comes from a commercial conversation with Ekart, after which you receive a three character merchant code, an API credential and a documentation pack.

Hosts, verified live on 2026-09-22:

The API surface, established by probing each path with each verb. The gateway is precise: an unknown path returns 404, a known path with the wrong verb returns 405, and a known path with the right verb but no credential returns 401. That distinction is what makes the table below verifiable rather than guessed.

Two things that surface immediately from that map. There is no serviceability or pincode endpoint, so a pre booking check against Ekart is not possible over this API; you need a serviceability file from Ekart or you rely on the creation call failing. And there is no pickup endpoint, so pickups are a standing arrangement rather than a per shipment request.

There are no official SDKs, and no published version policy. The presence of /v3/shipments/track alongside /v2/shipments/track, with no /v3 equivalent for creation, suggests tracking was versioned independently.

Authentication

Two headers, no exchange step and nothing to refresh.

  1. Authorization: <token>. Note: the production integrations send the token bare, with no Bearer prefix. The token's origin is not publicly documented; it is issued by Ekart rather than obtained from a login endpoint, and no login path exists anywhere on the API surface probed.
  2. HTTP_X_MERCHANT_CODE: <three-character-merchant-code>.
  3. Content-Type: application/json.
curl -X POST 'https://api.ekartlogistics.com/v2/shipments/track' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: <ekart-token>' \
  -H 'HTTP_X_MERCHANT_CODE: ABC' \
  -d '{"request_details": [{"tracking_id": "ABCC1234567890"}]}'

Anything missing or wrong returns HTTP 401 with {"unauthorised":"invalid_user_credential"}, verified live. Supplying HTTP Basic credentials or a merchant code without a valid token produces the same body, so the error message does not distinguish which of the two headers is at fault.

Multi account is one merchant code per Ekart shipper. Because the merchant code is also the prefix of every tracking id (see below), a platform shipping for several brands under one Ekart contract cannot separate them by tracking id alone.

Objects we can read

Shipments and tracking

POST /v2/shipments/track, with /v3/shipments/track also deployed. The request carries a request_details array of tracking_id values, matching the shape used by the other operations on this API.

There is no pagination, no date window and no "changed since" filter: a lookup by key. The response shape could not be verified without credentials. What can be established from a production integration is that Ekart responses are envelopes with a response array positionally parallel to the request array, each element carrying at least a tracking_id and a status_code, where status_code: 200 means the operation succeeded for that element. Expect tracking to follow the same pattern.

No proof of delivery artefact is exposed by any endpoint on the probed surface.

Orders, listings, inventory, serviceability, returns, settlements

None. The API surface is shipments only. Reverse flows exist as operations rather than as readable objects. COD remittance and freight invoicing are handled outside this API.

Writing back: listings, price and stock

Not applicable, this is a carrier. There are no listings, no prices and no stock. The write path is the shipment lifecycle, and it is the richest part of this API.

Create a shipment

POST /v2/shipments/create. The body is deeply nested, unlike every other Indian carrier in this set, and is organised around services and service legs rather than around a flat shipment:

{
  "client_name": "ABC",
  "services": [
    {
      "service_code": "Regular",
      "service_details": [
        {
          "service_leg": "FORWARD",
          "service_data": {
            "vendor_name": "Ekart",
            "delivery_type": "SMALL",
            "amount_to_collect": 999,
            "source": {
              "address": {
                "first_name": "Main Warehouse",
                "address_line1": "Plot 7, Industrial Area",
                "city": "Delhi", "state": "Delhi", "pincode": "110030",
                "primary_contact_number": "9811111111",
                "email_id": "warehouse@example.com"
              }
            },
            "destination": {
              "address": {
                "first_name": "Ramesh Kumar",
                "address_line1": "12, MG Road",
                "city": "Pune", "state": "Maharashtra", "pincode": "411001",
                "primary_contact_number": "9876543210"
              }
            },
            "return_location": {
              "address": {
                "first_name": "Main Warehouse",
                "address_line1": "Plot 7, Industrial Area",
                "city": "Delhi", "state": "Delhi", "pincode": "110030",
                "primary_contact_number": "9811111111",
                "email_id": "warehouse@example.com"
              }
            }
          },
          "shipment": {
            "tracking_id": "ABCC1234567890",
            "shipment_value": 999,
            "shipment_dimensions": {
              "length": { "value": 20 },
              "breadth": { "value": 15 },
              "height": { "value": 5 },
              "weight": { "value": 0.5 }
            },
            "shipment_items": [
              {
                "quantity": 1,
                "seller_details": { "seller_reg_name": "Example Brand" },
                "item_attributes": [
                  { "name": "order_id", "value": "ORD-10231" },
                  { "name": "invoice_id", "value": "INV-10231" }
                ]
              }
            ]
          }
        }
      ]
    }
  ]
}

The single most important thing on this page: you generate the tracking id yourself. Ekart does not assign it. The format observed in a production integration is the three character merchant code, then a single character C for cash on delivery or P for prepaid, then ten digits. So a merchant code of ABC on a COD shipment produces a tracking id like ABCC1234567890. That has real consequences: uniqueness is your problem, the payment mode is baked into the AWB and cannot be changed after the fact, and you must never reuse an id.

Other notes:

  • client_name repeats the merchant code that is already in the header.
  • amount_to_collect is the COD amount, zero for prepaid.
  • delivery_type takes size band values such as SMALL.
  • service_leg is FORWARD here; reverse flows use the dedicated endpoints below rather than a different leg on this one.
  • item_attributes is a free form name and value list, and it is the only place to record your own order id and invoice number. Nothing in the request has a dedicated field for them.
  • Dimensions are wrapped one level deeper than necessary, as {"value": n} objects. Units are not published; the production integration passes centimetres for dimensions and kilograms for weight.

The response carries response[0].tracking_id, echoing back the id you supplied, and a status_code.

Update a shipment, including NDR actions

PUT /v2/shipments/update_shipment is the workhorse. There is no separate NDR endpoint on this API: failed delivery actions are expressed as shipment updates.

{
  "update_request_type": "RESCHEDULE_DELIVERY_DATE",
  "update_request_details": { "updated_delivery_date": "2026-09-23" },
  "tracking_id": "ABCC1234567890"
}

The update_request_type values observed in a production integration:

A practical NDR re-attempt is therefore two calls: correct the address or phone with CUSTOMER_DETAILS or CUSTOMER_CONTACT, then reschedule with RESCHEDULE_DELIVERY_DATE. There is no "re-attempt as instructed" action and no deferred delivery slot.

PUT /v2/shipments/update also exists on the probed surface and is distinct from update_shipment. Its purpose is unverified.

Return to origin

PUT /v2/shipments/rto/create with {"request_details": [{"tracking_id": "ABCC1234567890"}]}. Batched: request_details is an array. The response is a parallel response array where status_code: 200 per element means the RTO was accepted.

This is also how you cancel: there is no /v2/shipments/cancel path (it returns 404), so sending a shipment back is the cancellation mechanism once it is in the network.

Reverse pickup cancellation

PUT /v2/shipments/rvp/cancel with the same request_details array shape. Note that rvp/create returns 404, so reverse pickups are presumably created through /v2/shipments/create with a different service_leg or service_code. That mapping is unverified.

Warning

The verbs matter and the public integration is inconsistent with the live gateway. A production integration POSTs to /v2/shipments/rto/create and /v2/shipments/update_shipment in one place and PUTs to them in another. Probing on 2026-09-22 shows POST returning 405 and PUT returning 401 on both, so PUT is the verb the gateway accepts. Use PUT for update, update_shipment, rto/create and rvp/cancel, and POST for create and track.

Webhooks and notifications

Not published, and there is no subscription endpoint anywhere on the probed surface. Ekart does push status to large partners under separate arrangements; that is an account conversation.

Poll POST /v2/shipments/track. Because the request takes a request_details array, batch your tracking ids rather than calling per shipment. With no published rate limit, poll in flight shipments every 60 to 120 minutes in batches, and stop at a terminal status.

Rate limits and pagination

Neither is published, and neither could be measured without credentials.

  • Pagination: none. Tracking, RTO and reverse pickup cancellation all take arrays and return parallel arrays; there is no cursor and no page.
  • Rate limits: not published, and no quota headers were observed on the 401 responses. Implement your own limiter and back off on any non-200.

One structural note on batching: because responses are positionally parallel to requests, a partial response or a reordering would silently mis-attribute results. Match on tracking_id in the response element, not on array index.

Mapping to the unified model

Ekart contributes shipments only.

ship_to_address maps to service_data.destination.address, which is PII. locations maps to service_data.source.address and return_location.address, both sent per shipment rather than registered once, so there is no warehouse registry to read. The payment method is recoverable from the tracking id's fourth character, which is the only place it survives.

Gaps and open questions

  • No public documentation at all. Ekart publishes nothing. This page is a map of the live gateway plus one production integration's request bodies.
  • Every response shape is unverified. Tracking in particular: the field names for status and scan history are unknown. Budget a discovery round against a live tracking id.
  • The token's origin is unknown. No login or token endpoint exists on the probed surface, so the Authorization value is presumably a long lived credential issued by Ekart. Its lifetime and rotation procedure are unpublished.
  • No serviceability, no rates, no pickup. All three are absent from the API. Serviceability has to come from a file, pricing from your contract, and pickups from a standing arrangement. This is the most operationally significant gap.
  • Reverse pickup creation is unmapped. rvp/cancel exists but rvp/create returns 404, so reverse shipments are created some other way, presumably through create with a different service_leg. Unverified.
  • /v2/shipments/update versus /v2/shipments/update_shipment. Both exist, both take PUT, and only the second appears in any public integration. The difference is unknown.
  • /v3/shipments/track exists with no /v3 sibling for creation. Whether v3 is a drop in replacement, and whether v2 tracking is deprecated, is unpublished.
  • Tracking id generation is the caller's responsibility, with no published format specification and no collision check documented. The merchant code plus payment character plus ten digit format comes from one integration. Confirm your allocated range with Ekart before generating anything, and treat a duplicate id as a serious defect.
  • No published rate limits and no quota headers.
  • Units unpublished for dimensions and weight.

Sources

Verified live on 2026-09-22 by direct request against https://api.ekartlogistics.com:

  • POST /v2/shipments/create, POST /v2/shipments/track, POST /v3/shipments/track, PUT /v2/shipments/update, PUT /v2/shipments/update_shipment, PUT /v2/shipments/rto/create, PUT /v2/shipments/rvp/cancel: all return HTTP 401 {"unauthorised":"invalid_user_credential"}
  • GET /v2/shipments/track, GET and POST on the four PUT paths, PATCH and DELETE on /v2/shipments/update: HTTP 405 {"code":405,"message":"HTTP 405 Method Not Allowed"}
  • /v2/shipments, /v2/shipments/cancel, /v2/shipments/label, /v2/shipments/status, /v2/shipments/reverse, /v2/shipments/rvp/create, /v2/shipments/track/bulk, /v2/serviceability, /v2/pincodes, /v2/pincode/serviceability, /v2/pickup/create, /v2/ndr, /v1/shipments/track, /v1/shipments/create, /v3/shipments/create, /v3/shipments/cancel: all HTTP 404 {"code":404,"message":"HTTP 404 Not Found"}
  • https://staging.ekartlogistics.com/v2/shipments/track: HTTP 401 with the same envelope, confirming the staging host
  • Supplying HTTP Basic credentials or an HTTP_X_MERCHANT_CODE header without a valid token returns the same 401 body
  • DNS: ekartlogistics.com resolves to 163.53.77.41, api.ekartlogistics.com to 163.53.76.23, staging.ekartlogistics.com to 163.53.76.0. developer.ekartlogistics.com does not resolve
  • https://ekartlogistics.com/ redirects to /ekartlogistics-web and serves an internal application titled "EKL Grocery Dashboards", whose error reporting points at sentry.flipkart.com, confirming Flipkart ownership. It is not a developer or marketing site

Secondary, one production integration read for request bodies:

  • Avry123/node-worker, src/actions/deliveryPartner/ekart.ts: the Authorization and HTTP_X_MERCHANT_CODE headers, the tracking id generation format, the full /v2/shipments/create body with services, service_details, service_leg, service_data, shipment and shipment_items, the update_shipment request with its three update_request_type values, the rto/create and rvp/cancel request_details array shape, and the response[].tracking_id and response[].status_code envelope