# Node
> Use this guide to migrate to the new Dropbox Sign Node SDK, which is powered by our OpenAPI specification. Contains concepts and examples to help you migrate successfully.
# Node Migration Guide
## Migrating the Node SDK from `hellosign-sdk` to `@dropbox/sign`
## Architecture and Tooling
## Core Concepts and Patterns
This section contains the core concepts and patterns of the new SDK and highlights differences from the legacy SDK.
### Installation
There are two methods for installing the new SDK:
-
Optionally, to scaffold your
package.json first run:
```bash
npm init
```
-
To install from NPM run:
```bash
npm install @dropbox/sign
```
-
Clone the repo locally
```bash
git clone https://github.com/hellosign/dropbox-sign-node.git
```
-
Run
npm pack
-
Move generated file (
dropbox-sign-1.0.0.tgz or similar) to your project directory
-
In the
dependencies array of your package.json file, add
```json
"@dropbox/sign": "file:dropbox-sign-1.0.0.tgz"
```
-
Run
npm install
***
### Importing the SDK
The new Node SDK is packaged as an [ES Module rather than CommonJS](https://nodejs.org/api/esm.html#differences-between-es-modules-and-commonjs), which means you'll bring it into your code base differently.
Use
require
statement to bring in the entire Dropbox Sign SDK.
Use
import
statement to add the entire SDK or only the pieces you need.
```javascript title="Legacy SDK - require"
const sign_sdk = require('hellosign-sdk')({ key: "API_KEY" });
```
```javascript title="New SDK - import"
// Add entire SDK
import * as DropboxSign from "@dropbox/sign";
// or add only what you need
import { SignatureRequestApi } from "@dropbox/sign";
const signatureApi = new SignatureRequestApi();
```
To support ES Modules and use import statements in your Node project, your *package.json* file must contain `"type": "module"`.
***
### Authentication
Rather than one big SDK with access to everything, the new Node SDK is organized into groups of similar endpoints.
Pass credentials
once
when instantiating the SDK.
Pass credentials
each time
a new section of the SDK is instantiated (Signature Request, Template, Account, etc.)
```javascript Legacy SDK - Authentication
const sign_sdk = require('hellosign-sdk')({key: 'YOUR API KEY HERE'});
```
```javascript New SDK - Authentication with API Key
import { SignatureRequestApi, AccountApi } from "@dropbox/sign";
const signatureApi = new SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const accountApi = new AccountApi();
accountApi.username = "YOUR_API_KEY";
```
```javascript New SDK - Authentication with OAuth Token
import { SignatureRequestApi, AccountApi } from "@dropbox/sign";
const signatureApi = new SignatureRequestApi();
signatureApi.accessToken = "YOUR_ACCESS_TOKEN";
const accountApi = new AccountApi();
accountApi.accessToken = "YOUR_ACCESS_TOKEN";
```
***
### Endpoints Grouped into Classes
The new SDK divides endpoints across unique Classes:
| Class Name and Reference | API Reference |
| --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| [AccountApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/AccountApi.md) | [/account/\* Endpoints](/api/account) |
| [ApiAppApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/ApiAppApi.md) | [/api\_app/\* Endpoints](/api/api-app) |
| [BulkSendJobApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/BulkSendJobApi.md) | [/bulk\_send\_job/\* Endpoints](/api/bulk-send-job) |
| [EmbeddedApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/EmbeddedApi.md) | [/embedded/\* Endpoints](/api/embedded) |
| [OAuthApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/OAuthApi.md) | [/oauth/\* Endpoints](/docs/guides/o-auth/overview) |
| [ReportApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/ReportApi.md) | [/report/\* Endpoints](/api/report) |
| [SignatureRequestApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/SignatureRequestApi.md) | [/signature\_request/\* Endpoints](/api/signature-request) |
| [TeamApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/TeamApi.md) | [/team/\* Endpoints](/api/team) |
| [TemplateApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/TemplateApi.md) | [/template/\* Endpoints](/api/template) |
| [UnclaimedDraftApi](https://github.com/hellosign/dropbox-sign-node/blob/main/docs/api/UnclaimedDraftApi.md) | [/unclaimed\_draft/\* Endpoints](/api/unclaimed-draft) |
***
### Using Models to Pass Parameters
[Models](https://github.com/hellosign/dropbox-sign-node/blob/main/README.md#models) are used to define the structure and value of the parameters being passed. The fully assembled model is passed to the API endpoint method.
**New SDK Using Models to Pass Parameters**
```javascript
import * as DropboxSign from "@dropbox/sign";
const fs = require('fs');
const apiAppApi = new DropboxSign.ApiAppApi();
apiAppApi.username = "YOUR_API_KEY";
const oauth = {
callbackUrl: "https://example.com/oauth",
scopes: [
"basic_account_info",
"request_signature"
]
};
const whiteLabelingOptions = {
primaryButtonColor: "#00b3e6",
primaryButtonTextColor: "#ffffff"
};
const data = {
name: "My Production App",
domains: ["example.com"],
customLogoFile: fs.createReadStream("CustomLogoFile.png"),
oauth,
whiteLabelingOptions
};
const result = apiAppApi.apiAppCreate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Path and Query Parameters
When passing parameters to the API methods in the legacy SDK it was standard to pass the parameters inside of an object to the API method. For example using the `opts` object below:
**Legacy SDK - Path and Query Parameters**
```javascript
const hellosign = require('hellosign-sdk')({ key: 'HelloSign_API_KEY' });
const opts = {
page: 1,
account_id: 'all'
}
hellosign.signatureRequest.list(opts).then((res) => {
console.log(res);
}).catch((err) => {
console.error(err);
});
```
The new SDK no longer accepts objects when passing path or query parameters to endpoints. Instead you will need to pass the parameters as separate variables such as `accountId` and `page` below:
**New SDK - Path and Query Parameters**
```javascript
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const accountId = null;
const page = 1;
const result = signatureApi.signatureRequestList(accountId, page);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
Endpoints that have both path or query parameters, and accept POST data, will have a mix of both styles:
```javascript New SDK - Path, Query, and Post Data with Javascript
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const data = {
emailAddress: "john@example.com"
};
const signatureRequestId = "2f9781e1a8e2045224d808c153c2e1d3df6f8f2f";
const result = signatureRequestApi.signatureRequestRemind(signatureRequestId, data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - Path, Query, and Post Data with TypeScript
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const data: DropboxSign.SignatureRequestRemindRequest = {
emailAddress: "john@example.com"
};
const signatureRequestId = "2f9781e1a8e2045224d808c153c2e1d3df6f8f2f";
const result = signatureRequestApi.signatureRequestRemind(signatureRequestId, data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Error Handling and Warnings
The New SDK handles errors and warnings differently.
#### Error Handling
Errors are an instance of [HttpError](https://github.com/hellosign/dropbox-sign-node/blob/main/api/apis.ts#L27-L36) with its `body` parameter being an instance of [ErrorResponse](https://github.com/hellosign/dropbox-sign-node/blob/main/model/errorResponse.ts) class and should be handled using Try/Catch blocks.
```javascript New SDK - Error Handling
import * as DropboxSign from "@dropbox/sign";
const accountApi = new DropboxSign.AccountApi();
accountApi.username = "YOUR_API_KEY";
const data = {
emailAddress: "newuser@dropboxsign.com"
};
const result = accountApi.accountCreate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
// error is instance of HttpError
console.log("Exception when calling Dropbox Sign API:");
// error.body is instance of ErrorResponse
console.log(error.body);
});
```
#### Warnings
Warnings are a list of [WarningResponse](https://github.com/hellosign/dropbox-sign-node/blob/main/model/warningResponse.ts).
**New SDK - Warnings**
```javascript
import * as DropboxSign from "@dropbox/sign";
const accountApi = new DropboxSign.AccountApi();
accountApi.username = "YOUR_API_KEY";
const data = {
emailAddress: "newuser@dropboxsign.com"
};
const result = accountApi.accountCreate(data);
result.then(response => {
console.log(response.body);
// warning loop
response.body.warnings.forEach(warning => {
console.log(`Warning Name: ${warning.warningName}`);
console.log(`Warning Message: ${warning.warningMsg}`);
});
}).catch(error => {
// error is instance of HttpError
console.log("Exception when calling Dropbox Sign API:");
// error.body is instance of ErrorResponse
console.log(error.body);
});
```
***
### Instantiating Objects From Data
There are two ways to instantiate an object.
* You can instantiate a class directly and use setters to set your data
* You can use an object literal that matches expected type definitions
```javascript New SDK - Using Setters
const signer1 = new DropboxSign.SubSignatureRequestSigner();
signer1.name = "George";
signer1.emailAddress = "george@example.com";
const attachment1 = new DropboxSign.SubAttachment();
attachment1.name = "Attachment 1";
attachment1.instructions = "Please download this file";
attachment1.signerIndex = 0;
attachment1.required = true;
```
```javascript New SDK - Using Object Literal
// with optional TypeScript type
const signer1: DropboxSign.SubSignatureRequestSigner = {
name: "George",
emailAddress: "george@example.com"
};
// with optional TypeScript type
const attachment1: DropboxSign.SubAttachment = {
name: "Attachment 1",
instructions: "Please download this file",
signerIndex: 0,
required: true
};
```
***
### Event Callback Helper
A callback helper class is included in the [New SDK repo](https://github.com/hellosign/dropbox-sign-node/blob/main/model/eventCallbackHelper.ts) to assist in verifying callbacks. The helper simplifies:
1. Checking event authenticity with built in event hash check
2. Displaying event types (account callback vs. app callback)
3. Displaying event messages
The `EventCallbackHelper` and `EventCallbackRequest` classes facilitate parsing of event data and assist in validating that a callback originated from Dropbox Sign.
We will send event callback payloads to you as a `multipart/form-data` request with a single `json` formfield that contains your event callback as a JSON string.
**Example Event Callback Request From US to YOU**
```bash
curl -X POST 'https://example.com/YOUR_EVENT_CALLBACK_URL' \
-F 'json={"event":{"event_type":"account_confirmed","event_time":"1669926463","event_hash":"ff8b03439122f9160500c3fb855bdee5a9ccba5fff27d3b258745d8f3074832f","event_metadata":{"related_signature_id":null,"reported_for_account_id":"6421d70b9bd45059fa207d03ab8d1b96515b472c","reported_for_app_id":null,"event_message":null}}}'
```
**Example JSON Payload**
```json
{
"event": {
"event_type": "account_confirmed",
"event_time": "1669926463",
"event_hash": "ff8b03439122f9160500c3fb855bdee5a9ccba5fff27d3b258745d8f3074832f",
"event_metadata": {
"related_signature_id": null,
"reported_for_account_id": "6421d70b9bd45059fa207d03ab8d1b96515b472c",
"reported_for_app_id": null,
"event_message": null
}
}
}
```
**How to use the EventCallbackHelper**
```javascript
import { EventCallbackRequest, EventCallbackHelper } from "@dropbox/sign";
// use your API key
const api_key = '324e3b0840f065eb51f3fd63231d0d33daa35d4ed10d27718839e81737065782';
// callback_data represents data we send to you
const callback_data = JSON.parse(req.body.json);
const callback_event = EventCallbackRequest.init(callback_data);
// verify that a callback came from HelloSign.com
if (EventCallbackHelper.isValid(api_key, callback_event)) {
// one of "account_callback" or "api_app_callback"
const callback_type = EventCallbackHelper.getCallbackType(callback_event);
// do your magic below!
}
```
### Native TypeScript Support
The new SDK is written in TypeScript and comes fully typed for the best possible developer experience.
If you do not use TypeScript you can still use the new SDK as normal.
***
## Differences from Legacy SDK
This section highlights larger changes to be aware of when migrating to the new SDK.
### Form Fields Per Document
The Form Fields per Document parameter has changed from a two dimensional array, to a one dimensional array—allowing you to designate which file you to add the field to using `documentIndex`. You can learn more about this change here: [Form Fields per Document](/docs/sd-ks/open-api/form-fields-per-document).
```javascript Legacy SDK - Form Fields Per Document
const hellosign = require('hellosign-sdk')({ key: process.env.HelloSign_API_KEY });
module.exports = {
send_signature_request: function () {
const opts = {
test_mode: 1,
files: ['Demo-Mutual-Non-Disclosure-Agreement.pdf'],
title: 'NDA with Acme Co.',
subject: 'The NDA we talked about',
message: 'Please sign this NDA and then we can discuss more.',
signers: [
{
name: 'Jill',
email_address: 'jill@example.com'
}
],
form_fields_per_document: [[{
"api_id": "abcd",
"name": "signer_signature",
"type": "signature",
"x": 200,
"y": 300,
"page": 1,
"width": 280,
"height": 72,
"required": true,
"signer": 0
}]]
};
hellosign.signatureRequest.send(opts).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
}
}
```
```javascript New SDK - Form Fields Per Document
import * as DropboxSign from "@dropbox/sign";
const fs = require('fs');
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const yourFile = fs.createReadStream('./Demo-Mutual-Non-Disclosure-Agreement.pdf');
const signer1 = {
emailAddress: "Jack@example.com",
name: "Jack",
order: 0
};
const data = {
testMode: true,
files: [yourFile],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [
{
documentIndex: 0,
apiId: "abcd",
name: "signer_signature",
type: "signature",
x: 200,
y: 300,
page: 1,
width: 280,
height: 72,
required: true,
signer: "0"
}
]
};
const result = signatureApi.signatureRequestSend(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
#### Instantiating the Correct Field Class
There are several different types of form fields you can define, identified by the value of the `type` field and a few ways to instantiate the correct object when making an API request.
The different classes for each type are:
| Field Type | Class |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| checkbox | [SubFormFieldsPerDocumentCheckbox](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentCheckbox.ts) |
| checkbox-merge | [SubFormFieldsPerDocumentCheckboxMerge](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentCheckboxMerge.ts) |
| date\_signed | [SubFormFieldsPerDocumentDateSigned](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentDateSigned.ts) |
| dropdown | [SubFormFieldsPerDocumentDropdown](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentDropdown.ts) |
| hyperlink | [SubFormFieldsPerDocumentHyperlink](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentHyperlink.ts) |
| initials | [SubFormFieldsPerDocumentInitials](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentInitials.ts) |
| radio | [SubFormFieldsPerDocumentRadio](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentRadio.ts) |
| signature | [SubFormFieldsPerDocumentSignature](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentSignature.ts) |
| text | [SubFormFieldsPerDocumentText](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentText.ts) |
| text-merge | [SubFormFieldsPerDocumentTextMerge](https://github.com/hellosign/dropbox-sign-node/blob/main/model/subFormFieldsPerDocumentTextMerge.ts) |
You can use a literal object definition with no typing:
```javascript New SDK - Form Fields Per Document Literal Signature
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [
{
type: "signature",
documentIndex: 0,
apiId: "abcd",
name: "field_1",
x: 200,
y: 300,
page: 1,
width: 280,
height: 72,
required: true,
signer: "0"
}
]
};
```
```javascript New SDK - Form Fields Per Document Literal Text
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [
{
type: "text",
documentIndex: 0,
apiId: "abcd",
name: "field_1",
x: 200,
y: 300,
page: 1,
width: 280,
height: 72,
required: true,
signer: "0",
placeholder: "Fill me in!",
masked: false
}
]
};
```
You can also instantiate an instance of the correct class. In this scenario the `type` field is automatically set to the correct value for you:
```javascript New SDK - Form Fields Per Document Instance Signature
// type is automatically set to "signature"
const formField1 = new DropboxSign.SubFormFieldsPerDocumentSignature();
formField1.documentIndex = 0;
formField1.apiId = "abcd";
formField1.name = "signer_signature";
formField1.x = 200;
formField1.y = 300;
formField1.page = 1;
formField1.width = 280;
formField1.height = 72;
formField1.required = true;
formField1.signer = "0";
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [ formField1 ]
};
```
```javascript New SDK - Form Fields Per Document Instance Text
// type is automatically set to "text"
const formField1 = new DropboxSign.SubFormFieldsPerDocumentText();
formField1.documentIndex = 0;
formField1.apiId = "abcd";
formField1.name = "signer_signature";
formField1.x = 200;
formField1.y = 300;
formField1.page = 1;
formField1.width = 280;
formField1.height = 72;
formField1.required = true;
formField1.signer = "0";
formField1.placeholder = "Fill me in!";
formField1.masked = false;
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [ formField1 ]
};
```
If you are using TypeScript you can use a literal object definition with typehint on the object itself. If you use a typehint any invalid or missing data will be highlighted on the object itself in your IDE.
If you use TypeScript but do not typehint the object, you will see the error when passing the data to the API endpoint.
```javascript New SDK - Form Fields Per Document with Typescript Typehinted
// TS2741: Property '"type"' is missing in type [...]
const formField1: DropboxSign.SubFormFieldsPerDocumentSignature = {
documentIndex: 0,
apiId: "abcd",
name: "field_1",
x: 200,
y: 300,
page: 1,
width: 280,
height: 72,
required: true,
signer: "0"
}
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [ formField1 ]
};
const result = signatureApi.signatureRequestSend(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - Form Fields Per Document with Typescript NOT Typehinted
const formField1 = {
documentIndex: 0,
apiId: "abcd",
name: "field_1",
x: 200,
y: 300,
page: 1,
width: 280,
height: 72,
required: true,
signer: "0"
}
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ],
formFieldsPerDocument: [ formField1 ]
};
// TS2345: Argument of type [...]
const result = signatureApi.signatureRequestSend(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### "role" Value in `signers` Object
In the Legacy SDK when making a Signature Request using a Template the `signers` property was an object with the role name as the key. In the new SDK the role value has been moved into the signer object itself.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `signers` property could be represented as:
```json Legacy SDK - signers with Roles
{
"signers": {
"Client": {
"name": "George",
"email_address": "george@example.com"
},
"Manager": {
"name": "Bob",
"email_address": "bob@example.com"
}
}
}
```
```json New SDK - signers with Roles
{
"signers": [
{
"role": "Client",
"name": "George",
"email_address": "george@example.com"
},
{
"role": "Manager",
"name": "Bob",
"email_address": "bob@example.com"
}
]
}
```
Using the new SDK you would now send this data as follows:
```javascript New SDK - signers with Roles Example #1
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [
{
"role": "Client",
"name": "George",
"emailAddress": "george@example.com"
},
{
"role": "Manager",
"name": "Bob",
"emailAddress": "bob@example.com"
}
]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - signers with Roles Example #2
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const signer1 = {
role: "Client",
name: "George",
emailAddress: "george@example.com"
};
const signer2 = {
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
};
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [ signer1, signer2 ]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### "role" Value in `ccs` Property
In the Legacy SDK when making a Signature Request using a Template the `ccs` property was an object with the role name as the key. In the new SDK the role value has been moved into the cc object itself, alongside a new `email_address` property.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `ccs` property could be represented as:
```json Legacy SDK - ccs
{
"ccs": {
"Client": "george@example.com",
"Manager": "bob@example.com"
}
}
```
```json New SDK - ccs
{
"ccs": [
{
"role": "Client",
"email_address": "george@example.com"
},
{
"role": "Manager",
"email_address": "bob@example.com"
}
]
}
```
Using the new SDK you would now send this data as follows:
```javascript New SDK - ccs Example #1
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [
{
role: "Client",
name: "George",
emailAddress: "george@example.com"
},
{
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
}
],
ccs: [
{
role: "Client",
emailAddress: "george@example.com"
},
{
role: "Manager",
emailAddress: "bob@example.com"
}
]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - ccs Example #2
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const signer1 = {
role: "Client",
name: "George",
emailAddress: "george@example.com"
};
const signer2 = {
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
};
const cc1 = {
role: "Client",
emailAddress: "george@example.com"
};
const cc2 = {
role: "Manager",
emailAddress: "bob@example.com"
};
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [ signer1, signer2 ],
ccs: [ cc1, cc2 ]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### "name" Value in `custom_fields` Property
In the Legacy SDK when making a Signature Request with the `custom_fields` property it was an object with the name as the key. In the new SDK the name value has been moved into the custom\_field object itself.
For example for the [/signature\_request/send\_with\_template](/api/signature-request/send-with-template) endpoint the `custom_fields` property could be represented as:
```json Legacy SDK - custom_fields
{
"custom_fields": {
"company": {
"value": "ABC Corp",
"required": true
}
}
}
```
```json New SDK - custom_fields
{
"custom_fields": [
{
"name": "company",
"value": "ABC Corp",
"required": true
}
]
}
```
Using the new SDK you would now send this data as follows:
```javascript New SDK - custom_fields Example #1
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [
{
role: "Client",
name: "George",
emailAddress: "george@example.com"
},
{
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
}
],
customFields: [
{
name: "company",
value: "ABC Corp",
required: true
}
]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - custom_fields Example #2
import * as DropboxSign from "@dropbox/sign";
const signatureRequestApi = new DropboxSign.SignatureRequestApi();
signatureRequestApi.username = "YOUR_API_KEY";
const signer1 = {
role: "Client",
name: "George",
emailAddress: "george@example.com"
};
const signer2 = {
role: "Manager",
name: "Bob",
emailAddress: "bob@example.com"
};
const customField1 = {
name: "company",
value: "ABC Corp",
required: true
}
const data = {
templateIds: ["c26b8a16784a872da37ea946b9ddec7c1e11dff6"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [ signer1, signer2 ],
customFields: [ customField1 ]
};
const result = signatureRequestApi.signatureRequestSendWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### `template_id` to `template_ids`
The `template_id` parameter has been removed. You must now use `template_ids`.
| Legacy SDK version | New SDK Version |
| ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Template ID (`template_id`) is passed as a singular string:
template\_id : "1234567890"
| Template ID is passed as an array of strings (`templateIds`):
templateIds: \["1234567890"]
|
***
### `file` to `files`
The `file` parameter has been renamed to `files`. Usage remains the same.
***
### `file_url` to `file_urls`
The `file_url` parameter has been renamed to `file_urls`. Usage remains the same.
***
### snake\_case to camelCase
The variables, properties, and functions in the Legacy SDK were written in `snake_case`. The New SDK now uses `camelCase` instead, as this is what is standard practice for Node.
```bash Legacy SDK - Parameters
test_mode
template_id
custom_fields
form_fields_per_document
signing_options
```
```bash New SDK - Parameters
testMode
templateId
customFields
formFieldsPerDocument
signingOptions
```
***
### Interacting with Files
The new SDK version introduces some new patterns around uploading and downloading files. You can read about them more in depth here: [Interacting with Files](/docs/sd-ks/open-api/interacting-with-files).
#### Uploading Files
Passing a file with with your API request using the `files` parameter is different:
| Legacy SDK version | New SDK Version |
| ----------------------------------------------- | ------------------------------ |
| Accepts a file binary or a path to a local file | **Only** accepts a file binary |
```javascript Legacy SDK - Files Parameter
const hellosign = require('hellosign-sdk')({ key: process.env.HelloSign_API_KEY });
module.exports = {
send_signature_request: function () {
const opts = {
test_mode: 1,
files: ['Demo-Mutual-Non-Disclosure-Agreement.pdf'],
title: 'NDA with Acme Co.',
subject: 'The NDA we talked about',
message: 'Please sign this NDA and then we can discuss more.',
signers: [
{
name: 'Jill',
email_address: 'jill@example.com'
}
]
};
hellosign.signatureRequest.send(opts).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
}
}
```
```javascript New SDK - File Parameter
import * as DropboxSign from "@dropbox/sign";
const fs = require('fs');
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const yourFile = fs.createReadStream('./Demo-Mutual-Non-Disclosure-Agreement.pdf');
const signer1 = {
emailAddress: "Jack@example.com",
name: "Jack",
order: 0
};
const data = {
testMode: true,
files: [ yourFile ],
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1 ]
};
const result = signatureApi.signatureRequestSend(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
#### Downloading Files
Download functionality is now spread across multiple endpoints.
| Legacy SDK Version | New SDK version |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Download Files is a single endpoint and the return is configured by parameters. | Download Files spread across three endpoints
- [Download Files](/api/signature-request/files)
- [Download Files as Data Uri](/api/signature-request/files-as-data-uri)
- [Download Files as File UR](/api/signature-request/files-as-file-url)
|
```javascript Legacy SDK - Download Files
var signature_request_id = 'SIGNATURE_REQUEST_ID'
hellosign.signatureRequest.download(signature_request_id, {file_type: 'zip'}, function(err, response) {
var file = fs.createWriteStream("files.zip");
response.pipe(file);
file.on('finish', function() {
file.close();
});
});
```
```javascript New SDK - Download Files
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const signatureRequestId = "SIGNATURE_REQUEST_ID";
const result = signatureApi.signatureRequestFiles(signatureRequestId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript Legacy SDK - Download Files as Data URI
var signature_request_id = 'SIGNATURE_REQUEST_ID'
hellosign.signatureRequest.download('SIGNATURE_REQUEST_ID', { get_data_uri: true }, (err, res) => {
console.log(res)
});
```
```javascript New SDK - Download Files as Data URI
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const signatureRequestId = "SIGNATURE_REQUEST_ID";
const result = signatureApi.signatureRequestFilesAsDataUri(signatureRequestId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript Legacy SDK - Download Files as File URL
var signature_request_id = 'SIGNATURE_REQUEST_ID'
hellosign.signatureRequest.download('SIGNATURE_REQUEST_ID', { get_url: true }, (err, res) => {
console.log(res)
});
```
```javascript New SDK - Download Files as File URL
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = "YOUR_API_KEY";
const signatureRequestId = "SIGNATURE_REQUEST_ID";
const result = signatureApi.signatureRequestFilesAsFileUrl(signatureRequestId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
**Downloading Templates**
```javascript New SDK - Download Template Files
import * as DropboxSign from "@dropbox/sign";
import * as fs from 'fs';
const templateApi = new DropboxSign.TemplateApi();
// Configure HTTP basic authorization: api_key
templateApi.username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// templateApi.accessToken = "YOUR_ACCESS_TOKEN";
const templateId = "5de8179668f2033afac48da1868d0093bf133266";
const fileType = "pdf";
const result = templateApi.templateFiles(templateId, fileType);
result.then(response => {
fs.createWriteStream('file_response.pdf').write(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - Template File as Data Uri
import * as DropboxSign from "@dropbox/sign";
const templateApi = new DropboxSign.TemplateApi();
// Configure HTTP basic authorization: api_key
templateApi.username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// templateApi.accessToken = "YOUR_ACCESS_TOKEN";
const templateId = "5de8179668f2033afac48da1868d0093bf133266";
const result = templateApi.templateFilesAsDataUri(templateId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
```javascript New SDK - Template File as File Url
import * as DropboxSign from "@dropbox/sign";
const templateApi = new DropboxSign.TemplateApi();
// Configure HTTP basic authorization: api_key
templateApi.username = "YOUR_API_KEY";
// or, configure Bearer authorization: oauth2
// templateApi.accessToken = "YOUR_ACCESS_TOKEN";
const templateId = "5de8179668f2033afac48da1868d0093bf133266";
const result = templateApi.templateFilesAsFileUrl(templateId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
## Endpoint Mapping
This section shows you how endpoints in the legacy SDK map to the new SDK. It doesn't cover all endpoints, but gives you an idea of mapping implementations between the two SDKs. Please [reach out](https://faq.hellosign.com/hc/en-us/requests/new) if you think we're missing an important example.
* [Get Account](#get-account)
* [Get Signature Request](#get-signature-request)
* [Send Signature Request](#send-signature-request)
* [Create Embedded with Template](#create-embedded-with-template)
* [Update API App](#update-api-app)
### Get Account
```javascript Legacy SDK - Get Account
const hellosign = require('hellosign-sdk')({ key: process.env.HelloSign_API_KEY });
hellosign.account.get().then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
```
```javascript New SDK - Get Account
import * as DropboxSign from "@dropbox/sign";
const accountApi = new DropboxSign.AccountApi();
accountApi.username = "YOUR_API_KEY";
const result = accountApi.accountGet();
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Get Signature Request
```javascript Legacy SDK - Get Signature Request
const hellosign = require('hellosign-sdk')({ key: 'HelloSign_API_KEY' });
hellosign.signatureRequest.get(SIGNATURE_REQUEST_ID).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
```
```javascript New SDK - Get Signature Request
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = 'YOUR_API_KEY';
const signatureRequestId = "SIGNATURE_REQUEST_ID";
const result = signatureApi.signatureRequestGet(signatureRequestId);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Send Signature Request
```javascript Legacy SDK - Send Signature Request
const hellosign = require('hellosign-sdk')({ key: 'HelloSign_API_KEY' });
var signers = [
{
email_address : 'jack@example.com',
name : 'Jack',
order : 0,
},
{
email_address : 'jill@example.com',
name : 'Jill',
order : 1,
}
]
var options = {
test_mode : 1,
title : 'NDA with Acme Co.',
subject : 'The NDA we talked about',
message : 'Please sign this NDA and then we can discuss more. Let me know if you have any questions.',
signers : signers,
cc_email_addresses : ['lawyer@example.com', 'lawyer2@example.com'],
files : ['./Demo-Mutual-Non-Disclosure-Agreement.pdf'],
metadata : {
clientId : '1234',
custom_text : 'NDA #9'
}
};
hellosign.signatureRequest.send(options)
.then(function(res){
console.log(res.signature_request);
});
```
```javascript New SDK - Send Signature Request
import * as DropboxSign from "@dropbox/sign";
const fs = require('fs');
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = 'YOUR_API_KEY';
const myFile = fs.createReadStream('./Demo-Mutual-Non-Disclosure-Agreement.pdf');
const signer1 = {
emailAddress: "jack@example.com",
name: "Jack",
order: 0,
};
const signer2 = {
emailAddress: "jill@example.com",
name: "Jill",
order: 1,
};
const data = {
testMode: true,
title: "NDA with Acme Co.",
subject: "The NDA we talked about",
message: "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
signers: [ signer1, signer2 ],
ccEmailAddresses: [
"austin.hs.demo@gmail.com",
"dbxsign.test@gmail.com",
],
files: [myFile],
metadata: {
"custom_id": 1234,
"custom_text": "NDA #9",
}
};
const result = signatureApi.signatureRequestSend(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Create Embedded with Template
```javascript Legacy SDK - Create Embedded with Template
const hellosign = require('hellosign-sdk')({ key: 'HelloSign_API_KEY' });
var options = {
test_mode : 1,
clientId : 'CLIENT_ID',
template_id : 'TEMPLATE_ID',
subject : 'Purchase Order',
message : 'Glad we could come to an agreement.',
signers : [
{
role : 'Client',
email_address : 'george@example.com',
name : 'George',
}
]
};
hellosign.signatureRequest.createEmbeddedWithTemplate(options);
.then(function(res){
console.log(res.signature_request);
});
```
```javascript New SDK - Create Embedded with Template
import * as DropboxSign from "@dropbox/sign";
const signatureApi = new DropboxSign.SignatureRequestApi();
signatureApi.username = 'YOUR_API_KEY';
const signer1 = {
role: "Client",
emailAddress: "george@example.com",
name: "George",
};
const data = {
testMode: true,
clientId: "CLIENT_ID",
templateIds: ["TEMPLATE_ID"],
subject: "Purchase Order",
message: "Glad we could come to an agreement.",
signers: [ signer1 ]
};
const result = signatureApi.signatureRequestCreateEmbeddedWithTemplate(data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
### Update API App
```javascript Legacy SDK - Update API App
const opts = {
name: 'My Cool App',
white_labeling_options: '{"primary_button_color":"#ff0000","primary_button_text_color":"#000000"}'
};
hellosign.apiApp.update('CLIENT_ID', opts).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
```
```javascript New SDK - Update API App
import * as DropboxSign from "@dropbox/sign";
const apiAppApi = new DropboxSign.ApiAppApi();
apiAppApi.username = "YOUR_API_KEY";
const whiteLabelingOptions = {
primaryButtonColor: "#00b3e6",
primaryButtonTextColor: "#ffffff",
};
const data = {
whiteLabelingOptions,
};
const clientId = "CLIENT_ID";
const result = apiAppApi.apiAppUpdate(clientId, data);
result.then(response => {
console.log(response.body);
}).catch(error => {
console.log("Exception when calling Dropbox Sign API:");
console.log(error.body);
});
```
***
## Supporting Legacy SDKs
***
## Feedback and Assistance