mirror of
https://github.com/documenso/documenso.git
synced 2026-08-19 04:51:50 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a43d09be9b | ||
|
|
905e68fdea | ||
|
|
ced5af4d5a | ||
|
|
b076a70d98 | ||
|
|
6ace46fefd | ||
|
|
478229aa90 | ||
|
|
d3eb0c7999 | ||
|
|
918e42b992 | ||
|
|
f21eddef19 |
@@ -32,9 +32,9 @@ A document object contains the following properties:
|
|||||||
| --------------- | -------------- | -------------------------------------------------------------- |
|
| --------------- | -------------- | -------------------------------------------------------------- |
|
||||||
| `id` | string | Unique identifier (e.g., `envelope_abc123`) |
|
| `id` | string | Unique identifier (e.g., `envelope_abc123`) |
|
||||||
| `type` | string | `DOCUMENT` or `TEMPLATE` |
|
| `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 |
|
| `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` |
|
| `visibility` | string | Who can view: `EVERYONE`, `ADMIN`, `MANAGER_AND_ABOVE` |
|
||||||
| `externalId` | string \| null | Your custom identifier for the document |
|
| `externalId` | string \| null | Your custom identifier for the document |
|
||||||
| `createdAt` | string | ISO 8601 timestamp |
|
| `createdAt` | string | ISO 8601 timestamp |
|
||||||
@@ -53,7 +53,7 @@ A document object contains the following properties:
|
|||||||
"id": "envelope_abc123xyz",
|
"id": "envelope_abc123xyz",
|
||||||
"type": "DOCUMENT",
|
"type": "DOCUMENT",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"source": "API",
|
"source": "DOCUMENT",
|
||||||
"visibility": "EVERYONE",
|
"visibility": "EVERYONE",
|
||||||
"title": "Service Agreement",
|
"title": "Service Agreement",
|
||||||
"externalId": "contract-2025-001",
|
"externalId": "contract-2025-001",
|
||||||
@@ -73,13 +73,13 @@ A document object contains the following properties:
|
|||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"id": "field_123",
|
"id": 123,
|
||||||
"type": "SIGNATURE",
|
"type": "SIGNATURE",
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"positionX": 10,
|
"positionX": "10",
|
||||||
"positionY": 80,
|
"positionY": "80",
|
||||||
"width": 30,
|
"width": "30",
|
||||||
"height": 5,
|
"height": "5",
|
||||||
"recipientId": 1
|
"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
|
## List Documents
|
||||||
|
|
||||||
Retrieve a paginated list of documents.
|
Retrieve a paginated list of documents.
|
||||||
@@ -114,7 +116,7 @@ GET /envelope
|
|||||||
| `page` | integer | Page number (default: 1) |
|
| `page` | integer | Page number (default: 1) |
|
||||||
| `perPage` | integer | Results per page (default: 10, max: 100) |
|
| `perPage` | integer | Results per page (default: 10, max: 100) |
|
||||||
| `type` | string | Filter by `DOCUMENT` or `TEMPLATE` |
|
| `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 |
|
| `source` | string | Filter by creation source |
|
||||||
| `folderId` | string | Filter by folder ID |
|
| `folderId` | string | Filter by folder ID |
|
||||||
| `orderByColumn` | string | Sort field (only `createdAt` supported) |
|
| `orderByColumn` | string | Sort field (only `createdAt` supported) |
|
||||||
@@ -154,8 +156,8 @@ const response = await fetch(`${BASE_URL}/envelope`, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data, pagination } = await response.json();
|
const { data, count } = await response.json();
|
||||||
console.log(`Found ${pagination.totalItems} documents`);
|
console.log(`Found ${count} documents`);
|
||||||
|
|
||||||
// Filter by status
|
// Filter by status
|
||||||
const pendingResponse = await fetch(
|
const pendingResponse = await fetch(
|
||||||
@@ -197,12 +199,10 @@ const pendingDocs = await pendingResponse.json();
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pagination": {
|
"count": 42,
|
||||||
"page": 1,
|
"currentPage": 1,
|
||||||
"perPage": 10,
|
"perPage": 10,
|
||||||
"totalPages": 5,
|
"totalPages": 5
|
||||||
"totalItems": 42
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
<Tabs items={['curl', 'TypeScript']}>
|
||||||
|
<Tab value="curl">
|
||||||
|
```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."
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
|
<Tab value="TypeScript">
|
||||||
|
```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();
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### 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 Document
|
||||||
|
|
||||||
Delete a document. Completed documents cannot be deleted.
|
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();
|
const { success } = await response.json();
|
||||||
|
|
||||||
````
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
@@ -680,7 +746,7 @@ const { success } = await response.json();
|
|||||||
{
|
{
|
||||||
"success": true
|
"success": true
|
||||||
}
|
}
|
||||||
````
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -694,9 +760,11 @@ POST /envelope/get-many
|
|||||||
|
|
||||||
### Request Body
|
### Request Body
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
| ------------- | ----- | -------- | --------------------- |
|
| ---------- | ------ | -------- | ---------------------------------------------------------------------------- |
|
||||||
| `envelopeIds` | array | Yes | Array of document IDs |
|
| `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
|
### Code Examples
|
||||||
|
|
||||||
@@ -707,12 +775,17 @@ curl -X POST "https://app.documenso.com/api/v2/envelope/get-many" \
|
|||||||
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{
|
-d '{
|
||||||
"envelopeIds": ["envelope_abc123", "envelope_def456", "envelope_ghi789"]
|
"ids": {
|
||||||
|
"type": "envelopeId",
|
||||||
|
"ids": ["envelope_abc123", "envelope_def456", "envelope_ghi789"]
|
||||||
|
}
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab value="TypeScript">
|
<Tab value="TypeScript">
|
||||||
```typescript
|
```typescript
|
||||||
|
const requestedIds = ['envelope_abc123', 'envelope_def456', 'envelope_ghi789'];
|
||||||
|
|
||||||
const response = await fetch('https://app.documenso.com/api/v2/envelope/get-many', {
|
const response = await fetch('https://app.documenso.com/api/v2/envelope/get-many', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -720,16 +793,36 @@ const response = await fetch('https://app.documenso.com/api/v2/envelope/get-many
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
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();
|
||||||
|
|
||||||
````
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### 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
|
## Document Statuses
|
||||||
@@ -740,6 +833,7 @@ const documents = await response.json();
|
|||||||
| `PENDING` | Document has been sent. Waiting for recipients to sign. |
|
| `PENDING` | Document has been sent. Waiting for recipients to sign. |
|
||||||
| `COMPLETED` | All recipients have signed. Document is sealed. |
|
| `COMPLETED` | All recipients have signed. Document is sealed. |
|
||||||
| `REJECTED` | A recipient rejected the document. |
|
| `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
|
### Status Transitions
|
||||||
|
|
||||||
@@ -747,11 +841,13 @@ const documents = await response.json();
|
|||||||
flowchart LR
|
flowchart LR
|
||||||
DRAFT --> PENDING --> COMPLETED
|
DRAFT --> PENDING --> COMPLETED
|
||||||
PENDING --> REJECTED
|
PENDING --> REJECTED
|
||||||
|
PENDING --> CANCELLED
|
||||||
```
|
```
|
||||||
|
|
||||||
- **DRAFT to PENDING**: Call the distribute endpoint
|
- **DRAFT to PENDING**: Call the distribute endpoint
|
||||||
- **PENDING to COMPLETED**: All recipients complete their signing
|
- **PENDING to COMPLETED**: All recipients complete their signing
|
||||||
- **PENDING to REJECTED**: A recipient rejects the document
|
- **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
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
You cannot modify recipients or fields after a document moves to `PENDING` status.
|
You cannot modify recipients or fields after a document moves to `PENDING` status.
|
||||||
@@ -773,8 +869,8 @@ flowchart LR
|
|||||||
| Parameter | Values | Description |
|
| Parameter | Values | Description |
|
||||||
| ---------- | ------------------------------------------- | ------------------------- |
|
| ---------- | ------------------------------------------- | ------------------------- |
|
||||||
| `type` | `DOCUMENT`, `TEMPLATE` | Filter by envelope type |
|
| `type` | `DOCUMENT`, `TEMPLATE` | Filter by envelope type |
|
||||||
| `status` | `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED` | Filter by status |
|
| `status` | `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, `CANCELLED` | Filter by status |
|
||||||
| `source` | `DOCUMENT`, `TEMPLATE`, `API` | Filter by creation source |
|
| `source` | `DOCUMENT`, `TEMPLATE`, `TEMPLATE_DIRECT_LINK` | Filter by creation source |
|
||||||
| `folderId` | string | Filter by folder |
|
| `folderId` | string | Filter by folder |
|
||||||
|
|
||||||
### Sorting
|
### Sorting
|
||||||
@@ -800,10 +896,10 @@ async function getAllPendingDocuments() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, pagination } = await response.json();
|
const { data, currentPage, totalPages } = await response.json();
|
||||||
documents.push(...data);
|
documents.push(...data);
|
||||||
|
|
||||||
hasMore = page < pagination.totalPages;
|
hasMore = currentPage < totalPages;
|
||||||
page++;
|
page++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ description: Add signature and form fields to documents via API.
|
|||||||
import { Callout } from 'fumadocs-ui/components/callout';
|
import { Callout } from 'fumadocs-ui/components/callout';
|
||||||
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
||||||
|
|
||||||
|
<EnvelopeWarning />
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
This guide may not reflect the latest endpoints or parameters. For an always up-to-date reference,
|
This guide may not reflect the latest endpoints or parameters. For an always up-to-date reference,
|
||||||
see the [OpenAPI Reference](https://openapi.documenso.com).
|
see the [OpenAPI Reference](https://openapi.documenso.com).
|
||||||
@@ -19,13 +21,13 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
|||||||
| `secondaryId` | string | Secondary identifier for audit logs |
|
| `secondaryId` | string | Secondary identifier for audit logs |
|
||||||
| `type` | string | Field type (see [Field Types](#field-types)) |
|
| `type` | string | Field type (see [Field Types](#field-types)) |
|
||||||
| `recipientId` | number | ID of the recipient assigned to this field |
|
| `recipientId` | number | ID of the recipient assigned to this field |
|
||||||
| `envelopeId` | number | ID of the parent envelope |
|
| `envelopeId` | string | ID of the parent envelope |
|
||||||
| `envelopeItemId` | string | ID of the PDF item the field is placed on |
|
| `envelopeItemId` | string | ID of the PDF item the field is placed on |
|
||||||
| `page` | number | Page number (1-indexed) |
|
| `page` | number | Page number (1-indexed) |
|
||||||
| `positionX` | number | X coordinate as percentage (0-100) |
|
| `positionX` | string | X coordinate as percentage (0-100), a decimal serialized as a string |
|
||||||
| `positionY` | number | Y coordinate as percentage (0-100) |
|
| `positionY` | string | Y coordinate as percentage (0-100), a decimal serialized as a string |
|
||||||
| `width` | number | Width as percentage of page (0-100) |
|
| `width` | string | Width as percentage of page (0-100), a decimal serialized as a string |
|
||||||
| `height` | number | Height as percentage of page (0-100) |
|
| `height` | string | Height as percentage of page (0-100), a decimal serialized as a string |
|
||||||
| `customText` | string | Value entered by the recipient |
|
| `customText` | string | Value entered by the recipient |
|
||||||
| `inserted` | boolean | Whether the field has been completed |
|
| `inserted` | boolean | Whether the field has been completed |
|
||||||
| `fieldMeta` | object \| null | Type-specific configuration options |
|
| `fieldMeta` | object \| null | Type-specific configuration options |
|
||||||
@@ -38,18 +40,19 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
|||||||
"secondaryId": "field_abc123",
|
"secondaryId": "field_abc123",
|
||||||
"type": "SIGNATURE",
|
"type": "SIGNATURE",
|
||||||
"recipientId": 123,
|
"recipientId": 123,
|
||||||
"envelopeId": 789,
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"envelopeItemId": "envelope_item_xyz",
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"positionX": 10,
|
"positionX": "10",
|
||||||
"positionY": 80,
|
"positionY": "80",
|
||||||
"width": 30,
|
"width": "30",
|
||||||
"height": 5,
|
"height": "5",
|
||||||
"customText": "",
|
"customText": "",
|
||||||
"inserted": false,
|
"inserted": false,
|
||||||
"fieldMeta": {
|
"fieldMeta": {
|
||||||
"type": "signature",
|
"type": "signature",
|
||||||
"required": true
|
"required": true,
|
||||||
|
"overflow": "auto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -61,7 +64,7 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
|||||||
| Type | Description | Auto-filled |
|
| Type | Description | Auto-filled |
|
||||||
| ---------------- | ----------------------------------------- | ----------- |
|
| ---------------- | ----------------------------------------- | ----------- |
|
||||||
| `SIGNATURE` | Drawn, typed, or uploaded signature | No |
|
| `SIGNATURE` | Drawn, typed, or uploaded signature | No |
|
||||||
| `FREE_SIGNATURE` | Unrestricted signature without validation | No |
|
| `FREE_SIGNATURE` | Legacy free-form signature. Accepted by the v2 create schema but rejected by the v1 API and unsupported in the signing UI — avoid in new integrations | No |
|
||||||
| `INITIALS` | Recipient's initials | No |
|
| `INITIALS` | Recipient's initials | No |
|
||||||
| `NAME` | Recipient's full name | Yes |
|
| `NAME` | Recipient's full name | Yes |
|
||||||
| `EMAIL` | Recipient's email address | Yes |
|
| `EMAIL` | Recipient's email address | Yes |
|
||||||
@@ -134,10 +137,12 @@ POST /envelope/field/create-many
|
|||||||
|
|
||||||
### Request Body
|
### Request Body
|
||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
| ----------- | ------ | -------- | ------------------------------- |
|
| ------------ | ------ | -------- | ------------------------------- |
|
||||||
| `documentId`| number | Yes | The document ID |
|
| `envelopeId` | string | Yes | The envelope ID |
|
||||||
| `fields` | array | Yes | Array of field configurations |
|
| `data` | array | Yes | Array of field configurations |
|
||||||
|
|
||||||
|
Each entry in `data` requires a `type`, a `recipientId`, and a position — either explicit coordinates (`page`, `positionX`, `positionY`, `width`, `height`) or a [text placeholder](#placeholder-based-field-positioning) (`placeholder` with optional `width`, `height`, and `matchAll`). Optional per-entry properties: `envelopeItemId` (which PDF in the envelope to place the field on; defaults to the first item) and `fieldMeta`.
|
||||||
|
|
||||||
### Code Examples
|
### Code Examples
|
||||||
|
|
||||||
@@ -148,32 +153,32 @@ curl -X POST "https://app.documenso.com/api/v2/envelope/field/create-many" \
|
|||||||
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{
|
-d '{
|
||||||
"documentId": 123,
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"fields": [
|
"data": [
|
||||||
{
|
{
|
||||||
"type": "SIGNATURE",
|
"type": "SIGNATURE",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"pageNumber": 1,
|
"page": 1,
|
||||||
"pageX": 10,
|
"positionX": 10,
|
||||||
"pageY": 80,
|
"positionY": 80,
|
||||||
"width": 30,
|
"width": 30,
|
||||||
"height": 5
|
"height": 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DATE",
|
"type": "DATE",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"pageNumber": 1,
|
"page": 1,
|
||||||
"pageX": 50,
|
"positionX": 50,
|
||||||
"pageY": 80,
|
"positionY": 80,
|
||||||
"width": 20,
|
"width": 20,
|
||||||
"height": 3
|
"height": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "TEXT",
|
"type": "TEXT",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"pageNumber": 1,
|
"page": 1,
|
||||||
"pageX": 10,
|
"positionX": 10,
|
||||||
"pageY": 70,
|
"positionY": 70,
|
||||||
"width": 40,
|
"width": 40,
|
||||||
"height": 4,
|
"height": 4,
|
||||||
"fieldMeta": {
|
"fieldMeta": {
|
||||||
@@ -199,32 +204,32 @@ const response = await fetch(
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
documentId: 123,
|
envelopeId: 'envelope_abcdefhiklmnorst',
|
||||||
fields: [
|
data: [
|
||||||
{
|
{
|
||||||
type: 'SIGNATURE',
|
type: 'SIGNATURE',
|
||||||
recipientId: 456,
|
recipientId: 456,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 10,
|
positionX: 10,
|
||||||
pageY: 80,
|
positionY: 80,
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 5,
|
height: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'DATE',
|
type: 'DATE',
|
||||||
recipientId: 456,
|
recipientId: 456,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 50,
|
positionX: 50,
|
||||||
pageY: 80,
|
positionY: 80,
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 3,
|
height: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'TEXT',
|
type: 'TEXT',
|
||||||
recipientId: 456,
|
recipientId: 456,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 10,
|
positionX: 10,
|
||||||
pageY: 70,
|
positionY: 70,
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 4,
|
height: 4,
|
||||||
fieldMeta: {
|
fieldMeta: {
|
||||||
@@ -239,8 +244,8 @@ const response = await fetch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { fields } = await response.json();
|
const { data } = await response.json();
|
||||||
console.log(`Created ${fields.length} fields`);
|
console.log(`Created ${data.length} fields`);
|
||||||
|
|
||||||
````
|
````
|
||||||
</Tab>
|
</Tab>
|
||||||
@@ -250,36 +255,68 @@ console.log(`Created ${fields.length} fields`);
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"fields": [
|
"data": [
|
||||||
{
|
{
|
||||||
"id": 101,
|
"id": 101,
|
||||||
|
"secondaryId": "field_abc123",
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
"type": "SIGNATURE",
|
"type": "SIGNATURE",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"positionX": 10,
|
"positionX": "10",
|
||||||
"positionY": 80,
|
"positionY": "80",
|
||||||
"width": 30,
|
"width": "30",
|
||||||
"height": 5
|
"height": "5",
|
||||||
|
"customText": "",
|
||||||
|
"inserted": false,
|
||||||
|
"fieldMeta": {
|
||||||
|
"type": "signature",
|
||||||
|
"fontSize": 18,
|
||||||
|
"overflow": "auto"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 102,
|
"id": 102,
|
||||||
|
"secondaryId": "field_def456",
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
"type": "DATE",
|
"type": "DATE",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"positionX": 50,
|
"positionX": "50",
|
||||||
"positionY": 80,
|
"positionY": "80",
|
||||||
"width": 20,
|
"width": "20",
|
||||||
"height": 3
|
"height": "3",
|
||||||
|
"customText": "",
|
||||||
|
"inserted": false,
|
||||||
|
"fieldMeta": {
|
||||||
|
"type": "date",
|
||||||
|
"fontSize": 12,
|
||||||
|
"textAlign": "left",
|
||||||
|
"overflow": "auto"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 103,
|
"id": 103,
|
||||||
|
"secondaryId": "field_ghi789",
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
"type": "TEXT",
|
"type": "TEXT",
|
||||||
"recipientId": 456,
|
"recipientId": 456,
|
||||||
"page": 1,
|
"page": 1,
|
||||||
"positionX": 10,
|
"positionX": "10",
|
||||||
"positionY": 70,
|
"positionY": "70",
|
||||||
"width": 40,
|
"width": "40",
|
||||||
"height": 4
|
"height": "4",
|
||||||
|
"customText": "",
|
||||||
|
"inserted": false,
|
||||||
|
"fieldMeta": {
|
||||||
|
"type": "text",
|
||||||
|
"label": "Job Title",
|
||||||
|
"placeholder": "Enter your job title",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -299,8 +336,10 @@ POST /envelope/field/update-many
|
|||||||
|
|
||||||
| Field | Type | Required | Description |
|
| Field | Type | Required | Description |
|
||||||
| ------------ | ------ | -------- | ----------------------------- |
|
| ------------ | ------ | -------- | ----------------------------- |
|
||||||
| `documentId` | number | Yes | The document ID |
|
| `envelopeId` | string | Yes | The envelope ID |
|
||||||
| `fields` | array | Yes | Array of field update objects |
|
| `data` | array | Yes | Array of field update objects |
|
||||||
|
|
||||||
|
Each entry in `data` requires the field `id` and `type`. Position properties (`page`, `positionX`, `positionY`, `width`, `height`), `envelopeItemId`, and `fieldMeta` are optional — only supplied values are updated. Placeholder positioning is not supported when updating; use coordinates.
|
||||||
|
|
||||||
### Code Examples
|
### Code Examples
|
||||||
|
|
||||||
@@ -311,17 +350,17 @@ curl -X POST "https://app.documenso.com/api/v2/envelope/field/update-many" \
|
|||||||
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{
|
-d '{
|
||||||
"documentId": 123,
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"fields": [
|
"data": [
|
||||||
{
|
{
|
||||||
"id": 101,
|
"id": 101,
|
||||||
"type": "SIGNATURE",
|
"type": "SIGNATURE",
|
||||||
"pageY": 85
|
"positionY": 85
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 102,
|
"id": 102,
|
||||||
"type": "DATE",
|
"type": "DATE",
|
||||||
"pageY": 85
|
"positionY": 85
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}'
|
}'
|
||||||
@@ -338,16 +377,16 @@ const response = await fetch(
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
documentId: 123,
|
envelopeId: 'envelope_abcdefhiklmnorst',
|
||||||
fields: [
|
data: [
|
||||||
{ id: 101, type: 'SIGNATURE', pageY: 85 },
|
{ id: 101, type: 'SIGNATURE', positionY: 85 },
|
||||||
{ id: 102, type: 'DATE', pageY: 85 },
|
{ id: 102, type: 'DATE', positionY: 85 },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { fields } = await response.json();
|
const { data } = await response.json();
|
||||||
|
|
||||||
````
|
````
|
||||||
</Tab>
|
</Tab>
|
||||||
@@ -357,9 +396,48 @@ const { fields } = await response.json();
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"fields": [
|
"data": [
|
||||||
{ "id": 101, "type": "SIGNATURE", "positionY": 85 },
|
{
|
||||||
{ "id": 102, "type": "DATE", "positionY": 85 }
|
"id": 101,
|
||||||
|
"secondaryId": "field_abc123",
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
|
"type": "SIGNATURE",
|
||||||
|
"recipientId": 456,
|
||||||
|
"page": 1,
|
||||||
|
"positionX": "10",
|
||||||
|
"positionY": "85",
|
||||||
|
"width": "30",
|
||||||
|
"height": "5",
|
||||||
|
"customText": "",
|
||||||
|
"inserted": false,
|
||||||
|
"fieldMeta": {
|
||||||
|
"type": "signature",
|
||||||
|
"fontSize": 18,
|
||||||
|
"overflow": "auto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 102,
|
||||||
|
"secondaryId": "field_def456",
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"envelopeItemId": "envelope_item_abcdefhiklmnorst",
|
||||||
|
"type": "DATE",
|
||||||
|
"recipientId": 456,
|
||||||
|
"page": 1,
|
||||||
|
"positionX": "50",
|
||||||
|
"positionY": "85",
|
||||||
|
"width": "20",
|
||||||
|
"height": "3",
|
||||||
|
"customText": "",
|
||||||
|
"inserted": false,
|
||||||
|
"fieldMeta": {
|
||||||
|
"type": "date",
|
||||||
|
"fontSize": 12,
|
||||||
|
"textAlign": "left",
|
||||||
|
"overflow": "auto"
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
````
|
````
|
||||||
@@ -443,8 +521,8 @@ Fields use percentage-based coordinates relative to the PDF page dimensions.
|
|||||||
(0,0) ─────────────────────────── (100,0)
|
(0,0) ─────────────────────────── (100,0)
|
||||||
│ │
|
│ │
|
||||||
│ ┌─────────┐ │
|
│ ┌─────────┐ │
|
||||||
│ │ Field │ (pageX: 10, │
|
│ │ Field │ (positionX: 10, │
|
||||||
│ │ │ pageY: 20, │
|
│ │ │ positionY: 20, │
|
||||||
│ └─────────┘ width: 30, │
|
│ └─────────┘ width: 30, │
|
||||||
│ height: 5) │
|
│ height: 5) │
|
||||||
│ │
|
│ │
|
||||||
@@ -457,9 +535,9 @@ Fields use percentage-based coordinates relative to the PDF page dimensions.
|
|||||||
const field = {
|
const field = {
|
||||||
type: 'SIGNATURE',
|
type: 'SIGNATURE',
|
||||||
recipientId: 123,
|
recipientId: 123,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 60, // 60% from left
|
positionX: 60, // 60% from left
|
||||||
pageY: 85, // 85% from top (near bottom)
|
positionY: 85, // 85% from top (near bottom)
|
||||||
width: 30, // 30% of page width
|
width: 30, // 30% of page width
|
||||||
height: 8, // 8% of page height
|
height: 8, // 8% of page height
|
||||||
};
|
};
|
||||||
@@ -479,6 +557,33 @@ This approach is useful when generating PDFs programmatically or using templates
|
|||||||
|
|
||||||
See the [PDF Placeholders](/docs/users/documents/advanced/pdf-placeholders) guide for the full placeholder format reference, including supported field types, recipient identifiers, and field options.
|
See the [PDF Placeholders](/docs/users/documents/advanced/pdf-placeholders) guide for the full placeholder format reference, including supported field types, recipient identifiers, and field options.
|
||||||
|
|
||||||
|
### Placeholder Positioning via the API
|
||||||
|
|
||||||
|
`POST /envelope/field/create-many` accepts a placeholder position in place of coordinates. Instead of `page`, `positionX`, `positionY`, `width`, and `height`, pass:
|
||||||
|
|
||||||
|
| Field | Type | Required | Description |
|
||||||
|
| ------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| `placeholder` | string | Yes | Text to search for in the PDF (e.g. `{{name}}`). The field is placed at the bounding box of the first match. |
|
||||||
|
| `width` | number | No | Override the field width. Defaults to the width of the matched text. |
|
||||||
|
| `height` | number | No | Override the field height. Defaults to the height of the matched text. |
|
||||||
|
| `matchAll` | boolean | No | Create a field at every occurrence of the placeholder instead of only the first. |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"type": "SIGNATURE",
|
||||||
|
"recipientId": 456,
|
||||||
|
"placeholder": "{{signature}}",
|
||||||
|
"matchAll": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`POST /envelope/field/update-many` does not accept placeholders — field updates are coordinate-only.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Field Meta Options
|
## Field Meta Options
|
||||||
@@ -643,15 +748,15 @@ All field types support these base options:
|
|||||||
Create a document with a signature block containing multiple field types:
|
Create a document with a signature block containing multiple field types:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
async function addSignatureBlock(documentId: number, recipientId: number) {
|
async function addSignatureBlock(envelopeId: string, recipientId: number) {
|
||||||
const fields = [
|
const data = [
|
||||||
// Signature
|
// Signature
|
||||||
{
|
{
|
||||||
type: 'SIGNATURE',
|
type: 'SIGNATURE',
|
||||||
recipientId,
|
recipientId,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 10,
|
positionX: 10,
|
||||||
pageY: 80,
|
positionY: 80,
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 8,
|
height: 8,
|
||||||
fieldMeta: {
|
fieldMeta: {
|
||||||
@@ -663,9 +768,9 @@ async function addSignatureBlock(documentId: number, recipientId: number) {
|
|||||||
{
|
{
|
||||||
type: 'NAME',
|
type: 'NAME',
|
||||||
recipientId,
|
recipientId,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 10,
|
positionX: 10,
|
||||||
pageY: 90,
|
positionY: 90,
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 4,
|
height: 4,
|
||||||
fieldMeta: {
|
fieldMeta: {
|
||||||
@@ -677,9 +782,9 @@ async function addSignatureBlock(documentId: number, recipientId: number) {
|
|||||||
{
|
{
|
||||||
type: 'DATE',
|
type: 'DATE',
|
||||||
recipientId,
|
recipientId,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 50,
|
positionX: 50,
|
||||||
pageY: 80,
|
positionY: 80,
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 4,
|
height: 4,
|
||||||
fieldMeta: {
|
fieldMeta: {
|
||||||
@@ -691,9 +796,9 @@ async function addSignatureBlock(documentId: number, recipientId: number) {
|
|||||||
{
|
{
|
||||||
type: 'TEXT',
|
type: 'TEXT',
|
||||||
recipientId,
|
recipientId,
|
||||||
pageNumber: 1,
|
page: 1,
|
||||||
pageX: 50,
|
positionX: 50,
|
||||||
pageY: 90,
|
positionY: 90,
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 4,
|
height: 4,
|
||||||
fieldMeta: {
|
fieldMeta: {
|
||||||
@@ -710,7 +815,7 @@ async function addSignatureBlock(documentId: number, recipientId: number) {
|
|||||||
Authorization: 'api_xxxxxxxxxxxxxxxx',
|
Authorization: 'api_xxxxxxxxxxxxxxxx',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ documentId, fields }),
|
body: JSON.stringify({ envelopeId, data }),
|
||||||
});
|
});
|
||||||
|
|
||||||
return response.json();
|
return response.json();
|
||||||
|
|||||||
@@ -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` | `GET /api/v2/envelope` |
|
||||||
| `GET /api/v2/document/{documentId}` | `GET /api/v2/envelope/{envelopeId}` |
|
| `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` | `POST /api/v2/envelope/create` |
|
||||||
| `POST /api/v2/document/create/beta` | `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` |
|
| `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` | `GET /api/v2/envelope` (with `type=TEMPLATE`) |
|
||||||
| `GET /api/v2/template/{templateId}` | `GET /api/v2/envelope/{envelopeId}` |
|
| `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` | `POST /api/v2/envelope/create` (`type=TEMPLATE`) |
|
||||||
| `POST /api/v2/template/create/beta` | `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` |
|
| `POST /api/v2/template/update` | `POST /api/v2/envelope/update` |
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ Documenso enforces rate limits on all API endpoints to ensure service stability.
|
|||||||
|
|
||||||
## HTTP Rate Limits
|
## HTTP Rate Limits
|
||||||
|
|
||||||
|
The rate limit applies to:
|
||||||
|
|
||||||
|
- `/api/v1/*`
|
||||||
|
- `/api/v2/*`
|
||||||
|
- `/api/v2-beta/*`
|
||||||
|
|
||||||
**Limit:** 1000 requests per minute per IP address
|
**Limit:** 1000 requests per minute per IP address
|
||||||
**Response:** 429 Too Many Requests
|
**Response:** 429 Too Many Requests
|
||||||
|
|
||||||
@@ -19,7 +25,7 @@ Documenso enforces rate limits on all API endpoints to ensure service stability.
|
|||||||
this value, in which case you can be rate-limited before reaching the global limit.
|
this value, in which case you can be rate-limited before reaching the global limit.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
### Rate Limit Response
|
### Global per-IP 429 Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -27,10 +33,22 @@ Documenso enforces rate limits on all API endpoints to ensure service stability.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<Callout type="warn">
|
### Rate Limit Headers
|
||||||
No rate limit headers are currently provided. When you receive a 429 response, wait at least 60
|
|
||||||
seconds before retrying.
|
Responses from `/api/v1/*`, `/api/v2/*`, and `/api/v2-beta/*` include these headers. The only
|
||||||
</Callout>
|
exception is CORS preflight (`OPTIONS`) requests, which are answered before the rate limiter runs
|
||||||
|
and carry no rate limit headers:
|
||||||
|
|
||||||
|
| Header | Description |
|
||||||
|
| ----------------------- | ---------------------------------------------------------------------- |
|
||||||
|
| `X-RateLimit-Limit` | Maximum requests allowed in the current global window |
|
||||||
|
| `X-RateLimit-Remaining` | Requests remaining in the current global window |
|
||||||
|
| `X-RateLimit-Reset` | End of the current global window, as a Unix epoch timestamp in seconds |
|
||||||
|
|
||||||
|
A 429 response from a windowed limiter also includes `Retry-After`, in seconds, with a minimum
|
||||||
|
value of `1`. The global API limit uses fixed, epoch-aligned one-minute buckets, so the actual wait
|
||||||
|
until the next window is between 1 and 60 seconds. Honor `Retry-After` exactly instead of sleeping
|
||||||
|
for a fixed 60 seconds. See the [Retry-After handling example](/docs/developers/examples/common-workflows#error-handling-patterns).
|
||||||
|
|
||||||
## Resource Limits
|
## Resource Limits
|
||||||
|
|
||||||
@@ -44,24 +62,55 @@ Beyond HTTP rate limits, your account has usage limits based on your subscriptio
|
|||||||
| Total Recipients | 10 | Unlimited | Unlimited | Unlimited |
|
| Total Recipients | 10 | Unlimited | Unlimited | Unlimited |
|
||||||
| Direct Templates | 3 | Unlimited | Unlimited | Unlimited |
|
| Direct Templates | 3 | Unlimited | Unlimited | Unlimited |
|
||||||
|
|
||||||
### Error Response
|
### Organisation Limit 429 Responses
|
||||||
|
|
||||||
When you exceed a resource limit:
|
Organisation windowed limits and organisation monthly quotas produce 429 responses whose body
|
||||||
|
shape depends on the API version, and neither matches the global per-IP limiter's
|
||||||
|
`{ "error": "..." }` body.
|
||||||
|
|
||||||
|
On `/api/v1/*`, the body contains only a message:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"error": "You have reached your document limit for this month. Please upgrade your plan.",
|
"message": "Too many requests, please try again later. Contact support if you require higher limits."
|
||||||
"code": "LIMIT_EXCEEDED",
|
|
||||||
"statusCode": 400
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On `/api/v2/*` and `/api/v2-beta/*`, the body is a structured error object:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message": "Too many requests, please try again later. Contact support if you require higher limits.",
|
||||||
|
"code": "TOO_MANY_REQUESTS",
|
||||||
|
"data": {
|
||||||
|
"code": "TOO_MANY_REQUESTS",
|
||||||
|
"httpStatus": 429,
|
||||||
|
"appError": {
|
||||||
|
"code": "TOO_MANY_REQUESTS",
|
||||||
|
"message": "Too many requests, please try again later. Contact support if you require higher limits."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Organisation windowed limit responses include the `X-RateLimit-*` headers and `Retry-After` for
|
||||||
|
their own window. Monthly quota responses carry no quota-specific rate limit headers or
|
||||||
|
`Retry-After` because the quota is not a time window; rely on the status code and message instead.
|
||||||
|
|
||||||
## Error Codes
|
## Error Codes
|
||||||
|
|
||||||
| Code | Status | Description |
|
| Code | Status | Description |
|
||||||
| ------------------- | ------ | ----------------------------- |
|
| ------------------- | ------ | ------------------------------------------------------------------ |
|
||||||
| `TOO_MANY_REQUESTS` | 429 | HTTP rate limit exceeded |
|
| `TOO_MANY_REQUESTS` | 429 | Global per-IP, organisation windowed, or monthly quota exceeded |
|
||||||
| `LIMIT_EXCEEDED` | 400 | Resource usage limit exceeded |
|
| `LIMIT_EXCEEDED` | 400 | Resource usage limit exceeded |
|
||||||
|
|
||||||
|
There are three sources of `TOO_MANY_REQUESTS` responses:
|
||||||
|
|
||||||
|
1. The global per-IP limit, returning the `{ "error": "..." }` body shown above.
|
||||||
|
2. Organisation windowed rate limits for the `api`, `document`, and `email` counters.
|
||||||
|
3. Organisation monthly quotas for the same three counters. Every authenticated API request
|
||||||
|
consumes the `api` counter, so any endpoint can return this 429 once the monthly API quota is
|
||||||
|
exhausted — not just envelope-related ones.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1000,9 +1000,12 @@ async function fetchWithRetry(
|
|||||||
// Retry on rate limit
|
// Retry on rate limit
|
||||||
if (response.status === 429) {
|
if (response.status === 429) {
|
||||||
const retryAfter = response.headers.get('Retry-After');
|
const retryAfter = response.headers.get('Retry-After');
|
||||||
const delay = retryAfter ? parseInt(retryAfter) * 1000 : baseDelayMs * Math.pow(2, attempt);
|
// Honor Retry-After exactly; the cap only applies to the exponential fallback.
|
||||||
|
const delay = retryAfter
|
||||||
|
? parseInt(retryAfter) * 1000
|
||||||
|
: Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
||||||
console.log(`Rate limited, waiting ${delay}ms...`);
|
console.log(`Rate limited, waiting ${delay}ms...`);
|
||||||
await new Promise((resolve) => setTimeout(resolve, Math.min(delay, maxDelayMs)));
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,14 @@ All webhook events share a common structure:
|
|||||||
|
|
||||||
| Field | Type | Description |
|
| Field | Type | Description |
|
||||||
| ---------------- | --------- | ------------------------------------------------------ |
|
| ---------------- | --------- | ------------------------------------------------------ |
|
||||||
| `id` | number | Document or template ID |
|
| `id` | number | Legacy numeric v1 document or template ID |
|
||||||
|
| `envelopeId` | string | Canonical v2 identifier (`envelope_` + 16 characters) |
|
||||||
| `externalId` | string? | External identifier for integration |
|
| `externalId` | string? | External identifier for integration |
|
||||||
| `userId` | number | Owner's user ID |
|
| `userId` | number | Owner's user ID |
|
||||||
| `authOptions` | object? | Document-level authentication options |
|
| `authOptions` | object? | Document-level authentication options |
|
||||||
| `formValues` | object? | PDF form values associated with the document |
|
| `formValues` | object? | PDF form values associated with the document |
|
||||||
| `title` | string | Document or template title |
|
| `title` | string | Document or template title |
|
||||||
| `status` | string | Current status: `DRAFT`, `PENDING`, `COMPLETED` |
|
| `status` | string | Current status: `DRAFT`, `PENDING`, `COMPLETED`, `REJECTED`, `CANCELLED` |
|
||||||
| `visibility` | string | Document visibility setting |
|
| `visibility` | string | Document visibility setting |
|
||||||
| `createdAt` | datetime | Document creation timestamp |
|
| `createdAt` | datetime | Document creation timestamp |
|
||||||
| `updatedAt` | datetime | Last modification timestamp |
|
| `updatedAt` | datetime | Last modification timestamp |
|
||||||
@@ -47,8 +48,8 @@ All webhook events share a common structure:
|
|||||||
| `deletedAt` | datetime? | Deletion timestamp |
|
| `deletedAt` | datetime? | Deletion timestamp |
|
||||||
| `teamId` | number? | Team ID if document belongs to a team |
|
| `teamId` | number? | Team ID if document belongs to a team |
|
||||||
| `templateId` | number? | Template ID if created from a template |
|
| `templateId` | number? | Template ID if created from a template |
|
||||||
| `source` | string | Source: `DOCUMENT` or `TEMPLATE` |
|
| `source` | string | Source: `DOCUMENT`, `TEMPLATE`, or `TEMPLATE_DIRECT_LINK` |
|
||||||
| `documentMeta` | object | Document metadata (subject, message, signing options) |
|
| `documentMeta` | object? | Nullable document metadata (subject, message, signing options) |
|
||||||
| `recipients` | array | List of recipient objects |
|
| `recipients` | array | List of recipient objects |
|
||||||
| `Recipient` | array | List of recipient objects (legacy, same as recipients) |
|
| `Recipient` | array | List of recipient objects (legacy, same as recipients) |
|
||||||
|
|
||||||
@@ -60,7 +61,6 @@ All webhook events share a common structure:
|
|||||||
| `subject` | string? | Email subject line |
|
| `subject` | string? | Email subject line |
|
||||||
| `message` | string? | Email message body |
|
| `message` | string? | Email message body |
|
||||||
| `timezone` | string | Timezone for date display |
|
| `timezone` | string | Timezone for date display |
|
||||||
| `password` | string? | Document access password (if set) |
|
|
||||||
| `dateFormat` | string | Date format string |
|
| `dateFormat` | string | Date format string |
|
||||||
| `redirectUrl` | string? | URL to redirect after signing |
|
| `redirectUrl` | string? | URL to redirect after signing |
|
||||||
| `signingOrder` | string | `PARALLEL` or `SEQUENTIAL` |
|
| `signingOrder` | string | `PARALLEL` or `SEQUENTIAL` |
|
||||||
@@ -77,8 +77,9 @@ All webhook events share a common structure:
|
|||||||
| Field | Type | Description |
|
| Field | Type | Description |
|
||||||
| ---------------------- | --------- | ------------------------------------------ |
|
| ---------------------- | --------- | ------------------------------------------ |
|
||||||
| `id` | number | Recipient ID |
|
| `id` | number | Recipient ID |
|
||||||
| `documentId` | number? | Parent document ID |
|
| `envelopeId` | string | Canonical parent envelope ID |
|
||||||
| `templateId` | number? | Template ID if created from a template |
|
| `documentId` | number? | Legacy parent document ID; null for templates |
|
||||||
|
| `templateId` | number? | Legacy parent template ID; null for documents |
|
||||||
| `email` | string | Recipient email address |
|
| `email` | string | Recipient email address |
|
||||||
| `name` | string | Recipient name |
|
| `name` | string | Recipient name |
|
||||||
| `token` | string | Unique signing token |
|
| `token` | string | Unique signing token |
|
||||||
@@ -94,6 +95,8 @@ All webhook events share a common structure:
|
|||||||
| `sendStatus` | string | `NOT_SENT` or `SENT` |
|
| `sendStatus` | string | `NOT_SENT` or `SENT` |
|
||||||
| `rejectionReason` | string? | Reason if recipient rejected |
|
| `rejectionReason` | string? | Reason if recipient rejected |
|
||||||
|
|
||||||
|
Use `recipient.envelopeId` as the reliable parent link. The legacy `documentId` and `templateId` fields depend on the parent envelope type, so one of them is always null.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Document Lifecycle Events
|
## Document Lifecycle Events
|
||||||
@@ -111,6 +114,7 @@ Triggered when a new document is created.
|
|||||||
"event": "DOCUMENT_CREATED",
|
"event": "DOCUMENT_CREATED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"externalId": null,
|
"externalId": null,
|
||||||
"userId": 1,
|
"userId": 1,
|
||||||
"authOptions": null,
|
"authOptions": null,
|
||||||
@@ -129,9 +133,8 @@ Triggered when a new document is created.
|
|||||||
"id": "doc_meta_123",
|
"id": "doc_meta_123",
|
||||||
"subject": "Please sign this document",
|
"subject": "Please sign this document",
|
||||||
"message": "Hello, please review and sign this document.",
|
"message": "Hello, please review and sign this document.",
|
||||||
"timezone": "UTC",
|
"timezone": "Etc/UTC",
|
||||||
"password": null,
|
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||||
"dateFormat": "MM/DD/YYYY",
|
|
||||||
"redirectUrl": null,
|
"redirectUrl": null,
|
||||||
"signingOrder": "PARALLEL",
|
"signingOrder": "PARALLEL",
|
||||||
"allowDictateNextSigner": false,
|
"allowDictateNextSigner": false,
|
||||||
@@ -145,6 +148,7 @@ Triggered when a new document is created.
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -166,6 +170,7 @@ Triggered when a new document is created.
|
|||||||
"Recipient": [
|
"Recipient": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -203,6 +208,7 @@ The document status changes to `PENDING` and recipients have `sendStatus: "SENT"
|
|||||||
"event": "DOCUMENT_SENT",
|
"event": "DOCUMENT_SENT",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"externalId": null,
|
"externalId": null,
|
||||||
"userId": 1,
|
"userId": 1,
|
||||||
"authOptions": null,
|
"authOptions": null,
|
||||||
@@ -221,9 +227,8 @@ The document status changes to `PENDING` and recipients have `sendStatus: "SENT"
|
|||||||
"id": "doc_meta_123",
|
"id": "doc_meta_123",
|
||||||
"subject": "Please sign this document",
|
"subject": "Please sign this document",
|
||||||
"message": "Hello, please review and sign this document.",
|
"message": "Hello, please review and sign this document.",
|
||||||
"timezone": "UTC",
|
"timezone": "Etc/UTC",
|
||||||
"password": null,
|
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||||
"dateFormat": "MM/DD/YYYY",
|
|
||||||
"redirectUrl": null,
|
"redirectUrl": null,
|
||||||
"signingOrder": "PARALLEL",
|
"signingOrder": "PARALLEL",
|
||||||
"allowDictateNextSigner": false,
|
"allowDictateNextSigner": false,
|
||||||
@@ -237,6 +242,7 @@ The document status changes to `PENDING` and recipients have `sendStatus: "SENT"
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -258,6 +264,7 @@ The document status changes to `PENDING` and recipients have `sendStatus: "SENT"
|
|||||||
"Recipient": [
|
"Recipient": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -295,12 +302,14 @@ The recipient's `readStatus` changes to `OPENED`.
|
|||||||
"event": "DOCUMENT_OPENED",
|
"event": "DOCUMENT_OPENED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"title": "contract.pdf",
|
"title": "contract.pdf",
|
||||||
"source": "DOCUMENT",
|
"source": "DOCUMENT",
|
||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
"role": "SIGNER",
|
"role": "SIGNER",
|
||||||
@@ -328,6 +337,7 @@ The recipient's `signingStatus` changes to `SIGNED` and `signedAt` is populated.
|
|||||||
"event": "DOCUMENT_SIGNED",
|
"event": "DOCUMENT_SIGNED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"status": "COMPLETED",
|
"status": "COMPLETED",
|
||||||
"title": "contract.pdf",
|
"title": "contract.pdf",
|
||||||
"source": "DOCUMENT",
|
"source": "DOCUMENT",
|
||||||
@@ -335,6 +345,7 @@ The recipient's `signingStatus` changes to `SIGNED` and `signedAt` is populated.
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 51,
|
"id": 51,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
"role": "SIGNER",
|
"role": "SIGNER",
|
||||||
@@ -361,12 +372,14 @@ Triggered when an individual recipient completes their required action (signing,
|
|||||||
"event": "DOCUMENT_RECIPIENT_COMPLETED",
|
"event": "DOCUMENT_RECIPIENT_COMPLETED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"title": "contract.pdf",
|
"title": "contract.pdf",
|
||||||
"source": "DOCUMENT",
|
"source": "DOCUMENT",
|
||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
"role": "SIGNER",
|
"role": "SIGNER",
|
||||||
@@ -395,6 +408,7 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
"event": "DOCUMENT_COMPLETED",
|
"event": "DOCUMENT_COMPLETED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"externalId": null,
|
"externalId": null,
|
||||||
"userId": 1,
|
"userId": 1,
|
||||||
"authOptions": null,
|
"authOptions": null,
|
||||||
@@ -413,9 +427,8 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
"id": "doc_meta_123",
|
"id": "doc_meta_123",
|
||||||
"subject": "Please sign this document",
|
"subject": "Please sign this document",
|
||||||
"message": "Hello, please review and sign this document.",
|
"message": "Hello, please review and sign this document.",
|
||||||
"timezone": "UTC",
|
"timezone": "Etc/UTC",
|
||||||
"password": null,
|
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||||
"dateFormat": "MM/DD/YYYY",
|
|
||||||
"redirectUrl": null,
|
"redirectUrl": null,
|
||||||
"signingOrder": "PARALLEL",
|
"signingOrder": "PARALLEL",
|
||||||
"allowDictateNextSigner": false,
|
"allowDictateNextSigner": false,
|
||||||
@@ -429,6 +442,7 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 50,
|
"id": 50,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "reviewer@example.com",
|
"email": "reviewer@example.com",
|
||||||
@@ -451,6 +465,7 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 51,
|
"id": 51,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -475,6 +490,7 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
"Recipient": [
|
"Recipient": [
|
||||||
{
|
{
|
||||||
"id": 50,
|
"id": 50,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "reviewer@example.com",
|
"email": "reviewer@example.com",
|
||||||
@@ -497,6 +513,7 @@ The document status changes to `COMPLETED` and `completedAt` is set.
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 51,
|
"id": 51,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 10,
|
"documentId": 10,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -537,12 +554,14 @@ The recipient's `signingStatus` changes to `REJECTED` and `rejectionReason` cont
|
|||||||
"event": "DOCUMENT_REJECTED",
|
"event": "DOCUMENT_REJECTED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"title": "contract.pdf",
|
"title": "contract.pdf",
|
||||||
"source": "DOCUMENT",
|
"source": "DOCUMENT",
|
||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
"role": "SIGNER",
|
"role": "SIGNER",
|
||||||
@@ -561,7 +580,7 @@ The recipient's `signingStatus` changes to `REJECTED` and `rejectionReason` cont
|
|||||||
|
|
||||||
### `document.cancelled`
|
### `document.cancelled`
|
||||||
|
|
||||||
Triggered when the document owner or a team member deletes a document. Draft and pending documents are hard-deleted, while completed documents are soft-deleted.
|
Triggered when a pending document is explicitly cancelled with `POST /envelope/cancel`, or when a document owner or team member deletes a document. Deleting a draft or pending document hard-deletes it, while deleting a completed document soft-deletes it.
|
||||||
|
|
||||||
This event is **not** triggered when a recipient hides a document from their inbox.
|
This event is **not** triggered when a recipient hides a document from their inbox.
|
||||||
|
|
||||||
@@ -572,6 +591,7 @@ This event is **not** triggered when a recipient hides a document from their inb
|
|||||||
"event": "DOCUMENT_CANCELLED",
|
"event": "DOCUMENT_CANCELLED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 7,
|
"id": 7,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"externalId": null,
|
"externalId": null,
|
||||||
"userId": 3,
|
"userId": 3,
|
||||||
"authOptions": null,
|
"authOptions": null,
|
||||||
@@ -591,7 +611,6 @@ This event is **not** triggered when a recipient hides a document from their inb
|
|||||||
"subject": "",
|
"subject": "",
|
||||||
"message": "",
|
"message": "",
|
||||||
"timezone": "Etc/UTC",
|
"timezone": "Etc/UTC",
|
||||||
"password": null,
|
|
||||||
"dateFormat": "yyyy-MM-dd hh:mm a",
|
"dateFormat": "yyyy-MM-dd hh:mm a",
|
||||||
"redirectUrl": "",
|
"redirectUrl": "",
|
||||||
"signingOrder": "PARALLEL",
|
"signingOrder": "PARALLEL",
|
||||||
@@ -606,6 +625,7 @@ This event is **not** triggered when a recipient hides a document from their inb
|
|||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 7,
|
"documentId": 7,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -627,6 +647,7 @@ This event is **not** triggered when a recipient hides a document from their inb
|
|||||||
"Recipient": [
|
"Recipient": [
|
||||||
{
|
{
|
||||||
"id": 7,
|
"id": 7,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"documentId": 7,
|
"documentId": 7,
|
||||||
"templateId": null,
|
"templateId": null,
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
@@ -651,6 +672,45 @@ This event is **not** triggered when a recipient hides a document from their inb
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `recipient.expired`
|
||||||
|
|
||||||
|
Triggered when a recipient's signing deadline passes on a pending document before they sign or reject it.
|
||||||
|
|
||||||
|
**Event name:** `RECIPIENT_EXPIRED`
|
||||||
|
|
||||||
|
The recipient's `expiresAt` contains the signing deadline, and `expirationNotifiedAt` is set when the expiration is processed.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"event": "RECIPIENT_EXPIRED",
|
||||||
|
"payload": {
|
||||||
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"status": "PENDING",
|
||||||
|
"title": "contract.pdf",
|
||||||
|
"source": "DOCUMENT",
|
||||||
|
"recipients": [
|
||||||
|
{
|
||||||
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
|
"documentId": 10,
|
||||||
|
"templateId": null,
|
||||||
|
"email": "signer@example.com",
|
||||||
|
"name": "John Doe",
|
||||||
|
"role": "SIGNER",
|
||||||
|
"expiresAt": "2024-04-22T11:51:00.000Z",
|
||||||
|
"expirationNotifiedAt": "2024-04-22T11:52:00.000Z",
|
||||||
|
"readStatus": "OPENED",
|
||||||
|
"signingStatus": "NOT_SIGNED",
|
||||||
|
"sendStatus": "SENT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"createdAt": "2024-04-22T11:52:00.000Z",
|
||||||
|
"webhookEndpoint": "https://your-endpoint.com/webhook"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### `document.reminder.sent`
|
### `document.reminder.sent`
|
||||||
|
|
||||||
Triggered when a reminder email is sent to a recipient who has not yet completed their action.
|
Triggered when a reminder email is sent to a recipient who has not yet completed their action.
|
||||||
@@ -662,12 +722,14 @@ Triggered when a reminder email is sent to a recipient who has not yet completed
|
|||||||
"event": "DOCUMENT_REMINDER_SENT",
|
"event": "DOCUMENT_REMINDER_SENT",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"title": "contract.pdf",
|
"title": "contract.pdf",
|
||||||
"source": "DOCUMENT",
|
"source": "DOCUMENT",
|
||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 52,
|
"id": 52,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"name": "John Doe",
|
"name": "John Doe",
|
||||||
"role": "SIGNER",
|
"role": "SIGNER",
|
||||||
@@ -686,7 +748,7 @@ Triggered when a reminder email is sent to a recipient who has not yet completed
|
|||||||
|
|
||||||
## Template Events
|
## Template Events
|
||||||
|
|
||||||
Template events track changes to reusable document templates. Template payloads use the same structure as document payloads, with `source` set to `TEMPLATE` and `templateId` populated.
|
Template events track changes to reusable document templates. Template payloads use the same structure as document payloads. For `TEMPLATE_CREATED`, `TEMPLATE_UPDATED`, and `TEMPLATE_DELETED` the template's own legacy numeric ID is in `id` and `templateId` is `null`. Only `TEMPLATE_USED` — whose payload describes the new document envelope created from the template — carries the originating template's legacy ID in `templateId`, with `source` set to `TEMPLATE`.
|
||||||
|
|
||||||
### `template.created`
|
### `template.created`
|
||||||
|
|
||||||
@@ -699,9 +761,10 @@ Triggered when a new template is created.
|
|||||||
"event": "TEMPLATE_CREATED",
|
"event": "TEMPLATE_CREATED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"title": "My Template",
|
"title": "My Template",
|
||||||
"status": "DRAFT",
|
"status": "DRAFT",
|
||||||
"templateId": 10,
|
"templateId": null,
|
||||||
"source": "TEMPLATE",
|
"source": "TEMPLATE",
|
||||||
"recipients": []
|
"recipients": []
|
||||||
},
|
},
|
||||||
@@ -721,9 +784,10 @@ Triggered when a template's settings, recipients, or fields are modified.
|
|||||||
"event": "TEMPLATE_UPDATED",
|
"event": "TEMPLATE_UPDATED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"title": "My Updated Template",
|
"title": "My Updated Template",
|
||||||
"status": "DRAFT",
|
"status": "DRAFT",
|
||||||
"templateId": 10,
|
"templateId": null,
|
||||||
"source": "TEMPLATE",
|
"source": "TEMPLATE",
|
||||||
"recipients": []
|
"recipients": []
|
||||||
},
|
},
|
||||||
@@ -743,9 +807,10 @@ Triggered when a template is deleted.
|
|||||||
"event": "TEMPLATE_DELETED",
|
"event": "TEMPLATE_DELETED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"title": "Deleted Template",
|
"title": "Deleted Template",
|
||||||
"status": "DRAFT",
|
"status": "DRAFT",
|
||||||
"templateId": 10,
|
"templateId": null,
|
||||||
"source": "TEMPLATE",
|
"source": "TEMPLATE",
|
||||||
"recipients": []
|
"recipients": []
|
||||||
},
|
},
|
||||||
@@ -765,6 +830,7 @@ Triggered when a document is created from a template. This event fires alongside
|
|||||||
"event": "TEMPLATE_USED",
|
"event": "TEMPLATE_USED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 10,
|
"id": 10,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"title": "Document from Template",
|
"title": "Document from Template",
|
||||||
"status": "DRAFT",
|
"status": "DRAFT",
|
||||||
"templateId": 10,
|
"templateId": 10,
|
||||||
@@ -791,7 +857,8 @@ Triggered when a document is created from a template. This event fires alongside
|
|||||||
| `DOCUMENT_RECIPIENT_COMPLETED` | Recipient completes their action | Recipient `signingStatus: "SIGNED"`, `signedAt` set |
|
| `DOCUMENT_RECIPIENT_COMPLETED` | Recipient completes their action | Recipient `signingStatus: "SIGNED"`, `signedAt` set |
|
||||||
| `DOCUMENT_COMPLETED` | All recipients complete actions | `status: "COMPLETED"`, `completedAt` set |
|
| `DOCUMENT_COMPLETED` | All recipients complete actions | `status: "COMPLETED"`, `completedAt` set |
|
||||||
| `DOCUMENT_REJECTED` | Recipient rejects document | Recipient `signingStatus: "REJECTED"`, `rejectionReason` set |
|
| `DOCUMENT_REJECTED` | Recipient rejects document | Recipient `signingStatus: "REJECTED"`, `rejectionReason` set |
|
||||||
| `DOCUMENT_CANCELLED` | Owner or team member deletes document | Document cancelled or deleted |
|
| `DOCUMENT_CANCELLED` | Pending document explicitly cancelled, or document deleted | `status: "CANCELLED"` after explicit cancellation; deletion may remove or soft-delete the document |
|
||||||
|
| `RECIPIENT_EXPIRED` | Recipient signing deadline passes | Recipient `expiresAt` passed, `expirationNotifiedAt` set |
|
||||||
| `DOCUMENT_REMINDER_SENT` | Reminder email sent to recipient | No status changes |
|
| `DOCUMENT_REMINDER_SENT` | Reminder email sent to recipient | No status changes |
|
||||||
|
|
||||||
### Template Events
|
### Template Events
|
||||||
@@ -821,7 +888,7 @@ When processing webhook events:
|
|||||||
**Process idempotently** — Webhooks may be retried, so handle duplicate events
|
**Process idempotently** — Webhooks may be retried, so handle duplicate events
|
||||||
</Step>
|
</Step>
|
||||||
<Step>
|
<Step>
|
||||||
**Respond quickly** — Return a 200 status code within 30 seconds
|
**Respond quickly** — Return a `2xx` status code within 10 seconds
|
||||||
</Step>
|
</Step>
|
||||||
</Steps>
|
</Steps>
|
||||||
|
|
||||||
|
|||||||
@@ -42,12 +42,14 @@ Documenso supports webhook events for the full document lifecycle (created, sent
|
|||||||
"event": "DOCUMENT_COMPLETED",
|
"event": "DOCUMENT_COMPLETED",
|
||||||
"payload": {
|
"payload": {
|
||||||
"id": 123,
|
"id": 123,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"title": "Contract",
|
"title": "Contract",
|
||||||
"status": "COMPLETED",
|
"status": "COMPLETED",
|
||||||
"completedAt": "2024-01-15T10:30:00.000Z",
|
"completedAt": "2024-01-15T10:30:00.000Z",
|
||||||
"recipients": [
|
"recipients": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
|
"envelopeId": "envelope_abcdefhiklmnorst",
|
||||||
"email": "signer@example.com",
|
"email": "signer@example.com",
|
||||||
"signingStatus": "SIGNED"
|
"signingStatus": "SIGNED"
|
||||||
}
|
}
|
||||||
@@ -58,6 +60,8 @@ Documenso supports webhook events for the full document lifecycle (created, sent
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`payload.id` is the legacy numeric v1 ID. Use `payload.envelopeId` as the canonical v2 identifier. Each recipient repeats `envelopeId` as the reliable parent link because the legacy `documentId` and `templateId` fields depend on the parent envelope type, leaving one of them null.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ func main() {
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
Always respond with a `200 OK` status within 30 seconds. Documenso will retry failed deliveries.
|
Always respond with a `2xx` status within 10 seconds. Documenso will retry failed deliveries according to the configured background-job provider.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
## Configuring Webhooks in Documenso via the Dashboard
|
## Configuring Webhooks in Documenso via the Dashboard
|
||||||
@@ -184,7 +184,7 @@ Fill in the following fields:
|
|||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
| ----- | ----------- |
|
| ----- | ----------- |
|
||||||
| **Webhook URL** | The HTTPS endpoint that will receive webhook events |
|
| **Webhook URL** | The HTTP or HTTPS endpoint that will receive webhook events |
|
||||||
| **Events** | Select which events should trigger this webhook |
|
| **Events** | Select which events should trigger this webhook |
|
||||||
| **Secret** (optional) | A secret key used to sign the payload for verification |
|
| **Secret** (optional) | A secret key used to sign the payload for verification |
|
||||||
</Step>
|
</Step>
|
||||||
@@ -202,12 +202,21 @@ Your webhook endpoint must meet these requirements:
|
|||||||
|
|
||||||
| Requirement | Details |
|
| Requirement | Details |
|
||||||
| ----------- | ------- |
|
| ----------- | ------- |
|
||||||
| **Protocol** | HTTPS required (HTTP not allowed in production) |
|
| **Protocol** | HTTP and HTTPS are accepted; use HTTPS in production |
|
||||||
| **Response** | Must return `2xx` status code within 30 seconds |
|
| **Response** | Must return a `2xx` status code within 10 seconds |
|
||||||
| **Method** | Must accept HTTP POST requests |
|
| **Method** | Must accept HTTP POST requests |
|
||||||
| **Content-Type** | Must accept `application/json` payloads |
|
| **Content-Type** | Must accept `application/json` payloads |
|
||||||
| **Availability** | Must be publicly accessible from the internet |
|
| **Availability** | Must be publicly accessible from the internet |
|
||||||
|
|
||||||
|
<Callout type="warn">
|
||||||
|
Documenso performs a best-effort check that rejects webhook URLs which use or resolve to private
|
||||||
|
or loopback addresses. This is not a complete SSRF mitigation — it does not cover DNS rebinding
|
||||||
|
and fails open on DNS lookup errors or timeouts — so self-hosted deployments should still enforce
|
||||||
|
network-level egress rules. Self-hosters that need to deliver to a hostname resolving to a
|
||||||
|
private address can add that hostname to the comma-separated
|
||||||
|
`NEXT_PRIVATE_WEBHOOK_SSRF_BYPASS_HOSTS` environment variable.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
<Callout type="info">
|
<Callout type="info">
|
||||||
For local development, use a tunneling service like [ngrok](https://ngrok.com) or [localtunnel](https://localtunnel.me) to expose your local server.
|
For local development, use a tunneling service like [ngrok](https://ngrok.com) or [localtunnel](https://localtunnel.me) to expose your local server.
|
||||||
</Callout>
|
</Callout>
|
||||||
@@ -225,7 +234,8 @@ When creating a webhook, you can subscribe to one or more events:
|
|||||||
| `DOCUMENT_RECIPIENT_COMPLETED` | A recipient completes their required action |
|
| `DOCUMENT_RECIPIENT_COMPLETED` | A recipient completes their required action |
|
||||||
| `DOCUMENT_COMPLETED` | All recipients have completed their actions |
|
| `DOCUMENT_COMPLETED` | All recipients have completed their actions |
|
||||||
| `DOCUMENT_REJECTED` | A recipient rejects the document |
|
| `DOCUMENT_REJECTED` | A recipient rejects the document |
|
||||||
| `DOCUMENT_CANCELLED` | The document owner deletes the document |
|
| `DOCUMENT_CANCELLED` | A pending document is explicitly cancelled or a document owner deletes it |
|
||||||
|
| `RECIPIENT_EXPIRED` | A recipient's signing deadline passes before they sign or reject |
|
||||||
| `DOCUMENT_REMINDER_SENT` | A reminder email is sent to a recipient |
|
| `DOCUMENT_REMINDER_SENT` | A reminder email is sent to a recipient |
|
||||||
| `TEMPLATE_CREATED` | A new template is created |
|
| `TEMPLATE_CREATED` | A new template is created |
|
||||||
| `TEMPLATE_UPDATED` | A template is modified |
|
| `TEMPLATE_UPDATED` | A template is modified |
|
||||||
@@ -318,17 +328,17 @@ Documenso will attempt to deliver the same payload again
|
|||||||
|
|
||||||
## Retry Policy
|
## Retry Policy
|
||||||
|
|
||||||
When a webhook delivery fails (non-2xx response or timeout), Documenso automatically retries with exponential backoff:
|
A delivery fails when the endpoint returns a non-`2xx` response, the 10-second timeout expires, or the request fails. Redirects are not followed, so `3xx` responses also fail. Network and SSRF-blocked requests are recorded with response code `0`.
|
||||||
|
|
||||||
| Attempt | Delay |
|
For self-hosted deployments, retries are handled by the background-job provider selected with `NEXT_PRIVATE_JOBS_PROVIDER`:
|
||||||
| ------- | ----- |
|
|
||||||
| 1 | Immediate |
|
|
||||||
| 2 | 1 minute |
|
|
||||||
| 3 | 5 minutes |
|
|
||||||
| 4 | 30 minutes |
|
|
||||||
| 5 | 2 hours |
|
|
||||||
|
|
||||||
After 5 failed attempts, the webhook is marked as failed and no further automatic retries occur. You can manually resend failed webhooks from the dashboard.
|
| Provider | Total attempts | Retry timing |
|
||||||
|
| -------- | -------------- | ------------ |
|
||||||
|
| Local (default) | 4 | Back-to-back, with no backoff |
|
||||||
|
| BullMQ | 3 | Exponential backoff starting at 1 second |
|
||||||
|
| Inngest | 5 | Inngest platform backoff |
|
||||||
|
|
||||||
|
Only the individual delivery (`WebhookCall`) record is marked as failed. Documenso does not automatically disable the webhook or apply a circuit breaker, so future matching events continue to be delivered. After automatic attempts are exhausted, you can manually resend a failed delivery from the dashboard.
|
||||||
|
|
||||||
<Callout type="warn">
|
<Callout type="warn">
|
||||||
If your endpoint consistently fails, consider reviewing your server logs and ensuring your endpoint meets all [URL requirements](#webhook-url-requirements).
|
If your endpoint consistently fails, consider reviewing your server logs and ensuring your endpoint meets all [URL requirements](#webhook-url-requirements).
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ const validEvents = [
|
|||||||
'DOCUMENT_REJECTED',
|
'DOCUMENT_REJECTED',
|
||||||
'DOCUMENT_CANCELLED',
|
'DOCUMENT_CANCELLED',
|
||||||
'DOCUMENT_REMINDER_SENT',
|
'DOCUMENT_REMINDER_SENT',
|
||||||
|
'RECIPIENT_EXPIRED',
|
||||||
'TEMPLATE_CREATED',
|
'TEMPLATE_CREATED',
|
||||||
'TEMPLATE_UPDATED',
|
'TEMPLATE_UPDATED',
|
||||||
'TEMPLATE_DELETED',
|
'TEMPLATE_DELETED',
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ export const cancelEnvelopeMeta: TrpcRouteMeta = {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/envelope/cancel',
|
path: '/envelope/cancel',
|
||||||
summary: 'Cancel envelope',
|
summary: 'Cancel envelope',
|
||||||
|
description: 'Cancel a pending envelope',
|
||||||
tags: ['Envelope'],
|
tags: ['Envelope'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZCancelEnvelopeRequestSchema = z.object({
|
export const ZCancelEnvelopeRequestSchema = z.object({
|
||||||
envelopeId: z.string(),
|
envelopeId: z.string().describe('The ID of the envelope to cancel.'),
|
||||||
reason: z.string().optional(),
|
reason: z.string().describe('The reason for cancelling the envelope.').optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ZCancelEnvelopeResponseSchema = ZSuccessResponseSchema;
|
export const ZCancelEnvelopeResponseSchema = ZSuccessResponseSchema;
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ export const deleteEnvelopeMeta: TrpcRouteMeta = {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/envelope/delete',
|
path: '/envelope/delete',
|
||||||
summary: 'Delete envelope',
|
summary: 'Delete envelope',
|
||||||
|
description: 'Delete an envelope',
|
||||||
tags: ['Envelope'],
|
tags: ['Envelope'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZDeleteEnvelopeRequestSchema = z.object({
|
export const ZDeleteEnvelopeRequestSchema = z.object({
|
||||||
envelopeId: z.string(),
|
envelopeId: z.string().describe('The ID of the envelope to delete.'),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ZDeleteEnvelopeResponseSchema = ZSuccessResponseSchema;
|
export const ZDeleteEnvelopeResponseSchema = ZSuccessResponseSchema;
|
||||||
|
|||||||
@@ -29,7 +29,17 @@ export const updateEnvelopeFieldsRoute = authenticatedProcedure
|
|||||||
id: envelopeId,
|
id: envelopeId,
|
||||||
},
|
},
|
||||||
type: null,
|
type: null,
|
||||||
fields,
|
fields: fields.map((field) => ({
|
||||||
|
id: field.id,
|
||||||
|
type: field.type,
|
||||||
|
pageNumber: field.page,
|
||||||
|
pageX: field.positionX,
|
||||||
|
pageY: field.positionY,
|
||||||
|
width: field.width,
|
||||||
|
height: field.height,
|
||||||
|
fieldMeta: field.fieldMeta,
|
||||||
|
envelopeItemId: field.envelopeItemId,
|
||||||
|
})),
|
||||||
requestMetadata: ctx.metadata,
|
requestMetadata: ctx.metadata,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,24 +12,32 @@ export const updateEnvelopeMeta: TrpcRouteMeta = {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/envelope/update',
|
path: '/envelope/update',
|
||||||
summary: 'Update envelope',
|
summary: 'Update envelope',
|
||||||
|
description: 'Update envelope properties and settings',
|
||||||
tags: ['Envelope'],
|
tags: ['Envelope'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZUpdateEnvelopeRequestSchema = z.object({
|
export const ZUpdateEnvelopeRequestSchema = z.object({
|
||||||
envelopeId: z.string(),
|
envelopeId: z.string().describe('The ID of the envelope to update.'),
|
||||||
data: z
|
data: z
|
||||||
.object({
|
.object({
|
||||||
title: ZDocumentTitleSchema.optional(),
|
title: ZDocumentTitleSchema.optional(),
|
||||||
externalId: ZDocumentExternalIdSchema.nullish(),
|
externalId: ZDocumentExternalIdSchema.nullish(),
|
||||||
visibility: ZDocumentVisibilitySchema.optional(),
|
visibility: ZDocumentVisibilitySchema.optional(),
|
||||||
globalAccessAuth: z.array(ZDocumentAccessAuthTypesSchema).optional(),
|
globalAccessAuth: z
|
||||||
globalActionAuth: z.array(ZDocumentActionAuthTypesSchema).optional(),
|
.array(ZDocumentAccessAuthTypesSchema)
|
||||||
folderId: z.string().nullish(),
|
.describe('The authentication methods required to access the envelope.')
|
||||||
templateType: z.nativeEnum(TemplateType).optional(),
|
.optional(),
|
||||||
|
globalActionAuth: z
|
||||||
|
.array(ZDocumentActionAuthTypesSchema)
|
||||||
|
.describe('The authentication methods required to sign the envelope.')
|
||||||
|
.optional(),
|
||||||
|
folderId: z.string().describe('The ID of the folder containing the envelope.').nullish(),
|
||||||
|
templateType: z.nativeEnum(TemplateType).describe('The template type.').optional(),
|
||||||
})
|
})
|
||||||
|
.describe('The envelope properties to update.')
|
||||||
.optional(),
|
.optional(),
|
||||||
meta: ZDocumentMetaUpdateSchema.optional(),
|
meta: ZDocumentMetaUpdateSchema.describe('The email and signing settings to update.').optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ZUpdateEnvelopeResponseSchema = ZEnvelopeLiteSchema;
|
export const ZUpdateEnvelopeResponseSchema = ZEnvelopeLiteSchema;
|
||||||
|
|||||||
Reference in New Issue
Block a user