notarize-node-client
TypeScript icon, indicating that this package has built-in type declarations

0.1.6 • Public • Published

notarize-node-client

notarize-node-client is a Node/JS and TypeScript Client for Notarize.com that allows you to use normal Node syntax to start notarizations - as opposed to writing a client based on the REST endpoints documented on the Notarize.com Developer portal.

Install

# with npm
$ npm install notarize-node-client

Usage

This README isn't going to cover all the specifics of what Notarize.com is, and how to use it - it's targeted as a companion to the Notarize developer docs that explain each of the endpoints and how the general Notarize workflow works.

However, we'll put in plenty of examples so that it's clear how to use this library to interact with Notarize.com.

Getting your API Key

As documented on the Notarize.com site, the first step is getting an API Key for the calls to Notarize.com. This is available on their API Keys page, once you login. For the rest of this document, the API Key will be seen as: [Your API Key], and will need to be replaced with the API Key you obtain from the site.

Creating the Client

All Notarize functions are available from the client, and the basic construction of the client is:

import { Notarize } from 'notarize-node-client'
const client = new Notarize('[Your API Key]')

If you'd like to provide the webhook URL in the constructor, you can do that with:

const client = new Notarize(
  '[Your API Key]',
  {
    webhookUrl: 'https://my.service.com/notarize/callback'
  }
)

where the options can include:

  • webhookUrl - the URL for all Notarize updates to be sent
  • webhookHeader - the header to be sent on each of the calls for authentication, or validation by the receiver.

Document Calls

Get a Document

const doc = await client.document.get(id, transactionId)

This will get the document with id, in the transaction with transactionId and return that data. The response will be something like:

{
  "success": true,
  "document": {
    "id": "do_9f7b097a-6469-41dc-86b9-c7aa9743cfc4",
    "dateCreated": "2021-03-26T19:57:37.946749Z",
    "dateUpdated": "2021-03-26T19:57:39.216662Z",
    "documentName": "dummy.pdf",
    "allowedActions": [
      "CUSTOMER_CAN_ANNOTATE",
      "ESIGN_REQUIRED"
    ],
    "bundlePosition": 2,
    "isEnote": false,
    "trackingId": null,
    "signedUrl": null,
    "processingState": "done",
    "processingError": null,
    "permissions": [
      "CUSTOMER_CAN_ANNOTATE",
      "ESIGN_REQUIRED"
    ],
    "signingDesignations": [],
    "signingType": "NOTARIZATION",
    "data": "...BASE64STRING..."
  }
}

If there had been an error, the response would be:

{
  "success": false,
  "errors": [ "(Error message from Notarize.com...)" ]
}

So looking at the success value of the response will quickly let you know the outcome of the call.

Update a Document

const doc = await client.document.update(id, opts)

where opts is an Object with one or more of these optional properties:

{
  name?: string;
  trackingId?: string;
  customerCanAnnotate?: boolean;
  notarizationRequired?: boolean;
  identityConfirmationRequired?: boolean;
  witnessRequired?: boolean;
  authorizationHeader?: string;
}

This will update the document with id, assuming the transaction it's in is still draft. The response will be something like:

{
  "success": true,
  "document": {
    "id": "do_29f983a4-8485-4afb-8343-95996f75c2d5",
    "date_created": "2017-05-10T13:10:20.702098Z",
    "date_updated": "2017-05-10T13:10:20.702098Z",
    "document_name": "document.pdf",
    "allowed_actions": ["CUSTOMER_CAN_ANNOTATE"],
    "bundle_position": 1,
    "processing_state": "pending"
  }
}

Delete a Document

const doc = await client.document.delete(id)

This will delete the document with id from the transaction it's in, assuming the transaction is still draft. The response will be something like:

{
  "success": true,
  "message": "Deleted Document abcdefghijk successfully"
}

Template Calls

List Templates

const trans = await client.template.list()

This will get the document with id, in the transaction with transactionId and return that data. The response will be something like:

{
  "success": true,
  "totalCount": 2,
  "templates": [
    {
      "id": "od6nzpx5n",
      "name": "Test Template",
      "permalink": "my_first_template",
      "createdAt": "2017-05-09T16:46:39.767123Z",
      "updatedAt": "2017-05-09T16:46:39.767123Z"
    },
    {
      "id": "od8zzpx7z",
      "name": "Another Template",
      "permalink": "my_favorite_template",
      "createdAt": "2017-05-09T16:46:39.767123Z",
      "updatedAt": "2017-05-09T16:46:39.767123Z"
    }
  ]
}

Transaction Calls

Retrieve Transaction

const trans = await client.transaction.retrieve(id)

This will get the transaction with id and the response will be something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "dateCreated": "2016-10-01T18:52:44.725Z",
    "dateUpdated": "2016-10-02T20:13:54.245Z",
    "signerInfo": {
      "email": "miguel.lee@notarize.com",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
    },
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2017-05-09T17:09:52.248711Z",
      "dateUpdated": "2017-05-09T17:09:52.248711Z",
      "documentName": "document.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0,
      "processingState": "done",
      "finalDocumentUrl": "https://s3-us-west-2.amazonaws.com/assets.notarize.com/document.pdf?AWSAccessKeyId=AKIAJVT3IPSNH662QU6A&Expires=1449430428&Signature=j%2FTzUuHJkrlbAJZGNpCm3xfxgmE%3D"
    }],
    "transactionName": "Miguel's TPS notarization for Leeroy.",
    "transactionType": "Power of Attorney",
    "detailedStatus": "started",
    "messageToSigner": "Please notarize your TPS Report.",
    "messageSignature": "Love, Leeroy.",
    "status": "created",
    "requireSecondaryPhotoId": false,
    "detailedStatus": "complete",
    "auditTrailUrl": "https://463675841562-notarize-productionmirror-documents.s3.amazonaws.com/a6d9272144840dd05b49_AuditTrail.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAITYYWRHD2HZKXQ%2F20210211%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210211T161632Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=cdd0b69d3017e8296936d0207c8aa376a"
  }
}

Create Transaction

const trans = await client.transaction.create({
  draft: true,
  transactionName: 'Power of Attorney - Signer Smith',
  transactionType: 'Power of Attorney',
  documents: [
    {
      resource: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
      requirement: 'notarization',
      customerCanAnnotate: false
    },
    {
      resource: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
      requirement: 'notarization',
      customerCanAnnotate: true
    }
  ],
  signers: [
    { email: 'signer@notarize.com' },
  ],
})

This will create the transaction, starting in the draft mode so that documents can be added, and then the transaction can be activated. The response will be something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "status": "draft",
    "dateCreated": "2019-10-01T18:52:44.725Z",
    "dateUpdated": "2019-10-02T20:13:54.245Z",
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2019-10-02T17:09:52.248711Z",
      "dateUpdated": "2019-10-02T17:09:52.248711Z",
      "documentName": "document.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0,
      "processingState": "pending"
    }],
    "signers": [{
      "email": "signer@notarize.com",
      "firstName": "Signer",
      "lastName": "Smith",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?1234"
    }],
    "transactionName": "Power of Attorney - Signer Smith",
    "transactionType": "Power of Attorney",
    "detailedStatus": "started",
    "messageToSigner": "Please notarize this power of attorney form.",
    "messageSignature": "The Team"
  }
}

List Transactions

const lst = await client.transaction.list()

This will list up to 10 transactions with the response:

{
  "success": true,
  "count": 2,
  "transactions":  [
    {
      "id": "ot_anpr8qn",
      "dateCreated": "2016-10-01T18:52:44.725Z",
      "dateUpdated": "2016-10-02T20:13:54.245Z",
      "signerInfo": {
        "email": "miguel.lee@notarize.com",
        "firstName": "Miguel",
        "lastName": "Lee",
        "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
      },
      "documents": [{
        "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
        "dateCreated": "2017-05-09T17:09:52.248711Z",
        "dateUpdated": "2017-05-09T17:09:52.248711Z",
        "documentName": "document.pdf",
        "allowedActions": ["NOTARIZATION_REQUIRED"],
        "bundlePosition": 0
      }],
      "transactionName": "Miguel's TPS notarization for Leeroy.",
      "transactionType": "Power of Attorney",
      "messageToSigner": "Please notarize your TPS Report.",
      "status": "sent",
      "requireSecondaryPhotoId": false
    },
    {
      "id": "ot_anpr8qn",
      "dateCreated": "2016-10-01T18:52:44.725Z",
      "dateUpdated": "2016-10-02T20:13:54.245Z",
      "signerInfo": {
        "email": "miguel.lee@notarize.com",
        "firstName": "Miguel",
        "lastName": "Lee",
        "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
      },
      "documents": [{
        "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
        "dateCreated": "2017-05-09T17:09:52.248711Z",
        "dateUpdated": "2017-05-09T17:09:52.248711Z",
        "documentName": "pdf.pdf",
        "allowedActions": ["NOTARIZATION_REQUIRED"],
        "bundlePosition": 0
      }, {
        "id": "do_d46a3751-399f-4149-b7b2-d46aea498011",
        "dateCreated": "2017-05-09T17:09:52.872688Z",
        "dateUpdated": "2017-05-09T17:09:52.872688Z",
        "documentName": "pdf-sample.pdf",
        "allowedActions": ["NOTARIZATION_REQUIRED"],
        "bundlePosition": 1
      }],
      "transactionName": "Miguel's TPS notarization for Leeroy.",
      "transactionType": "Power of Attorney",
      "detailedStatus": "started",
      "messageToSigner": "Please notarize your TPS Report.",
      "messageSignature": "Love, Leeroy.",
      "status": "sent",
      "requireSecondaryPhotoId": false
    }
  ],
}

Yet this function also takes options:

const lst = await client.transaction.list(opts)

where the options can be:

{
  limit?: number;
  offset?: number;
}

So, to get the first 100, simply call:

const lst = await client.transaction.list({ limit: 100 })

Add Document

const doc = await client.transaction.addDocument(id, {
  resource: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
  requirement: 'esign',
  customer_CanAnnotate: true
})

where id is the id of a transaction to add the document to, and this will return something like:

{
  "success": true,
  "document": {
    "id": "do_29f983a4-8485-4afb-8343-95996f75c2d5",
    "dateCreated": "2019-05-10T13:10:20.702098Z",
    "dateUpdated": "2019-05-10T13:10:20.702098Z",
    "documentName": "document.pdf",
    "allowedActions": ["ESIGN_REQUIRED","CUSTOMER_CAN_ANNOTATE"],
    "bundlePosition": 1,
    "processingState": "pending"
  }
}

Update Draft Transaction

const trans = await client.transaction.update(id, {
  allowSignerAnnotations: false,
  requireSecondaryPhotoId: false,
  suppressEmail: false
})

where id is the id of a transaction to update, and this will return something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "dateCreated": "2016-10-01T18:52:44.725Z",
    "dateUpdated": "2016-10-02T20:13:54.245Z",
    "signerInfo": {
      "email": "miguel.lee@notarize.com",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
    },
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2017-05-09T17:09:52.248711Z",
      "dateUpdated": "2017-05-09T17:09:52.248711Z",
      "documentName": "document.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0
    }],
    "transactionName": "Miguel's TPS notarization for Leeroy",
    "transactionType": "Power of Attorney",
    "messageToSigner": "Please notarize your TPS Report.",
    "messageSignature": "Love, Leeroy.",
    "status": "sent",
    "detailedStatus": "started",
    "requireSecondary_photo_id": false
  }
}

Activate Draft Transaction

const trans = await client.transaction.activate(id)

where id is the id of a transaction to activate, and this will return something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "dateCreated": "2016-10-01T18:52:44.725Z",
    "dateUpdated": "2016-10-02T20:13:54.245Z",
    "signerInfo": {
      "email": "miguel.lee@notarize.com",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
    },
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2017-05-09T17:09:52.248711Z",
      "dateUpdated": "2017-05-09T17:09:52.248711Z",
      "documentName": "pdf.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0
    }, {
      "id": "do_d46a3751-399f-4149-b7b2-d46aea498011",
      "dateCreated": "2017-05-09T17:09:52.872688Z",
      "dateUpdated": "2017-05-09T17:09:52.872688Z",
      "documentName": "pdf-sample.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 1
    }],
    "transactionName": "Miguel's TPS notarization for Leeroy.",
    "transactionType": "Power of Attorney",
    "detailedStatus": "sent_to_signer",
    "messageToSigner": "Please notarize your TPS Report.",
    "messageSignature": "Love, Leeroy.",
    "status": "sent",
    "requireSecondaryPhotoId": false
  }
}

