# Function Hub

### Obtaining an API Key

Function Hub is presently available as an early beta and has not yet been fully integrated into the Adalo Builder. To generate an API key you can use the command-line tool cURL, passing in your application ID:

```
$ curl -X POST https://functionhub.adalo.com/api/keys \
-H "Content-Type: application/json" \
-d '{"app_id": "YOUR-APP-ID"}' \
{"api_key":"124TYghFYU9898123PRTNF"}%
```

Your API key will be returned in a JSON response. In the above example the key is `124TYghFYU9898123PRTNF`. Copy that key and save it to your password manager.

### Configuring Custom Actions to Use Function Hub

To call any Function Hub endpoint from your Adalo app:

1. Open your app in the Adalo editor
2. Select the component or screen that should trigger the action
3. Add a **Custom Action**
4. Set the **API Base URL** to `https://functionhub.adalo.com`
5. Set the **Method** (POST or GET, depending on the endpoint)
6. Set the **URL path** for the specific endpoint (e.g. `/api/math/sort`)
7. Under **Headers**, add:
   * **Key:** `X-API-Key`
   * **Value:** your API key
8. Under **Headers**, add (for POST requests with a JSON body):
   * **Key:** `Content-Type`
   * **Value:** `application/json`
9. Configure the **Body** or **URL parameters** as described for each endpoint
10. Under the **Response**, map the output fields (e.g. `result`) to Magic Text or a property in your app

### Supported Endpoints

A limited number of useful endpoints are currently available. We will continue expanding capabilities based on Maker request!

#### Sort Numbers

Sort a list of comma-separated numbers in ascending order.&#x20;

**Use Cases**

* Sort a list of scores or ratings
* Order prices from lowest to highest
* Rank numerical data from a collection

| **Method** | POST             |
| ---------- | ---------------- |
| **URL**    | `/api/math/sort` |
| **Auth**   | Required         |

**Request Body**

| Parameter | Type   | Required | Description                                   |
| --------- | ------ | -------- | --------------------------------------------- |
| `numbers` | string | Yes      | Comma-separated integers (e.g. `"5,2,9,1,3"`) |

**Example**

**Request:**

```
POST /api/math/sort
Content-Type: application/json
X-API-Key: your-api-key

{
  "numbers": "5,2,9,1,3"
}
```

**Response (200):**

```json
{
  "result": "1,2,3,5,9"
}
```

**You can test this endpoint using cURL and your API key:**

```
curl -X POST https://functionhub.adalo.com/api/math/sort \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your-api-key" \
    -d '{"numbers": "5,3,8,1,9,2"}'

  Response:

  {"result": "1,2,3,5,8,9"}
```

**Configuring a Custom Action to Sort Numbers**

* **Method:** POST
* **URL:** `/api/math/sort`
* **Body:** Set `numbers` to a comma-separated list — you can use Magic Text to pull values from your database
* **Output:** Map `result` to display the sorted list

#### Replace Text

Replace all occurrences of a substring within a string.&#x20;

**Use Cases**

* Clean up user input (remove unwanted characters)
* Replace placeholder text with dynamic values
* Redact sensitive words from displayed content

| **Method** | POST                                               |
| ---------- | -------------------------------------------------- |
| **URL**    | `/api/string/replace/{string}/{search}/{replace?}` |
| **Auth**   | Required                                           |

**URL Parameters**

| Parameter | Required | Description                                                   |
| --------- | -------- | ------------------------------------------------------------- |
| `string`  | Yes      | The original text to modify                                   |
| `search`  | Yes      | The substring to find                                         |
| `replace` | No       | The replacement text. If omitted, the search term is removed. |

**Examples**

**Replace a word:**

```
POST /api/string/replace/hello world/world/universe
X-API-Key: your-api-key
```

```json
{
  "result": "hello universe"
}
```

**Remove a word (no replacement):**

```
POST /api/string/replace/hello world/world
X-API-Key: your-api-key
```

```json
{
  "result": "hello "
}
```

**Configuring a Custom Action to Replace String**

* **Method:** POST
* **URL:** Build the path dynamically using Magic Text: `/api/string/replace/{YourTextField}/{SearchTerm}/{ReplacementText}`
* **Output:** Map `result` to a text property or display field

#### Text Manipulation

Transform a string using one of several built-in options.

**Use Cases**

* Normalize user names to title case (`capitalize`)
* Store email addresses as lowercase
* Display headings in uppercase

|            |                                           |
| ---------- | ----------------------------------------- |
| **Method** | POST                                      |
| **URL**    | `/api/string/convert/{function}/{string}` |
| **Auth**   | Required                                  |

**URL Parameters**

