# 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:
  1. Optionally, to scaffold your package.json first run: ```bash npm init ```
  2. To install from NPM run: ```bash npm install @dropbox/sign ```
  1. Clone the repo locally ```bash git clone https://github.com/hellosign/dropbox-sign-node.git ```
  2. Run npm pack
  3. Move generated file (dropbox-sign-1.0.0.tgz or similar) to your project directory
  4. In the dependencies array of your package.json file, add ```json "@dropbox/sign": "file:dropbox-sign-1.0.0.tgz" ```
  5. 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
| ```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