Delivery Tracking Event Webhooks Guide

This guide is for developers integrating with the iDrive Shipping API outbound webhook system. It covers what the service does, how to authenticate, how to create and manage subscriptions, what event payloads look like, and how to build a reliable consumer.

iDrive Shipping API Webhooks

Push: Receive tracking updates to your endpoint as they happen. You don't need to poll.

📘

Prefer to fetch tracking data on demand?

See the Tracking Event (polling) Guide for pulling tracker data yourself.

Who this is for

3PLs (most integrators). You manage many merchants, each set up as a subtenant under your 3PL tenant. You create one subscription on your 3PL tenant, and it receives events for every merchant under it. Each event tells you which merchant it belongs to.

Single shippers. You ship for your own business only, so you create a subscription on your own tenant. Everything below still applies, and you can skip the 3PL notes.

Events

EventFires when
tracking.updatedA shipment's tracking status changes

Environments

https://api.beta.idrivelogistics.com   # sandbox (testing)
https://api.idrivelogistics.com        # production

The sandbox uses its own account and API keys. Ask your iDrive contact for sandbox credentials.

1. Get an access token

Create an API key in the iDrive TMS under Settings > API Keys and choose Full access. Read-only keys can't manage webhooks. 3PLs should create the key while logged into the 3PL tenant. You can also ask your iDrive contact to create the key for you.

POST /api/v1/tokens/m2m
Content-Type: application/json

{ "grantType": "clientCredentials", "clientId": "...", "clientSecret": "..." }

tenantId is optional in this request and defaults to your key's tenant. 3PLs should use their 3PL tenant.

Send Authorization: Bearer <accessToken> on every request. Tokens last 1 hour, so request a new one before the current one expires.

2. Create a subscription

curl -X POST https://api.idrivelogistics.com/api/v1/webhooks \
  -H "Authorization: Bearer <accessToken>" \
  -H "Content-Type: application/json" \
  -d '{
    "uri": "https://your-app.example.com/webhooks/idrive",
    "email": "[email protected]",
    "registeredEvents": ["tracking.updated"],
    "secret": "your-hmac-secret"
  }'
FieldRequiredNotes
uriYesHTTPS only. Must be publicly reachable. Redirects are not followed.
emailYesReceives an alert if the subscription is auto-disabled
registeredEventsYesFor example ["tracking.updated"]
secretOne of these twoUsed to sign each delivery (recommended)
credentialsOne of these two{ "username", "password" }, sent as Basic Auth
customHeaderNoOne extra { "key", "value" } header sent on every delivery

Secrets are never returned. The response shows hasSecret, hasCredentials and hasCustomHeader instead.

Other endpoints:

  • GET /api/v1/webhooks lists your subscriptions.
  • GET /api/v1/webhooks/{webhookId} gets one subscription.
  • PATCH /api/v1/webhooks/{webhookId} updates one. To change a stored secret, credentials or custom header, also send updateSecret, updateCredentials or updateCustomHeader set to true.
  • DELETE /api/v1/webhooks/{webhookId} deletes one.

3. What you receive

{
  "id": "kwevt_abc123",
  "eventType": "tracking.updated",
  "tenantId": "merchant-tenant-id",
  "payloadType": "TrackerV1",
  "createdDate": "2026-06-15T12:00:00.000Z",
  "payload": { }
}
  • tenantId is the merchant the shipment belongs to. 3PLs should use it to route each event to the right merchant. Single shippers will always see their own tenant ID.
  • payload is the full tracker. Its fields and statuses are described in The Tracker resource.
  • Check payloadType before processing. If you see a value you don't recognize, log it and skip it.

4. Build your endpoint

Your endpoint should do the following:

  1. Verify the signature. The X-Hmac-Sha256 header is a base64 HMAC-SHA256 of the raw request body. Compute it before you parse the JSON.

    import { createHmac, timingSafeEqual } from "node:crypto";
    
    function isValid(rawBody: string, signature: string, secret: string) {
      const expected = Buffer.from(
        createHmac("sha256", secret).update(rawBody, "utf8").digest("base64")
      );
      const received = Buffer.from(signature);
      return expected.length === received.length && timingSafeEqual(expected, received);
    }
  2. Respond within 500 ms. Return a 2xx right away and do the real work in a background queue. Slower responses count as failures.

  3. Skip duplicates. The same event can arrive more than once. Save each id (also sent in the x-idrive-event-id header) for at least 48 hours, and skip any you've already seen.

  4. Handle events arriving out of order. Compare payload.updatedAt with what you have stored, and ignore anything older.

5. Retries and auto-disable

If your endpoint fails or times out, we retry after about 30 s, 60 s, 120 s and 240 s, for 5 attempts in total. After that, we don't send that event again.

If 10 events in a row fail every retry, the subscription is turned off and the email on file is notified. To turn it back on:

PATCH /api/v1/webhooks/{webhookId}
{ "isActive": true }

3PLs: one subscription covers all of your merchants, so if it's disabled, events stop for every merchant at once. Watch that inbox.

6. Expiration

Subscriptions expire 120 days after they're created (see expirationDate in the response). Expired subscriptions stop receiving events, and no email is sent when that happens.

To keep receiving events, create a new subscription before the old one expires, then delete the old one. The new subscription gets a new webhookId, so don't hard-code it.

7. Catching up on missed events

If events were missed, for example while your endpoint was down or the subscription was disabled:

  • 3PLs: use GET /api/v1/trackers with your 3PL token. It returns trackers for all of your merchants.
  • Single shippers: use GET /api/v1/trackers, or GET /api/v1/webhookEvents to see what we sent.

8. Errors

Error responses include message, statusCode, errorCode, errors and correlationId.

StatusMeaning
400Invalid request. Check errors.
403Your API key doesn't have access. Use a Full access key.
404The item doesn't exist or isn't yours.
500Our error. Retry, and include the correlationId if you contact support.

FAQ

Can I send events to more than one URL? Yes. Create one subscription per URL.

Can a 3PL get events for only some of its merchants? No. A subscription on the 3PL tenant receives events for every merchant under it. Filter by tenantId on your side.

How do I test locally? Use a tunnel such as ngrok against the sandbox (api.beta.idrivelogistics.com).


Did this page help you?