| Parameter  | Required | Description                                               |
| ---------- | -------- | --------------------------------------------------------- |
| `function` | Yes      | One of: `uppercase`, `lowercase`, `capitalize`, `reverse` |
| `string`   | Yes      | The text to transform                                     |

**Available Functions**

| Function     | Description                              | Example Input | Example Output |
| ------------ | ---------------------------------------- | ------------- | -------------- |
| `uppercase`  | Convert all characters to uppercase      | `hello world` | `HELLO WORLD`  |
| `lowercase`  | Convert all characters to lowercase      | `Hello World` | `hello world`  |
| `capitalize` | Capitalize the first letter of each word | `hello world` | `Hello World`  |
| `reverse`    | Reverse the string                       | `hello`       | `olleh`        |

**Example**

```
POST /api/string/convert/capitalize/john doe
X-API-Key: your-api-key
```

```json
{
  "result": "John Doe"
}
```

**Error Response**

If the function name is invalid:

```json
{
  "error": "Invalid function"
}
```

Status: **404**

**Configuring a Custom Action to Manipulate Text**

* **Method:** POST
* **URL:** `/api/string/convert/capitalize/{YourTextField}` — replace `capitalize` with your desired function
* **Output:** Map `result` to a text property

#### Concatenate Text

Join comma-separated text segments into a single string separated by spaces.

**Use Cases**

* Combine first name, last name, and suffix into a full name
* Build a full address from street, city, state, and zip fields
* Merge multiple text fields into a single display string

| **Method** | POST                             |
| ---------- | -------------------------------- |
| **URL**    | `/api/string/concatenate/{text}` |
| **Auth**   | Required                         |

**URL Parameters**

| Parameter | Required | Description                                         |
| --------- | -------- | --------------------------------------------------- |
| `text`    | Yes      | Comma-separated values to join (e.g. `hello,world`) |

Empty values are automatically filtered out, and each segment is trimmed of whitespace.

**Example**

```
POST /api/string/concatenate/John,Doe,Jr.
X-API-Key: your-api-key
```

```json
{
  "result": "John Doe Jr."
}
```

**Configuring a Custom Action to Concatenate Text**

* **Method:** POST
* **URL:** Build the path with Magic Text: `/api/string/concatenate/{FirstName},{LastName},{Suffix}`
* **Output:** Map `result` to a text property (e.g. full name)

#### Time Difference

Calculate the difference between two times.

**Use Cases**

* Calculate how long a shift lasted
* Show the duration between two scheduled events
* Display time remaining until a deadline

| **Method** | GET                                                   |
| ---------- | ----------------------------------------------------- |
| **URL**    | `/api/temporal/between/{startTime}/{endTime}/{unit?}` |
| **Auth**   | Required                                              |

**URL Parameters**

| Parameter   | Required | Description                                                                   |
| ----------- | -------- | ----------------------------------------------------------------------------- |
| `startTime` | Yes      | Start time in 24-hour format (`HH:MM`, e.g. `09:00`)                          |
| `endTime`   | Yes      | End time in 24-hour format (`HH:MM`, e.g. `17:30`)                            |
| `unit`      | No       | Output unit. Default: `minutes`. Options: `minutes`, `hours`, `seconds`, `hm` |

**Unit Options**

| Unit      | Response Key    | Description                 | Example (09:00 to 10:30) |
| --------- | --------------- | --------------------------- | ------------------------ |
| `minutes` | `minutes`       | Total minutes               | `90`                     |
| `hours`   | `hours`         | Whole hours (rounded down)  | `1`                      |
| `seconds` | `seconds`       | Total seconds               | `5400`                   |
| `hm`      | `hours_minutes` | Hours and minutes as `H:MM` | `"1:30"`                 |

**Examples**

**Default (minutes):**

```
GET /api/temporal/between/09:00/17:30
X-API-Key: your-api-key
```

```json
{
  "minutes": 510
}
```

**Hours and minutes:**

```
GET /api/temporal/between/09:00/17:30/hm
X-API-Key: your-api-key
```

```json
{
  "hours_minutes": "8:30"
}
```

**Configuring a Custom Action to Calculate Time Difference**

* **Method:** GET
* **URL:** Build the path with Magic Text: `/api/temporal/between/{StartTimeField}/{EndTimeField}/hm`
* **Output:** Map `hours_minutes` (or `minutes`, `hours`, `seconds` depending on your chosen unit) to a text or number property

#### Sum Numbers

Calculate the sum of a list of comma-separated numbers.

**Use Cases**

* Add up line items in an order
* Calculate a running total from a list of values
* Sum scores across multiple categories

|            |                 |
| ---------- | --------------- |
| **Method** | POST            |
| **URL**    | `/api/math/sum` |
| **Auth**   | Required        |

