Signhost.com is a service that makes it possible to digitally sign, seal or deliver your documents. Documents can be signed directly from your Betty Blocks app or by sending a signing request by email or other message to the end-user.
In some countries Signhost is branded by a local domain, like ondertekenen.nl in The Netherlands. This means instead of signhost.com, you can also use one of these local domains.

In this article we'll show you how to connect with them by using their REST API. The REST API is the underlying interface for all official Signhost API methods. It’s the most direct way to access the API. 

Let's start off by taking a look at Signhost's documentation: Signhost API

The Basics

The Signhost API is RESTful and HTTP-based. Basically, this means that the communication is made through normal HTTP requests. Signing a document is done through a so-called 'transaction'.

Required steps to create a transaction:

  1. Create a new transaction with POST api/transaction.
  2. Optionally you can add metadata to generate fields with PUT api/transaction/{transactionId}/file/{fileId}. You have to submit the metadata first before you upload the file. Make sure you use the same fileId  for both the metadata and the file.
  3. Upload the documents you want to be signed by performing a PUT api/transaction/{transactionId}/file/{fileId}. Repeat for each file.
  4. Finally start the transaction with PUT api/transaction/{transactionId}/start.

Laying the foundation

Start off by creating the Webservice in your application. Go to Webservices in your application and click New in the top-left corner. Add the following values:

  • Name: Signhost API
  • Protocol: HTTPS
  • Host: api.signhost.com/api/
  • Authentication Type: None
  • Request Content-Type: JSON
  • Response Content-Type: JSON
  • Headers: Authorization and Application
  • Help text: -

It's important to set the Response Content-Type to JSON, as it enables us to create a Custom model for the response. Leave the header variables empty for now, we'll discuss that in the next chapter.

That should have your Webservice looking like:

The Authentication

It is required to authenticate yourself with each request you want to do. This is done by including (at least) 2 headers in your Webservice: Authorization and Application.
How convenient, as we already added 2 header variables to our webservice. Now we just need to fill them with the required values.
How to get these values can be found here.

With the headers in place, it should look like this:

Now we can move on to creating some endpoints!

Different operations explained

The Webservice we created above serves as a base for each request we will be executing. The actual request, which operations we're performing, is defined in the webservice's endpoints. Each operation gets its own endpoint. In this article we will be showing the following operations:

For exact information about the different requests, take a look at the documentation provided by Signhost. This will focus on how to apply these operations in a Betty Blocks application.

Create a transaction (POST /api/transaction)

This request can be used to create a new transaction. A template has to be used when executing the request to determine which 'Signers' the transaction are destined for. More information can be found here: 

  • Name: Create transaction
  • Http method: POST
  • Path: "/transaction"
  • Request Content-Type: [inherit]
  • Response Content-Type: [inherit]
  • Template: - New -

Save the endpoint and open the newly created template. Rename it Signhost: Create transaction and build the template. See Definitions for all possible options included in your templates. For this example, we'll use the following data:

Template

{
 "Signers": [
{
 "Email": "johndoe@bettyblocks.com",
 "RequireScribble": true,
 "SendSignRequest": true,
 "SignRequestMessage": "Hello, could you please sign this document? Best regards, Jane Doe",
 "DaysToRemind": 15,
 "ScribbleName": "John Doe",
 "ScribbleNameFixed": false
}
],
 "SendEmailNotifications": true
}

Save the template and go back to the webservice endpoint. Click Run test in the top-right corner and see how a transaction is created. The response should look something like this:

Response

{
  "Id": "d5f6aa53-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "Status": 5,
  "Files": {},
  "Seal": false,
  "Signers": [
    {
      "Id": "Signer1",
      "Expires": null,
      "Email": "johndoe@bettyblocks.com",
      "Verifications": [
        {
          "Type": "Scribble",
          "RequireHandsignature": true,
          "ScribbleNameFixed": false,
          "ScribbleName": "John Doe"
        }
      ],
      "Mobile": null,
      "Iban": null,
      "BSN": null,
      "RequireScribbleName": false,
      "RequireScribble": false,
      "RequireEmailVerification": true,
      "RequireSmsVerification": false,
      "RequireIdealVerification": false,
      "RequireDigidVerification": false,
      "RequireKennisnetVerification": false,
      "RequireSurfnetVerification": false,
      "SendSignRequest": true,
      "SendSignConfirmation": true,
      "SignRequestMessage": "Hello, could you please sign this document? Best regards, Jane Doe",
      "DaysToRemind": 15,
      "Language": "nl-NL",
      "ScribbleName": "John Doe",
      "ScribbleNameFixed": false,
      "Reference": null,
      "IntroText": null,
      "ReturnUrl": null,
      "Activities": [],
      "RejectReason": null,
      "SignUrl": "https://view.signhost.com/sign/671267b8-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "SignedDateTime": null,
      "RejectDateTime": null,
      "CreatedDateTime": "2019-02-08T09:21:26.1059732+01:00",
      "ModifiedDateTime": "2019-02-08T09:21:26.1059732+01:00",
      "Context": null
    }
  ],
  "Receivers": [],
  "Reference": null,
  "PostbackUrl": null,
  "SignRequestMode": 2,
  "DaysToExpire": 30,
  "SendEmailNotifications": true,
  "CreatedDateTime": "2019-02-08T09:21:26.1059732+01:00",
  "ModifiedDateTime": "2019-02-08T09:21:26.1059732+01:00",
  "CanceledDateTime": null,
  "Context": null
}

