Vamaship

Vamaship's public REST Customer API, bearer-token auth: pincode coverage, quotes, booking with AWB and labels, tracking, NDR, cancellation, wallet and webhooks.

Vamaship is an Indian shipping aggregator for D2C, marketplace and B2B sellers, founded in Mumbai in 2015. A seller books through Vamaship, Vamaship allocates the parcel to one of its courier partners, and the seller gets one rate card, one waybill format, one tracking feed and one COD remittance. Unusually for an Indian aggregator of this size, Vamaship publishes a complete first-party API reference as a public Postman collection at docs.vamaship.com, including a sandbox base URL, real sample responses, the full tracking status code table and webhook registration. That makes it one of the easiest Indian carrier connectors to build against.

At a glance

What it is

Vamaship describes itself as India's leading shipping aggregator for D2C and e-commerce brands. Its site claims, as of 2026-09-21: founded 2015 in Mumbai, 3,000 or more businesses on the platform, 70 lakh or more shipments handled, 15 or more courier partners, coverage of 27,000 or more pincodes, zero platform fees, instant COD remittance and a 4.4 out of 5 rating on the Shopify App Store.

It is a carrier aggregator, not a marketplace. Sellers connect stores (Amazon, Shopify, WooCommerce, Instamojo) or order systems (ClickPost, Unicommerce, Zoho Inventory, EasyEcom, Vinculum) and Vamaship does the last-mile execution. The booking_medium field in the webhook API exposes exactly this set of upstream sources, which is useful: it tells you which system originated a shipment when the same account is also booking through an aggregator.

Services split into Air Domestic (express, forward and reverse) and Surface (B2B and B2C). Partner selection can be automatic, driven by rules configured in the Vamaship panel, or explicit by passing a supplier_id obtained from the quote call.

API access

  • Sign up at vamaship.com. The panel issues the API key. The collection refers to it only as "Your Bearer token" and does not document a key-issuance endpoint, so key rotation is a panel operation.
  • Two environments are documented in the collection:

Note the path differs between them: sandbox has /ecom/api/v1, production has /ecom/v1. Make the base URL a single configuration value rather than assembling it from parts.

  • Bookings are charged against a prepaid wallet held at the account ("entity") level and shared by all users under it. If the wallet is empty, bookings fail. The Wallet API exists precisely so a seller's own system can keep it funded.
  • No official SDK is published. The Postman collection itself is the artefact to import; it ships code snippets in cURL, C#, Dart, Go, Java, JavaScript, Node, Objective-C and others.
  • There is an "Ambassador API" group for reseller accounts (GET /ambassadors/entities/{id}/credits, POST /ambassadors/users), which is not relevant to a single-seller connector.

Authentication

There is no token exchange. The API key is long-lived and sent directly.

  1. Obtain the API key from the Vamaship panel for the seller account.
  2. Send it on every request as Authorization: Bearer plus the API key, with Content-Type: application/json on calls that have a body.
  3. There is no documented refresh, no expiry and no scope system. Multi-account support is therefore trivial: store one key per channel_account_id and select it per request.
curl -X POST "https://api.vamaship.com/ecom/v1/dom/coverage" \
  -H "Authorization: Bearer $VAMASHIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"prepaid","origin":400005,"subtype":"general"}'
Warning

The key is a bearer credential with no expiry and full booking rights against a funded wallet. Store it encrypted, never in client code, and ask Vamaship how to rotate it before you go live.

Objects we can read

Orders

