> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alvys.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Document events

> Alvys webhook events sent when a document is uploaded to or deleted from a load, trip, driver, carrier, truck, or trailer, with payload and download links.

Alvys sends a webhook event when a document is uploaded to, or deleted from, a load, trip, driver, carrier, truck, or trailer. Use these events to copy documents into your system without polling the list-documents endpoints.

| Event | Fires when | Holder key in `data` |
| - | - | - |
| `load.document.uploaded` | A document is uploaded to a load | `loadNumber` |
| `load.document.deleted` | A document is deleted from a load | `loadNumber` |
| `trip.document.uploaded` | A document is uploaded to a trip | `tripId` |
| `trip.document.deleted` | A document is deleted from a trip | `tripId` |
| `driver.document.uploaded` | A document is uploaded to a driver | `driverId` |
| `driver.document.deleted` | A document is deleted from a driver | `driverId` |
| `carrier.document.uploaded` | A document is uploaded to a carrier | `carrierId` |
| `carrier.document.deleted` | A document is deleted from a carrier | `carrierId` |
| `truck.document.uploaded` | A document is uploaded to a truck | `truckId` |
| `truck.document.deleted` | A document is deleted from a truck | `truckId` |
| `trailer.document.uploaded` | A document is uploaded to a trailer | `trailerId` |
| `trailer.document.deleted` | A document is deleted from a trailer | `trailerId` |

Subscribe to each event by its exact name. There is no wildcard. The full list of valid event-type strings is returned by `GET /api/p/v1.0/webhooks/event-types`.

## When document events fire