We highly recommend generating a custom model based on the response, as it enables you to use the response for further processing in your actions much easier! 

After creating the custom model, it's time to replace values in your template with variables. Because each time an action is started, it will process different values. The variables will be used as placeholders for the data from the record used in the action
Some examples of values to replace with variables:

  • Email: johndoe@bettyblocks.com >>> {{var:record.customer.email}} 
  • ScribbleName: John Doe >>> {{var:record.customer.name}} 
  • SignRequestMessage: ... Best regards, Jane Doe >>> ... Best regards, {{current_user.name}}

Now you can include this webservice endpoint in an action!
As seen below, we can use the response we received by selecting the new_transaction variable.

Based on the response, you can create/update a record with the new values.

Show transaction details (GET /api/transaction/{transactionId})

This request can be used to show a transaction's details. A value is required in the url to determine which transaction we are collecting the details from. This is done by including a path variable.
More information can be found here: Show transaction details

  • Name: Show transaction details
  • Http method: GET
  • Path: "/transaction/" + var:transaction_id 
  • Request Content-Type: [inherit]
  • Response Content-Type: [inherit]
  • Path variable: transaction_id (is input variable)

Save the endpoint and click Run test. If the variable was added correctly, you should be prompted to enter a value for the transaction's ID. You can use the ID from the transaction you received in the response from the Create transaction endpoint.

After entering a value and running the test, the response should look something like this:

{
  "Id": "99e599d2-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "Status": 5,
  "Files": {},
  "Seal": false,
  "Signers": [
    {
      "Id": "Signer1",
      "Expires": null,
      "Email": "johndoe@bettyblocks.com",
      "Verifications": [
        {
          "Type": "Scribble",
          "RequireHandsignature": true,
          "ScribbleNameFixed": false,
          "ScribbleName": "John Doe"
        }
      ],
      "Mobile": null,
      "Iban": null,
      "BSN": null,
      "RequireScribbleName": true,
      "RequireScribble": true,
      "RequireEmailVerification": true,
      "RequireSmsVerification": false,
      "RequireIdealVerification": false,
      "RequireDigidVerification": false,
      "RequireKennisnetVerification": false,
      "RequireSurfnetVerification": false,
      "SendSignRequest": true,
      "SendSignConfirmation": true,
      "SignRequestMessage": "Hello, could you please sign this document? Best regards, Jane Doe",
      "DaysToRemind": 15,
      "Language": "nl-NL",
      "ScribbleName": "John Doe",
      "ScribbleNameFixed": false,
      "Reference": null,
      "IntroText": null,
      "ReturnUrl": null,
      "Activities": [],
      "RejectReason": null,
      "SignUrl": "https://view.signhost.com/sign/635792a6-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "SignedDateTime": null,
      "RejectDateTime": null,
      "CreatedDateTime": "2019-02-08T12:05:50.9107909+01:00",
      "ModifiedDateTime": "2019-02-08T12:05:50.9107909+01:00",
      "Context": null
    }
  ],
  "Receivers": [],
  "Reference": null,
  "PostbackUrl": null,
  "SignRequestMode": 2,
  "DaysToExpire": 30,
  "SendEmailNotifications": true,
  "CreatedDateTime": "2019-02-08T12:05:50.9107909+01:00",
  "ModifiedDateTime": "2019-02-08T12:05:50.9107909+01:00",
  "CanceledDateTime": null,
  "Context": null
}

We highly recommend generating a custom model based on the response, as it enables you to use the response for further processing in your actions much easier! 

Now you can include this webservice endpoint in an action!
As seen below, we're using a variable from the action to pass on to the Path variable on the webservice endpoint. We can use the response we received by selecting the transaction_response variable.