Vamaship has a first-class order object that exists before a shipment is booked, which is convenient: you can push orders as they are captured and decide on the carrier later.

  • POST /orders create one or more orders. Each entry in shipments becomes a separate order.
  • GET /orders?status=Created&page=1 list, newest first, 25 per page. Filters: status (Created, Fulfilled, Cancelled), q (search by reference), payment_type (Prepaid, COD), page.
  • GET /orders/{id} fetch one.
  • PUT /orders/{id} update, and DELETE /orders/{id} cancel, both only while the order is in Created status.
{
  "success": true,
  "orders": [
    {
      "id": 26738887,
      "accounts_entity_id": 1509,
      "shipment_no": null,
      "payment_type": "Prepaid",
      "from_pincode": "400077",
      "to_pincode": "110001",
      "order_date": "2026-09-15 13:27:47",
      "cod_value": "0.00",
      "product_value": "1500.00",
      "currency_code": "INR",
      "product": "Wireless Headphones",
      "weight": "0.50",
      "weight_unit": "KG",
      "quantity": 1,
      "reference1": "DOC-EX-001",
      "status": "Created",
      "booking_medium": "customer_api",
      "dest_full_name": "Rahul Sharma",
      "dest_address_line_1": "45, Connaught Place",
      "dest_pincode": "110001",
      "dest_state": "Delhi"
    }
  ],
  "pagination": { "current_page": 1, "per_page": 25, "total": 1, "last_page": 1 }
}

dest_full_name and the dest_address_line_* fields are PII. reference1 and reference2 are the two slots available for your own identifiers; use reference1 for your order_id and keep it unique, since the tracking API can look shipments up by reference number.

Order items

Not modelled. An order carries a single product description, product_value, quantity and hsn_code. There is no line-item array, so a multi-line order has to be flattened into one description or split into several Vamaship orders.

Products and listings, inventory

Not applicable, this is a carrier. Neither object exists.

Shipments and tracking

Booking is asynchronous. POST /dom/book returns status_code: 300 with a refid, and the actual result is fetched from the polling endpoint or pushed to the booking webhook.

{
  "message": "Shipment is being processed. Hit the polling API to keep checking the status.",
  "refid": "718901863",
  "status_code": 300,
  "success": true
}

GET /details/{refid} returns the completed booking, with AWB, allocated partner and document URLs:

{
  "status_code": 200,
  "success": true,
  "documents": {
    "labels": ["https://api.vamaship.com/ecom/v1/download/Vamaship-Label-718901107.pdf?q=..."],
    "thermal_labels": ["https://api.vamaship.com/ecom/v1/download/Vamaship-Thermal-Label-718901107.pdf?q=..."],
    "manifests": ["https://api.vamaship.com/ecom/v1/download/Vamaship-Manifest-718901107.pdf?q=..."]
  },
  "refid": "718901107",
  "shipments": [
    {
      "awb": "SF1714561728VAE",
      "order_id": 305481187,
      "supplier_id": 161,
      "supplier_name": "STD B2C - Shadowfax",
      "reference1": "002",
      "reference2": "refno2",
      "success": true,
      "type": "prepaid",
      "duration": 3
    }
  ]
}

Three tracking entry points, all GET with comma-separated keys in the path:

{
  "tracking_details": {
    "305480906": {
      "success": true,
      "trackingEvents": [
        {
          "datetime": "2025-05-02 12:39:00",
          "status": "Pickup Scheduled",
          "location": "GHATKOPAR (GHT)",
          "comments": "PICKUP HAS BEEN REGISTERED",
          "status_code": 1070
        }
      ],
      "supplier_id": 119,
      "chargeable_weight": 0.6,
      "shipment_cost": "234.46",
      "payment_type": "COD",
      "cod_amount": "100.00",
      "partner_track_url": "https://www.bluedart.com/...",
      "vamaship_track_url": "https://vamaship.co/?tracking_ids=305480906",
      "trackId": "80787319653",
      "order_id": 305480906,
      "rto_charge": 0,
      "estimated_delivery_date": "2025-05-04 00:00:00"
    }
  }
}

The status code table is published in full. The ones that matter for state machines: 1000 Booking Pending, 1010 Shipment Booked, 1020 Shipment Manifested, 1025 Cancel Requested, 1039 Missed Pickup, 1050 Pickup Cancelled, 1070 Pickup Scheduled, 1083 Pickup Re-scheduled, 1100 Out for Pickup, 1200 Picked Up from Origin, 1220 Shipment In-Transit, 1250 Shipment Cancelled, 1280 Received at Origin Hub, 1300 Shipment On-Hold, 1400 Received at Destination Hub, 1440 Shipment Misrouted, 1500 Shipment Lost, 1550 Shipment Damaged, 1560 Unexpected Challenge, 1570 Address Incorrect, 1616 Delay in Delivery expected, 1700 Shipment Out for Delivery, 1770 Delivery Attempt Failed, 1800 Partial Delivery, 1850 Pending, 1880 Contact Customer Support, 1900 Delivered, 2000 Return Shipment Initiated, 2020 Return Shipment In Transit, 2025 Return Shipment Exception, 2030 Return Shipment Delivered, 8000 Tracking Closed.

Codes in the 2000 range are the RTO lane. 1770 is the NDR trigger.

For a bulk backfill rather than per-shipment tracking, POST /data/shipments takes from_date, to_date and page_no and returns shipment_no, tracking_id, rto_tracking_id, tracking_status, reference1, reference2 and created_at, paginated at 100 per page. This is the right endpoint for a nightly reconciliation job.

Rates and serviceability

  • POST /dom/coverage with a body of type (prepaid, cod or reverse), origin (a pincode) and optional subtype (general or valuable) returns a plain array of serviceable destination pincodes for that origin. The response is large (thousands of integers), so cache it per origin and refresh daily rather than calling it per order. POST /surface/coverage is the surface equivalent.
  • POST /dom/quote (and /dom/quote-reverse, /surface/quote, /surface/essential/quote) returns rates per partner. Set seller.get_all_quotes: true to get every partner rather than the panel default.
{
  "status_code": 200,
  "success": true,
  "quotes": [
    {
      "success": true,
      "suppliers": [
        {
          "supplier_id": 119,
          "supplier": "EXP - Bluedart",
          "shipping_cost": 234.46,
          "duration": 4,
          "break_up": {
            "charge_heads": { "freight": 138, "fuel_surcharge": 20.7, "cod_charge": 40 },
            "total_before_tax": 198.7
          }
        }
      ],
      "reference1": "002"
    }
  ]
}

Returns and cancellations

  • Reverse shipments: POST /dom/quote-reverse then POST /dom/book-reverse. In a reverse booking the roles invert: the seller block is the delivery destination and the shipments[] address is the pickup location, that is the customer.
  • POST /cancel with {"order_ids":[305480906, ...]}. The response is keyed by order id. Cancellation is auto-approved after 2 working days if pickup has not happened, and auto-rejected if it has.
  • NDR: GET /ndr?page=N returns a Laravel-style paginated list (current_page, data, per_page 25, total, next_page_url). POST /ndr/addComment takes shipment_numbers (array of integers), response_code with values return, reattempt or fake_remark, and optional additional_details. This is the write path for NDR resolution and is worth wiring into the connector, not just reading.

Payments and settlements

There is no settlement statement API. What exists is the prepaid wallet:

  • GET /credits returns {"status":"success","status_code":200,"credit":"-79892.12"}. Note the balance is a string and can be negative.
  • POST /wallet/payment-link returns a payment_token and a hosted payment_url. GET /wallet/payment-link/{token} polls the result, or the payment webhook pushes it.

COD remittance is a headline product claim ("COD remitted in hours") but no remittance API is published. Treat COD reconciliation as a panel or report exercise.

Customers, locations

No customer object. Consignee details are attributes of a shipment. No location or pickup-address-book endpoint is published either: the pickup address is supplied inline on every quote and book call as the seller block.

Writing back: listings, price and stock

Not applicable, this is a carrier. Vamaship holds no catalogue, price or sellable stock, so there is nothing to write back in the listings sense.

The write surface is the shipment lifecycle:

Pickup is not a separate call. It is implicit in booking, and the resulting pickup state shows up as tracking codes 1070, 1083, 1100, 1039 and 1050. The deprecated pickup_date field still appears in the book request body; the documentation marks it deprecated, so do not rely on it.

