salesforce-composite-envelo.../composite-envelope-builder/docs/api-reference.md

12 KiB

API Reference

Project: Salesforce Composite Envelope Builder
Version: 1.1
Date: February 23, 2026 (updated March 11, 2026)


1. Docusign REST API Integration

1.1 Base Endpoint

Production:

https://na3.docusign.net/restapi/v2.1

Sandbox:

https://demo.docusign.net/restapi/v2.1

Note: Replace na3 with your account's data center (na2, na3, eu1, etc.)


2. Create Composite Envelope

2.1 HTTP Request

Method: POST
Endpoint: /accounts/{accountId}/envelopes
Content-Type: application/json
Authorization: Bearer {access_token}

2.2 Request Headers

POST /restapi/v2.1/accounts/12345678-abcd-1234-abcd-1234567890ab/envelopes HTTP/1.1
Host: na3.docusign.net
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjY4MTg...
Content-Type: application/json
Accept: application/json

2.3 Request Body (Composite Templates)

Minimum Example (2 templates)

{
  "status": "sent",
  "emailSubject": "Please review and sign these forms",
  "compositeTemplates": [
    {
      "compositeTemplateId": "1",
      "serverTemplates": [
        {
          "sequence": "1",
          "templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        }
      ]
    },
    {
      "compositeTemplateId": "2",
      "serverTemplates": [
        {
          "sequence": "2",
          "templateId": "b2c3d4e5-f6g7-8901-bcde-fg2345678901"
        }
      ]
    }
  ]
}

Advanced Example (with merge fields)

{
  "status": "sent",
  "emailSubject": "Please review and sign these forms",
  "compositeTemplates": [
    {
      "compositeTemplateId": "1",
      "serverTemplates": [
        {
          "sequence": "1",
          "templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        }
      ],
      "inlineTemplates": [
        {
          "sequence": "1",
          "customFields": {
            "textCustomFields": [
              {
                "name": "SalesforceRecordId",
                "value": "0018V00000ABC123"
              },
              {
                "name": "CaseNumber",
                "value": "00001234"
              }
            ]
          }
        }
      ]
    }
  ]
}

2.4 Response

Success (201 Created)

{
  "envelopeId": "f9876543-21ab-cdef-0123-456789abcdef",
  "uri": "/envelopes/f9876543-21ab-cdef-0123-456789abcdef",
  "statusDateTime": "2026-02-23T12:34:56.789Z",
  "status": "sent"
}

Error (400 Bad Request)

{
  "errorCode": "INVALID_REQUEST_PARAMETER",
  "message": "The request contained at least one invalid parameter. The template with ID 'invalid-id' does not exist."
}

Error (401 Unauthorized)

{
  "errorCode": "USER_AUTHENTICATION_FAILED",
  "message": "One or both of Username and Password are invalid."
}

3. Composite Template Structure

3.1 Key Concepts

compositeTemplates (array):

  • Each element represents a server template to include in the envelope
  • Order in array determines document order in envelope

compositeTemplateId (string):

  • Unique identifier for this composite template within the request
  • Can be any string (recommend using sequence numbers: "1", "2", "3")

serverTemplates (array):

  • References pre-existing templates in your Docusign account
  • Must include templateId (GUID from Docusign)

sequence (string):

  • Determines document order within the envelope
  • "1" = first document, "2" = second, etc.
  • Important: Use strings, not integers

inlineTemplates (array, optional):

  • Allows runtime override of template values
  • Used for custom fields, recipient data, tabs

3.2 Recipient Merging

Automatic Merge: When multiple templates have recipients with the same roleName, Docusign automatically merges them into a single recipient.

Example:

  • Template A has recipient role: "Signer"
  • Template B has recipient role: "Signer"
  • Result: One recipient signs all documents

Requirements for merge:

  • Exact match on roleName
  • Same recipient routingOrder (signing order)
  • Merge happens automatically, no additional configuration needed

4. Authentication

4.1 JWT (JSON Web Token)

Preferred method for server-to-server integration

Step 1: Generate JWT

// Apex pseudocode
String jwt = generateJWT(
    integrationKey,    // From Docusign Apps & Keys
    userId,            // Docusign user GUID
    rsaPrivateKey,     // RSA private key (PEM format)
    'https://account-d.docusign.com/oauth/auth',  // Sandbox
    3600               // Token expiry (1 hour)
);

Step 2: Exchange JWT for Access Token

Request:

POST /oauth/token HTTP/1.1
Host: account-d.docusign.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={jwt}

Response:

{
  "access_token": "eyJ0eXAiOiJNVCIsImFsZyI...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Step 3: Use Access Token

Authorization: Bearer eyJ0eXAiOiJNVCIsImFsZyI...

4.2 OAuth2 Authorization Code

User-based authentication (not recommended for this use case)

See Docusign OAuth2 documentation for details.


5. Error Codes

5.1 Common Error Codes

Error Code HTTP Meaning Resolution
INVALID_REQUEST_PARAMETER 400 Invalid parameter in request Check JSON structure, template IDs
USER_AUTHENTICATION_FAILED 401 Invalid or expired access token Refresh access token
USER_LACKS_PERMISSIONS 403 User doesn't have permission Check Docusign user permissions
RESOURCE_NOT_FOUND 404 Template ID not found Verify template exists in account
DUPLICATE_RESOURCE 409 Duplicate request Check for duplicate envelope
ONESIGNAL_GENERIC_ERROR 500 Docusign server error Retry after delay

5.2 Rate Limits

Hourly limit: Varies by plan (1,000 - 10,000+ API calls/hour)

Response header when nearing limit:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 50
X-RateLimit-Reset: 1614358800

Error when limit exceeded:

{
  "errorCode": "HOURLY_APIINVOCATION_LIMIT_EXCEEDED",
  "message": "The maximum number of hourly API invocations has been exceeded."
}

Mitigation:

  • Implement exponential backoff
  • Cache access tokens (don't generate new token for each request)
  • Batch operations when possible

6. Custom Fields

6.1 Text Custom Fields

Use case: Store Salesforce record ID in envelope

{
  "compositeTemplates": [
    {
      "inlineTemplates": [
        {
          "customFields": {
            "textCustomFields": [
              {
                "name": "SalesforceRecordId",
                "value": "0018V00000ABC123",
                "show": "false",
                "required": "false"
              }
            ]
          }
        }
      ]
    }
  ]
}

6.2 List Custom Fields

{
  "customFields": {
    "listCustomFields": [
      {
        "name": "FormLanguage",
        "value": "English",
        "listItems": ["English", "Spanish"]
      }
    ]
  }
}

7. Webhook Configuration

7.1 Connect Webhook (for document retrieval)

Not required for Phase 1, but useful for future automation.

Endpoint: Configure in Docusign Admin → Connect → Add Configuration

Webhook payload (when envelope completes):

{
  "event": "envelope-completed",
  "apiVersion": "v2.1",
  "uri": "/restapi/v2.1/accounts/123/envelopes/abc",
  "envelopeId": "f9876543-21ab-cdef-0123-456789abcdef",
  "envelopeSummary": {
    "status": "completed",
    "emailSubject": "Please review and sign",
    "completedDateTime": "2026-02-23T14:30:00Z"
  }
}

8. Template Management APIs

8.1 List Templates

Use case: Retrieve template list for Flow dropdown

Request:

GET /restapi/v2.1/accounts/{accountId}/templates?count=100&order=name&order_by=asc

Response:

{
  "resultSetSize": "14",
  "totalSetSize": "14",
  "envelopeTemplates": [
    {
      "templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Form A - English",
      "shared": "true",
      "description": "English version of Form A"
    },
    {
      "templateId": "b2c3d4e5-f6g7-8901-bcde-fg2345678901",
      "name": "Form B - English",
      "shared": "true",
      "description": "English version of Form B"
    }
  ]
}

8.2 Get Template Details

Use case: Retrieve template metadata (recipients, tabs)

Request:

GET /restapi/v2.1/accounts/{accountId}/templates/{templateId}

Response:

{
  "templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Form A - English",
  "recipients": {
    "signers": [
      {
        "roleName": "Signer 1",
        "recipientId": "1",
        "routingOrder": "1"
      },
      {
        "roleName": "Signer 2",
        "recipientId": "2",
        "routingOrder": "2"
      }
    ]
  },
  "documents": [
    {
      "documentId": "1",
      "name": "Form_A.pdf",
      "pages": "2"
    }
  ]
}

9. Apex HTTP Callout Example

9.1 Complete Callout

public static String createCompositeEnvelope(String envelopeJSON, String accessToken, String accountId) {
    HttpRequest req = new HttpRequest();
    req.setEndpoint('callout:DocusignAPI/accounts/' + accountId + '/envelopes');
    req.setMethod('POST');
    req.setHeader('Authorization', 'Bearer ' + accessToken);
    req.setHeader('Content-Type', 'application/json');
    req.setHeader('Accept', 'application/json');
    req.setBody(envelopeJSON);
    req.setTimeout(120000); // 120 seconds
    
    Http http = new Http();
    HttpResponse res = http.send(req);
    
    if (res.getStatusCode() == 201) {
        Map<String, Object> responseMap = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        return (String) responseMap.get('envelopeId');
    } else {
        throw new CalloutException('Docusign API error [' + res.getStatusCode() + ']: ' + res.getBody());
    }
}

9.2 Named Credential Configuration

Setup → Named Credentials → New Named Credential

Settings:

  • Label: Docusign API
  • Name: DocusignAPI
  • URL: https://na3.docusign.net/restapi/v2.1
  • Identity Type: Named Principal
  • Authentication Protocol: OAuth 2.0
  • Scope: signature impersonation
  • Token Endpoint: https://account-d.docusign.com/oauth/token (sandbox)
  • JWT Token Exchange: Enabled

Usage in Apex:

req.setEndpoint('callout:DocusignAPI/accounts/' + accountId + '/envelopes');

10. Testing with Postman

10.1 Import Docusign Collection

Docusign provides an official Postman collection:
https://github.com/docusign/postman-collections

10.2 Create Composite Envelope Test

Request:

POST {{baseUrl}}/accounts/{{accountId}}/envelopes
Headers:
  Authorization: Bearer {{accessToken}}
  Content-Type: application/json
Body:
  {
    "status": "sent",
    "emailSubject": "Test Composite Envelope",
    "compositeTemplates": [
      {
        "compositeTemplateId": "1",
        "serverTemplates": [
          {
            "sequence": "1",
            "templateId": "{{templateId1}}"
          }
        ]
      },
      {
        "compositeTemplateId": "2",
        "serverTemplates": [
          {
            "sequence": "2",
            "templateId": "{{templateId2}}"
          }
        ]
      }
    ]
  }


Document Version: 1.0
Last Updated: February 23, 2026