**Request Body**

| Parameter | Type   | Required | Description                               |
| --------- | ------ | -------- | ----------------------------------------- |
| `numbers` | string | Yes      | Comma-separated integers (e.g. `"1,2,3"`) |

**Example Request:**

```
POST /api/math/sum
Content-Type: application/json
X-API-Key: your-api-key

{
  "numbers": "1,2,3"
}
```

**Response (200):**

```json
{
  "result": 6
}
```

**Adalo Setup**

* **Method:** POST
* **URL:** `/api/math/sum`
* **Body:** Set `numbers` to a comma-separated list — you can use Magic Text to pull values from your database
* **Output:** Map `result` to a number property

***

### **Add Minutes**

Add a specified number of minutes to a date/time value.

#### **Use Cases**

* Calculate an appointment end time based on a start time and duration
* Set a reminder time a certain number of minutes after an event
* Schedule a follow-up a set number of minutes into the future

| **Method** | POST                       |
| ---------- | -------------------------- |
| **URL**    | `/api/temporal/addminutes` |
| **Auth**   | Required                   |

#### **Request Body**

| Parameter  | Type   | Required | Description                                                                        |
| ---------- | ------ | -------- | ---------------------------------------------------------------------------------- |
| `datetime` | string | Yes      | A date/time string in `MM/DD/YYYY H:MM AM/PM` format (e.g. `"02/12/2026 9:24 AM"`) |
| `minutes`  | number | Yes      | The number of minutes to add (e.g. `7`)                                            |

#### **Example Request**

```
POST /api/temporal/addminutes
Content-Type: application/json
X-API-Key: your-api-key

{
  "datetime": "02/12/2026 9:24 AM",
  "minutes": 7
}
```

**Response (200)**

```json
{
  "result": "02/12/2026 9:31 AM"
}
```

**You can test this endpoint using cURL and your API key:**

```
curl -X POST https://functionhub.adalo.com/api/temporal/addminutes \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your-api-key" \
    -d '{"datetime": "02/12/2026 9:24 AM", "minutes": 7}'

  Response:

  {"result": "02/12/2026 9:31 AM"}
```

**Configuring a Custom Action to Add Minutes**

* **Method:** POST
* **URL:** `https://functionhub.adalo.com/api/temporal/addminutes`
* **Body:** Set `datetime` to your date/time property using Magic Text, and set `minutes` to the number of minutes to add
* **Output:** Map `result` to a date/time property to store the adjusted time

***

### **Subtract Minutes**

Subtract a specified number of minutes from a date/time value.

#### **Use Cases**

* Calculate a check-in time a set number of minutes before an appointment
* Determine a cutoff time before an event deadline
* Set a buffer period before a scheduled activity

| **Method** | POST                            |
| ---------- | ------------------------------- |
| **URL**    | `/api/temporal/subtractminutes` |
| **Auth**   | Required                        |

#### **Request Body**

| Parameter  | Type   | Required | Description                                                                        |
| ---------- | ------ | -------- | ---------------------------------------------------------------------------------- |
| `datetime` | string | Yes      | A date/time string in `MM/DD/YYYY H:MM AM/PM` format (e.g. `"02/12/2026 9:24 AM"`) |
| `minutes`  | number | Yes      | The number of minutes to subtract (e.g. `7`)                                       |

#### **Example Request**

```
POST /api/temporal/subtractminutes
Content-Type: application/json
X-API-Key: your-api-key

{
  "datetime": "02/12/2026 9:24 AM",
  "minutes": 7
}
```

**Response (200):**

```json
{
  "result": "02/12/2026 9:17 AM"
}
```

**You can test this endpoint using cURL and your API key:**

```
curl -X POST https://functionhub.adalo.com/api/temporal/subtractminutes \
    -H "Content-Type: application/json" \
    -H "X-API-Key: your-api-key" \
    -d '{"datetime": "02/12/2026 9:24 AM", "minutes": 7}'

  Response:

  {"result": "02/12/2026 9:17 AM"}
```

**Configuring a Custom Action to Subtract Minutes**

* **Method:** POST
* **URL:** `https://functionhub.adalo.com/api/temporal/subtractminutes`
* **Body:** Set `datetime` to your date/time property using Magic Text, and set `minutes` to the number of minutes to subtract
* **Output:** Map `result` to a date/time property to store the adjusted time

### Average Numbers

Calculate the average (mean) of a list of comma-separated numbers.

|            |                     |
| ---------- | ------------------- |
| **Method** | POST                |
| **URL**    | `/api/math/average` |
| **Auth**   | Required            |

#### **Request Body**

