> For the complete documentation index, see [llms.txt](https://docs.keyfax.biz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keyfax.biz/product-suite/admin/entities/databoxes/http-request.md).

# HTTP Request

### Introduction

HTTP Query Databoxes can be used to retrieve information from any web API.  They are also capable of updating data in certain environments that supply a web API to do so. &#x20;

To demonstrate the functionality this page will show how to produce this message based upon the HTTP APIs offered by Geoapify (a paid for service that provides local area information around the globe - see here: <https://www.geoapify.com/>):

<figure><img src="/files/etbv35Zt5WhvBB1lFFNm" alt=""><figcaption></figcaption></figure>

### Creating the HTTP Databoxes

Two HTTP databoxes are required to get the data for the above message box.  This is due to the design of the Geoapify API.  The hospital search API requires a 'Place\_id' which is defined within Geoapfify; this place\_id can only be accessed by providing the tenant's postcode to the Geoapify API.  So:

* The first HTTP databox gets the place\_id by passing Geoapify the tenant's postcode.
* The second HTTP databox passes the place\_id to Geoapify and gets back the list of hospitals in the local area (equally this could be dental surgeries or supermarkets)

The first databox looks as follows (with the apiKey blanked here - the Geoapify website will provide you with an API key when an account is created).

<figure><img src="/files/mxoAi87973C6Cmam8WQR" alt=""><figcaption></figcaption></figure>

The second databox references the first, utilising the returned place\_id in it's HTTP URL:

<figure><img src="/files/GIcdNUwLJ6v5j3FNO1ZQ" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
In previous versions of Keyfax it was not possible to 'chain' calls to SQL databoxes by nesting references to other bookmarks within the SQL - but in 4.4.8 these rules have been relaxed to make multi-call SQL or HTTP databoxes a possibility.
{% endhint %}

### Creating the Message

The message is a normal message - but as we are creating HTML elements from the output of a databox (in this case a list using 'ul' and 'li' HTML elements) there's a little bit of scripting trickery to take care of.

The 'HTML Source' view of the message should be set to the following:

```
<p>Local services:</p>

<div id="hospitals">{HTTP.NearestHospitals.Hospital}</div>
<script>
    // Hospital injection!
    var data = document.getElementById('hospitals').innerHTML;
    var items = data.split('&lt;br/&gt;');

    var html = items
        .filter(x => x.trim().length > 0)
        .map(x => x.trim())
        .join('</li><li>');
    html = '<ul><li>' + html + '</li></ul>';
    document.getElementById("hospitals").innerHTML = html;
</script>
```

### Overview

### Properties

**Group** - when displayed in the Selection List, Databoxes are arranged into groups. Select a group from the drop down list to add the Databox to an existing group or type in a new group name to create a new group.

**HTTP Verb -** a the 'verb' is part of the HTTP protocol specification. Common verbs to use are: GET, POST, PUT, UPDATE, OPTIONS - see <https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods> for the full list

**Name** – a descriptive name for the Databox. If you can, make this a meaningful description to enable easy identification in your scripts..

**Xpath Record Identifier** – all data retrieved from an HTTP databox is converted to XML (even JSON responses), this setting allows Xpath to be used to identify the root element of each record of data in a multi-record response. &#x20;

**Description** - a short description of the Databox. This is displayed in the Databox Selection list in and is searchable using the filter.

**URL** – The URL to call when this databox is executed - this field can incorporate references to other databox expressions to pass URL parameters taken from, for example, the startup XML.

**Headers -** some HTTP web api servers require authorisation headers to be callable, those authorisation and authentication headers can be placed here.  In some cases and initial HTTP call to retrieve a token (via one databox) is required before that token is used in a second HTTP databox to full authenticate against the service.  Headers are also used to specify the format of the incoming Body of the HTTP request - please see an HTTP tutorial for full details.

**Body -** the HTTP body is usually only passed in a POST or PUT (HTTP Verb) request but can be present for any call.  If the aim of the request is to update a server with information, that information is almost always POST'ed in the body section of the request in either JSON or 'Forms Encoded' format. Once again, please see an HTTP tutorial for full details.

**Test** – [test](/product-suite/admin/entities/databoxes/sql-query/testing-sql-query-databoxes.md) the HTTP request and Expressions setup against the databox.&#x20;

**Expressions** – these are covered in-depth in the [Databox Expressions](/product-suite/admin/databox-expressions.md) section. Typically, the Expression Item will be used to access individual 'columns' of data returned by the query. In the example above you'll see a rowmerge Expression which merges the 'formatted' field returned from the HTTP request into a single string which is then displayed by the message definition in script.

{% hint style="warning" %}
All Databoxes are re-evaluated **every time they are referenced** either directly or through an Expression; for HTTP Databoxes this will re-run the HTTP query and could be inefficient. If it is known the request will always return the same result and the request returns multiple values or is referenced several times in the script then it is better to use a Databox-Write to store the original result into a separate [Script](/product-suite/admin/entities/databoxes/script-data.md) Databox and use the latter for all subsequent references.
{% endhint %}

### Handling multiple rows of data

Since 4.4.8 of Keyfax it is now possible to handle multiple rows of data with both SQL and HTTP databoxes.  For HTTP databoxes this is built in by default.  For SQL databoxes - so as not to change the operation of existing scripts - the multi-row support requires an opt-in on the SQL databox definition page by selecting 'Multiple records in result allowed'.

{% hint style="warning" %}
For 4.4.7 and earlier:

If an SQL Query returns **more than a single row**, this is considered an error and the SQL query should be amended to ensure this cannot happen. It is good practice to always test for this eventuality in which case you will see this message: '<mark style="color:red;">**Unable to process multiple rows returned**</mark>'.&#x20;

Depending on the context, there may be various techniques to restrict results to a single row; typically this may use the '**TOP n**'  clause. For example, to return a single row containing the current balance for the most recent tenancy record:\
\
**SELECT TOP 1 CurrentBalance FROM Tenants WHERE TenantID = {Import.CallerId} ORDER BY TenancyStartDate DESC**   \
&#x20;\
Having said that, there are exceptions where multiple rows *can* be returned but the results must be coerced into an XML packet; this will require more specialist knowledge - see the section [Handling multiple rows from SQL](/product-suite/admin/best-practices/handling-multiple-rows-from-sql.md).

It should also be taken into consideration that if an SQL Query doesn't return anything then any Expressions against it will not run.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.keyfax.biz/product-suite/admin/entities/databoxes/http-request.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
