Subscription Documents
Resource endpoints for a trade's DocuSign subscription documents. Use them to create the envelope from the offering's template, send it, get embedded signing URLs, resend, and void.
Requests authenticate with the Authorization: Bearer {clientID}:{apiKey} header. The examples below read the host and credentials from $TAPI_HOST, $TAPI_CLIENT_ID and $TAPI_API_KEY — see Running the Examples.
Sandbox base URL: https://api-sandboxdash.norcapsecurities.com — the examples read it from $TAPI_HOST.
Document lifecycle
esignStatus | Meaning | Next |
CREATED | Draft envelope, not yet delivered to any signer | send, void |
NOTSIGNED | Sent and waiting on one or more signers | resend, void |
SIGNED | Every signer has completed | Download via downloadUrl on the detail endpoint |
DECLINED | A signer declined to sign | Create a new document |
VOIDED | Cancelled. A voided draft is deleted at DocuSign | Create a new document |
esignStatus updates when DocuSign reports that the envelope was completed, declined or voided. To read DocuSign's current state on demand, use the update endpoint with action: "sync".
To show progress before every signer has completed, read the detail endpoint: envelopeStatus is DocuSign's own envelope status, and each recipient carries its roleName and DocuSign status. For example, while a countersigner the template adds has yet to sign, esignStatus is NOTSIGNED, envelopeStatus is sent, the PrimaryParty recipient is completed and the countersigner is sent.
Signers
Signers come from the trade's party and the account's joint party:
| Role | Party | Routing order | How they sign |
PrimaryParty | The trade's party | 1 | Embedded only, using a signingUrl from the detail endpoint. DocuSign does not email this signer |
SecondaryParty | The joint party (account link type secondary), when it has an email address | 2 | By email only. DocuSign emails this signer once the primary signer completes. No signingUrl is returned for them |
- Unfilled roles are removed. After the draft is created, every template recipient without an email address is removed, so a template with both roles works for single-signer accounts. Template roles that carry their own email address in the template are kept.
- The primary signer needs an email address. A trade party with no email is not rejected at create, but the envelope cannot be sent.
- Re-delivery. Use
action: "resend". A document stays NOTSIGNED until every signer has completed.
One document per template
A trade has at most one active (not VOIDED or DECLINED) document per template:
- Creating a document for a template that already has one returns the existing document, in the same shape as a new document. This includes documents created by
sendSubscriptionDocument. The create response echoes the requested template ID; the list, detail and update endpoints return such documents with templateId as {templateId}--{template name}. - The status is HTTP
200 when every template in the request matched an existing document, and 201 when at least one was created. - Concurrent requests for the same trade and template are processed one at a time, so they cannot create two envelopes. A
409 means another request was still running. Retry the whole request: templates already created come back as existing documents. - After a document is voided or declined, the next create makes a new one.
Creating a document is therefore safe to retry. See Timeouts, Retries and Idempotency.
Errors
Errors return the HTTP status with a statusCode / statusDesc envelope. statusDesc gives the detail.
| HTTP | statusCode | When |
400 | 1400 | Missing or invalid parameter, an action not allowed in the document's current status, or DocuSign rejected a void |
400 | 214 | The client has no DocuSign account connected, or DocuSign rejected creating the envelope or a resend |
403 | 1403 | The API key lacks the required scope |
404 | 1404 | The trade or document does not exist for this client |
409 | 1409 | Another request for the same trade and template is still running. Retry |
500 | 500 | DocuSign failed while preparing, sending, voiding or syncing the envelope |
GET /v3/trades/{tradeId}/subscription-documents
Returns every subscription document for a trade, newest first. Requires the trade.read scope.
Path Parameters
| Parameter | Type | Description |
tradeId | string | Trade ID |
Query Parameters
| Parameter | Type | Required | Description |
includeRecipients | string | No | Set to true to include DocuSign recipient details |
Example Request
curl -X GET "$TAPI_HOST/v3/trades/123456789/subscription-documents" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY"
Response
| Field | Type | Description |
subscriptionDocuments | array | Subscription documents, newest first |
subscriptionDocuments[].documentId | string | DocuSign envelope ID |
subscriptionDocuments[].templateId | string | DocuSign template ID |
subscriptionDocuments[].esignStatus | string | CREATED, NOTSIGNED, SIGNED, DECLINED or VOIDED. See Document lifecycle |
subscriptionDocuments[].createdDate | string | Creation timestamp |
subscriptionDocuments[].updatedDate | string | Last update timestamp |
subscriptionDocuments[].recipients | array | Recipients, only when includeRecipients=true. Same fields as on the detail endpoint, without signingUrl |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocuments": [
{
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateId": "tmpl-abc123",
"esignStatus": "NOTSIGNED",
"createdDate": "2026-03-24 10:30:00",
"updatedDate": "2026-03-24 10:30:00"
}
]
}
GET /v3/trades/{tradeId}/subscription-documents/{documentId}
Returns one subscription document with its recipients and embedded signing URLs. Requires the trade.read.pii_high scope.
Path Parameters
| Parameter | Type | Description |
tradeId | string | Trade ID |
documentId | string | DocuSign envelope ID |
Query Parameters
| Parameter | Type | Required | Description |
returnUrl | string | No | Where DocuSign sends the signer after embedded signing. Defaults to the configured DocuSign callback URL |
Example Request
curl -X GET "$TAPI_HOST/v3/trades/123456789/subscription-documents/a1b2c3d4-e5f6-7890-abcd-ef1234567890?returnUrl=https://example.com/signed" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY"
Response
| Field | Type | Description |
subscriptionDocument.documentId | string | DocuSign envelope ID |
subscriptionDocument.templateId | string | DocuSign template ID |
subscriptionDocument.esignStatus | string | CREATED, NOTSIGNED, SIGNED, DECLINED or VOIDED |
subscriptionDocument.envelopeStatus | string | The envelope's status in DocuSign, passed through as DocuSign reports it, for example created, sent, delivered, completed, declined or voided. Omitted when DocuSign could not be reached |
subscriptionDocument.recipients | array | DocuSign recipients with signing status |
subscriptionDocument.recipients[].roleName | string | Template role: PrimaryParty, SecondaryParty, or a role the template defines, such as a countersigner. null when DocuSign reports no role |
subscriptionDocument.recipients[].embedded | boolean | true when the recipient signs in your application with a signingUrl and DocuSign does not email them; false when DocuSign emails them |
subscriptionDocument.recipients[].status | string | The recipient's status in DocuSign, for example created, sent, delivered, completed or declined |
subscriptionDocument.recipients[].routingOrder | string | 1 for the primary signer, 2 for the secondary signer. Template roles keep the template's order |
subscriptionDocument.recipients[].signingUrl | string | Embedded signing URL for an embedded signer, normally the primary signer, present only while it is their turn (sent or delivered). A new URL is minted on every call. Not returned for the secondary signer, except on documents created before the secondary became an email-only signer |
subscriptionDocument.downloadUrl | string | Download URL for the signed copy, valid for 3 minutes. Present only when esignStatus is SIGNED and the signed copy has been stored; call getTradeSignedDocument to store it if it is missing |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocument": {
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateId": "tmpl-abc123",
"esignStatus": "NOTSIGNED",
"createdDate": "2026-03-24 10:30:00",
"updatedDate": "2026-03-24 10:35:00",
"envelopeStatus": "sent",
"recipients": [
{
"recipientId": "1",
"name": "John Doe",
"email": "john@example.com",
"roleName": "PrimaryParty",
"embedded": true,
"routingOrder": "1",
"status": "sent",
"type": "signer",
"signingUrl": "https://na3.docusign.net/Signing/StartInSession.aspx?t=..."
}
]
}
}
POST /v3/trades/{tradeId}/subscription-documents
Creates a draft DocuSign envelope for each template, with the investor's data filled in. Nothing is delivered to signers until you send it. A template that already has an active document returns that document instead (see One document per template). Requires the trade.write scope.
Path Parameters
| Parameter | Type | Description |
tradeId | string | Trade ID |
Request Body (JSON)
| Parameter | Type | Required | Description |
templateIds | array of strings | Yes | DocuSign template IDs (templateKey from the templates endpoint) |
Example Request
curl -X POST "$TAPI_HOST/v3/trades/123456789/subscription-documents" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"templateIds": ["tmpl-abc123"]}'
Response
HTTP 201 when at least one document was created. HTTP 200 when every template already had an active document. Both return one entry per template.
| Field | Type | Description |
subscriptionDocuments[].documentId | string | DocuSign envelope ID |
subscriptionDocuments[].templateId | string | DocuSign template ID |
subscriptionDocuments[].esignStatus | string | CREATED for a new document, or the existing document's status |
subscriptionDocuments[].createdDate | string | Creation timestamp |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocuments": [
{
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateId": "tmpl-abc123",
"esignStatus": "CREATED",
"createdDate": "2026-03-24 10:30:00"
}
]
}
PATCH /v3/trades/{tradeId}/subscription-documents/{documentId}
Sends, resends, voids or syncs a subscription document. Requires the trade.write scope.
Path Parameters
| Parameter | Type | Description |
tradeId | string | Trade ID |
documentId | string | DocuSign envelope ID |
Request Body (JSON)
| Parameter | Type | Required | Description |
action | string | Yes | send, resend, void or sync |
recipientIds | array | No | resend only: the recipients to re-deliver to. Defaults to the recipients whose turn it is |
returnUrl | string | No | Where DocuSign sends the signer after embedded signing, for the signingUrl values in the response |
voidedReason | string | No | void only: the reason shown to recipients, 1–200 characters. Defaults to Voided via TransactAPI |
Actions
| Action | Allowed when esignStatus is | Result |
send | CREATED | NOTSIGNED. The response includes the primary signer's signingUrl |
resend | NOTSIGNED | Re-delivers to the recipients whose turn it is, or to the ones in recipientIds |
void | CREATED or NOTSIGNED | VOIDED. A voided draft is deleted at DocuSign |
sync | Any | Reads the envelope's status from DocuSign and updates esignStatus |
Any other combination returns 400.
Example Request
curl -X PATCH "$TAPI_HOST/v3/trades/123456789/subscription-documents/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "send", "returnUrl": "https://example.com/signed"}'
Response
| Field | Type | Description |
subscriptionDocument.documentId | string | DocuSign envelope ID |
subscriptionDocument.templateId | string | DocuSign template ID |
subscriptionDocument.esignStatus | string | Status after the action |
subscriptionDocument.envelopeStatus | string | The envelope's status in DocuSign after the action. Omitted when DocuSign could not be reached |
subscriptionDocument.updatedDate | string | Update timestamp |
subscriptionDocument.recipients | array | Same fields as on the detail endpoint, including signingUrl for the primary signer while it is their turn |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocument": {
"documentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateId": "tmpl-abc123",
"esignStatus": "NOTSIGNED",
"updatedDate": "2026-03-24 10:35:00",
"envelopeStatus": "sent",
"recipients": [
{
"recipientId": "1",
"name": "John Doe",
"email": "john@example.com",
"roleName": "PrimaryParty",
"embedded": true,
"routingOrder": "1",
"status": "sent",
"type": "signer",
"signingUrl": "https://na3.docusign.net/Signing/StartInSession.aspx?t=..."
}
]
}
}
GET /v3/offerings/{offeringId}/subscription-document-templates
Returns the subscription document templates attached to an offering, most recently added first. Pass a template's templateKey in templateIds when creating a subscription document. Requires the offering.read scope.
Path Parameters
| Parameter | Type | Description |
offeringId | string | Offering ID |
Query Parameters
| Parameter | Type | Required | Description |
limit | integer | No | Maximum number of templates to return. Defaults to 100, capped at 1000 |
offset | integer | No | Zero-based index of the first template to return. Defaults to 0 |
Example Request
curl -X GET "$TAPI_HOST/v3/offerings/97618/subscription-document-templates?limit=10&offset=0" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY"
Response
| Field | Type | Description |
subscriptionDocumentTemplates | array | Template objects, newest first. Empty when the offering has no templates |
subscriptionDocumentTemplates[].templateId | string | Template record ID, used in the {templateId} path segment |
subscriptionDocumentTemplates[].offeringId | string | Offering ID the template belongs to |
subscriptionDocumentTemplates[].templateKey | string | DocuSign template ID |
subscriptionDocumentTemplates[].templateName | string | Template display name |
subscriptionDocumentTemplates[].templateUrl | string | URL of the uploaded template document |
subscriptionDocumentTemplates[].createdDate | string | When the template was attached to the offering |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocumentTemplates": [
{
"templateId": "4521",
"offeringId": "97618",
"templateKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateName": "Subscription Agreement",
"templateUrl": "https://api-sandboxdash.norcapsecurities.com/admin_v3/Upload_documentation/uploadDocument/MTIzNDU=",
"createdDate": "2026-03-24 10:30:00"
}
]
}
GET /v3/offerings/{offeringId}/subscription-document-templates/{templateId}
Returns one subscription document template attached to an offering. A template that exists but belongs to a different offering returns 404. Requires the offering.read scope.
Path Parameters
| Parameter | Type | Description |
offeringId | string | Offering ID |
templateId | string | Template record ID (templateId from the list endpoint) |
Example Request
curl -X GET "$TAPI_HOST/v3/offerings/97618/subscription-document-templates/4521" \
-H "Authorization: Bearer $TAPI_CLIENT_ID:$TAPI_API_KEY"
Response
| Field | Type | Description |
subscriptionDocumentTemplate.templateId | string | Template record ID |
subscriptionDocumentTemplate.offeringId | string | Offering ID the template belongs to |
subscriptionDocumentTemplate.templateKey | string | DocuSign template ID |
subscriptionDocumentTemplate.templateName | string | Template display name |
subscriptionDocumentTemplate.templateUrl | string | URL of the uploaded template document |
subscriptionDocumentTemplate.createdDate | string | When the template was attached to the offering |
Example Response
{
"statusCode": "101",
"statusDesc": "Ok",
"subscriptionDocumentTemplate": {
"templateId": "4521",
"offeringId": "97618",
"templateKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"templateName": "Subscription Agreement",
"templateUrl": "https://api-sandboxdash.norcapsecurities.com/admin_v3/Upload_documentation/uploadDocument/MTIzNDU=",
"createdDate": "2026-03-24 10:30:00"
}
}