* **Uploaded** fires when a document is first saved. In rare cases it can fire again for the same document, so deduplicate on `data.document.id`.
* **Deleted** fires when a document is removed.
* A rename, or a change to the document type, sends **no** event. For example, a call to [Change load document type](https://docs.alvys.com/en/api/reference/loads/change-load-document-type.md) or [Change trip document type](https://docs.alvys.com/en/api/reference/trips/change-trip-document-type.md) sends nothing. If you need the current name and type, read the documents again with the list-documents endpoint.

## Payload

Document events use the standard Alvys webhook [envelope](https://docs.alvys.com/en/api/reference/webhooks/event-delivery-reliability.md#event-request-format). The envelope `version` is `v1`. `data` has two fields:

* The holder key from the table above (for example `loadNumber`). It identifies the record the document belongs to.
* `document`, an object that describes the document.

Property names are camelCase. Fields with a `null` value are omitted, except the top-level `subsidiaryId`.

For document events, the envelope `id` has the form `{documentId}-{etag}`. Treat the `id` as an opaque string. Use it only to deduplicate, and do not parse it.

### The `document` object

| Field | Type | Present | Description |
| - | - | - | - |
| `id` | string | Always | The document id. |
| `attachmentPath` | string | Always (can be `""`) | The stored file name of the document. |
| `attachmentType` | string | Always (can be `""`) | The display name of the document type, for example `Bill of Lading`, `Rate Confirmation`, `Proof of Delivery`, or `Other`. This is a string, not an enum. Accept values that you do not recognize. |
| `attachmentSize` | integer | Omitted if unknown | The file size in bytes. |
| `uploadedAt` | datetime | Omitted if unknown | When the document was uploaded. |
| `parentId` | string | Always | The id of the record the document is stored against. For trip documents, this is the **load number**. See [Trip documents](#trip-documents). |
| `parentType` | string | Always | One of `Load`, `Trip`, `Driver`, `Carrier`, `Truck`, `Trailer`. |
| `uploadedBy` | string | Omitted if unknown | The id of the user who uploaded the document. |
| `downloadUrl` | string | `*.uploaded` only | A link to download the file. It is valid for 10 minutes. Omitted on `*.deleted`. |
| `expiresAt` | datetime | `*.uploaded` only | When `downloadUrl` stops working. Omitted on `*.deleted`. |

## Download links expire after 10 minutes

`downloadUrl` is valid for 10 minutes from the time Alvys builds the event, not from the time your endpoint receives it. Alvys builds the event one time. Each retry sends the same body, so a retry can carry a link that has already expired.

If `expiresAt` is in the past, or the download fails, get a fresh link from the list-documents endpoint for the holder:

* Load: `GET /api/p/v2.0/loads/{loadNumber}/documents` ([List load documents](https://docs.alvys.com/en/api/reference/loads/list-load-documents.md))
* Trip: [List trip documents](https://docs.alvys.com/en/api/reference/trips/list-trip-documents.md)
* Driver: [List driver documents](https://docs.alvys.com/en/api/reference/drivers/list-driver-documents.md)
* Carrier: [List carrier documents](https://docs.alvys.com/en/api/reference/carriers/list-carrier-documents.md)
* Truck: [List truck documents](https://docs.alvys.com/en/api/reference/trucks/list-truck-documents.md)
* Trailer: [List trailer documents](https://docs.alvys.com/en/api/reference/trailers/list-trailer-documents.md)

> [!TIP]
>
> Start the download as soon as you receive the event. Do not store `downloadUrl` for later use.

## Trip documents

For trip document events, the two identifiers are different:

* `data.tripId` is the trip id.
* `data.document.parentId` is the **load number** of the trip's load, not the trip id.

Use `data.tripId` to find the trip.

## Carrier documents go to every webhook

A carrier has no Subsidiary. For `carrier.document.uploaded` and `carrier.document.deleted`:

* The envelope `subsidiaryId` is always `null`.
* Alvys sends the event to every webhook in the tenant that subscribes to it, whatever Subsidiaries the webhook covers.

The other document events are matched on the Subsidiary of the load, trip, driver, truck, or trailer. See [Which events reach your subscription](https://docs.alvys.com/en/api/reference/webhooks/overview.md#which-events-reach-your-subscription).

## Examples

```json load.document.uploaded theme={null}
{
  "id": "e2b9f6d4-8a1c-4e3b-b7d5-0c9f2a6e3d18-2e00d4f5-0000-0300-0000-6726f3d40000",
  "type": "load.document.uploaded",
  "timestamp": "2026-11-04T18:01:33+00:00",
  "version": "v1",
  "etag": "2e00d4f5-0000-0300-0000-6726f3d40000",
  "subsidiaryId": "2d7e4c19-5a3b-4f8e-b1d6-7c9a0e3f5b42",
  "data": {
    "loadNumber": "1008222",
    "document": {
      "id": "e2b9f6d4-8a1c-4e3b-b7d5-0c9f2a6e3d18",
      "attachmentPath": "BOL_1008222.pdf",
      "attachmentType": "Bill of Lading",
      "attachmentSize": 284113,
      "uploadedAt": "2026-11-04T18:01:33+00:00",
      "parentId": "1008222",
      "parentType": "Load",
      "uploadedBy": "9f4b2d71-6c3e-4a85-b0d9-2e7f1a5c8b36",
      "downloadUrl": "https://files.example.com/d/e2b9f6d4-8a1c-4e3b-b7d5-0c9f2a6e3d18?token=...",
      "expiresAt": "2026-11-04T18:11:34.5512+00:00"
    }
  }
}
```

```json load.document.deleted theme={null}
{
  "id": "e2b9f6d4-8a1c-4e3b-b7d5-0c9f2a6e3d18-2f00e506-0000-0300-0000-6727a1e50000",
  "type": "load.document.deleted",
  "timestamp": "2026-11-05T09:14:02+00:00",
  "version": "v1",
  "etag": "2f00e506-0000-0300-0000-6727a1e50000",
  "subsidiaryId": "2d7e4c19-5a3b-4f8e-b1d6-7c9a0e3f5b42",
  "data": {
    "loadNumber": "1008222",
    "document": {
      "id": "e2b9f6d4-8a1c-4e3b-b7d5-0c9f2a6e3d18",
      "attachmentPath": "BOL_1008222.pdf",
      "attachmentType": "Bill of Lading",
      "attachmentSize": 284113,
      "uploadedAt": "2026-11-04T18:01:33+00:00",
      "parentId": "1008222",
      "parentType": "Load",
      "uploadedBy": "9f4b2d71-6c3e-4a85-b0d9-2e7f1a5c8b36"
    }
  }
}
```

```json trip.document.uploaded theme={null}
{
  "id": "4c7a1e93-6b2d-4f80-a3c5-9e1d7b0f2a64-3000f617-0000-0300-0000-6726f4e50000",
  "type": "trip.document.uploaded",
  "timestamp": "2026-11-04T19:10:00+00:00",
  "version": "v1",
  "etag": "3000f617-0000-0300-0000-6726f4e50000",
  "subsidiaryId": "2d7e4c19-5a3b-4f8e-b1d6-7c9a0e3f5b42",
  "data": {
    "tripId": "9a3d5e71-2c84-4b1f-a6e9-3f0b7d2c8e14",
    "document": {
      "id": "4c7a1e93-6b2d-4f80-a3c5-9e1d7b0f2a64",
      "attachmentPath": "POD_1008222-1.pdf",
      "attachmentType": "Proof of Delivery",
      "attachmentSize": 512330,
      "uploadedAt": "2026-11-04T19:10:00+00:00",
      "parentId": "1008222",
      "parentType": "Trip",
      "downloadUrl": "https://files.example.com/d/4c7a1e93-6b2d-4f80-a3c5-9e1d7b0f2a64?token=...",
      "expiresAt": "2026-11-04T19:20:01.03+00:00"
    }
  }
}
```

```json driver.document.uploaded theme={null}
{
  "id": "7d2f0b85-1e6c-4a39-8b74-c5a9e3d1f026-3100a728-0000-0300-0000-6726f5f60000",
  "type": "driver.document.uploaded",
  "timestamp": "2026-11-04T20:00:00+00:00",
  "version": "v1",
  "etag": "3100a728-0000-0300-0000-6726f5f60000",
  "subsidiaryId": "2d7e4c19-5a3b-4f8e-b1d6-7c9a0e3f5b42",
  "data": {
    "driverId": "5b8e2c4f-0a7d-4913-b6e2-8f1c3d9a7e50",
    "document": {
      "id": "7d2f0b85-1e6c-4a39-8b74-c5a9e3d1f026",
      "attachmentPath": "medical_card.pdf",
      "attachmentType": "Medical Card",
      "uploadedAt": "2026-11-04T20:00:00+00:00",
      "parentId": "5b8e2c4f-0a7d-4913-b6e2-8f1c3d9a7e50",
      "parentType": "Driver",
      "downloadUrl": "https://files.example.com/d/7d2f0b85-1e6c-4a39-8b74-c5a9e3d1f026?token=...",
      "expiresAt": "2026-11-04T20:10:00.7+00:00"
    }
  }
}
```

```json carrier.document.deleted theme={null}
{
  "id": "8e3a1c96-2f7d-4b4a-9c85-d6b0f4e2a137-3200b839-0000-0300-0000-6727b2f60000",
  "type": "carrier.document.deleted",
  "timestamp": "2026-11-05T10:00:00+00:00",
  "version": "v1",
  "etag": "3200b839-0000-0300-0000-6727b2f60000",
  "subsidiaryId": null,
  "data": {
    "carrierId": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
    "document": {
      "id": "8e3a1c96-2f7d-4b4a-9c85-d6b0f4e2a137",
      "attachmentPath": "coi_2026.pdf",
      "attachmentType": "Certificate of Insurance (COI)",
      "parentId": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
      "parentType": "Carrier"
    }
  }
}
```

`truck.document.*` and `trailer.document.*` events have the same shape as the driver example, with `truckId` or `trailerId` in place of `driverId`.

The examples show these points:

* On `load.document.deleted`, `downloadUrl` and `expiresAt` are absent. They are not sent as `null`.
* On `trip.document.uploaded`, `uploadedBy` is absent because it is unknown. `parentId` is the load number.
* On `carrier.document.deleted`, `subsidiaryId` is `null`. Fields such as `attachmentSize` and `uploadedAt` are absent because they are unknown.

## Notes

* Delivery is **at-least-once**. Deduplicate on `X-Alvys-Event-Id`. See [Event Delivery & Reliability](https://docs.alvys.com/en/api/reference/webhooks/event-delivery-reliability.md).
* Document events do not carry a `data.diff` node.
* Load and trip changes send their own events. See [Load events](https://docs.alvys.com/en/api/reference/webhooks/load-events.md) and [Trip events](https://docs.alvys.com/en/api/reference/webhooks/trip-events.md).
