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

# Multi-document envelopes

> Attach multiple PDFs to one envelope and route signers through all documents before they sign.

## Overview

A single envelope can contain multiple PDFs. Each document is independently sealed with its own SHA-256 hash; the envelope's `document_hash_final` is derived from all per-document hashes combined. Signers see every document in one signing session and cannot submit until they have scrolled through all pages of all documents.

Multi-document envelopes require a **Pro plan or higher**.

***

## Creating a multi-document envelope

Upload each PDF separately using the console document upload endpoint, then reference all document IDs when building the envelope.

```bash theme={null}
# 1. Upload document 1
curl -X POST https://api.thesignproof.com/v1/console/envelopes/{id}/documents \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@contract.pdf"

# 2. Upload document 2  (Pro+ only — rejected on Starter / Solo)
curl -X POST https://api.thesignproof.com/v1/console/envelopes/{id}/documents \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@exhibit-a.pdf"
```

The second upload is gated: if your plan is below Pro, it returns `402 Payment Required`.

***

## Signer experience

When a signer opens their tokenized link, the signing UI fetches the full document list:

```http theme={null}
GET /v1/signing/{token}/documents
```

```json theme={null}
[
  { "documentId": "doc-uuid-1", "pageCount": 6, "order": 1 },
  { "documentId": "doc-uuid-2", "pageCount": 3, "order": 2 }
]
```

The UI presents a document navigator. Signers step through each document in order using `GET /v1/signing/{token}/documents/{docId}` to stream each PDF. The **Sign** button stays disabled until all pages of all documents have been scrolled — enforced client-side with a toast prompt ("Please read all documents before signing").

Each page view is recorded:

```http theme={null}
POST /v1/signing/{token}/page-view
Content-Type: application/json

{
  "documentId": "doc-uuid-1",
  "page": 3,
  "dwellMs": 4200
}
```

These events appear in the audit trail export as `page_viewed` entries.

***

## Sealing

On completion, `SealingService` seals each document independently and stores:

* `envelopes/{id}/sealed/{docId}.pdf` per document
* `envelopes/{id}/sealed.pdf` for the first document (legacy path, backward compatible)

The envelope's `document_hash_final` is computed as:

```
SHA-256( SHA-256(doc1) ‖ SHA-256(doc2) ‖ … )
```

where hashes are sorted by `document_order` before concatenation. This means tampering with any single document breaks the combined hash, and the full set of per-document hashes is preserved in the audit log for independent verification.

***

## Delivery

On completion, the sealed copy of every document is emailed to all parties. Large payloads (total > `Email:MaxAttachmentBytes`, default 10 MB) fall back to a tokenized `/download/{token}` link. Each document is delivered as a separate attachment or link.

***

## Backward compatibility

Existing single-document integrations are unaffected. The `document_order` column defaults to `1`, and `GET /v1/signing/{token}/document` (without `/{docId}`) continues to serve the single original PDF. The `document_hash_final` for a single-document envelope equals the hash of that one document — identical to the pre-multi-doc behavior.
