Skip to content
v3
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Hellosign NodeJS SDK Build Status

A NodeJS / JavaScript wrapper for the HelloSign API

Installation

First time using npm? Read more about installing npm packages [here] (https://docs.npmjs.com/downloading-and-installing-packages-locally).

Install from npm:

# Optionally, to scaffold your package.json first
npm init

npm install hellosign-sdk
# Optionally, to install testing / development dependencies
cd node_modules/hellosign-sdk
npm install

Install from code:

git clone https://github.com/HelloFax/hellosign-nodejs-sdk.git
cd hellosign-nodejs-sdk
# install dependencies
npm install

Configuration

In your Node application, require hellosign-sdk (or the path to the sdk folder if not using npm) and pass authentication information to initialize it:

// Initialize using api key
var hellosign = require('hellosign-sdk')({key: 'YOUR API KEY HERE'});

OR

// Initialize using email and password
var hellosign = require('hellosign-sdk')({username: 'your_email_address', password: 'your_password'});

OR

// Initialize for embedded requests using your api key, client id, and (optionally, for OAuth) client secret
var hellosign = require('hellosign-sdk')({key: 'YOUR API KEY HERE', client_id: 'your client id', client_secret: 'your client secret'});

For initialization for Oauth app-specific calls, see the Oauth section below.

Usage

Each function in the SDK is called from your initialized hellosign object, followed by the module name, and then the method.

    hellosign.template.list();

See below for a list of modules and their associated endpoint methods.

Return values

The results of each method can be accessed either as a callback, or a promise:

Callback style responses are included as the last (or only, in the case of no others) parameter in a call:

hellosign.signatureRequest.send({/*options*/}, function(err, response){
    if (err) {
        //do something with error
    } else {
        //parse response
    }
});

Promise style access is through the when library:

hellosign.signatureRequest.send({/*options*/})
    .then(function(response){
        //parse response
    })
    .catch(function(err){
        //do something with error
    })
    .finally(function(){
        //optionally do yet another thing
    });

Returned promises are then-able, or can be returned for later resolution.

Modules

Modules in the SDK are as follows:

Account

Get current account information

hellosign.account.get()
    .then();

Update your account information

var new_callback_url = "https://www.example.com/callback"
hellosign.account.update({callback_url: new_callback_url})
    .then();

Create a new HelloSign account

var email: "new_user@example.com";

hellosign.account.create({
    email_address: email
})
.then();

Verify if an account exists (only for paid API users)

var email: "possibly_existing_user@example.com";
var account_id: '12738igfe87egqo22';

hellosign.account.verify({email_address: email,})
.then();

hellosign.account.verify({account_id: email,})
.then();

Signature Request

Get an existing Signature Request by ID

hellosign.signatureRequest.get("fa5c8a0b0f492d768749333ad6fcc214c111e967")
.then();

Get a list of your Signature Requests

hellosign.signatureRequest.list()
  .then(function(res){
    console.log(res.signature_requests);
  });

This endpoint can optionally receive the parameters page, and page_size, passed in as an options object:

hellosign.signatureRequest.list({page: 2, page_size: 15})

This endpoint can optionally be used to query and search for items such as page, title, and from passed in as an options object:

const opts = {
  page: 1,
  query: 'title:Test +title AND from:me'
}

hellosign.signatureRequest.list(opts).then((res) => {
  console.log(res);
}).catch((err) => {
  console.error(err);
});

Send a Signature Request

var signers = [
      {
        email_address : 'jack@example.com',
        name : 'Jack',
        order : 0,
        sms_phone_number: '+14155550101',
      },
      {
        email_address : 'jill@example.com',
        name : 'Jill',
        order : 1,
      }
    ]

OR

// Any of the signers is eligible to sign for the entire group.
var signerGroup = [
  {
    group: 'Authorized signatory',
    [0]: {
      name: 'Jack',
      email_address: 'jack@example.com'
    },
    [1]: {
      name: 'Jill',
      email_address: 'jill@example.com'
    }
  },
]

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,
    attachments: [
        {
          name: 'Example Name',
          instructions: 'Example instructions',
          signer_index: 1,
          required: 1,
        },
      ],        
    cc_email_addresses : ['lawyer@example.com', 'lawyer2@example.com'],
    files : ['my/docs/nda.pdf'],
    metadata : {
                  clientId : '1234',
                  custom_text : 'NDA #9'
        }
};

hellosign.signatureRequest.send(options)
      .then(function(res){
        console.log(res.signature_request);
      });

Send a Signature Request with Template

