Skip to main content
API v1 is deprecated. For new integrations, please use API v2.

Overview

Templates allow you to create reusable document structures with predefined recipients and fields. Instead of adding recipients and fields every time, you can generate documents from templates and override specific values.

Template Object

{
  "id": 123,
  "externalId": "template-nda-2024",
  "type": "PRIVATE",
  "title": "Standard NDA Template",
  "userId": 456,
  "teamId": 789,
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:35:00.000Z",
  "templateMeta": {
    "subject": "Please sign: NDA",
    "message": "Please review and sign this NDA.",
    "timezone": "America/New_York",
    "signingOrder": "PARALLEL"
  },
  "templateDocumentData": {
    "id": "data_abc123",
    "type": "S3_PATH",
    "data": "s3://bucket/path/to/template.pdf"
  },
  "Recipient": [
    {
      "id": 1,
      "email": "signer@example.com",
      "name": "Template Signer",
      "role": "SIGNER",
      "signingOrder": null
    }
  ],
  "Field": [
    {
      "id": 1,
      "recipientId": 1,
      "type": "SIGNATURE",
      "page": 1,
      "positionX": 10,
      "positionY": 80,
      "width": 30,
      "height": 5
    }
  ]
}

List Templates

Retrieve a paginated list of templates.
GET /api/v1/templates

Query Parameters

ParameterTypeDefaultDescription
pagenumber1Page number (1-indexed)
perPagenumber10Results per page (1-100)

Code Examples

curl -X GET "https://app.documenso.com/api/v1/templates" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"

# Paginate
curl -X GET "https://app.documenso.com/api/v1/templates?page=1&perPage=20" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"

Response

{
  "templates": [
    {
      "id": 123,
      "externalId": "template-nda-2024",
      "type": "PRIVATE",
      "title": "Standard NDA Template",
      "userId": 456,
      "teamId": 789,
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-15T10:35:00.000Z",
      "Recipient": [],
      "Field": []
    }
  ],
  "totalPages": 3
}

Get Template

Retrieve a single template by ID, including all recipients and fields.
GET /api/v1/templates/:id

Path Parameters

ParameterTypeDescription
idnumberThe template ID

Code Examples

curl -X GET "https://app.documenso.com/api/v1/templates/123" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"

Response

Returns the full template object including templateMeta, templateDocumentData, Recipient, and Field arrays.

Create Template

Create a new template and get a presigned URL for uploading the PDF.
POST /api/v1/templates

Request Body

FieldTypeRequiredDescription
titlestringYesTemplate title
externalIdstringNoYour custom identifier
typestringNoPRIVATE or PUBLIC (default: PRIVATE)
recipientsarrayNoPredefined recipients
fieldsarrayNoPredefined fields
metaobjectNoEmail and signing settings

Code Examples

curl -X POST "https://app.documenso.com/api/v1/templates" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Standard NDA Template",
    "externalId": "template-nda-2024",
    "type": "PRIVATE"
  }'

Response

{
  "uploadUrl": "https://s3.amazonaws.com/bucket/presigned-url...",
  "templateId": 123
}
After creating a template, upload your PDF to the uploadUrl using a PUT request with Content-Type: application/octet-stream.

Delete Template

Delete a template.
DELETE /api/v1/templates/:id

Code Examples

curl -X DELETE "https://app.documenso.com/api/v1/templates/123" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx"

Generate Document from Template

Create a new document from an existing template. This is the recommended way to use templates in v1.
POST /api/v1/templates/:templateId/generate-document

Path Parameters

ParameterTypeDescription
templateIdnumberThe template ID

Request Body

FieldTypeRequiredDescription
titlestringNoOverride template title
externalIdstringNoYour custom identifier
folderIdstringNoFolder to create document in
recipientsarrayNoOverride template recipients
metaobjectNoOverride email/signing settings
authOptionsobjectNoAuthentication options
formValuesobjectNoPrefill form field values
prefillFieldsarrayNoPrefill specific fields

Recipients Override Schema

When providing recipients, you must match them to template recipients by ID:
{
  "recipients": [
    {
      "id": 1,          // Template recipient ID
      "email": "actual@example.com",
      "name": "Actual Name",
      "signingOrder": 1
    }
  ]
}