If you'd like to update the suppressEmail flag on the transaction, that's done with the optional argument on the call:

const trans = await client.transaction.activate(id, false)

will indicating that suppressEmail should be set to false.

Delete Transaction

const resp = await client.transaction.delete(id)

where id is the id of a transaction to delete, and this will return something like:

{
  "success": true,
  "message": "Deleted Transaction abcdefghijk successfully"
}

Resend Transaction Email

const trans = await client.transaction.resendEmail(id)

where id is the id of a transaction to resend the email(s) for, and this will return something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "dateCreated": "2016-10-01T18:52:44.725Z",
    "dateUpdated": "2016-10-02T20:13:54.245Z",
    "signerInfo": {
      "email": "miguel.lee@notarize.com",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com"
    },
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2017-05-09T17:09:52.248711Z",
      "dateUpdated": "2017-05-09T17:09:52.248711Z",
      "documentName": "document.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0
    }],
    "transactionName": "Miguel's TPS notarization for Leeroy.",
    "transactionType": "Power of Attorney",
    "detailedStatus": "started",
    "messageToSigner": "Please notarize your TPS Report.",
    "messageSignature": "Love, Leeroy.",
    "status": "sent",
    "requireSecondaryPhotoId": false
  }
}

This function also allows the messageToSender to be passed-into the call as an optional parameter:

const trans = await client.transaction.resendEmail(id, 'Second email message')

Resend Transaction SMS

const trans = await client.transaction.resendSms(id)

where id is the id of a transaction to resend the SMS message(s) for, and this will return something like:

{
  "success": true,
  "transaction": {
    "id": "ot_anpr8qn",
    "dateCreated": "2016-10-01T18:52:44.725Z",
    "dateUpdated": "2016-10-02T20:13:54.245Z",
    "signerInfo": {
      "email": "testerson@notarize.com",
      "firstName": "Testy",
      "lastName": "McTesterson",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&email=some@email.com",
      "phone": {
        "countryCode": "1",
        "number": "5555555555"
      }
    },
    "documents": [{
      "id": "do_c7e0e599-5e94-4ac1-a4a3-7e09f9994934",
      "dateCreated": "2017-05-09T17:09:52.248711Z",
      "dateUpdated": "2017-05-09T17:09:52.248711Z",
      "documentName": "document.pdf",
      "allowedActions": ["NOTARIZATION_REQUIRED"],
      "bundlePosition": 0
    }],
    "transactionName": "Miguel's TPS notarization for Leeroy.",
    "transactionType": "Power of Attorney",
    "detailedStatus": "started",
    "messageToSigner": "Please notarize your TPS Report.",
    "messageSignature": "Love, Leeroy.",
    "status": "sent",
    "requireSecondaryPhotoId": false
  }
}

This function also allows the phone to be passed-into the call as an optional parameter:

const trans = await client.transaction.resendSms(id, {
  countryCode: '1',
  number: '515-555-5555'
})

Retrieve Meeting Record

const rec = await client.transaction.retrieveMeetingRecord(id)

where id is the id of a transaction to pull the meeting record for, and this will return something like:

