diff --git a/apps/docs/content/docs/developers/api/documents.mdx b/apps/docs/content/docs/developers/api/documents.mdx index dbe2e6a85..293182057 100644 --- a/apps/docs/content/docs/developers/api/documents.mdx +++ b/apps/docs/content/docs/developers/api/documents.mdx @@ -32,9 +32,9 @@ A document object contains the following properties: | --------------- | -------------- | -------------------------------------------------------------- | | `id` | string | Unique identifier (e.g., `envelope_abc123`) | | `type` | string | `DOCUMENT` or `TEMPLATE` | -| `status` | string | Current status: `DRAFT`, `PENDING`, `COMPLETED`, or `REJECTED` | +| `status` | string | Current status: `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, or `CANCELLED` | | `title` | string | Document title | -| `source` | string | How the document was created: `DOCUMENT`, `TEMPLATE`, `API` | +| `source` | string | How the document was created: `DOCUMENT`, `TEMPLATE`, `TEMPLATE_DIRECT_LINK` | | `visibility` | string | Who can view: `EVERYONE`, `ADMIN`, `MANAGER_AND_ABOVE` | | `externalId` | string \| null | Your custom identifier for the document | | `createdAt` | string | ISO 8601 timestamp | @@ -53,7 +53,7 @@ A document object contains the following properties: "id": "envelope_abc123xyz", "type": "DOCUMENT", "status": "PENDING", - "source": "API", + "source": "DOCUMENT", "visibility": "EVERYONE", "title": "Service Agreement", "externalId": "contract-2025-001", @@ -73,13 +73,13 @@ A document object contains the following properties: ], "fields": [ { - "id": "field_123", + "id": 123, "type": "SIGNATURE", "page": 1, - "positionX": 10, - "positionY": 80, - "width": 30, - "height": 5, + "positionX": "10", + "positionY": "80", + "width": "30", + "height": "5", "recipientId": 1 } ], @@ -99,6 +99,8 @@ A document object contains the following properties: } ``` +Field position and size values are stored as decimals and serialized as strings in API responses. + ## List Documents Retrieve a paginated list of documents. @@ -114,7 +116,7 @@ GET /envelope | `page` | integer | Page number (default: 1) | | `perPage` | integer | Results per page (default: 10, max: 100) | | `type` | string | Filter by `DOCUMENT` or `TEMPLATE` | -| `status` | string | Filter by status: `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED` | +| `status` | string | Filter by status: `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, `CANCELLED` | | `source` | string | Filter by creation source | | `folderId` | string | Filter by folder ID | | `orderByColumn` | string | Sort field (only `createdAt` supported) | @@ -154,8 +156,8 @@ const response = await fetch(`${BASE_URL}/envelope`, { }, }); -const { data, pagination } = await response.json(); -console.log(`Found ${pagination.totalItems} documents`); +const { data, count } = await response.json(); +console.log(`Found ${count} documents`); // Filter by status const pendingResponse = await fetch( @@ -197,12 +199,10 @@ const pendingDocs = await pendingResponse.json(); ] } ], - "pagination": { - "page": 1, - "perPage": 10, - "totalPages": 5, - "totalItems": 42 - } + "count": 42, + "currentPage": 1, + "perPage": 10, + "totalPages": 5 } ``` @@ -628,6 +628,72 @@ The response includes signing URLs for each recipient: --- +## Cancel Document + +Cancel a pending document. This changes its status from `PENDING` to `CANCELLED`. + +``` +POST /envelope/cancel +``` + +### Request Body + +| Field | Type | Required | Description | +| ------------ | ------ | -------- | ----------------------------------- | +| `envelopeId` | string | Yes | Document ID | +| `reason` | string | No | Reason for cancelling the document | + +### Code Examples + + + +```bash +curl -X POST "https://app.documenso.com/api/v2/envelope/cancel" \ + -H "Authorization: api_xxxxxxxxxxxxxxxx" \ + -H "Content-Type: application/json" \ + -d '{ + "envelopeId": "envelope_abc123", + "reason": "The agreement is no longer needed." + }' +``` + + +```typescript +const response = await fetch('https://app.documenso.com/api/v2/envelope/cancel', { + method: 'POST', + headers: { + Authorization: 'api_xxxxxxxxxxxxxxxx', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + envelopeId: 'envelope_abc123', + reason: 'The agreement is no longer needed.', + }), +}); + +const { success } = await response.json(); +``` + + + +### Response + +```json +{ + "success": true +} +``` + +### Behavior + +- Only documents in `PENDING` status can be cancelled. Other statuses return `400`. +- Cancellation is not idempotent. Cancelling the same document again returns `400`. +- The document owner and team members with `MANAGER` or higher permissions can cancel it. Requests for documents you cannot view return `404`; requests for visible documents without sufficient permissions return `401`. +- A successful cancellation fires the `DOCUMENT_CANCELLED` webhook. +- Cancellation emails are sent only to eligible non-CC, non-rejected recipients who were sent or opened the document. + +--- + ## Delete Document Delete a document. Completed documents cannot be deleted. @@ -670,7 +736,7 @@ const response = await fetch('https://app.documenso.com/api/v2/envelope/delete', const { success } = await response.json(); -```` +``` @@ -680,7 +746,7 @@ const { success } = await response.json(); { "success": true } -```` +``` --- @@ -694,9 +760,11 @@ POST /envelope/get-many ### Request Body -| Field | Type | Required | Description | -| ------------- | ----- | -------- | --------------------- | -| `envelopeIds` | array | Yes | Array of document IDs | +| Field | Type | Required | Description | +| ---------- | ------ | -------- | ---------------------------------------------------------------------------- | +| `ids` | object | Yes | ID selector containing `type` and `ids` | +| `ids.type` | string | Yes | `envelopeId`, `documentId`, or `templateId` | +| `ids.ids` | array | Yes | 1-20 IDs: strings for `envelopeId`; numbers for `documentId` or `templateId` | ### Code Examples @@ -707,12 +775,17 @@ curl -X POST "https://app.documenso.com/api/v2/envelope/get-many" \ -H "Authorization: api_xxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ - "envelopeIds": ["envelope_abc123", "envelope_def456", "envelope_ghi789"] + "ids": { + "type": "envelopeId", + "ids": ["envelope_abc123", "envelope_def456", "envelope_ghi789"] + } }' ``` ```typescript +const requestedIds = ['envelope_abc123', 'envelope_def456', 'envelope_ghi789']; + const response = await fetch('https://app.documenso.com/api/v2/envelope/get-many', { method: 'POST', headers: { @@ -720,16 +793,36 @@ const response = await fetch('https://app.documenso.com/api/v2/envelope/get-many 'Content-Type': 'application/json', }, body: JSON.stringify({ - envelopeIds: ['envelope_abc123', 'envelope_def456', 'envelope_ghi789'], + ids: { + type: 'envelopeId', + ids: requestedIds, + }, }), }); -const documents = await response.json(); +const { data } = await response.json(); -```` +``` +### Response + +```json +{ + "data": [ + { + "id": "envelope_abc123", + "type": "DOCUMENT", + "status": "PENDING", + "title": "Service Agreement" + } + ] +} +``` + +The endpoint silently omits envelopes you cannot access instead of returning `404`. Compare `data.length` with `requestedIds.length` to detect omissions. + --- ## Document Statuses @@ -740,6 +833,7 @@ const documents = await response.json(); | `PENDING` | Document has been sent. Waiting for recipients to sign. | | `COMPLETED` | All recipients have signed. Document is sealed. | | `REJECTED` | A recipient rejected the document. | +| `CANCELLED` | The document was cancelled by its owner or a team member with `MANAGER` or higher permissions. | ### Status Transitions @@ -747,11 +841,13 @@ const documents = await response.json(); flowchart LR DRAFT --> PENDING --> COMPLETED PENDING --> REJECTED + PENDING --> CANCELLED ``` - **DRAFT to PENDING**: Call the distribute endpoint - **PENDING to COMPLETED**: All recipients complete their signing - **PENDING to REJECTED**: A recipient rejects the document +- **PENDING to CANCELLED**: The document owner or a team member with `MANAGER` or higher permissions cancels the document You cannot modify recipients or fields after a document moves to `PENDING` status. @@ -773,8 +869,8 @@ flowchart LR | Parameter | Values | Description | | ---------- | ------------------------------------------- | ------------------------- | | `type` | `DOCUMENT`, `TEMPLATE` | Filter by envelope type | -| `status` | `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED` | Filter by status | -| `source` | `DOCUMENT`, `TEMPLATE`, `API` | Filter by creation source | +| `status` | `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, `CANCELLED` | Filter by status | +| `source` | `DOCUMENT`, `TEMPLATE`, `TEMPLATE_DIRECT_LINK` | Filter by creation source | | `folderId` | string | Filter by folder | ### Sorting @@ -800,10 +896,10 @@ async function getAllPendingDocuments() { }, ); - const { data, pagination } = await response.json(); + const { data, currentPage, totalPages } = await response.json(); documents.push(...data); - hasMore = page < pagination.totalPages; + hasMore = currentPage < totalPages; page++; } diff --git a/apps/docs/content/docs/developers/api/migrate-to-envelopes.mdx b/apps/docs/content/docs/developers/api/migrate-to-envelopes.mdx index 2bd5c8568..5a719e90c 100644 --- a/apps/docs/content/docs/developers/api/migrate-to-envelopes.mdx +++ b/apps/docs/content/docs/developers/api/migrate-to-envelopes.mdx @@ -119,7 +119,7 @@ Full reference in the [V2 OpenAPI reference](https://openapi.documenso.com). | ------------------------------------------------- | ----------------------------------------------------- | | `GET /api/v2/document` | `GET /api/v2/envelope` | | `GET /api/v2/document/{documentId}` | `GET /api/v2/envelope/{envelopeId}` | -| `POST /api/v2/document/get-many` | `POST /api/v2/envelope/get-many` | +| `POST /api/v2/document/get-many` | `POST /api/v2/envelope/get-many` (body changes from `documentIds: number[]` to `ids: { type: "documentId"; ids: number[] }`) | | `POST /api/v2/document/create` | `POST /api/v2/envelope/create` | | `POST /api/v2/document/create/beta` | `POST /api/v2/envelope/create` | | `POST /api/v2/document/update` | `POST /api/v2/envelope/update` | @@ -140,7 +140,7 @@ Full reference in the [V2 OpenAPI reference](https://openapi.documenso.com). | ------------------------------------- | ------------------------------------------------ | | `GET /api/v2/template` | `GET /api/v2/envelope` (with `type=TEMPLATE`) | | `GET /api/v2/template/{templateId}` | `GET /api/v2/envelope/{envelopeId}` | -| `POST /api/v2/template/get-many` | `POST /api/v2/envelope/get-many` | +| `POST /api/v2/template/get-many` | `POST /api/v2/envelope/get-many` (body changes from `templateIds: number[]` to `ids: { type: "templateId"; ids: number[] }`) | | `POST /api/v2/template/create` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) | | `POST /api/v2/template/create/beta` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) | | `POST /api/v2/template/update` | `POST /api/v2/envelope/update` |