Overview
Documents are the core resource in Documenso API v1. The typical workflow:
- Create a document (get a presigned upload URL)
- Upload your PDF to the presigned URL
- Add recipients and fields
- Send the document for signing
- Download the completed document
Document Object
{
"id": 123,
"externalId": "order-12345",
"userId": 456,
"teamId": 789,
"folderId": "folder_abc123",
"title": "Service Agreement",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:35:00.000Z",
"completedAt": null
}
Properties
| Field | Type | Description |
|---|
id | number | Unique document identifier |
externalId | string | null | Your custom identifier for idempotency |
userId | number | ID of the user who created the document |
teamId | number | null | ID of the team (if created in team context) |
folderId | string | null | ID of the folder containing the document |
title | string | Document title |
status | string | Current status (see Document Statuses) |
createdAt | string | ISO 8601 timestamp |
updatedAt | string | ISO 8601 timestamp |
completedAt | string | null | Timestamp when all recipients signed |
List Documents
Retrieve a paginated list of documents.
Query Parameters
| Parameter | Type | Default | Description |
|---|
page | number | 1 | Page number (1-indexed) |
perPage | number | 10 | Results per page (1-100) |
folderId | string | - | Filter by folder ID |
Code Examples
# List all documents
curl -X GET "https://app.documenso.com/api/v1/documents" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
# Paginate results
curl -X GET "https://app.documenso.com/api/v1/documents?page=2&perPage=20" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
# Filter by folder
curl -X GET "https://app.documenso.com/api/v1/documents?folderId=folder_abc123" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
import { initClient } from '@ts-rest/core';
import { ApiContractV1 } from '@documenso/api/v1/contract';
const client = initClient(ApiContractV1, {
baseUrl: 'https://app.documenso.com/api/v1',
baseHeaders: {
authorization: 'Bearer api_xxxxxxxxxxxxxxxx',
},
});
// List all documents
const { status, body } = await client.getDocuments({
query: { page: 1, perPage: 10 },
});
if (status === 200) {
console.log(`Total pages: ${body.totalPages}`);
body.documents.forEach((doc) => {
console.log(`${doc.id}: ${doc.title} (${doc.status})`);
});
}
Response
{
"documents": [
{
"id": 123,
"title": "Service Agreement",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:35:00.000Z",
"completedAt": null
}
],
"totalPages": 5
}
Get Document
Retrieve a single document by ID, including recipients and fields.
GET /api/v1/documents/:id
Path Parameters
| Parameter | Type | Description |
|---|
id | number | The document ID |
Code Examples
curl -X GET "https://app.documenso.com/api/v1/documents/123" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
const { status, body } = await client.getDocument({
params: { id: '123' },
});
if (status === 200) {
console.log(`Title: ${body.title}`);
console.log(`Status: ${body.status}`);
console.log(`Recipients: ${body.recipients.length}`);
console.log(`Fields: ${body.fields.length}`);
}
Response
{
"id": 123,
"externalId": "order-12345",
"userId": 456,
"teamId": 789,
"folderId": null,
"title": "Service Agreement",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:35:00.000Z",
"completedAt": null,
"recipients": [
{
"id": 1,
"documentId": 123,
"email": "john@example.com",
"name": "John Doe",
"role": "SIGNER",
"signingOrder": 1,
"token": "abc123xyz",
"signedAt": null,
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT",
"signingUrl": "https://app.documenso.com/sign/abc123xyz"
}
],
"fields": [
{
"id": 1,
"documentId": 123,
"recipientId": 1,
"type": "SIGNATURE",
"page": 1,
"positionX": 10,
"positionY": 80,
"width": 30,
"height": 5,
"customText": "",
"fieldMeta": null
}
]
}
Create Document
Create a new document and get a presigned URL for uploading the PDF.
Request Body
| Field | Type | Required | Description |
|---|
title | string | Yes | Document title |
externalId | string | No | Your custom identifier |
folderId | string | No | Folder ID to organize the document |
recipients | array | Yes | List of recipients (see below) |
meta | object | No | Email and signing settings |
authOptions | object | No | Authentication options |
formValues | object | No | Prefill form field values |
attachments | array | No | Document attachments |
Recipients Schema
Each recipient object:
| Field | Type | Required | Description |
|---|
name | string | Yes | Recipient’s full name |
email | string | Yes | Recipient’s email address |
role | string | No | Default: SIGNER (see Recipient Roles) |
signingOrder | number | No | Order for sequential signing |
| Field | Type | Description |
|---|
subject | string | Email subject line |
message | string | Email message body |
timezone | string | Timezone for date fields (default: Etc/UTC) |
dateFormat | string | Date format string |
redirectUrl | string | URL to redirect after signing |
signingOrder | string | PARALLEL or SEQUENTIAL |
language | string | Language code (e.g., en, de) |
typedSignatureEnabled | boolean | Allow typed signatures |
uploadSignatureEnabled | boolean | Allow uploaded signatures |
drawSignatureEnabled | boolean | Allow drawn signatures |
distributionMethod | string | EMAIL or NONE |
Code Examples
curl -X POST "https://app.documenso.com/api/v1/documents" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Service Agreement",
"externalId": "order-12345",
"recipients": [
{
"name": "John Doe",
"email": "john@example.com",
"role": "SIGNER"
},
{
"name": "Jane Smith",
"email": "jane@example.com",
"role": "APPROVER",
"signingOrder": 1
}
],
"meta": {
"subject": "Please sign: Service Agreement",
"message": "Hi {signer.name}, please review and sign this agreement.",
"redirectUrl": "https://example.com/thank-you",
"signingOrder": "SEQUENTIAL"
}
}'
const { status, body } = await client.createDocument({
body: {
title: 'Service Agreement',
externalId: 'order-12345',
recipients: [
{
name: 'John Doe',
email: 'john@example.com',
role: 'SIGNER',
},
{
name: 'Jane Smith',
email: 'jane@example.com',
role: 'APPROVER',
signingOrder: 1,
},
],
meta: {
subject: 'Please sign: Service Agreement',
message: 'Hi {signer.name}, please review and sign this agreement.',
redirectUrl: 'https://example.com/thank-you',
signingOrder: 'SEQUENTIAL',
},
},
});
if (status === 200) {
const { uploadUrl, documentId, recipients } = body;
// Upload PDF to presigned URL
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/octet-stream' },
body: pdfBuffer,
});
console.log(`Document created: ${documentId}`);
console.log(`Signing URLs:`);
recipients.forEach((r) => {
console.log(` ${r.email}: ${r.signingUrl}`);
});
}
Response
{
"uploadUrl": "https://s3.amazonaws.com/bucket/presigned-url...",
"documentId": 123,
"externalId": "order-12345",
"recipients": [
{
"recipientId": 1,
"name": "John Doe",
"email": "john@example.com",
"token": "abc123xyz",
"role": "SIGNER",
"signingOrder": null,
"signingUrl": "https://app.documenso.com/sign/abc123xyz"
}
]
}
After receiving the response, you must upload your PDF to the uploadUrl using a PUT request with Content-Type: application/octet-stream.
Send Document
Send a document to recipients for signing.
POST /api/v1/documents/:id/send
Path Parameters
| Parameter | Type | Description |
|---|
id | number | The document ID |
Request Body
| Field | Type | Default | Description |
|---|
sendEmail | boolean | true | Send email to recipients |
sendCompletionEmails | boolean | - | Override completion email settings |
If sendEmail is false, recipients won’t receive email notifications. You must manually distribute the signing URLs from the response.
Code Examples
# Send with email
curl -X POST "https://app.documenso.com/api/v1/documents/123/send" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "sendEmail": true }'
# Send without email (get signing URLs)
curl -X POST "https://app.documenso.com/api/v1/documents/123/send" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "sendEmail": false }'
// Send with email
const { status, body } = await client.sendDocument({
params: { id: '123' },
body: { sendEmail: true },
});
if (status === 200) {
console.log('Document sent successfully');
console.log(`Status: ${body.status}`);
// Signing URLs are included in response
body.recipients.forEach((r) => {
console.log(`${r.email}: ${r.signingUrl}`);
});
}
Response
{
"message": "Document sent successfully",
"id": 123,
"externalId": "order-12345",
"userId": 456,
"teamId": 789,
"folderId": null,
"title": "Service Agreement",
"status": "PENDING",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:35:00.000Z",
"completedAt": null,
"recipients": [
{
"id": 1,
"email": "john@example.com",
"name": "John Doe",
"role": "SIGNER",
"token": "abc123xyz",
"signingUrl": "https://app.documenso.com/sign/abc123xyz",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
]
}
Resend Document
Resend the document to specific recipients.
POST /api/v1/documents/:id/resend
Request Body
| Field | Type | Required | Description |
|---|
recipients | array | Yes | Array of recipient IDs to resend to |
Code Examples
curl -X POST "https://app.documenso.com/api/v1/documents/123/resend" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "recipients": [1, 2] }'
const { status, body } = await client.resendDocument({
params: { id: '123' },
body: { recipients: [1, 2] },
});
if (status === 200) {
console.log(body.message); // "Document resent successfully"
}
Download Document
Get a download URL for the signed document (S3 storage only).
GET /api/v1/documents/:id/download
Query Parameters
| Parameter | Type | Default | Description |
|---|
downloadOriginalDocument | boolean | false | Download original instead of signed version |
Code Examples
# Download signed document
curl -X GET "https://app.documenso.com/api/v1/documents/123/download" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
# Download original document
curl -X GET "https://app.documenso.com/api/v1/documents/123/download?downloadOriginalDocument=true" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
const { status, body } = await client.downloadSignedDocument({
params: { id: '123' },
query: { downloadOriginalDocument: false },
});
if (status === 200) {
console.log(`Download URL: ${body.downloadUrl}`);
// Download the file
const pdfResponse = await fetch(body.downloadUrl);
const pdfBlob = await pdfResponse.blob();
}
Response
{
"downloadUrl": "https://s3.amazonaws.com/bucket/signed-document.pdf?presigned..."
}
Delete Document
Delete a document. Completed documents cannot be deleted.
DELETE /api/v1/documents/:id
Code Examples
curl -X DELETE "https://app.documenso.com/api/v1/documents/123" \
-H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"
const { status, body } = await client.deleteDocument({
params: { id: '123' },
body: null,
});
if (status === 200) {
console.log(`Deleted document ${body.id}`);
}
Response
{
"id": 123,
"title": "Service Agreement",
"status": "DRAFT"
}
Document Statuses
| Status | Description |
|---|
DRAFT | Document created but not sent |
PENDING | Document sent, waiting for signatures |
COMPLETED | All recipients have signed |
REJECTED | A recipient rejected the document |
Recipient Roles
| Role | Description |
|---|
SIGNER | Must sign the document |
APPROVER | Must approve before signers can sign |
CC | Receives a copy, no action required |
VIEWER | Can view but takes no action |
ASSISTANT | Can fill fields on behalf of others |
Complete Example
import { initClient } from '@ts-rest/core';
import { ApiContractV1 } from '@documenso/api/v1/contract';
import fs from 'fs';
const client = initClient(ApiContractV1, {
baseUrl: 'https://app.documenso.com/api/v1',
baseHeaders: {
authorization: 'Bearer api_xxxxxxxxxxxxxxxx',
},
});
async function createAndSendDocument() {
// 1. Create document
const { status, body } = await client.createDocument({
body: {
title: 'Service Agreement',
recipients: [
{
name: 'John Doe',
email: 'john@example.com',
role: 'SIGNER',
},
],
meta: {
subject: 'Please sign this document',
message: 'Hi {signer.name}, please sign the attached document.',
},
},
});
if (status !== 200) throw new Error('Failed to create document');
const { uploadUrl, documentId, recipients } = body;
// 2. Upload PDF
const pdfBuffer = fs.readFileSync('./contract.pdf');
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/octet-stream' },
body: pdfBuffer,
});
// 3. Add signature field
await client.createField({
params: { id: documentId.toString() },
body: {
type: 'SIGNATURE',
recipientId: recipients[0].recipientId,
pageNumber: 1,
pageX: 10,
pageY: 80,
pageWidth: 30,
pageHeight: 5,
fieldMeta: {},
},
});
// 4. Send document
const sendResult = await client.sendDocument({
params: { id: documentId.toString() },
body: { sendEmail: true },
});
console.log('Document sent!');
console.log('Signing URL:', sendResult.body.recipients[0].signingUrl);
}
createAndSendDocument().catch(console.error);
See Also