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

Overview

Recipients are the people who need to take action on a document. Each recipient has a role that determines what they can do (sign, approve, view, etc.). In v1, recipients are typically added during document creation, but you can also add, update, or remove them before sending the document.

Recipient Object

{
  "id": 1,
  "documentId": 123,
  "email": "john@example.com",
  "name": "John Doe",
  "role": "SIGNER",
  "signingOrder": 1,
  "token": "abc123xyz",
  "expiresAt": null,
  "expirationNotifiedAt": null,
  "signedAt": null,
  "readStatus": "NOT_OPENED",
  "signingStatus": "NOT_SIGNED",
  "sendStatus": "NOT_SENT",
  "signingUrl": "https://app.documenso.com/sign/abc123xyz"
}

Properties

FieldTypeDescription
idnumberUnique recipient identifier
documentIdnumberID of the parent document
emailstringRecipient’s email address
namestringRecipient’s full name
rolestringRecipient role (see Recipient Roles)
signingOrdernumber | nullOrder for sequential signing
tokenstringUnique token for signing URL
expiresAtstring | nullExpiration timestamp
expirationNotifiedAtstring | nullWhen expiration notice was sent
signedAtstring | nullISO timestamp when signed
readStatusstringNOT_OPENED or OPENED
signingStatusstringNOT_SIGNED, SIGNED, or REJECTED
sendStatusstringNOT_SENT or SENT
signingUrlstringURL for recipient to sign the document

Recipient Roles

RoleDescription
SIGNERMust sign the document. This is the default role.
APPROVERMust approve the document before signers can proceed.
CCReceives a copy of the completed document. No action required.
VIEWERCan view the document but takes no action.
ASSISTANTCan fill in fields on behalf of another recipient.

Add Recipient

Add a single recipient to a document in DRAFT status.
POST /api/v1/documents/:id/recipients

Path Parameters

ParameterTypeDescription
idnumberThe document ID

Request Body

FieldTypeRequiredDescription
namestringYesRecipient’s full name
emailstringYesRecipient’s email address
rolestringNoDefault: SIGNER
signingOrdernumberNoPosition in sequential signing
authOptionsobjectNoAuthentication options (Enterprise only)

Auth Options Schema

FieldTypeDescription
actionAutharrayAuthentication methods required for actions
Available authentication methods:
  • ACCOUNT - Must be logged in
  • PASSKEY - Must use passkey authentication
  • TWO_FACTOR_AUTH - Must provide 2FA code

Code Examples

# Basic recipient
curl -X POST "https://app.documenso.com/api/v1/documents/123/recipients" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "role": "SIGNER"
  }'

# With signing order
curl -X POST "https://app.documenso.com/api/v1/documents/123/recipients" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "email": "jane@example.com",
    "role": "APPROVER",
    "signingOrder": 1
  }'

# With auth options (Enterprise)
curl -X POST "https://app.documenso.com/api/v1/documents/123/recipients" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alice Johnson",
    "email": "alice@example.com",
    "role": "SIGNER",
    "authOptions": {
      "actionAuth": ["ACCOUNT", "TWO_FACTOR_AUTH"]
    }
  }'

Response

{
  "id": 2,
  "documentId": 123,
  "email": "john@example.com",
  "name": "John Doe",
  "role": "SIGNER",
  "signingOrder": null,
  "token": "def456uvw",
  "expiresAt": null,
  "expirationNotifiedAt": null,
  "signedAt": null,
  "readStatus": "NOT_OPENED",
  "signingStatus": "NOT_SIGNED",
  "sendStatus": "NOT_SENT",
  "signingUrl": "https://app.documenso.com/sign/def456uvw"
}
You can only add recipients to documents in DRAFT status. Once a document is sent (PENDING), recipients cannot be added or removed.

Update Recipient

Update a recipient’s details before the document is sent.
PATCH /api/v1/documents/:id/recipients/:recipientId

Path Parameters

ParameterTypeDescription
idnumberThe document ID
recipientIdnumberThe recipient ID

Request Body

All fields are optional. Only include the fields you want to update:
FieldTypeDescription
namestringRecipient’s full name
emailstringRecipient’s email address
rolestringRecipient role
signingOrdernumberPosition in sequential signing
authOptionsobjectAuthentication options

Code Examples

# Update email
curl -X PATCH "https://app.documenso.com/api/v1/documents/123/recipients/2" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newemail@example.com"
  }'

# Update name and role
curl -X PATCH "https://app.documenso.com/api/v1/documents/123/recipients/2" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Smith",
    "role": "APPROVER"
  }'

# Update signing order
curl -X PATCH "https://app.documenso.com/api/v1/documents/123/recipients/2" \
  -H "Authorization: Bearer api_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "signingOrder": 2
  }'

Response

Returns the updated recipient object.

Remove Recipient

Remove a recipient from a document in DRAFT status.
DELETE /api/v1/documents/:id/recipients/:recipientId

Path Parameters

ParameterTypeDescription
idnumberThe document ID
recipientIdnumberThe recipient ID

Code Examples

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

Response

Returns the deleted recipient object.
Removing a recipient also removes all fields assigned to that recipient.

