
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
notarize-node-client
Advanced tools
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.
# with npm
$ npm install notarize-node-client
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.
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.
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 sentwebhookHeader - the header to be sent on each of the calls for
authentication, or validation by the receiver.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.
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"
}
}
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"
}
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"
}
]
}
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"
}
}
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"
}
}
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 })
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"
}
}
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
}
}
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.
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"
}
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')
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'
})
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"
}
}
}
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'
)
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"
}
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
}
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
}
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.
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
pageNOTARIZE_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.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.
FAQs
Node.js Client for Notarize.com Business API
The npm package notarize-node-client receives a total of 1 weekly downloads. As such, notarize-node-client popularity was classified as not popular.
We found that notarize-node-client demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.