var signers = [
  {
    email_address : 'george@example.com',
    name : 'George',
    role : 'Signer'
  }
]

OR

// Any of the signers is eligible to sign for the entire group.
var signerGroup = [
  {
    role: 'Signer',
    group: 'Authorized signatory',
    [0]: {
      name: 'George',
      email_address: 'george@example.com',
    },
    [1]: {
      name: 'Gina',
      email_address: 'gina@example.com',
    }
  },
]

var options = {
   test_mode : 1,
   template_id : '7b63c2131099ef7effeb0e980e2c42005fe3405d',
   subject : 'Purchase Order',
   message : 'Glad we could come to an agreement.',
   signers : signers,
   custom_fields: [
     {
     	name: "start_date",
	value: "01/10/2016",
	editor: "Signer",
	required: true
     }
   ]
};

hellosign.signatureRequest.sendWithTemplate(options)
  .then(function(res){
    console.log(res.signature_request);
  });

Send a reminder about an outstanding signature request

var request_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967'
var email = 'thedude@abides.com'
hellosign.signatureRequest.remind(request_id,{email_address : email})
    .then(function(res){
        console.log(res.signature_request);
    });

Update an email address on a signature request

const opts = {
  signature_id: '35e3787bd2e61e496099',
  email_address: 'mary@example.com',
}

hellosign.signatureRequest.update('2f9781e1a8e2045224d808c153c2e1d3df6f8f2f', opts).then((res) => {
  console.log('what is the response?', res);
}).catch((err) => {
  console.error('what is the error?', err);
});

Download files from a signature request

var request_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967'
hellosign.signatureRequest.download(request_id, {file_type: 'zip'}, function(err, response) {
    var file = fs.createWriteStream("files.zip");
    response.pipe(file);
    file.on('finish', function() {
      file.close();
    });
});

Cancel an outstanding signature request

var request_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967';
hellosign.signatureRequest.cancel(request_id)
.then(function(response){
  console.log(response.statusCode);
  console.log(response.statusMessage);
})
.catch(function(err){
  // Handle errors
});

See below for more info on the statusCode / statusMessage properties.

Remove Signature Request Access

var request_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967';
hellosign.signatureRequest.removeAccess(request_id)
.then(function(response){
  console.log(response.statusCode);
  console.log(response.statusMessage);
})
.catch(function(err){
  // Handle errors
});

See below for more info on the statusCode / statusMessage properties.

Send an embedded signature request

var options = {
  test_mode : 1,
  clientId : '0836272d66a1b53f9822f3aa07aef704',
  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 : [
    {
      email_address : 'jack@example.com',
      name : 'Jack',
      order : 0,
      sms_phone_number: '+14155550101',
    },{
      email_address : 'jill@example.com',
      name : 'Jill',
      order : 1,
    }
  ],
  attachments: [
      {
        name: 'Example Name',
        instructions: 'Example instructions',
        signer_index: 1,
        required: 1,
      },
    ],
  cc_email_addresses : ['lawyer@example.com', 'lawyer@example2.com'],
  files : ['my/files/nda.pdf']
};

hellosign.signatureRequest.createEmbedded(options)
  .then(function(res){
    console.log(res.signature_request);
  });

Send an embedded signature request with a template

var options = {
   test_mode : 1,
   clientId : '0836272d66a1b53f9822f3aa07aef704',
   template_id : '7b63c2131099ef7effeb0e980e2c42005fe3405d',
   subject : 'Purchase Order',
   message : 'Glad we could come to an agreement.',
   signers : [
     {
       email_address : 'george@example.com',
       name : 'George',
       role : 'Signer'
     }
   ]
};

hellosign.signatureRequest.createEmbeddedWithTemplate(options);
  .then(function(res){
    console.log(res.signature_request);
  });

Release On-Hold Signature Request

var request_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967';
hellosign.signatureRequest.releaseHold(request_id)
.then(function(response){
  console.log(response);
})
.catch(function(err){
  // Handle errors
});

Embedded

Get an embedded sign URL

var signature_id = 'fa5c8a0b0f492d768749333ad6fcc214c111e967';
hellosign.embedded.getSignUrl(signature_id)
    .then();

Get an embedded template's edit URL

// GET
var template_id = '7b63c2131099ef7effeb0e980e2c42005fe3405d';
hellosign.embedded.getEditUrl(template_id)
    .then();

// POST
var template_id = '7b63c2131099ef7effeb0e980e2c42005fe3405d';

const opts = {
  test_mode: 1,
  merge_fields: [{"name":"Last Name","type":"text"}]
};
hellosign.embedded.postEditUrl(template_id, opts)
    .then();

