Skip to content
On this page

Public Key & Signature Verification

Creating Your Key Pair

Request

javascript
const FORMS_API_BASE_URL = 'https://api.visiontree.com/v1'
const TENANT_ID = '1'
const AUTH_TOKEN = 'Your_Auth_Token'
const options = {
  headers: {
    Authorization: `Bearer ${AUTH_TOKEN}`,
  },
}

axios
  .post(
    `${FORMS_API_BASE_URL}/tenant/${TENANT_ID}/webhook-public-key`,
    null,
    options
  )
  .then((res) => console.log(res.data))

Response

javascript
{
  id: 'e15f83b7-1686-464e-b0a9-c09cc7b24835',
  tenantId: '1',
  publicKey: 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQWFoa2k4VVUvUW9vYm9JR1BXZnhRODdQUE1WRDA5Y3czKzFVODJHNElxRkE9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=',
  createdOn: '2023-12-07T13:05:08.682Z',
  updatedOn: '2023-12-07T13:05:08.682Z'
}

Retrieving Your Public Key

Request

javascript
const FORMS_API_BASE_URL = 'https://api.visiontree.com/v1'
const TENANT_ID = '1'
const AUTH_TOKEN = 'Your_Auth_Token'
const options = {
  headers: {
    Authorization: `Bearer ${AUTH_TOKEN}`,
  },
}

axios
  .get(`${FORMS_API_BASE_URL}/tenant/${TENANT_ID}/webhook-public-key`, options)
  .then((res) => console.log(res.data))

Response

javascript
{
  id: 'e15f83b7-1686-464e-b0a9-c09cc7b24835',
  tenantId: '1',
  publicKey: 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQWFoa2k4VVUvUW9vYm9JR1BXZnhRODdQUE1WRDA5Y3czKzFVODJHNElxRkE9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=',
  createdOn: '2023-12-07T13:05:08.682Z',
  updatedOn: '2023-12-07T13:05:08.682Z'
}

Public Key Request & Response

Request

We will discuss the request line-for-line next. First, we made use of the axios library to simplify promise-based HTTP requests. You may use any HTTP library of your choosing. The following three lines set our base Forms API URL, our Tenant ID as well as our Auth Token previously retrieved. The Tenant ID here will be used to retrieve your tenant's public key for securing your webhook with Forms API.

Next, we have a GET request which will return the public key for your Tenant ID.

Response

The request's response contains your Tenant ID's public key, which will be used to verify each webhook's request.

Verify Signature

Forms API uses a EdDSA signature that is added to each request header to your webhook to help you secure your webhook and to trust incoming requests are only from the Forms API. We recommend that you use a signature verification library to manage this verification for you.

Before we show an example of what your verification logic may look like in your webhook it is important to know that we provide 2 headers to every request we send through the webhook:

1) X-PROMs-API-Webhook-Signature
2) X-PROMs-API-Webhook-Timestamp

The X-PROMs-API-Webhook-Signature header contains the request's signature which you will validate your incoming requests against and the X-PROMs-API-Webhook-Timestamp provides a timestamp of the request so that you can guard against replay-attacks. Below we will show how to verify a signature of an incoming webhook response:

javascript
import { verify } from 'node:crypto'

export const webhookHandler = (request) => {
  // get public key from environment, database or Forms API
  const publicKey = Buffer.from('LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQWFoa2k4VVUvUW9vYm9JR1BXZnhRODdQUE1WRDA5Y3czKzFVODJHNElxRkE9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=', 'base64').toString('utf8')

  // retrieve signature from header
  const headerSignature = request.headers['X-PROMs-API-Webhook-Signature']

  // verify signature
  const isValidRequest = verify(null, Buffer.from(request.body as string), { key: publicKey }, Buffer.from(headerSignature, 'base64'))

  if (isValidRequest) {
    // ... webhook logic here
  }
}