Agent skill
ClickPost Webhooks Skill
Receive and authenticate ClickPost shipment tracking webhooks. Use when setting up a ClickPost status webhook endpoint, verifying the Authorization: Token header, debugging 401s, or handling scan events by clickpost_status_code such as Delivered, OutForDelivery, PickedUp and InTransit.
Install this skill
npx skills add hookdeck/webhook-skills --skill clickpost-webhooks
ClickPost (shipment tracking for e-commerce) sends a JSON POST for each shipment scan: a flat record with waybill, cp_id, status, remark, location, timestamp, clickpost_status_code, clickpost_ and an additional object that includes latest_status. Webhooks are not signed. With Simple Token authentication every request carries Authorization: Token <secret>, and your endpoint authenticates the sender by comparing it with the token you configured.
Choose Simple Token authentication on the ClickPost webhook and paste the token.
When to Use This Skill
- How do I receive ClickPost webhooks?
- How do I verify the
Authorization: Tokenheader on a ClickPost webhook? - Does ClickPost sign webhook payloads? (No: it uses a shared token)
- How do I handle
clickpost_status_code8 (Delivered) or 6 (OutForDelivery)? - Why does my ClickPost webhook endpoint return 401?
Verification (core)
const crypto = require('crypto');
function safeEqual(a, b) { // hash both sides: equal-length buffers
const ha = crypto.createHash('sha256').update(String(a)).digest();
const hb = crypto.createHash('sha256').update(String(b)).digest();
return crypto.timingSafeEqual(ha, hb);
}
function verifyClickPostRequest(headers, configured = process.env.CLICKPOST_WEBHOOK_SECRET) {
if (!configured) return false; // never accept when unconfigured
const secret = configured.toLowerCase().startsWith('token ') ? configured.slice(6) : configured;
const header = headers['authorization'];
if (!header || header.slice(0, 6).toLowerCase() !== 'token ') return false; // not "Bearer"
return safeEqual(header.slice(6), secret);
}
- Header:
Authorization: Token <secret>. The scheme isToken, notBearer, and is matched case-insensitively. Store the bare secret inCLICKPOST_WEBHOOK_SECRET; if the stored value itself starts withToken, strip it. Don't trim or otherwise alter the secret. - Missing header, wrong scheme or mismatch:
401. A body that isn't a ClickPost scan object:400. Success is200/201/202/204within 5 seconds. - Read the body raw (
express.raw({ type: '*/*' })) and authenticate before parsing it. - A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS and rotate the token if it leaks.
- Only Simple Token is covered. ClickPost's dashboard also offers X-API-Key, Webhook-Key, Basic Auth and Dynamic Token; these are not covered by this skill or Hookdeck's ClickPost source.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Status Codes
Dispatch on clickpost_status_code, an integer:
| Code | clickpost_ |
|---|---|
| 1 | OrderPlaced |
| 2 | PickupPending |
| 4 | PickedUp |
| 5 | InTransit |
| 6 | OutForDelivery |
| 8 | Delivered |
| 9 | FailedDelivery |
| 41 / 42 / 43 / 44 | RiderAllocationFailed / RiderAllocated / ReachedPickupLocation / ReachedDropLocation |
| 47 / 48 / 50 / 52 | PartialRTOOutForDelivery / PartialDelivered / PartialRTO / PartialRTODelivered |
The list is longer; see the ClickPost docs. Scans may arrive out of order and can be redelivered, so dedupe on waybill + scan (e.g. waybill, clickpost_status_code, timestamp) and don't let an older scan overwrite a newer state.
Environment Variables
CLICKPOST_WEBHOOK_SECRET=your-simple-token # the bare token, without "Token "
Local Development
ClickPost can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 clickpost --path /webhooks/clickpost
Use the printed URL as the webhook URL in ClickPost.
Resources
- references/overview.md - What ClickPost webhooks are, status codes and payload shape
- references/setup.md - Configure the webhook and Simple Token in ClickPost
- references/verification.md - Token check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests