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

530 lines
12 KiB
Markdown

# 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
```http
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)
```json
{
"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)
```json
{
"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)
```json
{
"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)
```json
{
"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)
```json
{
"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
// 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**:
```http
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**:
```json
{
"access_token": "eyJ0eXAiOiJNVCIsImFsZyI...",
"token_type": "Bearer",
"expires_in": 3600
}
```
#### Step 3: Use Access Token
```http
Authorization: Bearer eyJ0eXAiOiJNVCIsImFsZyI...
```
### 4.2 OAuth2 Authorization Code
**User-based authentication** (not recommended for this use case)
See [Docusign OAuth2 documentation](https://developers.docusign.com/platform/auth/authcode/) 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**:
```http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 50
X-RateLimit-Reset: 1614358800
```
**Error when limit exceeded**:
```json
{
"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
```json
{
"compositeTemplates": [
{
"inlineTemplates": [
{
"customFields": {
"textCustomFields": [
{
"name": "SalesforceRecordId",
"value": "0018V00000ABC123",
"show": "false",
"required": "false"
}
]
}
}
]
}
]
}
```
### 6.2 List Custom Fields
```json
{
"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):
```json
{
"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**:
```http
GET /restapi/v2.1/accounts/{accountId}/templates?count=100&order=name&order_by=asc
```
**Response**:
```json
{
"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**:
```http
GET /restapi/v2.1/accounts/{accountId}/templates/{templateId}
```
**Response**:
```json
{
"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
```apex
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**:
```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}}"
}
]
}
]
}
```
---
## 11. Reference Links
- [Docusign REST API Reference](https://developers.docusign.com/docs/esign-rest-api/reference/)
- [Composite Templates Guide](https://developers.docusign.com/docs/esign-rest-api/how-to/request-signature-composite-template/)
- [JWT Authentication](https://developers.docusign.com/platform/auth/jwt/)
- [Salesforce Named Credentials](https://help.salesforce.com/s/articleView?id=sf.named_credentials_about.htm)
- [Salesforce HTTP Callouts](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_httprequest.htm)
---
**Document Version**: 1.0
**Last Updated**: February 23, 2026