Per-Entity Document Webhooks for Loads, Trips, Drivers, Carriers, Trucks & Trailers
What's New?
Twelve new webhook event types are now available on the Public API — two for each parent entity that exposes documents through the API. Whenever a document is uploaded or removed in Alvys, the platform emits a webhook to every active subscription that selected the corresponding event.
| Event | Fires when |
|---|---|
load.document.uploaded | A new document is attached to a load |
load.document.deleted | A load document is soft-deleted |
trip.document.uploaded | A new document is attached to a trip |
trip.document.deleted | A trip document is soft-deleted |
driver.document.uploaded | A new document is attached to a driver |
driver.document.deleted | A driver document is soft-deleted |
carrier.document.uploaded | A new document is attached to a carrier |
carrier.document.deleted | A carrier document is soft-deleted |
truck.document.uploaded | A new document is attached to a truck |
truck.document.deleted | A truck document is soft-deleted |
trailer.document.uploaded | A new document is attached to a trailer |
trailer.document.deleted | A trailer document is soft-deleted |
Events fire regardless of write source — UI uploads, Public API uploads, mobile-app uploads, EDI document ingestion, or third-party integrations all produce the same deliveries.
Every *.document.uploaded event ships with a short-lived pre-signed download URL (≤ 15-minute TTL) so partners can pull the file directly from blob storage without an additional API call.
What Changed?
Subscribing
In Settings → API → Webhooks → Create / Edit subscription, select any combination of the new event types. The full list is also returned by GET /p/v1.0/webhooks/event-types for programmatic configuration.
Envelope (general structure)
All document webhook deliveries share the standard envelope used by tender.*, load.status.changed, and trip.status.changed. id is the deterministic idempotency key ({documentId}-{etag}); etag is also exposed as its own top-level envelope field so consumers can detect out-of-order replays for the same documentId.
*.document.uploaded payload (general structure)
*.document.uploaded payload (general structure)Real production sample (trip.document.uploaded):
{
"id": "00000000-0000-0000-0000-000000000000-00000000-0000-0000-0000-000000000000",
"type": "trip.document.uploaded",
"timestamp": "2026-05-13T09:16:30.9797738+00:00",
"version": "v1",
"etag": "00000000-0000-0000-0000-000000000000",
"data": {
"tripId": "00000000000000000000000000000000",
"document": {
"id": "00000000-0000-0000-0000-000000000000",
"attachmentPath": "bol.pdf",
"attachmentType": "Bill of Lading",
"attachmentSize": 10000,
"uploadedAt": "2026-05-13T09:16:30.9797738+00:00",
"parentId": "1000000",
"parentType": "Trip",
"uploadedBy": "00000000000000000000000000000000",
"downloadUrl": "{url}",
"expiresAt": "2026-05-13T09:26:35.3227049+00:00"
}
}
}data.tripIdis the trip GUID (the natural public identifier returned byGET /p/v1.0/trips/{tripId}).data.document.parentIdon a trip document is the load number ("1000000") — matching how trip documents are stored internally and returned byGET /loads/{loadNumber}/documents.attachmentTypeis a human-readable Alvys document type (e.g."Bill of Lading","Proof of Delivery","Rate Confirmation") — same value returned by the document Public API endpoints.uploadedByis the user id (GUID) of the uploader.
The same shape applies to the other five parent types — data always contains the parent's natural public identifier (loadNumber, tripId, driverId, carrierId, truckId, or trailerId) plus a document block. For example, driver.document.uploaded swaps tripId for driverId; the document block is identical.
*.document.deleted payload (general structure)
*.document.deleted payload (general structure)// load.document.deleted
{
"id": "00000000-0000-0000-0000-000000000000-00000000-0000-0000-0000-000000000000",
"type": "load.document.deleted",
"timestamp": "2026-05-13T16:05:22.118+00:00",
"version": "v1",
"etag": "00000000-0000-0000-0000-000000000000",
"data": {
"loadNumber": "1000000",
"document": {
"id": "00000000-0000-0000-0000-000000000000",
"attachmentPath": "bol.pdf",
"attachmentType": "Bill of Lading",
"attachmentSize": 10000,
"uploadedAt": "2026-05-13T09:16:30.9797738+00:00",
"uploadedBy": "00000000000000000000000000000000",
"parentId": "1000000",
"parentType": "Load"
}
}
}downloadUrl and expiresAt are omitted on delete events — the document is logically gone, so consumers should not pull bytes.
Behavior notes
- An event fires only when a document is created or soft-deleted — rename, retype, and other metadata-only edits do not generate deliveries.
- Pre-signed
downloadUrlis short-lived (≤ 15 minutes). Pull the file promptly, or fall back toGET /p/v1.0/{parent}/{parentId}/documents/{documentId}if it expires.
Endpoints Affected
Webhook subscription management
These existing endpoints now accept the twelve new event types in their eventTypes array:
GET /p/v1.0/webhooks/event-types— returns the full catalog including the new document event types.POST /p/v1.0/webhooks— create a subscription that selects any combination of the new events.PUT /p/v1.0/webhooks/{id}— update an existing subscription to add or remove document events.GET /p/v1.0/webhooks/{id}— inspect which events a subscription is selecting.GET /p/v1.0/webhooks/{id}/deliveries— delivery history for the new events flows through the same logs surface astender.*and*.status.changed.
Document endpoints driving the events
Any write to the following document sub-resources will fire the corresponding webhook for active subscribers. No request or response shape has changed on these endpoints — they are listed here so you can correlate which API actions produce which events.
| Endpoint | Fires |
|---|---|
POST /p/v1.0/loads/{loadNumber}/documents | load.document.uploaded |
DELETE /p/v1.0/loads/{loadNumber}/documents/{documentId} | load.document.deleted |
POST /p/v1.0/trips/{tripId}/documents | trip.document.uploaded |
DELETE /p/v1.0/trips/{tripId}/documents/{documentId} | trip.document.deleted |
POST /p/v1.0/drivers/{driverId}/documents | driver.document.uploaded |
DELETE /p/v1.0/drivers/{driverId}/documents/{documentId} | driver.document.deleted |
POST /p/v1.0/carriers/{carrierId}/documents | carrier.document.uploaded |
DELETE /p/v1.0/carriers/{carrierId}/documents/{documentId} | carrier.document.deleted |
POST /p/v1.0/trucks/{truckId}/documents | truck.document.uploaded |
DELETE /p/v1.0/trucks/{truckId}/documents/{documentId} | truck.document.deleted |
POST /p/v1.0/trailers/{trailerId}/documents | trailer.document.uploaded |
DELETE /p/v1.0/trailers/{trailerId}/documents/{documentId} | trailer.document.deleted |
UI uploads, mobile-app uploads, EDI ingestion, and third-party integrations also produce the same events even though they don't go through the Public API endpoints above.
Fallback retrieval (if a downloadUrl expires)
downloadUrl expires)If the 15-minute pre-signed downloadUrl expires before you fetch the file, retrieve the document through the standard authenticated endpoint:
GET /p/v1.0/{parent}/{parentId}/documents/{documentId}
Why?
Until now, retrieving newly uploaded documents required polling the document sub-resource on each parent — /loads/{loadNumber}/documents, /drivers/{driverId}/documents, and four more. With these events in place:
- ⚡ Real-time document automation — POD-driven invoice automation, factoring, document management, and EDI 210 invoice validation no longer wait on a poll loop.
- 🔁 Lower API load — eliminates polling traffic against six different parent endpoints.
- 🎯 Subscribe narrowly — events are scoped per entity (
load.*vsdriver.*vscarrier.*…). A factoring integration that only cares about load-side documents won't receive driver med-card updates. - 🧾 Built-in audit trail — every delivery attempt is recorded and visible in the Webhook details page.
- 🔗 Direct download — every
*.uploadedevent carries a pre-signed download URL.
Who has access?
All Public API consumers with an active webhook subscription that selects any of the new event types. Subscription management requires Partner Admin / Admin / Support role under Settings → API → Webhooks.
Frequently Asked Questions (FAQ)
Q: Do I need a new credential or scope to receive these events? A: No. Existing webhook subscriptions can opt in by selecting the new event types.
Q: Is the downloadUrl reusable? A: It's a single short-lived pre-signed Azure Blob SAS — valid for up to 15 minutes from emission. If it expires, retrieve the document through the standard Public API endpoint instead.
Q: Are events ordered? A: Deliveries are best-effort ordered per document. Consumers should be idempotent and use the envelope id ({documentId}-{_etag}) as the idempotency key.
Q: Can I see delivery history for these events? A: Yes — the existing Logs sidebar on the webhook detail page shows every delivery attempt for these event types, with the same filtering, pagination, and CSV/JSON export as tender.* and status-change events.
Q: Are document update / rename events available? A: Not in this release. Today we emit on upload and soft-delete only. Update events may be added later as *.document.updated if there's customer demand.