A tracking webhook is an asynchronous delivery attempt, not a transaction that automatically updates your order database. Your receiver can fail before accepting it, or accept it and lose the acknowledgement. Reliable consumption therefore needs authentication, durable acceptance, idempotency and reconciliation.
Trace saves webhook delivery attempts and supports explicit replay of finished events. Those features make recovery inspectable, but they do not remove the need for a receiver that handles repeated events correctly.
Use the event ID as business identity
Trace-Event-Id identifies the event you should deduplicate. Trace-Delivery-Id identifies a delivery record, useful for support and attempt investigation. Replaying an event preserves its event ID, so a new delivery record must not produce a second buyer notification for the same business event.
Give the receiver’s inbox a unique constraint on the verified event ID. In one database transaction, insert that identity and the durable work item. Treat an existing identity as already accepted. This closes the gap where a process acknowledges 200 and then exits before saving the update.
| Failure point | Expected behavior |
|---|---|
| Crash before durable acceptance | Return failure or no acknowledgement; a later delivery can still be accepted. |
| Crash after commit, before response | A repeated event finds the saved identity and is acknowledged without redoing the action. |
| Two concurrent deliveries | The database uniqueness constraint decides which one inserts the business event. |
| Operator replay | The same event ID remains idempotent, even if the delivery record differs. |
Verify raw bytes and supported rotation signatures
Mount the raw-body route before a general JSON parser. JSON serialization can alter the bytes used by the HMAC. The Trace TypeScript helper returns a boolean; it does not parse the event or throw on every invalid signature. Check its result explicitly.
The signature can include multiple v1 values during the 24-hour rotation overlap. Validate the timestamp/header relationship and the helper’s five-minute tolerance, then parse the signed body and require its event_id to match Trace-Event-Id. Accept any supported matching v1 signature; a regular expression that allows only one signature breaks rotation.
- Store the signing secret on the server and fail closed if it is absent.
- Reject malformed or expired signatures before changing any order state.
- Parse the original bytes only after authentication, then validate the fields your consumer requires.
- Implement deduplication in persistent storage, not a process-local Set.
Distinguish redirects, authentication errors and transient failure
Configure the final public HTTPS URL of the receiver. Trace does not follow redirects to a customer destination or forward credentials to it. A redirect to a login page is not delivery success, even when the endpoint looks correct in a browser.
Investigate 401 and 403 responses as receiver authentication or signature-verification problems. Investigate 429 as receiver admission pressure and 5xx as receiver failure. A non-2xx response is not acknowledged delivery. Do not rely on repeated retries to repair a permanently wrong URL or a missing signing secret.
| Observed response | What to investigate |
|---|---|
| 3xx | Use the final endpoint URL; remove login or host redirects from the webhook route. |
| 401 / 403 | Check raw bytes, the configured secret, timestamp validation and route authentication. |
| 429 | Reduce receiver pressure and make durable acceptance efficient. |
| 5xx / timeout | Recover the receiver or its database, then inspect attempts and reconcile. |
| 2xx but missing business update | Audit your durable inbox and downstream consumer; acknowledgement alone does not prove business processing. |
Replay a finished event after fixing the receiver
Inspect the endpoint’s delivery history and the selected delivery’s saved attempts. When recovery requires replay, send a reason to the replay endpoint. Replay is limited to 60 requests per hour per account, preserves the event ID, and is a deliberate external delivery; it should not be triggered blindly from a page load.
The example below only reads attempt history. Set the two IDs from your account’s delivery history. Use the dashboard or the documented replay method for a conscious replay after checking the destination and receiver health.
TypeScript SDK · read-only receiver investigation
import { Trace } from '@traceapi/sdk';
const apiKey = process.env.TRACE_API_KEY;
if (!apiKey) throw new Error('Set TRACE_API_KEY');
const trace = new Trace(apiKey);
const webhookId = process.env.TRACE_WEBHOOK_ID;
const deliveryId = process.env.TRACE_DELIVERY_ID;
if (!webhookId || !deliveryId) throw new Error('Set owned endpoint and delivery IDs');
const attempts = await trace.attempts(webhookId, deliveryId);
for (const attempt of attempts.data) {
console.log(attempt.status, attempt.statusCode);
}
// Review the destination and receiver before invoking an explicit replay.Reconcile state when delivery cannot recover every observation
Re-read the owned shipment record to rebuild the current projection, and use its immutable observed events when you need scan history. Keep receipt time, carrier scan time and last verification time separate. An event that arrives later is not necessarily a later carrier scan.
Acquisition and webhook delivery are separate pipelines. Replaying a delivery cannot generate a carrier scan that was never retrieved. Trace monitoring is best effort and shares lookup quotas, so make unavailable or old observations visible in the application instead of manufacturing a delivery status.
- Test signature failures, duplicates and commit-before-acknowledgement recovery with local fixtures.
- Test failed and redirected receivers in staging without using customer endpoints.
- Keep an audit of verified event IDs, processing outcomes and deliberately replayed deliveries.
- Monitor recovery completeness and processing lag separately from the API’s readiness status.
Common questions
Does replay create a new business event?
No. It delivers the existing event again and preserves its event ID. Your durable deduplication should prevent repeated business actions.
Does the TypeScript verifyWebhook helper return the event body?
No. It returns a boolean. Check the return value, then parse and validate the authenticated raw body.
Can a redirect be treated as delivery success?
No. Configure the final public HTTPS receiver. Trace does not follow redirects to customer destinations.
References & next steps
Implementation details were checked against Trace’s current API. External product details may change; verify the linked documentation before deciding.