Sequential Signing

For workflows where recipients must sign in a specific order, use the signingOrder field:
// First, set document signing order to SEQUENTIAL
await client.createDocument({
  body: {
    title: 'Contract',
    recipients: [
      {
        name: 'Approver',
        email: 'approver@example.com',
        role: 'APPROVER',
        signingOrder: 1, // Signs first
      },
      {
        name: 'Manager',
        email: 'manager@example.com',
        role: 'SIGNER',
        signingOrder: 2, // Signs second
      },
      {
        name: 'Employee',
        email: 'employee@example.com',
        role: 'SIGNER',
        signingOrder: 3, // Signs last
      },
    ],
    meta: {
      signingOrder: 'SEQUENTIAL',
    },
  },
});

How Sequential Signing Works

  1. Only the recipient with signingOrder: 1 receives the initial email
  2. After they sign, the recipient with signingOrder: 2 receives an email
  3. This continues until all recipients have signed
  4. Recipients with signingOrder: null can sign at any time (parallel)

Signing URLs

Every recipient has a unique signing URL that can be shared directly:
const { body } = await client.createDocument({
  body: {
    title: 'Contract',
    recipients: [{ name: 'John', email: 'john@example.com', role: 'SIGNER' }],
  },
});

// Get signing URL from response
const signingUrl = body.recipients[0].signingUrl;
console.log(`Send this to recipient: ${signingUrl}`);
// https://app.documenso.com/sign/abc123xyz

// Or send via email automatically
await client.sendDocument({
  params: { id: body.documentId.toString() },
  body: { sendEmail: true },
});

Recipient Status

Recipients have three status fields:

Read Status

StatusDescription
NOT_OPENEDRecipient hasn’t opened the document
OPENEDRecipient has viewed the document

Signing Status

StatusDescription
NOT_SIGNEDRecipient hasn’t signed yet
SIGNEDRecipient has completed signing
REJECTEDRecipient rejected the document

Send Status

StatusDescription
NOT_SENTEmail hasn’t been sent to recipient
SENTEmail has been sent to recipient

Checking Recipient Progress

const { body: document } = await client.getDocument({
  params: { id: '123' },
});

document.recipients.forEach((recipient) => {
  console.log(`${recipient.name}:`);
  console.log(`  Sent: ${recipient.sendStatus}`);
  console.log(`  Opened: ${recipient.readStatus}`);
  console.log(`  Signed: ${recipient.signingStatus}`);
  
  if (recipient.signedAt) {
    console.log(`  Signed at: ${recipient.signedAt}`);
  }
});

Complete Example

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',
  },
});

async function manageRecipients() {
  // 1. Create document with initial recipient
  const { body: createBody } = await client.createDocument({
    body: {
      title: 'Service Agreement',
      recipients: [
        {
          name: 'John Doe',
          email: 'john@example.com',
          role: 'SIGNER',
        },
      ],
    },
  });

  const documentId = createBody.documentId;
  const { uploadUrl } = createBody;

  // Upload PDF...
  await fetch(uploadUrl, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/octet-stream' },
    body: pdfBuffer,
  });

  // 2. Add another recipient
  const { body: approver } = await client.createRecipient({
    params: { id: documentId.toString() },
    body: {
      name: 'Jane Smith',
      email: 'jane@example.com',
      role: 'APPROVER',
      signingOrder: 1,
    },
  });

  console.log(`Added approver: ${approver.id}`);

  // 3. Update existing recipient signing order
  await client.updateRecipient({
    params: {
      id: documentId.toString(),
      recipientId: createBody.recipients[0].recipientId.toString(),
    },
    body: {
      signingOrder: 2, // Signs after approver
    },
  });

  // 4. Add fields for each recipient
  await client.createField({
    params: { id: documentId.toString() },
    body: {
      type: 'SIGNATURE',
      recipientId: approver.id,
      pageNumber: 1,
      pageX: 10,
      pageY: 80,
      pageWidth: 30,
      pageHeight: 5,
      fieldMeta: {},
    },
  });

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

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

manageRecipients().catch(console.error);

Best Practices

1. Validate Email Addresses

Always validate email addresses before adding recipients:
function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

if (!isValidEmail(recipientEmail)) {
  throw new Error('Invalid email address');
}

2. Handle Duplicate Recipients

Check for duplicate email addresses before adding recipients:
const { body: document } = await client.getDocument({ params: { id: '123' } });

const emailExists = document.recipients.some(
  (r) => r.email === newRecipientEmail
);

if (emailExists) {
  console.warn('Recipient already exists');
}

3. Use Appropriate Roles

Use CaseRecommended Role
Must sign documentSIGNER
Must approve before othersAPPROVER
Just needs a copyCC
Can view but not signVIEWER

4. Sequential Signing Order

When using sequential signing, ensure signingOrder starts at 1 and increments:
const recipients = [
  { name: 'First', email: 'first@example.com', signingOrder: 1 },
  { name: 'Second', email: 'second@example.com', signingOrder: 2 },
  { name: 'Third', email: 'third@example.com', signingOrder: 3 },
];

See Also