FyndTMS

Fynd's logistics layer publishes a full OpenAPI 3.1 spec: client_id and client_secret exchange for a 3 hour bearer token, then serviceability to tracking.

Fynd is an Indian commerce platform, part of Reliance Retail, selling a stack of products to brands and retailers: storefront, order management, warehouse management, POS and a logistics layer. Two things in that stack carry the transport label. Fynd TMS, marketed at fynd.com/solutions/transport-management-system, is the fleet and rider side: route optimisation, dispatch, rider app, live rider location, polygon serviceability zones and electronic proof of delivery. Fynd Logistics, documented at documentation.fynd.com/logistics, is the courier side: multi-carrier shipment booking, rate comparison, AWB allocation, tracking, NDR, RTO and billing dispute. Only the second has a published API, and it is a good one. This page is built from that specification.

Note

The catalogue slug for this entry is fyndtms, and the two products are easy to confuse. The documented, integrable surface is Fynd Logistics. The TMS fleet product is described in marketing material only and has no published interface. Both are covered below, with the boundary marked clearly.

At a glance

What it is

Fynd, legally Shopsense Retail Technologies, is a Mumbai commerce platform majority owned by Reliance Retail. Its documentation site covers six product lines: Fynd Commerce, Fynd Konnect, Fynd AI PIM, Fynd Commerce B2B, Fynd Engage and Fynd Logistics.

Fynd Logistics is a multi-carrier shipping platform. Its own introduction describes the problem it solves as courier selection being manual, weight discrepancies going uncontested, NDR and RTO being hard to act on centrally, and rate comparison requiring several courier portals. What it does: create and manage shipments across courier partners, automate courier selection by destination, weight, payment mode or order value, compare rates and delivery timelines before booking, track through the full lifecycle, review courier billing and raise weight disputes, manage pickup and return addresses, configure the delivery promise shown at checkout, and report on NDR, RTO and on-time delivery.

Fynd TMS is a different product, aimed at own-fleet and hyperlocal operations: AI route planning, automated rider dispatch, polygon based serviceability zones, address enrichment to coordinates, minute level ETAs, live rider tracking, a rider mobile app, and electronic proof of delivery with OTP, images and barcodes. Its marketing page claims 730 plus pre-integrated global courier partners, 1,000 plus locations in a JioMart case study, and 15,000 requests per minute. None of that is documented as an interface.

One detail from the API examples is worth knowing before you design anything: a sample shipper_tracking_url in the shipment details response points at fynd-test.clickpost.in, so at least part of Fynd's carrier tracking is brokered through ClickPost. See /connectors/clickpost.

API access

Credentials are company scoped and come from the logistics panel. The token endpoint's own description says to refer to the Channels settings page, at documentation.fynd.com/logistics/docs/settings/channels, for creating them. Two identifiers appear in every path:

  • company_id, an integer, the Fynd company
  • application_id, a 24 character hexadecimal string, the sales channel within that company

So multi-channel and multi-company sellers are first class: one token per company, and the sales channel is a path segment rather than a separate credential.

The documentation site is unusually cooperative for machine reading. Every page has a Markdown twin: append .md to any documentation URL. The bundled specifications are downloadable:

  • API: https://documentation.fynd.com/_bundle/logistics/apis/@1.0.0/logistics.yaml
  • Webhook: https://documentation.fynd.com/_bundle/logistics/webhook/@1.0.0/logistics.yaml

Terms of service for the API are published at docs.fynd.com/partners/commerce/legal/api-terms, and support is help@fyndplatform.com. No SDK for the logistics API was found; Fynd publishes SDKs for its commerce platform separately.

The documented version is 1.0.0 with no deprecation policy and no changelog on the logistics spec.

Authentication

