diff --git a/apps/docs/content/docs/developers/api/index.mdx b/apps/docs/content/docs/developers/api/index.mdx
index e8d7139eb..ac64de966 100644
--- a/apps/docs/content/docs/developers/api/index.mdx
+++ b/apps/docs/content/docs/developers/api/index.mdx
@@ -60,8 +60,8 @@ Authorization: api_xxxxxxxxxxxxxxxx
href="/docs/developers/api/templates"
/>
diff --git a/apps/docs/content/docs/developers/api/teams.mdx b/apps/docs/content/docs/developers/api/teams.mdx
index 99d708b41..55d1ac3e5 100644
--- a/apps/docs/content/docs/developers/api/teams.mdx
+++ b/apps/docs/content/docs/developers/api/teams.mdx
@@ -1,44 +1,29 @@
---
-title: Teams API
-description: Manage team resources, documents, and templates with team-scoped API tokens.
+title: Team-Scoped API Access
+description: Use team-scoped API tokens with document and template envelopes.
---
import { Callout } from 'fumadocs-ui/components/callout';
import { Step, Steps } from 'fumadocs-ui/components/steps';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
+
+
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).
-## Team Object
+## Team Context
-A team object contains the following properties:
+
+ The V2 REST API does not expose `/team/*` endpoints. Create and manage teams, members, and team
+ settings in the Documenso web application. This page explains how a team-scoped token applies
+ that team context to supported API resources.
+
-| Property | Type | Description |
-| ----------------- | -------------- | --------------------------------------------------- |
-| `id` | number | Unique team identifier |
-| `name` | string | Team display name |
-| `url` | string | Unique team URL slug |
-| `createdAt` | string | ISO 8601 timestamp |
-| `avatarImageId` | string \| null | ID of the team's avatar image |
-| `organisationId` | string | ID of the parent organisation |
-| `currentTeamRole` | string | Your role in the team: `ADMIN`, `MANAGER`, `MEMBER` |
-
-### Example Team Object
-
-```json
-{
- "id": 123,
- "name": "Engineering",
- "url": "engineering",
- "createdAt": "2025-01-15T10:30:00.000Z",
- "avatarImageId": null,
- "organisationId": "org_abc123",
- "currentTeamRole": "ADMIN"
-}
-```
+The API resolves the team from your token. You do not pass a team ID when creating, listing, or
+using envelopes. The token's team ID determines which resources the request can access.
## Team-Scoped API Tokens
@@ -174,8 +159,8 @@ const response = await fetch('https://app.documenso.com/api/v2/envelope', {
},
});
-const { data, pagination } = await response.json();
-console.log(`Found ${pagination.totalItems} team documents`);
+const { data, count } = await response.json();
+console.log(`Found ${count} team documents`);
````
@@ -190,10 +175,11 @@ Templates created with a team token are shared across the team.
```bash
-curl -X POST "https://app.documenso.com/api/v2/template/create" \
+curl -X POST "https://app.documenso.com/api/v2/envelope/create" \
-H "Authorization: api_team_xxxxxxxxxxxxxxxx" \
-H "Content-Type: multipart/form-data" \
-F 'payload={
+ "type": "TEMPLATE",
"title": "NDA Template",
"recipients": [
{
@@ -223,6 +209,7 @@ curl -X POST "https://app.documenso.com/api/v2/template/create" \
const form = new FormData();
const payload = {
+ type: 'TEMPLATE',
title: 'NDA Template',
recipients: [
{
@@ -249,7 +236,7 @@ form.append('files', fs.createReadStream('./nda-template.pdf'), {
contentType: 'application/pdf',
});
-const response = await fetch('https://app.documenso.com/api/v2/template/create', {
+const response = await fetch('https://app.documenso.com/api/v2/envelope/create', {
method: 'POST',
headers: {
Authorization: TEAM_API_TOKEN,
@@ -257,8 +244,8 @@ const response = await fetch('https://app.documenso.com/api/v2/template/create',
body: form,
});
-const template = await response.json();
-console.log('Created team template:', template.id);
+const { id } = await response.json();
+console.log('Created team template envelope:', id);
````
@@ -268,14 +255,14 @@ console.log('Created team template:', template.id);
```bash
-curl -X GET "https://app.documenso.com/api/v2/template" \
+curl -X GET "https://app.documenso.com/api/v2/envelope?type=TEMPLATE" \
-H "Authorization: api_team_xxxxxxxxxxxxxxxx"
````
```typescript
-const response = await fetch('https://app.documenso.com/api/v2/template', {
+const response = await fetch('https://app.documenso.com/api/v2/envelope?type=TEMPLATE', {
method: 'GET',
headers: {
Authorization: TEAM_API_TOKEN,
@@ -341,8 +328,8 @@ const legalResponse = await fetch('https://app.documenso.com/api/v2/envelope?sta
});
const legalDocs = await legalResponse.json();
-console.log(`Sales team: ${salesDocs.pagination.totalItems} pending`);
-console.log(`Legal team: ${legalDocs.pagination.totalItems} completed`);
+console.log(`Sales team: ${salesDocs.count} pending`);
+console.log(`Legal team: ${legalDocs.count} completed`);
```
## Error Responses
diff --git a/apps/docs/content/docs/developers/api/templates.mdx b/apps/docs/content/docs/developers/api/templates.mdx
index b3f52e146..2d3675100 100644
--- a/apps/docs/content/docs/developers/api/templates.mdx
+++ b/apps/docs/content/docs/developers/api/templates.mdx
@@ -13,7 +13,194 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
see the [OpenAPI Reference](https://openapi.documenso.com).
-## Template Object
+## Use a Template Envelope
+
+New integrations should create a document from a template envelope with the Envelope API.
+
+```
+POST /envelope/use
+Content-Type: multipart/form-data
+```
+
+The request uses `multipart/form-data`:
+
+| Part | Type | Required | Description |
+| --------- | ------- | -------- | ------------------------------------------------------------------ |
+| `payload` | JSON | Yes | Template envelope ID, recipient details, and document settings |
+| `files` | File(s) | No | Replacement PDFs referenced by entries in `customDocumentData` |
+
+### Payload Schema
+
+| Field | Type | Required | Description |
+| -------------------- | ------- | -------- | ------------------------------------------------------------------------ |
+| `envelopeId` | string | Yes | ID of the template envelope |
+| `externalId` | string | No | Your identifier for the created document envelope |
+| `recipients` | array | No | Recipient details mapped to recipients in the template |
+| `distributeDocument` | boolean | No | If `true`, create the document as pending and distribute it |
+| `customDocumentData` | array | No | Maps uploaded replacement PDFs to template envelope items |
+| `folderId` | string | No | Folder in which to create the document |
+| `prefillFields` | array | No | Field values to prefill before distribution |
+| `override` | object | No | Template values to override for the created document |
+| `attachments` | array | No | Link attachments to add to the document |
+| `formValues` | object | No | PDF form values to apply |
+
+Each recipient entry accepts the following fields:
+
+| Field | Type | Required | Description |
+| -------------- | ------- | -------- | -------------------------------------------- |
+| `id` | number | Yes | Recipient ID from the template envelope |
+| `email` | string | Yes | Recipient email address |
+| `name` | string | No | Recipient display name |
+| `signingOrder` | number | No | Recipient position in sequential signing |
+
+Each `customDocumentData` entry maps an uploaded file to a template item:
+
+| Field | Type | Required | Description |
+| ---------------- | ---------------- | -------- | --------------------------------------------------------------- |
+| `identifier` | string \| number | Yes | Uploaded filename or zero-based file index |
+| `envelopeItemId` | string | Yes | Template envelope item whose PDF the uploaded file replaces |
+
+### Code Examples
+
+
+
+```bash
+curl -X POST "https://app.documenso.com/api/v2/envelope/use" \
+ -H "Authorization: api_xxxxxxxxxxxxxxxx" \
+ -F 'payload={
+ "envelopeId": "envelope_template123",
+ "externalId": "contract-2025-001",
+ "recipients": [
+ {
+ "id": 1,
+ "email": "john.doe@example.com",
+ "name": "John Doe"
+ }
+ ],
+ "prefillFields": [
+ {
+ "id": 101,
+ "type": "text",
+ "value": "Senior Software Engineer"
+ }
+ ],
+ "distributeDocument": false
+ }'
+```
+
+
+```typescript
+const form = new FormData();
+
+form.append(
+ 'payload',
+ JSON.stringify({
+ envelopeId: 'envelope_template123',
+ externalId: 'contract-2025-001',
+ recipients: [
+ {
+ id: 1,
+ email: 'john.doe@example.com',
+ name: 'John Doe',
+ },
+ ],
+ prefillFields: [
+ {
+ id: 101,
+ type: 'text',
+ value: 'Senior Software Engineer',
+ },
+ ],
+ distributeDocument: false,
+ }),
+);
+
+const response = await fetch('https://app.documenso.com/api/v2/envelope/use', {
+ method: 'POST',
+ headers: {
+ Authorization: 'api_xxxxxxxxxxxxxxxx',
+ },
+ body: form,
+});
+
+const document = await response.json();
+console.log('Created document envelope:', document.id);
+```
+
+
+
+### Response
+
+```json
+{
+ "id": "envelope_document123",
+ "recipients": [
+ {
+ "id": 1,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "token": "recipient_token",
+ "role": "SIGNER",
+ "signingOrder": 1,
+ "signingUrl": "https://app.documenso.com/sign/recipient_token"
+ }
+ ]
+}
+```
+
+### Distribute the Created Envelope
+
+If you leave `distributeDocument` unset or set it to `false`, distribute the created document with
+`POST /envelope/distribute`. Its response confirms delivery and includes each recipient's signing URL.
+
+```typescript
+const distributionResponse = await fetch(
+ 'https://app.documenso.com/api/v2/envelope/distribute',
+ {
+ method: 'POST',
+ headers: {
+ Authorization: 'api_xxxxxxxxxxxxxxxx',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ envelopeId: document.id,
+ }),
+ },
+);
+
+const distribution = await distributionResponse.json();
+console.log('Signing URL:', distribution.recipients[0].signingUrl);
+```
+
+```json
+{
+ "success": true,
+ "id": "envelope_document123",
+ "recipients": [
+ {
+ "id": 1,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "token": "recipient_token",
+ "role": "SIGNER",
+ "signingOrder": 1,
+ "signingUrl": "https://app.documenso.com/sign/recipient_token"
+ }
+ ]
+}
+```
+
+---
+
+## Deprecated Template Endpoint Reference
+
+
+ Every `/template/*` endpoint below is deprecated. Use the Envelope API for new integrations and
+ follow [Migrating to Envelopes](/docs/developers/api/migrate-to-envelopes) to replace existing calls.
+ The legacy reference remains here to support migrations.
+
+
+## Legacy Template Object
A template object contains the following properties:
@@ -91,7 +278,7 @@ A template object contains the following properties:
}
```
-## List Templates
+## List Templates (Deprecated)
Retrieve a paginated list of templates.
@@ -139,8 +326,8 @@ const response = await fetch(`${BASE_URL}/template`, {
},
});
-const { data, pagination } = await response.json();
-console.log(`Found ${pagination.totalItems} templates`);
+const { data, count } = await response.json();
+console.log(`Found ${count} templates`);
// Filter by type
const privateResponse = await fetch(
@@ -181,18 +368,16 @@ const privateTemplates = await privateResponse.json();
]
}
],
- "pagination": {
- "page": 1,
- "perPage": 10,
- "totalPages": 3,
- "totalItems": 25
- }
+ "count": 25,
+ "currentPage": 1,
+ "perPage": 10,
+ "totalPages": 3
}
```
---
-## Get Template
+## Get Template (Deprecated)
Retrieve a single template by ID.
@@ -238,9 +423,9 @@ Returns the full template object including recipients, fields, and metadata.
---
-## Create Document from Template
+## Create Document from Template (Deprecated)
-Create a new document using a template. This is the primary way to use templates programmatically.
+Create a new document using the deprecated template endpoint.
This endpoint does not support [PDF placeholder parsing](/docs/users/documents/advanced/pdf-placeholders). Use `POST /envelope/create` for placeholder-based field positioning.
@@ -415,32 +600,57 @@ const prefilledDocument = await prefillResponse.json();
### Response
-Returns the created document object with recipients and signing URLs.
+The endpoint returns the full legacy document object. The selected fields below show both the numeric
+legacy `id` and canonical `envelopeId`. Recipient entries do not include a `signingUrl`.
```json
{
- "id": "envelope_xyz789",
- "type": "DOCUMENT",
+ "id": 789,
+ "envelopeId": "envelope_xyz789",
"status": "PENDING",
- "title": "Employment Contract",
"source": "TEMPLATE",
+ "title": "Employment Contract",
"externalId": "contract-2025-001",
"recipients": [
{
"id": 1,
+ "envelopeId": "envelope_xyz789",
+ "documentId": 789,
+ "templateId": null,
"email": "john.doe@example.com",
"name": "John Doe",
"role": "SIGNER",
"signingStatus": "NOT_SIGNED",
- "signingUrl": "https://app.documenso.com/sign/abc123"
+ "signingOrder": 1
}
]
}
-````
+```
+
+To send a document created with `distributeDocument: false` and receive signing links, call
+`POST /envelope/distribute` with its `envelopeId`:
+
+```typescript
+const document = await response.json();
+
+const distributionResponse = await fetch(`${BASE_URL}/envelope/distribute`, {
+ method: 'POST',
+ headers: {
+ Authorization: API_TOKEN,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ envelopeId: document.envelopeId,
+ }),
+});
+
+const distribution = await distributionResponse.json();
+console.log('Signing URL:', distribution.recipients[0].signingUrl);
+```
---
-## Override Template Settings
+## Override Template Settings (Deprecated)
When creating a document from a template, you can override various settings:
@@ -488,7 +698,7 @@ const response = await fetch(`${BASE_URL}/template/use`, {
---
-## Prefill Fields
+## Prefill Fields (Deprecated)
Prefill field values when creating a document from a template. This is useful for populating known data before sending.
@@ -577,7 +787,7 @@ const response = await fetch(`${BASE_URL}/template/use`, {
---
-## Update Template
+## Update Template (Deprecated)
Update a template's properties.
@@ -643,7 +853,7 @@ const template = await response.json();
---
-## Duplicate Template
+## Duplicate Template (Deprecated)
Create a copy of an existing template.
@@ -695,7 +905,7 @@ console.log('New template ID:', duplicatedTemplate.id);
---
-## Delete Template
+## Delete Template (Deprecated)
Delete a template.
@@ -754,7 +964,7 @@ const { success } = await response.json();
---
-## Direct Link Templates
+## Direct Link Templates (Deprecated)
Direct link templates allow recipients to create and sign documents without requiring you to explicitly create each document. When a recipient visits the direct link, a new document is automatically created from the template.
@@ -898,7 +1108,7 @@ const { success } = await response.json();
---
-## Custom Document Data
+## Custom Document Data (Deprecated)
When creating a document from a template, you can replace the template's PDF with a custom PDF by using the `customDocumentData` parameter. This is useful when you need to generate the PDF dynamically while reusing the template's recipient and field configuration.
@@ -913,7 +1123,7 @@ See the [OpenAPI Reference](https://openapi.documenso.com) for the full request
---
-## Template Types
+## Template Types (Legacy)
| Type | Description |
| --------- | ------------------------------------------------------------------ |
@@ -922,7 +1132,7 @@ See the [OpenAPI Reference](https://openapi.documenso.com) for the full request
---
-## Complete Example: Contract Workflow
+## Complete Legacy Example: Contract Workflow (Deprecated)
This example demonstrates a complete workflow for using templates to send contracts.
@@ -996,16 +1206,29 @@ async function sendEmploymentContract(employeeData: {
subject: `Employment Contract for ${employeeData.name}`,
message: `Hi ${employeeData.name},\n\nPlease review and sign your employment contract.`,
},
- distributeDocument: true,
+ distributeDocument: false,
externalId: `emp-contract-${Date.now()}`,
}),
});
const document = await documentResponse.json();
+ // 5. Distribute the envelope and get recipient signing links
+ const distributionResponse = await fetch(`${BASE_URL}/envelope/distribute`, {
+ method: 'POST',
+ headers: {
+ Authorization: API_TOKEN,
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ envelopeId: document.envelopeId,
+ }),
+ });
+ const distribution = await distributionResponse.json();
+
return {
- documentId: document.id,
- signingUrl: document.recipients[0].signingUrl,
+ envelopeId: document.envelopeId,
+ signingUrl: distribution.recipients[0].signingUrl,
};
}
@@ -1018,7 +1241,7 @@ const result = await sendEmploymentContract({
startDate: '2025-03-01',
});
-console.log('Document created:', result.documentId);
+console.log('Document created:', result.envelopeId);
console.log('Signing URL:', result.signingUrl);
````