System Architecture

Our product is a backend-less desktop app. While it is made to serve a specific purpose for the NHS, we have designed its architecture to be modular. Developers can reuse these modules for various purposes involving SMS bots. In addition, the interaction of these modules is via custom but generalised APIs and file formats. This allows other developers to implement other modules that can be interchanged frictionlessly. Thus, this allows for a developer community to emerge.

Architectural Overview

Our standalone app is split into 3 main components - UI and two business logic entities.


All functionality is exposed by the business logic modules via a simplified API. The UI codebase only visualises data received from these modules and calls the respective API methods to manage that data. This allows us to have a clean separation between functionality and UX.

The modulevf-to-ubf is responsible for converting Voiceflow design data into the unified bot format (to be introduced later). This is used when the user wants to create an SMS bot from a Voiceflow file.

The moduleubf-to-twilio works with chatbot designs in the unified bot format. It supports deploying these bots to an SMS backend, connecting them to phone numbers, and other operations relating to SMS deployment and testing. This implements the UBF SMS API (to be introduced later).

sequence diagram Sequence diagram highlighting the main processes in deploying a chatbot

The business logic modules are designed to be self-contained and not depend on each other or the UI. They can be directly integrated into other software products to benefit developers.

The Unified Bot Format

During our previous proof of concepts, we decided to convert Voiceflow design data into a more convenient format we could work with. Since we were already doing format conversion, we started thinking: what if we define a generalised bot design format instead? This brings the major benefit that we become way less reliant on Voiceflow and their format and opens the door to interfacing with other design environments. For example, Microsoft’s Bot Composer Framework could be an interesting expansion.

From our research with other design platforms, we had some experience with alternative platforms’ capabilities and requirements. So we came up with the design of the Unified Bot Format. It is a JSON format representing a graph of a conversation flow between multiple-choice questions. It is explained further here.


While working on the UI, we decided to define an abstracting functional API. This would hide the complexity of the business logic as it is not within the responsibility of the UI to be aware of that. In addition, we were also aware that if the NHS were to deploy our system nation-wide, we would have to use a different SMS service to Twilio.

These factors led to the decision to create a common functional API for an SMS backend. That API would support creating SMS chatbots in Unified Bot Format, as well as managing the created chatbot instances and assigning phone numbers to them. We used our experience with alternative SMS platforms to ensure that the API generalises well. It is documented further here.

Why a Standalone Frontend?

Because we placed significant emphasis in our research on reusing as much technology as possible (the pros and cons of which are elaborated here), we do not have a backend. Our UBF SMS API implementation runs entirely in the frontend and stores all relevant data in Twilio servers. The application is standalone and does not store any local state. Anyone with access to a Twilio account can use our app to manage all chatbots uploaded on that account.

In short this allows us to:

  • Reduce the complexity enormously.
  • No risk of losing data locally.

What About The Business Logic?

The module vf-to-ubf implements the Unified Bot Format by converting Voiceflow designs to it. Module ubf-to-twilio implements the UBF SMS API for the Twilio backend. Both of these entities are self-contained npm packages. You can find out more in our dedicated posts for each package.