Code Examples

curl -X POST "https://app.documenso.com/api/v1/templates/123/generate-document" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "NDA for John Doe",
    "externalId": "nda-john-2024",
    "recipients": [
      {
        "id": 1,
        "email": "john@example.com",
        "name": "John Doe"
      }
    ],
    "meta": {
      "subject": "Please sign: NDA",
      "redirectUrl": "https://example.com/thank-you"
    }
  }'

Response

{
  "documentId": 456,
  "externalId": "nda-john-2024",
  "recipients": [
    {
      "recipientId": 10,
      "name": "John Doe",
      "email": "john@example.com",
      "token": "abc123xyz",
      "role": "SIGNER",
      "signingOrder": null,
      "signingUrl": "https://app.documenso.com/sign/abc123xyz"
    }
  ]
}
The document is created in DRAFT status. You must still send it using the Send Document endpoint.

Complete Template Workflow

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 createAndUseTemplate() {
  // 1. Create template
  const createResponse = await client.createTemplate({
    body: {
      title: 'Standard NDA Template',
      type: 'PRIVATE',
    },
  });

  if (createResponse.status !== 200) {
    throw new Error('Failed to create template');
  }

  const { uploadUrl, templateId } = createResponse.body;

  // 2. Upload PDF
  const pdfBuffer = fs.readFileSync('./nda-template.pdf');
  await fetch(uploadUrl, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/octet-stream' },
    body: pdfBuffer,
  });

  console.log(`Template created: ${templateId}`);

  // 3. Get template to find recipient IDs
  const getResponse = await client.getTemplate({
    params: { id: templateId.toString() },
  });

  const templateRecipientId = getResponse.body.Recipient[0].id;

  // 4. Generate document from template
  const generateResponse = await client.generateDocumentFromTemplate({
    params: { templateId: templateId.toString() },
    body: {
      title: 'NDA for John Doe',
      recipients: [
        {
          id: templateRecipientId,
          email: 'john@example.com',
          name: 'John Doe',
        },
      ],
    },
  });

  const { documentId } = generateResponse.body;

  // 5. Send the document
  await client.sendDocument({
    params: { id: documentId.toString() },
    body: { sendEmail: true },
  });

  console.log('Document sent!');
}

createAndUseTemplate().catch(console.error);

Template Types

TypeDescription
PRIVATEOnly you and your team can use this template
PUBLICTemplate can be shared publicly (if enabled)

Prefilling Fields

You can prefill field values when generating a document from a template:
const { status, body } = await client.generateDocumentFromTemplate({
  params: { templateId: '123' },
  body: {
    recipients: [
      {
        id: 1,
        email: 'john@example.com',
        name: 'John Doe',
      },
    ],
    // Prefill specific fields
    prefillFields: [
      {
        id: 'field_123',
        value: 'Senior Developer',
      },
      {
        id: 'field_456',
        value: 'Engineering',
      },
    ],
    // Or use form values for all form fields
    formValues: {
      jobTitle: 'Senior Developer',
      department: 'Engineering',
      startDate: '2024-01-15',
    },
  },
});

Best Practices

1. Use External IDs

Always set externalId to track which business entity the template represents:
{
  title: 'Standard NDA',
  externalId: 'template-nda-v2024.1',
}

2. Organize with Metadata

Include comprehensive metadata in templates:
{
  title: 'Employee Onboarding',
  meta: {
    subject: 'Welcome to {company.name}!',
    message: 'Please review and sign these onboarding documents.',
    timezone: 'America/New_York',
    signingOrder: 'SEQUENTIAL',
  },
}

3. Recipient Mapping

When generating documents, always verify template recipient IDs:
// First, get the template
const template = await client.getTemplate({ params: { id: '123' } });

// Map recipients by role or order
const signerRecipient = template.body.Recipient.find(r => r.role === 'SIGNER');

// Generate document with correct recipient mapping
await client.generateDocumentFromTemplate({
  params: { templateId: '123' },
  body: {
    recipients: [
      {
        id: signerRecipient.id,
        email: 'actual@example.com',
        name: 'Actual Name',
      },
    ],
  },
});

See Also