npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

notarize-node-client

v0.1.6

Published

Node.js Client for Notarize.com Business API

Downloads

1,046

Readme

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": "[email protected]",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
    },
    "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: '[email protected]' },
  ],
})

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": "[email protected]",
      "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": "[email protected]",
        "firstName": "Miguel",
        "lastName": "Lee",
        "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
      },
      "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": "[email protected]",
        "firstName": "Miguel",
        "lastName": "Lee",
        "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
      },
      "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": "[email protected]",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
    },
    "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": "[email protected]",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
    },
    "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": "[email protected]",
      "firstName": "Miguel",
      "lastName": "Lee",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]"
    },
    "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": "[email protected]",
      "firstName": "Testy",
      "lastName": "McTesterson",
      "transactionAccessLink": "https://app.notarize.com/activate-transaction?bundle_id=some-bundle-id&code=some-code&[email protected]",
      "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": "[email protected]",
      "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.