Middesk Implementation Guide

The goal of the guide is to walk you through creating a basic integration against Middesk's Identity API. For now we'll just focus on critical pieces of the integration and go more in-depth on a few topics in other articles. This article will cover the following topics:

This document assumes you are already familiar with key API concepts. If you haven't read already, we recommend starting here and reading the articles under the "Getting Started" and "Identity" headers.

Step 1: Hook Up Your Business Onboarding Flow Up To Middesk’s Create a Business endpoint.

The Create a Business endpoint is the main entry point for Middesk Identity API. You’ll first collect a few business attributes from the applicant in your onboarding flow before making a request to the Create a Business endpoint with those details. If successful, this request will result in the creation of a Business.

A Business is the the central object used by Middesk’s API and will store key results of the Identity run. If you've ordered premium products like liens, bankruptcies, litigations, and documents, those results will be stored on the business object as well.

3200

To make this request, you’ll need to find the “Test API key” provisioned for your account on the Middesk credentials page and plug that in to the “Authorization” header. Middesk API uses bearer authentication to authenticate your requests. If your request was submitted successfully, Middesk will return a 201 status code along with a json body containing the Business object for the newly created business.

For a list of the various test cases that work in Middesk’s sandbox environment, please see this article.

Items to Complete Before Moving to Next Step

  • Confirm request returns a 201 Status Code

📘

Please note that Middesk’s API is asynchronous in nature and the Business Object in the response will only contain submitted information for the business. Information provided by Middesk will never show up in this response. As such most customers can skip parsing this response and just look at the status code.

Step 2: Set Up and Listen for Webhooks

Middesk’s API is asynchronous in nature. While most responses can be auto resolved and will come back in a few seconds, some cases require a review by our internal analyst team. Those cases can take a few minutes to come back. As such, Middesk highly recommends implementing webhooks. If webhooks are not an option for your integration, you can instead poll Middesk's Retrieve a Business endpoint for completion.

Middesk allows you to set up webhooks for your account in two ways:

  1. [Recommended] - via the Webhooks UI in the Middesk dashboard
  2. Via the Create a Webhook API endpoint

Middesk allows you to create a separate set of webhooks for our sandbox and production environments. Sandbox webhooks can be set via the Webhooks UI in the Middesk dashboard by switching to “Sandbox Mode.”

When logged into the Middesk dashboard, you can switch to sandbox mode by clicking this button in the upper-right-hand corner with 9 dots on it. Then click the “View Sandbox” slider to enable sandbox mode.

When Sandbox Mode is enabled, this orange banner will appear at the top of the dashboard.

696 361

Once you’ve enabled Sandbox Mode, click the “Add Webhook” button and provide the url for your sandbox webhook. You can optionally add a secret key to your webhook as well. If a secret is provided, Middesk will begin sending an X-Middesk-Signature-256 header with all webhooks that can be used to verify the webhook was sent by Middesk using the method described in this article.

You will also be prompted to select a list of event types that the webhook will be triggered for. For most use cases it is sufficient to select business.updated and tin.retried as the only enabled events. For more information on the other events, please see our article on webhook events.

Once your webhook is set up, you can trigger requests to test it by creating a business in the sandbox using the Middesk dashboard or via the Create a Business endpoint. You can also view logs of requests made to the webhook you set up using the Middesk dashboard page by clicking "View Logs."

1299

This will pop open a table with all events that have been sent to that webhook. You can re-trigger a given webhook event by clicking the "Trigger" icon on the right side or view the specifics of what was provided in the webhook by clicking "View Details"

1659

Items to Complete Before Moving to Next Step

Step 3: Ingest Middesk Results and Make a Decision

Now that you’ve set up webhooks, it is time to add logic to parse the information stored in those webhooks.

Middesk business.updated webhooks contain a few top level fields:

  • data - This field contains a Middesk Business object. This is the field we'll focus on as it contains all the information about the business Middesk has located.
  • id - This is a Middesk generated identifier for the webhook. It is useful for debugging and can be used to search for pertinent webhook logs on the Middesk webhooks page
  • type - The type of webhook being provided. For a full list of webhooks Middesk supports, please see this article. In this case we'll just want to confirm that "type":"business.updated"
  • account_id - The Middesk generated identifier for the account the webhook is sent for. Useful if you are routing traffic across multiple Middesk accounts

Digging into the data field there are a few other key fields worth calling out:

  • data.object.id - this holds the Middesk business_id. Middesk highly recommends storing the business_id as it will be required when updating, retrieving results, or creating a new order for an existing business. It is also useful for debugging and will help you find pertinent logs on the Middesk API logs page
  • data.object.review.tasks - This holds high level insights based on each business attribute. Most Middesk customers render a KYB decision based on the review tasks array

Using Middesk Review Tasks to a Decision

We'll use the array of review tasks stored in the data.object.review.tasks field to determine if the business should be automatically approved or if it should be flagged for manual review. Here is an excerpt of what the data.object.review.tasks array might look like if a business name, address, person and TIN were submitted for a given business.

