Webhook Events & Verification
Webhook Events & Verification
Webhook Events & Verification
Register a webhook endpoint to receive real-time delivery status updates instead of polling.
Setup
The response includes a signing secret (prefixed alwh_). Store it securely. It is only shown once. Subsequent GET /dd/v1/webhooks responses return the secret masked as alwh_****.... If you need to rotate your secret later, call PUT /dd/v1/webhooks with { "rotate_secret": true } and the new secret is returned in full.
One webhook URL per organization
Each Autolane organization has a single webhook subscription. Re-registering with POST /dd/v1/webhooks while one already exists returns 409 WEBHOOK_EXISTS; use PUT /dd/v1/webhooks to update the URL or subscribed events instead. If you operate multiple sites under one organization, all of their delivery events arrive at the same URL. Note that external_delivery_id is unique per (retailer, external_delivery_id) in the API, so two sites under the same org could legitimately use the same external_delivery_id value for different deliveries; ensure your IDs are org-unique (for example, prefix them with your site identifier) before routing on that field alone. DSP aggregators that bridge multiple retailer organizations should register one webhook per partner organization’s API key.
Events
Subscribe to additional events at any time by calling PUT /dd/v1/webhooks with an updated events array.
Payloads
When an event fires, Autolane sends a POST request to your registered URL with a JSON body.
pickup_status.changed
estimated_arrival is the estimated arrival time at the customer — the delivery ETA locked when the quote was created. It is null only when no delivery ETA is available for the delivery.
If you are also subscribed to pickup.vehicle_location.changed, this event additionally carries a vehicle_location field with the vehicle’s position at the moment the status changed. The field is null when no fresh location fix (within the last 5 minutes) is available, and is omitted entirely when you are not subscribed to the location event.
tracking_link.created
pickup.vehicle_location.changed
recorded_at is the timestamp on the underlying telemetry sample. It may lag the outer timestamp by a few seconds.
Events are not strictly ordered across event types. A pickup.vehicle_location.changed event may arrive shortly after a terminal pickup_status.changed (ARRIVED_AT_CUSTOMER, COMPLETED) for the same delivery. Use the timestamp field to reconcile relative ordering on your side.
Request headers
Each request includes these headers:
Your endpoint should return any 2xx status code to acknowledge receipt. Non-2xx responses (and request timeouts past 10 seconds) trigger retries.
Verifying Signatures
Use the signing secret from your webhook registration to verify that each delivery is authentically from Autolane. The X-Autolane-Signature header contains an HMAC-SHA256 hex digest of the raw request body, computed using your alwh_-prefixed secret.
Always verify signatures using a timing-safe comparison to prevent timing attacks:
Replay protection
The signature covers the request body only and does not include a timestamp. To reject replayed events at your endpoint, combine two payload-level signals:
- The top-level
timestampfield on every event is an ISO 8601 string. Reject events whosetimestampis more than a small tolerance (e.g., 5 minutes) outside your server clock. - The
X-Autolane-Delivery-Idheader is a UUID stable across retries for the same delivery attempt. Treat it as the dedupe key (see the next section).
Idempotency
Each delivery includes an X-Autolane-Delivery-Id header, a UUID that stays the same across retries. Store processed delivery IDs in a shared store (Redis, your database, etc.) and reject duplicates so retried deliveries don’t double-fire your business logic.
Note that external_delivery_id is the create-side idempotency key (see Idempotency in the Overview). It identifies the underlying delivery and stays the same across all events for that delivery. X-Autolane-Delivery-Id identifies one webhook event delivery (stable across the retries for that event) and changes from one event to the next.
Retries
Failed deliveries (non-2xx responses or request timeouts past 10 seconds) are retried with exponential backoff on a 30-second base:
After 5 failed attempts the event is given up on. Failed attempts also increment a per-organization consecutive_failures counter; a successful delivery resets it to zero.
If the counter reaches 50 consecutive failures the webhook endpoint is automatically disabled and the notification email on your account receives a heads-up. Call PUT /dd/v1/webhooks (with any valid update body, or just { "url": "<your-current-url>" }) to re-enable the endpoint. Re-enabling resets the failure counter to zero.