Labels, thermal labels and manifests come back as signed PDF URLs from the polling response. GET /download/{id}/Vamaship-Label-{id}.pdf is the documented download shape; the signed ?q= query string on the URLs returned by polling suggests the links are time-limited, so fetch and store the PDF rather than storing the URL.

Webhooks and notifications

Three callback types, all registered through the same endpoint:

{
  "booking_medium": ["customer_api"],
  "booking_callback_url": "https://example.com/vamaship/booking",
  "tracking_callback_url": "https://example.com/vamaship/tracking"
}
  • POST /webhooks registers or updates. One URL is stored per callback type per booking medium; calling again with the same pair overwrites. payment_callback_url can be sent in the same request body and is scoped to the account rather than a booking medium.
  • GET /webhooks lists what is currently registered.
  • booking_medium accepts the upstream source of the shipment. Use ["customer_api"] for shipments you book yourself. Other documented values reflect the seller's other integrations, for example easyecom, unicommerce, vinculum or clickpost. Register for all the mediums the seller actually uses, otherwise you will silently miss events for shipments booked elsewhere.
  • Booking callbacks fire when a booking completes and carry the AWB, labels and manifest, so they remove the need to poll GET /details/{refid}. Tracking callbacks fire on every status change.
  • All callbacks are POST with a JSON body. Respond with HTTP 200 to acknowledge.

The wallet payment callback is the only one whose body is published:

{
  "event": "wallet.payment",
  "payment_token": "vamaship_olp6aa93ff585114_87567b64b2f157a765c5",
  "payment_status": "success",
  "amount": 500,
  "received_amount": 500,
  "payment_mode": "UPI",
  "reference_number": "INV-2026-0042",
  "error_message": null,
  "completed_at": "2026-09-15 18:13:25"
}
Warning

No signature header, HMAC secret or retry policy is documented for any of the three callbacks, and the booking and tracking callback bodies are not published at all. The collection's own advice for the payment callback is to treat the webhook as a notification and confirm with GET /wallet/payment-link/{token} before acting. Apply the same rule to booking and tracking: accept the push as a trigger, then read the authoritative state from GET /details/{refid} or GET /track/{ids}. Use an unguessable callback path and verify the shipment exists on your side before writing anything.

Rate limits and pagination

No rate limits, quota headers or throttling rules are published anywhere in the collection. Documented pagination:

A sane cadence: register both shipment webhooks and treat them as the primary feed; run POST /data/shipments once a night over a 3 day rolling window to catch missed events; refresh POST /dom/coverage per origin pincode once a day; call GET /credits every few minutes if you book at volume, since an empty wallet fails bookings silently from the seller's point of view.

Mapping to the unified model

Gaps and open questions

  • No rate limit is published. Ask Vamaship for a number before running a backfill.
  • Booking and tracking webhook bodies are not documented, and no signature mechanism is described for any callback. Both need confirming with Vamaship before you can treat pushes as authoritative.
  • The NDR sample response has an empty data array, so the per-record field names (reason code, attempt count, deadline) are unknown.
  • COD remittance, which is a headline commercial feature, has no API. Confirm whether a remittance report is available by SFTP or email.
  • The sandbox and production base URLs differ in path shape (/ecom/api/v1 versus /ecom/v1). Worth confirming that every endpoint exists under both, since the whole collection is written against the sandbox host.
  • The word "order_id" means the Vamaship order in the Orders API and the shipment number in the tracking and polling APIs. Confirm with Vamaship which identifier their support team uses, because it will matter on every escalation.
  • Whether the API key expires or can be rotated in the panel is not documented.

Sources

  • Vamaship Customer API docs, read 2026-09-21. Public Postman Documenter site. The underlying collection JSON (docs.vamaship.com/api/collections/7976991/2sBYAyupWA) was read directly for request bodies, sample responses, parameter tables and the tracking status code list.
  • Vamaship homepage, read 2026-09-21. Company facts, scale claims, integration list, signup flow.
  • Host probing of api.vamaship.com, app.vamaship.com, docs.vamaship.com, 2026-09-21. api.vamaship.com redirects a browser to app.vamaship.com; the API itself is served under the documented base paths.