Based on the response, you can create/update a record with the new values.

Add file to transaction (PUT /api/transaction/{transactionId}/file/{fileId})

This request can be used to add a file to a transaction. A template has to be used when executing the request to determine which file needs to go to which transaction. More information can be found here: Add file to transaction

  • Name: Add file to transaction
  • Http method: PUT
  • Path: "/transaction/" + var:transaction_id + "/start" 
  • Request Content-Type: Other
  • Response Content-Type: Other
  • Header variable: var:content-type (application/pdf)
  • Path variables: var:transaction_id (is input variable) and var:file_id (is input variable)
  • Template: - New -

Note: It's important to choose Other in Request Content-Type and Response Content-Type. If this is not the case, you'll receive errors, failing your action.

Save the endpoint and open the newly created template. Rename it Signhost: Add file to transaction. As content for the template, we'll use the following data:

Template

{{file}}

The variable {{file}} will be given a value in our action by creating a variable of the same name in the Http request event. We'll show you.

Create a Http request event in your action, using the webservice endpoint we just created. In this event, create a text expression variable with a read_file expression.
The read_file expression has to use the file property containing the document you want to add to the transaction. Depending on how your model/property is called, it should look like this: 

Save it and start connecting variables/properties to the path variables (transaction_id and file_id). Set a name for the Response as variable and save the event. 

If everything goes right, you should get a response like:

Start transaction (PUT /api/transaction/{transactionId}/start)

This request can be used to start a transaction. A value is required in the url to determine which transaction we are starting. This is done by including a path variable.
More information can be found here: Start transaction

  • Name: Start transaction
  • Http method: PUT
  • Path: "/transaction/" + var:transaction_id + "/file/" + var:file_id  
  • Request Content-Type: [inherit]
  • Response Content-Type: [inherit]
  • Path variables: var:transaction_id  (is input variable)

Save the endpoint and create an action that uses this endpoint in a Http request event. As seen below, we're using a variable from the action to pass on to the Path variable on the webservice endpoint. 

This endpoint won't respond with an actual message, it just sends a code back. If everything went successfully, this will be 204.
The signers of the transaction will receive a notification to sign the attached PDF.

Based on the response, you can create/update a record with the new values.

Get receipt (GET /api/file/receipt/{transactionId})

This request can be used to get the receipt of a signed transaction. A value is required in the url to determine which transaction's receipt we are collecting. This is done by including a path variable. More information can be found here: Get receipt

  • Name: Get receipt
  • Http method: GET
  • Path: "/file/receipt/" + var:transaction_id 
  • Request Content-Type: [inherit]
  • Response Content-Type: Other
  • Path variables: var:transaction_id  (is input variable)

Note: It's important to choose Other in Response Content-Type. If this is not the case, you'll receive errors, failing your action.

Save the endpoint and create an action that uses this endpoint in a Http request event. As seen below, we're using a variable from the action to pass on to the Path variable on the webservice endpoint.

This is where it gets a bit tricky. As seen above, we're receiving our response (the receipt) in the item variable, so we can select var:item in a later event. Unfortunately, we can't directly assign this response to a file property. We need to process its value in a text expression variable first.

Create a variable, select Text expression as kind and enter the following expression:

base64_decode(base64_encode(var:item))

So it looks like this:

Save the variable and assign it to a file property of your choice. In our example, we're saving the receipt on the Transaction record.

Delete transaction (DELETE /api/transaction/{transactionId})

This request can be used to delete a transaction. A value is required in the url to determine which transaction we're deleting. This is done by including a path variable.
More information can be found here: Delete transaction

  • Name: Delete transaction
  • Http method: DELETE
  • Path: "/transaction/" + var:transaction_id 
  • Request Content-Type: [inherit]
  • Response Content-Type: [inherit]
  • Path variables: var:transaction_id  (is input variable)

Save the endpoint and create an action that uses this endpoint in a Http request event. As seen below, we're using a variable from the action to pass on to the Path variable on the webservice endpoint.

The transaction won't actually be deleted, but gets a new status instead. When this request is performed, the transaction will be set to Canceled so it won't disappear from your overview. It also possible to enter a reason for cancellation. This is done by including the body variable Reason in your request.

Recap

This article is meant to show you a basic setup for implementing a Signhost integration in your Betty Blocks application. With the examples provided, you can create a flow for creating transactions, add files to them and start the transaction. After the documents have been signed, the receipts can be saved in your application. Redundant transactions can be cancelled. Further information can be found in the documentation provided by Signhost, which can be found here:
Signhost API documentation

Did this answer your question?