{
  "success": true,
  "record": {
    "id": "me_rnykzyn",
    "meetingStart": "2016-10-01T18:52:44.725Z",
    "meetingEnd": "2016-10-01T18:58:54.245Z",
    "notaryName": "Leeroy Jenkins",
    "notaryRegistration": "1337",
    "signerInfo": {
      "email": "miguel.lee@notarize.com",
      "firstName": "Miguel",
      "lastName": "Lee"
    },
    "notarizedDocuments": [{
      "notarialActs": [
        "jurat",
        "verification_of_fact"
      ],
      "documentUrl": "https://s3-us-west-2.amazonaws.com/assets.notarize.com/document.pdf?AWSAccessKeyId=AKIAJVT3IPSNH662QU6A&Expires=1449430428&Signature=j%2FTzUuHJkrlbAJZGNpCm3xfxgmE%3D"
    }],
    "verificationCredentials": {
      "retrievalId": "CTJHT32H",
      "retrievalPin": "7RNTNN",
      "lastName": "Lee",
      "dateCompleted": "10/19/2016"
    },
    "signerPhotoIdentification": {
      "primaryFront": "https://s3-us-west-2.amazonaws.com/assets.notarize.com/primary_front.png?AWSAccessKeyId=AKIAJVT3IPSNH662QU6A&Expires=1449430428&Signature=j%2FTzUuHJkrlbAJZGNpCm3xfxgmE%3D",
      "primaryBack": "https://s3-us-west-2.amazonaws.com/assets.notarize.com/primary_back.png?AWSAccessKeyId=AKIAJVT3IPSNH662QU6A&Expires=1449430428&Signature=j%2FTzUuHJkrlbAJZGNpCm3xfxgmE%3D",
      "secondaryFront": "https://s3-us-west-2.amazonaws.com/assets.notarize.com/primary_back.png?AWSAccessKeyId=AKIAJVT3IPSNH662QU6A&Expires=1449430428&Signature=j%2FTzUuHJkrlbAJZGNpCm3xfxgmE%3D"
    }
  }
}

Webhook Calls

Set/Update Webhook URL

const hook = await client.webhook.update('https://my.service.com/esign/callback')

This will set, or update, the webhook URL for all subsequent calls by Notarize.com - until the webhook is deleted, or changed to something else. The response will be something like:

{
  "success": true,
  "webhookUrl": "https://my.service.com/esign/callback",
  "header": ""
}

It's also possible to set the header to be returned on each webhook call, by including it as the second, optional, parameter to the call:

const hook = await client.webhook.update(
  'https://my.service.com/esign/callback',
  'MyHeaderName:mySecretValue'
)

Retrieve Webhook URL

const hook = await client.webhook.retrieve()

This will return the webhook URL for calls by Notarize.com - until the webhook is deleted, or changed to something else. The response will be something like:

{
  "success": true,
  "webhookUrl": "https://my.service.com/esign/callback"
}

Delete Webhook URL

const hook = await client.webhook.delete()

This will delete (clear) the webhook URL for any subsequent calls by Notarize.com - until the webhook is set. The response will be something like:

{
  "success": true
}

Simulate Webhook Responses

const hook = await client.webhook.simulateResponses({
  "event": "transaction_status_update",
  "data": {
    "transactionId": "jhkjhkjh",
    "status": "received"
  }
})

If a webhook is set, then this will send the provided data to the webhook URL for processing by your receiver code of the webhooks. This is simply a way to send test data through Notarize.com to your webhook receiver endpoint. The response will be something like:

{
  "success": true
}

Development

For those interested in working on the library, there are a few things that will make that job a little simpler. The organization of the code is all in src/, with one module per section of the Client: document, template, etc. This makes location of the function very easy.

Additionally, the main communication with the Notarize service is in the src/index.ts module in the fire() function. In the constructor for the Client, each of the sections are created, and then they link back to the main class for their communication work.

Setup

In order to work with the code, the development dependencies include dotenv so that each user can create a .env file with two values for working with Notarize.com:

  • NOTARIZE_API_KEY - this is the API Key referred to, above, and can be created on the Notarize website's API Keys page
  • NOTARIZE_TEST_EMAIL - this is your email, or a test email, that will be used in all the tests in tests/ so that you can easily control the destionation for the emails.

Testing

There are several test scripts that create, test, and tear-down, state on the Notarize.com service exercising different parts of the API. Each is self-contained, and can be run with:

$ npm run ts tests/update-transaction.ts
creating a new transaction...
Success!
updating the new transaction...
Success!
retrieving the updated transaction...
Success!
deleting the new transaction...
Success!

Each of the tests will run a series of calls through the Client, and check the results to see that the operation succeeded. As shown, if the steps all report back with Success! then things are working.

If there is an issue with one of the calls, then an Error! will be printed out, and the data returned from the client will be dumped to the console.

Package Sidebar

Install

npm i notarize-node-client

Weekly Downloads

131

Version

0.1.6

License

MIT

Unpacked Size

135 kB

Total Files

23

Last publish

Collaborators

  • senorflor
  • drbobbeaty