Build a Headless URL Shortener in One Minute Using No-Code

2022-07-20 - 5 min read

In this article, we will learn how to build a headless URL shortener in one minute using no-code. We will create an app with a database and REST API endpoints that can shorten a URL and use the shortened URL. Furthermore, we'll add a cron task for cleaning up old records.

What we will build

Creating a headless URL shortener is a great way to discover how you can create a meaningful app quickly. No coding is required for this tool. However, we're a tech product, so I'll continue with a curl command.

First, we want to shorten a URL with the following command:

curl -X POST -H 'Content-Type: application/json' - data '{
  "url": ""

The response must be similar to:


This call should return the same URL when called again with the identical long URL. And, of course, this URL must redirect to the long URL we've provided.

We do not want to pollute the database with links that are never used. Therefore, links that are over 30 days old and haven't been used for the last 30 days must be removed.

That's it for the specifications. Let's get started with the database structure!

API endpoints and database schema

You'll need to create a table schema that will store information about the shortened URLs. Fortunately, this can be done in no-code with just a few clicks from the data page. A quick method to define the schema is to generate it from JSON:

 "id": "FzBg32…",
 "url": "<>",
 "created": "1970–01–01T00:00:00Z",
 "lastUsed": "1970–01–01T00:00:00Z"

This will add all properties and correctly set the types. Yet, a few changes are needed. You must manually set the lastUsed property to be optional, as it is possible that it isn't used at all. Also, check the "indexed” property on all fields to be able to filter them. It is not advisable to always check this since it doubles the storage costs. However, we need to filter on each of them in this application.

Define a route to shorten URL

We need a URL in the database before we can test anything. So logically, we would continue creating the respective no-code endpoint based on the curl command given earlier. First, go to Flows and create a new flow. We'll be using the "REST endpoint” flow type. You can configure the endpoint on the start block. Set the method to POST and path to /url. Next, you can specify a post body, where we can use the "generate from JSON” again:

{"url": "<>"}

After which you get the following result:

REST endpoint configuration

After receiving a request, it first checks whether the URL is already in the database. If not, then it is inserted. Otherwise, it is used as-is. The short URL is sent as a response, which is done in the end block. Hence there are four parts:

  • Receiving (and validating) the request
  • Lookup URL in database
  • Create a new record (if nothing was found)
  • Send response

Each action has its own block in the flow, as you can see below. The configuration of each block is done in the connection targeting that block.

REST endpoint to create a short URL

Redirect the short URL

Now that we can create a short URL, we want to enable users to use it. Therefore, we need another REST endpoint. So, make a second REST endpoint flow. The configuration for this endpoint is more interesting. Let's start by setting the path to "/go/{url}”. The part between curly braces is a parameter and takes dynamic values. When you type this in the path, another input appears where you can specify the type of this parameter. Interestingly, we can choose the Url data type created earlier. When you do that, the object loads automatically from the database. Also, you don't need to handle 404s yourself in this case. This makes completing the flow effortless since we can directly map the full URL of the loaded object to the Location HTTP header in the flow's output, as shown below.

Redirect visitor to original url

The redirect already works with this mapping. However, we need to know when links are used to be able to write the cleanup process later. For this, we can connect another block from the start pin, in this case, UpdateUrl. We need to set the Url id and a datetime for the lastUsed property. The datetime is in ISO8601 format, which we can retrieve in JavaScript using Date's toiSOString method.

Mapping to update lastUsed property

Cleanup old records using a cron flow

You'll likely want to clean up old records from time to time. This can be easily done in no-code using a cron flow. You can specify when this flow runs in the start block's config. Once per week seems sufficient for now.

You can fetch the old records directly with the ListUrl block.

Configuration to list old URL's

Next, we need to loop over all returned rows and call the DeleteUrl block. Lastly, you need to ‘close the loop'. The end of the loop is marked with an ‘aggregate” block. This block aggregates all results from each iteration and, in turn, outputs all results in an array. There is, however, another way that a loop can end. That is when the list is empty. The aggregate block is not called in this case; hence you need the "empty” pin on the "loop” block to continue the flow for this case.


No-code tools are becoming increasingly popular as they make it possible for anyone to build complex applications without a single line of code. In this article, we showed you how to use Flowlet to create a headless URL shortener in just one minute. You can find the complete configuration in the marketplace, accessible from your workspace admin.