API Reference
Webhooks

Webhooks

What Are Webhooks?

When a shipment's status changes, TrackLogy sends a POST request to your store's webhook_url. This lets you react in real time — update your order system, trigger fulfillment workflows, send internal alerts, or sync data to a third-party service.

Webhooks are configured per store and fire for every shipment status change within that store.

Configuring a Webhook

Set webhook_url and webhook_secret on your store using either method:

  • Dashboard: Settings → Stores → Edit → Webhook URL
  • API: Include webhook_url and webhook_secret in the POST /v1/stores request body

The webhook_secret is used to sign outgoing requests. Choose any long, random string and store it securely on your server.

Webhook Request Format

Every webhook delivery includes the following:

  • Method: POST {your_webhook_url}
  • Header: Content-Type: application/json
  • Header: User-Agent: TrackLogy/1.0
  • Header: X-TrackLogy-Signature: sha256={hmac_signature}
  • Header: X-Hub-Signature-256: sha256={hmac_signature}

X-TrackLogy-Signature is TrackLogy's native signature header. X-Hub-Signature-256 carries the same value and exists as a GitHub-format alias so that WooCommerce and Shopify plugins that already verify X-Hub-Signature-256 work out of the box without any extra configuration.

The signature is HMAC-SHA256 of the raw request body using your store's webhook_secret.

Event: tracking.updated

TrackLogy fires this event whenever a tracked shipment transitions to a new status.

Full Payload Example

{
  "event": "tracking.updated",
  "shipment_id": 4201,
  "tracking_number": "1Z999AA10123456784",
  "tracking_provider": "ups",
  "status": "out_for_delivery",
  "est_delivery_date": "2025-05-08",
  "customer_name": "Jane Smith",
  "customer_email": "[email protected]",
  "order_id": "ORD-1001",
  "order_number": "ORD-1001",
  "store_platform": "woocommerce",
  "events": [
    {
      "status": "out_for_delivery",
      "description": "Out for delivery",
      "location": "New York, NY",
      "timestamp": "2025-05-08 08:15:00"
    },
    {
      "status": "in_transit",
      "description": "Arrived at facility",
      "location": "Newark, NJ",
      "timestamp": "2025-05-07 22:00:00"
    },
    {
      "status": "in_transit",
      "description": "Departed from facility",
      "location": "Philadelphia, PA",
      "timestamp": "2025-05-07 14:30:00"
    }
  ],
  "pushed_at": "2025-05-08 08:20:00"
}

The events array contains the full tracking history for the shipment at the time of push, ordered newest-first (up to 100 events). Each event includes status, description, location (may be null), and timestamp.

Verifying Signatures

⚠️

Always verify the X-TrackLogy-Signature header before trusting the payload. This confirms the request originated from TrackLogy and has not been tampered with in transit.

The signature is computed as:

sha256= + HMAC-SHA256(raw_request_body, webhook_secret)

Use your store's webhook_secret as the HMAC key. Always use the raw request body bytes — not a re-serialized JSON object — to compute the signature.

Verification in PHP

$payload   = file_get_contents('php://input');
$secret    = 'your_webhook_secret';
$signature = 'sha256=' . hash_hmac('sha256', $payload, $secret);
 
if (!hash_equals($signature, $_SERVER['HTTP_X_TRACKLOGY_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit('Invalid signature');
}
 
$data = json_decode($payload, true);
// handle $data['event'], $data['status'], etc.

Verification in Node.js

const crypto = require('crypto');
 
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-tracklogy-signature'];
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');
 
  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }
 
  const event = JSON.parse(req.body);
  console.log('Status:', event.status);
  res.status(200).send('OK');
});

Note that express.raw() is used instead of express.json() to preserve the raw body bytes needed for signature verification.

Testing Your Webhook

Via Dashboard

Go to Dashboard → Stores → Test Webhook to send a sample payload to your configured endpoint. This is the easiest way to verify that your handler is reachable and responding correctly.

Via API

curl -X POST https://api.tracklogy.com/v1/stores/webhook/test \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"store_id": 5}'

Replace 5 with your store's numeric ID.

Retry Policy

TrackLogy does not currently retry failed webhook deliveries. Your endpoint should return a 2xx response within 10 seconds. If your handler needs more time to process the event, acknowledge the request immediately and handle processing asynchronously.

Log incoming webhook payloads so you have a record if a delivery fails or your handler has a bug.