| Parameter | Type   | Required | Description                               |
| --------- | ------ | -------- | ----------------------------------------- |
| `numbers` | string | Yes      | Comma-separated integers (e.g. `"2,4,6"`) |

#### **Example Request**

```
POST /api/math/average
Content-Type: application/json
X-API-Key: your-api-key

{
  "numbers": "2,4,6"
}
```

**Response (200):**

```json
{
  "result": 4
}
```

**Adalo Setup**

* **Method:** POST
* **URL:** `/api/math/average`
* **Body:** Set `numbers` to a comma-separated list — you can use Magic Text to pull values from your database
* **Output:** Map `result` to a number property

**Use Cases**

* Calculate an average rating from multiple reviews
* Find the mean score across a set of assessments
* Compute an average price from a list of products

***

### Minimum Number

Find the smallest number in a list of comma-separated numbers.

**Use Cases**

* Find the lowest price in a set of products
* Identify the minimum score or rating
* Determine the earliest quantity in stock

|            |                 |
| ---------- | --------------- |
| **Method** | POST            |
| **URL**    | `/api/math/min` |
| **Auth**   | Required        |

**Request Body**

| Parameter | Type   | Required | Description                               |
| --------- | ------ | -------- | ----------------------------------------- |
| `numbers` | string | Yes      | Comma-separated integers (e.g. `"5,3,1"`) |

#### **Example Request**

```
POST /api/math/min
Content-Type: application/json
X-API-Key: your-api-key

{
  "numbers": "5,3,1"
}
```

**Response (200):**

```json
{
  "result": 1
}
```

#### **Adalo Setup**

* **Method:** POST
* **URL:** `/api/math/min`
* **Body:** Set `numbers` to a comma-separated list — you can use Magic Text to pull values from your database
* **Output:** Map `result` to a number property

***

#### Maximum Number

Find the largest number in a list of comma-separated numbers.

**Use Cases**

* Find the highest bid or offer
* Identify the top score in a leaderboard
* Determine the maximum capacity from a list of venues

|            |                 |
| ---------- | --------------- |
| **Method** | POST            |
| **URL**    | `/api/math/max` |
| **Auth**   | Required        |

**Request Body**

| Parameter | Type   | Required | Description                               |
| --------- | ------ | -------- | ----------------------------------------- |
| `numbers` | string | Yes      | Comma-separated integers (e.g. `"5,3,1"`) |

**Example**

**Request:**

```
POST /api/math/max
Content-Type: application/json
X-API-Key: your-api-key

{
  "numbers": "5,3,1"
}
```

**Response (200):**

```json
{
  "result": 5
}
```

**Adalo Setup**

* **Method:** POST
* **URL:** `/api/math/max`
* **Body:** Set `numbers` to a comma-separated list — you can use Magic Text to pull values from your database
* **Output:** Map `result` to a number property

***

#### Percentage

Calculate what percentage one number is of another.

**Use Cases**

* Show completion progress (e.g. 15 of 60 tasks = 25%)
* Calculate a discount percentage
* Display what portion of a goal has been reached

|            |                        |
| ---------- | ---------------------- |
| **Method** | POST                   |
| **URL**    | `/api/math/percentage` |
| **Auth**   | Required               |

**Request Body**

| Parameter | Type    | Required | Description                    |
| --------- | ------- | -------- | ------------------------------ |
| `number`  | numeric | Yes      | The part value (e.g. `"50"`)   |
| `total`   | numeric | Yes      | The whole value (e.g. `"200"`) |

**Example**

**Request:**

```
POST /api/math/percentage
Content-Type: application/json
X-API-Key: your-api-key

{
  "number": "50",
  "total": "200"
}
```

**Response (200):**

```json
{
  "result": 25
}
```

**Adalo Setup**

* **Method:** POST
* **URL:** `/api/math/percentage`
* **Body:** Set `number` to the part value and `total` to the whole value — you can use Magic Text to pull values from your database
* **Output:** Map `result` to a number property

### Tips & Best Practices

* **URL-encode special characters** — If your text contains spaces or special characters, they must be URL-encoded in path parameters (e.g. `hello%20world` for `hello world`). Adalo handles this automatically when using Magic Text.
* **Use `hm` for display** — The `hm` unit returns a human-readable format like `1:30` that's ideal for showing durations in your app UI.
* **Concatenate for dynamic text** — Use the concatenate endpoint to build full names, addresses, or any text from multiple Adalo database fields.
* **One key per app** — Create a single API key per Adalo app. Use the same key across all Custom Actions in that app.
* **Test with the interactive docs** — Visit `/docs/api` on the base URL to test endpoints directly in your browser before setting up Custom Actions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.adalo.com/integrations/function-hub.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
