Why an API Needs a Face
Regularly demoing a product with a UI is straightforward: show the screen, let stakeholders click around. But when the product is an API, the usual demo degenerates into scrolling through raw JSON that non-technical viewers can't interpret. Teams in this situation—like a bank selling a payment gateway API, or a service provider publishing an interface for price-comparison engines—need a better way to make their work tangible.
The solution adopted by Thoughtworks is a Demo Front-End: a lightweight UI built specifically for demonstrating and exploring an API. It doesn't need to be polished or integrated into a complex build pipeline; its only job is to make exercising the API trivially easy. The payoff extends well beyond the demo meeting. Once it exists, developers use it to test features locally before committing, quality analysts and product owners use it on test environments, and it can even be shown to prospective partners evaluating the product.
Building a Practical Demo UI
The most useful Demo Front-End sits right next to the API it exercises. In a Spring Boot application, for example, placing static assets in src/main/resources/public/testdrive makes the UI immediately available at https://localhost:8080/testdrive/—no separate deployment step.
The simplest version acts as a smart Postman replacement. It pre-loads a valid JSON request payload for an endpoint into a text area, lets the user tweak the method, path, and body by hand, and then displays the response with its HTTP status code and headers. Even this minimal version beats raw API clients, because a bit of JavaScript can inject dynamic values—like generating a random identifier or setting a date to 30 days in the future—that the user would otherwise have to remember to fix manually.
Keeping the tool frictionless is critical. Use plain JavaScript or lightweight libraries like htmx or jQuery, but avoid setting up a dedicated front-end build. An npm step between the API's own build and the ability to test slows the development loop and doubles the artifacts your CI must produce.
From Text Area to Guided Interface
A static JSON editor only goes so far. As the API grows, the natural evolution is to replace raw JSON input with an HTML form that generates the payload, and to parse the JSON response into a readable format.
Consider a flight-booking API that searches for price combinations. Real payloads are verbose:
{
"departure-airport": "LIN",
"arrival-airport" : "FCO",
"departure-date" : "2023-09-01",
"return-date" : "2023-09-10",
"adults" : 1,
"children" : 0,
"infants" : 0,
"currency" : "EUR"
}
The UI can spare users the pain of remembering this syntax by pre-filling it, but static dates become invalid as time passes. A more helpful form lets users select a departure horizon from drop-down menus—one week, three months, six months—and pick airport codes. The JavaScript then assembles a valid JSON payload behind the scenes. Users who need to test an obscure case can still inspect and edit the raw JSON directly.
The same logic applies to the response. A search that returns a matrix of prices across dates is hard to interpret as raw JSON. Parsing that output into a simple HTML table instantly clarifies whether the API is returning the expected combinations, for both technical and non-technical reviewers.
Weighing the Alternatives
What about Swagger UI? It shares the benefits of living in the same repo and being served from the same service. But it falls short in a few ways: it can’t make payloads more readable than JSON, it’s uninviting to non-technical users, it only serves static payloads (requiring users to manually fix dates or IDs), and it doesn't express workflows. A Demo Front-End can sequence calls, present them in order, and even pull values from one response to seed the next request.
Isn't this unrequested work? The Demo Front-End improves testability and developer experience, which clients rarely object to. In one engagement rewriting an API that made many downstream calls, the team extended the UI to show the request and response for every downstream service involved in a single API call. This gave testers a way to pinpoint exactly why a call failed—be it an HTTP error or a logical error code buried in a response payload—in minutes instead of days. The client later requested the tool be enabled in production so internal users could troubleshoot their partners' calls against the live service. The work wasn't in the original brief, but it solved a problem the client had explicitly described during inception.
Extending the Concept
API endpoints are frequently designed to be called in sequence for a workflow or a human decision process. The Demo Front-End can be extended to guide a user through those steps explicitly, effectively serving as living documentation of how the API is meant to be used—or as a prototype for a full-blown front-end implementation. Sample code for this pattern is available in a public git repository; the UI examples in this article were captured from that codebase.