Bearer JWT, obtained by exchanging an integration key pair.

  1. Create a company or store level integration in the logistics panel under Channels. This yields a client_id, described as the integration username, and a client_secret, described as the integration token or password.
  2. Exchange them for an access token.
  3. Send Authorization: Bearer <access_token> on every subsequent call.
  4. Re-exchange before expires_in elapses. There is no refresh token: the documented flow is to call the token endpoint again.
POST /external/api/v1/company/1234/token HTTP/1.1
Host: logistics.fynd.com
Content-Type: application/json

{
  "client_id": "5f5dc76fc3dd60adgsd1db",
  "client_secret": "970320cc1640c8ac1209525sdfg497eff9e"
}

The documented success response:

{
  "success": "true,",
  "access_token": "eyJhbGciOiJIUzI1NiJ9...",
  "expires_in": 10800,
  "token_type": "Bearer"
}

expires_in of 10800 seconds is three hours. A failure returns 400 with {"success": "false,", "message": "client_id and client_secret are required..."}, and 401 for a bad pair.

  # an authenticated call, once the token is in hand
curl -s 'https://logistics.fynd.com/external/api/v1/company/7404/carrier?is_active=true&page_no=1&page_size=10' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...'
Warning

The documented success values are the strings "true," and "false,", trailing comma included, rather than booleans. That is almost certainly a typo in Fynd's published examples, since the same field is a real boolean in the carrier, location and webhook responses. Parse defensively and do not branch on the token response's success field: branch on the presence of access_token and the HTTP status.

Multi-account handling is clean: one key pair and therefore one token per company_id, with application_id selecting the sales channel per call. A credential store should key on company_id and cache the token for slightly under three hours.

Objects we can read

Orders

Not a first-class object in the logistics API. An order_id and a partner_reference_id ride on the shipment, and client_name records the originating system, "shopify" in the published example. Read orders from the sales channel connector, or from Fynd Commerce, which has its own documented API.

Order items

Read as part of the shipment. The products array on a shipment carries name, quantity, price, sku, hsn_code, category, sub_category, brand, description, size, color, images_url, a weight object with value and unit, a dimensions object, and a full prices object with price_effective, value_of_good, price_marked, gst_fee, gst_percentage and the split igst, cgst and sgst fees and percentages. That is a more complete tax breakdown than most carrier APIs expose.

Products and listings

Not applicable. Fynd Logistics holds no catalogue. Fynd AI PIM and Fynd Commerce are the catalogue products, documented separately.

Inventory

Not applicable in the logistics API.

Shipments and tracking

The core object, and richly modelled.

GET /external/api/v1/company/{company_id}/application/{application_id}/shipment/{shipment_id}/details
Authorization: Bearer <token>

A trimmed version of the published response, with PII fields marked:

{
  "success": true,
  "message": "Shipment fetched successfully",
  "data": {
    "_id": "6a0e9193ba133105679b4af4",
    "order_id": "def84511-6c1e-4b23-b28a-3657d3c6ecc1",
    "shipment_id": "177933966707914T",
    "partner_reference_id": "21MAY26-4",
    "client_name": "shopify",
    "application_id": "66d822b36f9468499d28a3ef",
    "company_id": "33811",
    "status": "Order Placed",
    "status_slug": "orderPlaced",
    "milestone": "Order Placed",
    "shipment_type": "B2C",
    "mps": false,
    "order_type": "PREPAID",
    "delivery_type": "FORWARD",
    "prices": {
      "value_of_good": 666.67,
      "gst_fee": 133.34,
      "gst_percentage": 18,
      "cgst_gst_fee": 66.67,
      "sgst_gst_fee": 66.67,
      "collectible_amount": 123
    },
    "invoice_details": {
      "number": "I00125987A000007",
      "value": 40500,
      "date": "2026-01-07",
      "ewaybill_number": "",
      "ewaybill_date": ""
    },
    "auto_assign_carrier": true,
    "carrier_list": ["67c6f7e5e2af2c7854761738"],
    "carrier_executed_list": [
      {
        "id": "67c6f7e5e2af2c7854761738",
        "name": "Fynd logistics delhivery plan 4",
        "is_active": true,
        "status": "orderPlaced",
        "remarks": "Carrier assigned successfully"
      }
    ],
    "pickup_details": {
      "postal_code": "110035",
      "city": "South Delhi",
      "state": "Delhi",
      "country": "India",
      "lat": 19.1598726,
      "long": 72.99920130000001,
      "contact_details": { "name": "PII", "email": "PII", "phone_number": "PII" }
    },
    "drop_details": { "postal_code": "110035", "contact_details": { "name": "PII" } },
    "rto_details": { "postal_code": "110035", "contact_details": { "name": "PII" } },
    "created_on": "2026-05-21T05:01:07.117Z",
    "modified_on": "2026-05-21T05:03:05.877Z",
    "awb": "6806110210232",
    "carrier_id": "67c6f7e5e2af2c7854761738",
    "carrier_name": "Fynd logistics delhivery plan 4",
    "label": { "url": "https://cdn.fynd.com/.../177933966707914T_label.pdf" },
    "shipper_name": "Delhivery",
    "shipper_tracking_url": "https://fynd-test.clickpost.in/en?waybill=6806110210232"
  }
}

Three status fields coexist: status as a human string, status_slug as a machine token such as orderPlaced, and milestone. Key business logic on status_slug. No complete enumeration of slugs is published, which is the main gap on the read side.

Tracking history is a separate call:

GET /external/api/v1/company/{company_id}/application/{application_id}/shipment/{shipment_id}/awb/{awb}/tracking

All four path parameters are required, so you must already know the shipment id and the AWB. The spec describes it as returning "tracking history and shipment details for a specific AWB" but publishes no response example, so the event array shape is unconfirmed. Sample response not published for this endpoint.

Carriers

GET /external/api/v1/company/{company_id}/carrier?is_active=true&page_no=1&page_size=10
{
  "success": true,
  "items": [
    {
      "id": "691c10b4f7714b0ad15834cb",
      "name": "Fynd Blitz - HLD",
      "description": "hyper-local",
      "region": "intra-city",
      "transport": "surface",
      "payment_mode": ["PREPAID", "COD"],
      "is_active": true,
      "weight_min": 0.01,
      "weight_max": 1,
      "volumetric_weight_min": 0.01,
      "volumetric_weight_max": 1,
      "delivery_type": "hyperlocal"
    }
  ],
  "page": {
    "current": 1,
    "item_total": 10,
    "type": "number",
    "size": 10,
    "has_previous": true,
    "has_next": true
  }
}

The example names Fynd Blitz for hyperlocal and Fynd Bluedart B2B for inter-city, so carriers are configured per company as named plans rather than as a global catalogue. Cache this list: carrier_id on a shipment resolves against it.

Returns and cancellations

Cancellation is POST .../shipment/{shipment_id}/cancel. RTO is not a separate resource: it is an action on the AWB, documented alongside NDR, and rto_details is an address block carried on every shipment from creation. delivery_type on a shipment takes FORWARD, which implies a reverse value exists for return pickups, though the reverse enumeration is not published.

NDR

Handled through one action endpoint with a discriminated body, documented with two named examples:

POST /external/api/v1/company/{company_id}/application/{application_id}/shipment/{shipment_id}/awb/{awb}/action
{
  "action": "re-schedule",
  "address": "12 MG Road, Indiranagar",
  "pincode": "560001",
  "phone_number": "9999999999",
  "preferred_date": "2026-08-12"
}
{
  "action": "return-to-shipper",
  "reason": "Customer refused delivery"
}

The reschedule variant also amends the delivery address and phone, which is the usual NDR resolution. No enumeration of other action values is published.

Proof of delivery

Not exposed in the Fynd Logistics API. Electronic proof of delivery with OTP, images and barcodes is a Fynd TMS feature, on the own-fleet side, and has no documented interface.