Reports

Gives you insights into user activity and document status

Get a Report

const opts = {
  test_mode: 1,
  start_date: '09/13/2020',
  end_date: '09/20/2020',
  report_type: ['user_activity', 'document_status']
};

client.reports.get(opts).then((res) => {
  console.log('what is the response?', res);
}).catch((err) => {
  console.error('what is the error?', err);
});

OAuth

Get the user to authorize your app

You'll need to create an API app, and add OAuth support, and then use the URL provided to authorize users for your application. When you do so, you'll get a state and code value that can be used as below to get an OAuth access token.

See our OAuth 2.0 walkthrough for more details.

Get an app-specific access token

var hellosign = require('./hellosign.js')({key: 'YOUR API KEY HERE', client_id: 'your client id', client_secret: 'your client secret'});

hellosign.oauth.getToken({state : '53b02619', code : '1d0219ea3363aa67'})
    .then();

Make API calls using your OAuth token:

Use the access token to instantiate an app-specific HelloSign object:

var hellosignOauth = require('./hellosign-nodejs-sdk/lib/hellosign.js')({oauthToken: 'YOUR_ACCESS_TOKEN'});

You can then use the HelloSign object you've created with the Oauth key to perform requests with that key:

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 : [
        {
            email_address : 'jack@example.com',
            name : 'Jack',
            order : 0
        },
        {
            email_address : 'jill@example.com',
            name : 'Jill',
            order : 1
        }
    ],
    cc_email_addresses : ['lawyer@example.com', 'lawyer@example2.com'],
    files : ['nda.pdf']
};

hellosignOauth.signatureRequest.send(options)
    .then();

Refresh your OAuth token

From the HelloSign instance with your app's client_id and secret set, you can also use the refresh token you got in the first token call above to fetch a new access token for your use:

hellosign.oauth.refreshToken({refresh_token : 'YOUR_REFRESH_TOKEN'})
    .then();

Team

Get your team's information

hellosign.team.get()
    .then(function(res){
        console.log(res.team);
    });

Create a team (if you don't have one)

var team_name = 'Radion 6'
hellosign.team.create({name: team_name})
  .then(function(res){
    console.log(res.team);
  });

Update team

var newName = 'The Mr. T Team';
hellosign.team.update({name: newName})
  .then(function(res){
    console.log(res.team);
  });

Remove team

hellosign.team.destroy().then((res) => {
  console.log('what is the statusCode?', res.statusCode);
  console.log('what is the statusMessage?', res.statusMessage);
}).catch((err) => {
  console.error('what is the error?', err);
});

Add a team member

var memberEmail = 'benedict@cumberbatch.org';
hellosign.team.addMember({email_address: memberEmail})
  .then(function(res){
    console.log(res.team);
  });

Remove a team member

var memberEmail = 'benedictinemonk@cumberbatch.org';
hellosign.team.removeMember({email_address: memberEmail})
    .then(function(res){
      console.log(res.team);
    });

Template

List current templates

hellosign.template.list();
    .then(function(res){
        console.log(res.templates);
    }

Get a template by id

var template_id = '7b63c2131099ef7effeb0e980e2c42005fe3405d';
hellosign.template.get(template_id)
    .then(function(res){
        console.log(res.template);
    });

Add a team member to a template

var template_id = '7b63c2131099ef7effeb0e980e2c42005fe3405d';
var memberEmail = 'robin@batman.com'
hellosign.template.addUser(
        template_id,
        {
          email_address: memberEmail
        }
    )
    .then(function(res){
      console.log(res.template);
    });

Remove a team member from a template

var template_id = '7b63c2131099ef7effeb0e980e2c42005fe3405d';
var memberEmail = 'othersidekick@batman.com'
hellosign.template.removeUser(
        template_id,
        {
          email_address: memberEmail
        }
    )
    .then(function(res){
      console.log(res.template);
    });

Create an embedded template draft

var options = {
    test_mode: 1,
    files: ['my/files/nda.pdf'],
    title: 'embedded draft test',
    subject: 'embedded draft test',
    message: 'embedded draft test',
    signer_roles: [
        {
            name: 'Sherlock',
            order: 0
        },{
            name: 'Watson',
            order: 1
        }
    ],
    cc_roles: ['commissioner@metropolice.gov.uk']
};

var results = hellosign.template.createEmbeddedDraft(options)
    .then(function(res){
        console.log(res.template);
    });

Delete Template

hellosign.template.delete(templateId)
    .then(function(res){
        console.log(response.statusCode);
        console.log(response.statusMessage);
    })

Unclaimed Draft

Create an unclaimed draft

hellosign.unclaimedDraft.create({
        test_mode : 1,
        files : ['my/files/nda.pdf', 'other/files/secret.pdf']
        })
        .then(function(res){
            console.log(res.unclaimed_draft.claim_url);
        });

Create an embedded unclaimed draft

var options = {
    test_mode : 1,
    clientId : '0836272d66a1b53f9822f3aa07aef704',
    type : 'request_signature',
    subject : 'The NDA we talked about',
    requester_email_address : 'jack@hellosign.com',
    files : ['my/secret/lair/nda.pdf'],
    is_for_embedded_signing : 1
};

hellosign.unclaimedDraft.createEmbedded(options)
    .then(function(res){
        console.log(res.unclaimed_draft.claim_url);
    });

Create embedded unclaimed draft with template

var options = {
    test_mode: 1,
    template_id: '7b63c2131099ef7effeb0e980e2c42005fe3405d',
    title: 'embedded draft test',
    subject: 'embedded draft test',
    message: 'embedded draft test',
    signing_redirect_url: 'http://bondstreet.co.uk',
    requesting_redirect_url: 'http://met.police.uk',

    signers: [
        {
            name: 'Sherlock',
            role: 'Signer',
            email_address: 'sherlock@holmesdetective.co.uk',
            pin: 3645
        },{
            name: 'Watson',
            role: 'Assistant',
            email_address: 'watson@holmesdetective.co.uk',
            pin: 4657
        }
    ],
    attachments: [
        {
          name: 'Example Name',
          instructions: 'Example instructions',
          signer_index: 1,
          required: 1,
        },
      ],
    requester_email_address: 'mrshudson@landlady.com',
    metadata: {
        clue1: 'pink suitcase',
        clue2: 'rache...'
    }
};

hellosign.unclaimedDraft.createEmbeddedWithTemplate(options);
    .then(function(res){
        console.log(res.unclaimed_draft.claim_url);
    });

Create embedded unclaimed draft edit and resend

var options = {
    test_mode: 1,
    clientId: 'b6b8e7deaf8f0b95c029dca049356d4a2cf9710a'
};

hellosign.unclaimedDraft.editAndResend('2f9781e1a83jdja934d808c153c2e1d3df6f8f2f', opts)
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.error(err);
    });

