Skip to content
IMPROVEDAuto-detect is smarter - the right courier, first timeTry it →

API and webhooks

API quickstart

Create an API key, add shipments with one request and read their statuses. Base URL, authentication, limits and error codes.

Updated

The Business API lets your own systems add shipments to your workspace and read their statuses. It is on the Starter plan and above. It works on the shipments we already check for you, so reading from it never sends a fresh request to the courier; to be told about changes as they happen, add a webhook (see Verifying webhook signatures).

1. Create a key

Owners and Admins create keys under Developers → API keys. Creating a key asks for your authenticator code (see Two-step sign-in). Give the key a name and choose what it may do:

  • shipments:read to read shipments;
  • shipments:write to add, update, archive and refresh them;
  • webhooks:manage to manage webhook endpoints.

The key, starting tp_live_, is shown once: store it somewhere safe, such as your server's secrets. You can archive a key, or rotate it, which creates a new key and keeps the old one working for 24 hours while you switch.

2. The basics

  • Base address: https://trackparcel.in/api/v1
  • Send your key in the x-api-key header on every request.
  • Requests and responses are JSON. Times are in IST with the offset (+05:30).

3. Add shipments

Send 1 to 100 shipments in one request. Only tracking_number is required; leave out courier and we detect it, or give it to be sure. Each shipment in the reply says whether it was created, existing (already tracked), restored (brought back from the archive) or invalid, with the reason.

Add a shipment
curl -X POST https://trackparcel.in/api/v1/shipments \
  -H "x-api-key: tp_live_your_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9f1c2a7e-order-SO-1182" \
  -d '{
    "shipments": [
      {
        "tracking_number": "1234567890123",
        "courier": "delhivery",
        "order_id": "SO-1182",
        "label": "Blue kurta",
        "tags": ["priority"],
        "customer": {
          "name": "R Kumar",
          "phone": "+919812345678",
          "city": "Pune",
          "state": "Maharashtra",
          "pincode": "411001"
        }
      }
    ]
  }'
  • Send an Idempotency-Key header that is unique to the batch. If a network error makes you send the same request again with the same key within 24 hours, nothing is added twice.
  • customer is optional: the details are kept with the shipment for your team, and the API returns them when you read it.

4. Read shipments

List shipments that are stuck
curl "https://trackparcel.in/api/v1/shipments?exception=stuck&limit=100" \
  -H "x-api-key: tp_live_your_key_here"
Shipment endpoints
RequestWhat it does
GET /shipmentsLists shipments. Filter by status, courier, tag, exception, archived, updated_since (an ISO 8601 time) or search. Up to 100 a page; pass the cursor from one page to get the next.
GET /shipments/{id}One shipment, with its latest status, exceptions and expected delivery.
GET /shipments/lookup?tracking_number=…&courier=…Finds a shipment by its tracking number.
PATCH /shipments/{id}Updates the label, order ID, tags, customer or courier. Changing the courier checks it again.
POST /shipments/{id}/archiveArchives it. /unarchive restores it.
GET /shipments/{id}/eventsThe courier's updates, newest first.
POST /shipments/{id}/refreshAsks for a fresh check. Answers 202 and uses one of your manual refreshes.
GET /usageYour usage so far. Free to call, up to 30 times a minute.

Reads (the list, a lookup, one shipment and its events) cover the shipments added within your plan's history: a year on Starter and three years on Growth, and all of them on Pro and Enterprise. An older shipment answers not_found with a message saying it was added before your plan's history window. Older shipments are kept and appear when you upgrade.

A shipment

Shipment object
{
  "id": "6f1c…",
  "tracking_number": "1234567890123",
  "tracking_number_raw": "1234567890123",
  "courier": {"id": "delhivery", "name": "Delhivery"},
  "status": "out_for_delivery",
  "status_label": "Out for delivery",
  "status_text": "Out For Delivery",
  "exceptions": [{"type": "ofd_overdue", "since": "2026-10-12T09:10:00+05:30"}],
  "last_event": {"at": "2026-10-12T08:02:00+05:30", "location": "PUNE", "activity": "Out For Delivery"},
  "eta": {"date": "2026-10-12", "source": "courier"},
  "delivered_at": null,
  "order_id": "SO-1182", "label": "Blue kurta", "tags": ["priority"],
  "customer": {"name": "R Kumar", "phone": "+919812345678", "email": null, "city": "Pune", "state": "Maharashtra", "pincode": "411001"},
  "archived": false,
  "last_checked_at": "2026-10-12T10:40:11+05:30",
  "created_at": "2026-10-10T17:22:05+05:30"
}

status is one of the statuses in What statuses mean, status_label is how the app shows it, and status_text is the courier's own words. Tracking numbers are always returned in full; tracking_number_raw is exactly what was sent to us.

Shipments are archived, not deleted

DELETE /shipments/{id}
HTTP/1.1 405 Method Not Allowed

{"error":{"code":"archive_only","message":"Shipments can be archived, not deleted"}}

Limits

Business API limits by plan
PlanRequests per minute, per keyCalls per monthly period
Starter301,000
Growth6010,000
Pro12050,000
EnterpriseAs agreedAs agreed

Responses carry X-Quota-Limit, X-Quota-Used and X-Quota-Reset headers, so you can see where you stand without a separate call.

Errors

Every error carries a code and a readable message, with a matching HTTP status. The codes are:

Business API error codes
CodeMeaning
invalid_tracking_numberNot a tracking number we can use (6–40 letters or digits).
courier_requiredWe couldn't tell the courier from the number; send it.
unknown_courierWe don't recognise the courier you sent.
plan_limit_reachedYour plan's limit stops this request.
quota_exceededYou have used this period's API calls.
rate_limitedToo many requests this minute; wait and retry.
role_forbiddenThat isn't allowed for this workspace or key.
scope_missingThe key lacks the permission this request needs.
not_foundNo such shipment or webhook in your workspace, or a shipment added before your plan's history window.
archive_onlyShipments can be archived, not deleted.
idempotency_conflictThat Idempotency-Key was used for a different request.

The full reference is in the Business API section of the API documentation, with an OpenAPI 3.1 file at /api-docs/openapi.json.

Contact support.

Still stuck? Talk to us

In the app, open Help → Contact support to write to us, and follow your conversations under My conversations. On the Free plan, email us at support [at] trackparcel.in.

We answer Monday to Saturday, 10:00–19:00 IST, excluding national holidays. Include your workspace's name and the tracking numbers involved, in full, and we can look straight away.

Support channels and first-reply targets by plan
PlanHow to reach usFirst reply
FreeHelp centre, and email3 business days, best effort
StarterEmail and the in-app form2 business days
GrowthEmail and in-app1 business day
ProEmail and in-appSame business day
EnterpriseA named contact and an onboarding call4 business hours