Payments and settlements

Not in the logistics API. The operator documentation has a Billing section covering billing history and dispute management at documentation.fynd.com/logistics/docs/billing/, so weight disputes and courier billing are panel features. No settlement or remittance endpoint is published, and no COD remittance cycle is documented. collectible_amount on a shipment's prices is the COD amount to collect, not a remittance record.

Customers

Carried on the shipment as drop_details.contact_details, with name, email, phone_code and phone_number, plus the address, city, state, country, postal code and latitude and longitude. All PII, unmasked in the published examples. There is no customer resource.

Locations

GET  /external/api/v1/company/{company_id}/locations?is_active=true&page_no=1&page_size=10
POST /external/api/v1/company/{company_id}/locations
PUT  /external/api/v1/company/{company_id}/locations/{location_id}

Described as warehouse or store locations for the company, paginated the same way as carriers. No response example is published for the list. Sample response not published.

Writing back: listings, price and stock

Not applicable, this is a carrier layer. Fynd Logistics has no listings, no prices to publish and no stock. Catalogue writes belong to Fynd Commerce and Fynd AI PIM, which are separate documented products.

The write path here is the shipment lifecycle.

Rate and serviceability

POST /external/api/v1/company/{company_id}/application/{application_id}/serviceable-carriers
{
  "action": "GET_RATES",
  "order_type": "PREPAID",
  "delivery_type": "FORWARD",
  "pickup_details": { "postal_code": "400093" },
  "drop_details": { "postal_code": "400086" },
  "packages": [
    {
      "weight": { "value": 1, "unit": "kg" },
      "dimensions": { "height": 10, "length": 10, "breadth": 10, "unit": "cm" },
      "prices": { "value_of_good": 1000, "gst_fee": 180 }
    }
  ]
}

It returns the couriers that can service the pincode pair "along with their delivery promises and estimated rate details". Serviceability and rating are one call, which is the right design: a courier with no rate is not serviceable. No response example is published.

Create shipment

POST /external/api/v1/company/{company_id}/application/{application_id}/shipment

The published request example is large. Its top level fields are action, shipment_type as B2C, order_type as COD or PREPAID, delivery_type as FORWARD, mps for multi-piece shipments, then products, packages, prices, invoice_details, additional_details, pickup_details, drop_details and rto_details.

Points that matter when building the request body:

  • products and packages are separate arrays. A package repeats the product quantities and prices it contains, carries box_number, count, weight, volumetric_weight, dimensions and its own invoice_details including ewaybill_number and ewaybill_date. Multi-piece shipments are modelled properly.
  • Weight units are explicit per object: the example uses gm on products and packages and kg on volumetric weight. Always send the unit, never assume.
  • The tax model is Indian and complete: price_effective, value_of_good, price_marked, and split IGST, CGST and SGST fees and percentages at both product and package level.
  • prices.collectible_amount is the COD amount.
  • additional_details.pickup_date is an ISO timestamp and additional_details.label is a boolean requesting label generation inline.
  • drop_details accepts lat and long alongside the address, which matters for hyperlocal carriers.
  • rto_details is set at creation, so the return address is fixed at booking rather than at failure.
  • auto_assign_carrier, visible in the shipment details response, makes Fynd pick the carrier by the configured shipping rules. Set it false and supply carrier_list to choose yourself.

Label

POST /external/api/v1/company/{company_id}/application/{application_id}/shipment/{shipment_id}/awb/{awb_id}/label

Labels also appear inline on the shipment details response as label.url, a PDF on Fynd's CDN.

Warning

The published description of the label endpoint reads "Retrieve category-specific product attributes (mandatory and optional)", which is copy pasted from a catalogue API and does not describe this operation. The summary, "Generate label for a shipment", is correct. Treat the description as an error in Fynd's documentation, not as a hidden behaviour.