"tasks": [
    {
      "category": "tin",
      "key": "tin",
      "label": "TIN Match",
      "message": "The IRS does not have a record for the submitted TIN and Business Name combination",
      "name": "tin",
      "status": "failure",
      "sub_label": "Not Found",
      "sources": []
    },
    {
      "category": "name",
      "key": "name",
      "label": "Business Name",
      "message": "Match identified to the submitted Business Name",
      "name": "name",
      "status": "success",
      "sub_label": "Verified",
      "sources": [
        {
          "id": "cba235c3-be54-44f9-bfeb-4f474d6f7e33",
          "type": "name",
          "metadata": {
            "name": "Middesk, Inc",
            "submitted": true
          }
        }
      ]
    },
    {
      "category": "address",
      "key": "address_verification",
      "label": "Office Address",
      "message": "Match identified to the submitted Office Address",
      "name": "address",
      "status": "success",
      "sub_label": "Verified",
      "sources": [
        {
          "id": "afa00984-1d0d-4281-806c-5aadd581d29b",
          "type": "address",
          "metadata": {
            "city": "San Francisco",
            "state": "CA",
            "submitted": true,
            "postal_code": "94105-3459",
            "full_address": "85 2nd St, San Francisco, CA 94105-3459",
            "address_line1": "85 2nd St",
            "address_line2": null
          }
        }
      ]
    },
    {
      "category": "people",
      "key": "person_verification",
      "label": "People",
      "message": "Match identified to the submitted person",
      "name": "people",
      "status": "success",
      "sub_label": "Verified",
      "sources": []
    },
    {
      "category": "sos",
      "key": "sos_active",
      "label": "SOS Filings",
      "message": "3 of 5 filings are Active",
      "name": "sos",
      "status": "success",
      "sub_label": "Active",
      "sources": []
    },
    {
      "category": "watchlist",
      "key": "watchlist",
      "label": "Watchlist",
      "message": "No Watchlist hits were identified",
      "name": "watchlist",
      "status": "success",
      "sub_label": "No Hits",
      "sources": []
    }
  ]

Please note that several other review tasks would be returned in the array like address_deliverability but for now we're just focusing on a few key ones here.

Most Middesk customers create a ruleset based on the status or sub_label for each attribute.

  • status is a bit less granular than sub_label but it is consistent across the various review tasks. This field can only take the values success, warning, or failure
  • sub_label is a bit more granular than status but the values it takes depend on which attribute the review task is for. For example the name review task uses the sub_label values Verified, Similar Match, and Unverified whereas the tin review task uses the sub_label values Found, Not Found, Error, and Mismatch

We recommend attempting to create your ruleset based on status first and moving to using sub_label if you find that status is not granular enough for your use case. For a full list of available review tasks and how to interpret them please see this article.

📘

Disclaimer

The ruleset you'll apply to these Middesk results depends on your company's compliance program, use case, and risk tolerance. There is no one-size-fits-all ruleset that will ensure you are in compliance with regulations. The example provided below is a common configuration we observe many customers using but it does not represent any form of advice or recommendation on how to set your rules.

While Middesk can help customers fit our results to their KYB program, it is very important that you work with your compliance team and/or partner bank to ensure that the ruleset you create is compliant.

To illustrate how you might convert Middesk review tasks into a decision, a customer might auto approve a business if the all following conditions are met:

  • a review task with "key":"name" contains "status":"success" or "status":"warning"
    • this indicates the submitted business name was a very close or perfect match to SOS registration data
  • a review task with "key":"tin" contains "status":"success"
    • this indicates that the IRS confirmed a match between the submitted business name and TIN
  • a review task with "key":"sos_active" contains "status":"success"
    • this indicates that at least one active SOS registrations was found for the business
  • a review task with "key":"watchlist" contains "status":"success"
    • this indicates that no watchlist hits were found for the business

And one of the two following conditions are true:

  • a review task with "key":"address_verification" is returned and contains "status":"success" or "status":"warning"
    • this indicates that at least one of the submitted business address(es) was a close or perfect match to SOS registration data
  • a review task with "key":"person_verification" is returned and contains "status":"success"
    • this indicates that that at least one of the submitted person(s) was a perfect match to SOS registration data

Step 4: Set up Tin Error Handling

The way Middesk verifies the TIN attribute is a bit different than the way the other attributes work. Middesk takes the submitted business name and TIN and makes a synchronous request to the IRS to check for a match. In the vast majority of cases this works without issue. However, the IRS channels Middesk leverages to verify TINs do sometimes experience downtime. For information and updates on TIN outages please see the Middesk Status Page.

When a business encounters an IRS outage, you will see the following review task returned for the business.

{
      "category": "tin",
      "key": "tin",
      "label": "TIN Match",
      "message": "IRS is Unavailable",
      "name": "tin",
      "status": "failure",
      "sub_label": "Error",
      "sources": []
    }

All businesses that encounter an IRS outage will automatically be enrolled in Middesk's TIN Retry queue. Throughout the outage, Middesk will attempt to send traffic to the IRS every few seconds to make sure we know right away when they are back up. Once the IRS is back up, Middesk will begin working through the TIN Retry queue. When a business you ran is retried successfully, the results will be pushed to you via a tin.retried webhook.

{
  "object": "event",
  "id": "8e9ea7e4-80b5-4489-a4aa-8631d46ee44e",
  "account_id": "eda6cf84-761f-4c66-9a11-c070beb1cf62",
  "type": "tin.retried",
  "data": {
    "object": {
      "name": "Unregistered Business",
      "tin": "11-1222333",
      "mismatch": false,
      "unknown": false,
      "verified": true,
      "error": null,
      "updated_at": "2021-11-09T18:28:38.872Z",
      "business_id": "bfd9f8ea-e832-4e12-a06b-b8005fc3e10e"
    }
  },
  "created_at": "2021-11-09T18:28:39.052Z"
}

We recommend using the business_id field returned in the tin.retried webhook to map the results back to the other business details.

Its worth considering how this fits into your application flow as that will ultimately determine how you'll set your integration up to handle IRS outages. While most outages are short-lived, they can sometimes take a few hours to resolve. Depending on your application flow, one of the following approaches might make sense:

  • Leave the application pending until the tin.retried webhook is received and your full ruleset can be applied
  • Move the application into the manual review flow as soon as an "IRS is Unavailable" error is observed
  • If the other attribute results look good, grant provisional access to the applicant until their TIN result comes back