API App

Get API App

hellosign.apiApp.get(clientId).then((res) => {
  // handle response
}).catch((err) => {
  // handle error
});

List API App

hellosign.apiApp.list().then((res) => {
  // handle response
}).catch((err) => {
  // handle error
});

Create API App

const opts = {
  name: 'My Cool App',
  domain: 'http://www.example.com',
  callback_url: 'http://www.example.com/callback',
  white_labeling_options: '{"primary_button_color":"#ff0000","primary_button_text_color":"#000000"}'
};

hellosign.apiApp.create(opts).then((res) => {
  // handle response
}).catch((err) => {
  // handle error
});

Update API App

const opts = {
  name: 'My Cool App',
  domain: 'http://www.example.com',
  white_labeling_options: '{"primary_button_color":"#ff0000","primary_button_text_color":"#000000"}'
};

hellosign.apiApp.update(clientId, opts).then((res) => {
  // handle response
}).catch((err) => {
  // handle error
});

Delete API App

hellosign.apiApp.delete(clientId).then((res) => {
  console.log('what is the statusCode?', res.statusCode);
  console.log('what is the statusMessage?', res.statusMessage);
}).catch((err) => {
  console.error('what is the error?', err);
});

Warnings

Any warnings returned from the api will be accessible on the response object returned:

hellosign.account.get()
	.then(function(res){
		console.log(res.warnings);
	});

Status codes

On any response object, you can inspect the statusCode and statusMessage properties to get HTTP status information.

This is especially useful for endpoints that don't return any JSON information, like cancel:

hellosign.signatureRequest.cancel('fa5c8a0b0a492d768749333ad6fcc214c111e967')
.then(function(response){
  console.log(response.statusCode);
  console.log(response.statusMessage);
});

Tests

Unit tests can be run simply by executing:

npm test

Mocked functional tests are coming soon. Look inside the repo for a sneak peak.

Additional notes

Local callbacks

We do not allow app callbacks (event or OAuth) to be set to localhost. However it is still possible to test callbacks against a local server. Tunneling services such as ngrok (http://ngrok.com) can help you set this up.

License

The MIT License (MIT)

Copyright (C) 2020 hellosign.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.