Cancel, NDR and RTO

Covered above: POST .../cancel, and POST .../awb/{awb}/action with re-schedule or return-to-shipper.

No bulk variant of any write operation is documented, and no batch size limit is stated.

Webhooks and notifications

Fynd publishes a separate Webhook API, version 1.0.0, described as pushing "real-time delivery milestones, courier updates, and returns telemetry" so that downstream ERP, WMS, CRM or notification systems do not poll.

POST /external/api/v1/company/{company_id}/webhook

The registration body carries name, webhook_url, auth_type such as Bearer, auth_token and auth_key, which is the header name the token is sent under, defaulting to Authorization. In other words Fynd authenticates itself to your endpoint with a credential you choose, rather than signing the body.

{
  "success": true,
  "message": "Webhook created successfully",
  "data": {
    "name": "client webhook",
    "company_id": 33811,
    "webhook_url": "https://example.com/hooks/fynd",
    "modified_by": "shopify client",
    "is_active": true,
    "created_at": "2026-05-21T04:57:45.013Z",
    "updated_at": "2026-05-21T04:57:45.013Z",
    "id": "6a0e90c9ba133105679b4ae4"
  }
}

GET /external/api/v1/company/{company_id}/webhook lists registrations. The published example shows two registrations on one company, one named "cancel webhook" and one "client webhook", which suggests multiple endpoints can be registered, though no event filter field is documented.

Warning

Three gaps in the webhook documentation matter. The event catalogue is not published, so you cannot know in advance which status changes fire. The event request body is not published, so you cannot write a parser before you receive one. And there is no HMAC signature: authenticity rests entirely on the bearer token you supply at registration, so treat that token as a secret, rotate it, and still verify against the shipment details endpoint before acting on anything financial.

The webhook specification also declares a different server, https://fynd-logistics-platform.com, from the API's https://logistics.fynd.com. That is likely a documentation artefact, since the paths are the same shape, but confirm which host serves the registration call before writing the client.

If push is unavailable, poll GET .../shipment/{shipment_id}/details per open shipment. There is no list-shipments endpoint in the published API, which makes polling expensive: every 30 minutes per open shipment at most, and prefer the webhook.

Rate limits and pagination

No rate limit is published: no quota headers, no numbers in the specification or the operator guide. Fynd TMS marketing claims 15,000 requests per minute as a platform capability, which is not a client entitlement. Rate limit yourself and ask for the real number in the integration conversation.

Pagination is page based on the list endpoints, page_no and page_size, with a page object in the response carrying current, item_total, size, has_previous and has_next. Only carriers and locations are paginated; shipments are fetched individually.

Mapping to the unified model

Gaps and open questions

  • No enumeration of status_slug values. This is the single biggest gap, because every status mapping depends on it.
  • No response example for the AWB tracking endpoint, so the scan event array shape is unknown.
  • No response example for the locations list.
  • No webhook event catalogue and no webhook event body example, and no signature mechanism. Authenticity depends on the token you register.
  • The webhook specification declares a different server host from the API specification. One of the two is wrong.
  • No list-shipments endpoint, which forces per-shipment polling if webhooks are unavailable.
  • No rate limit, no sandbox host, no changelog, no deprecation policy on the logistics spec.
  • Two published documentation errors: the "true," and "false," string values on the token response, and a label endpoint description copied from a catalogue API.
  • Fynd TMS, the fleet and rider product, has no published API at all. Route planning, rider assignment, live rider location and electronic proof of delivery are all marketing claims with no documented interface. If the requirement is own-fleet dispatch rather than courier booking, this page does not cover it and a partner conversation is needed.
  • The 730 plus courier partner claim on the TMS page cannot be reconciled with the carrier list endpoint, which returns only the carriers a given company has configured.
  • Settlement and COD remittance have no interface. For a platform this size that is surprising and worth asking about directly.

Sources