> For the complete documentation index, see [llms.txt](https://docs.ninox.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ninox.com/ninox-scripting/automate-your-workflows/work-with-functions/integration-and-http.md).

# Integration and HTTP

Learn how to call external services, validate XML against XSD schemas, transform XML, send emails with Ninox scripts.

Integration functions connect your app to services and communication tools outside Ninox. You can call APIs, validate XML against schemas, transform XML, and send emails.

In this chapter, you will learn how to:

* Call external services with HTTP.
* Transform XML.

<table><thead><tr><th width="249.3359375">Function (A-Z)</th><th>Task</th></tr></thead><tbody><tr><td><code>email()</code></td><td>Return or reuse an email value</td></tr><tr><td><code>formatXML()</code></td><td>Convert JSON data to XML text</td></tr><tr><td><code>http()</code></td><td>Send an HTTP request</td></tr><tr><td><code>parseXML()</code></td><td>Convert XML text to a JSON object</td></tr></tbody></table>

## Call external services

Use these functions to call any REST API, to pull data from another service or push data between Ninox databases.

### Call an API with `http()`

Use `http()` to send a request to an external service.

Use it when you want to:

* Fetch data from, or send updates to another system.
* Connect Ninox to REST APIs and other Ninox databases.

{% hint style="warning" %}
**Don't place `http()` inside `do as transaction...end`**

Transactions use a single-threaded write queue. An HTTP call inside a transaction blocks all other writes until the request finishes. The app does not hang forever, but every pending write waits for the full duration of the call. That can make the app feel slow.
{% endhint %}

`http(method, url)`\
`http(method, url, body)`\
`http(method, url, header, body)`\
`http(method, url, header, body, files)`

* `method` text value of the HTTP method , for example, `"GET"` or `"POST"`
* `url` text value of the endpoint URL
* `header` optional headers as a JSON object, for example, `{ Authorization: token }`
* `body` optional request body as a JSON object
* `files` optional files to upload as `[file]` when the current execution context supports file uploads (server context)

{% hint style="warning" %}
**A body is required when accessing Ninox data**

If you use `http()` to access data in Ninox, a body must be passed. If no information needs to be passed in the body, it simply remains empty. An example of this would be:

`http("GET", "https://api.ninox.com/v1/[...]", {Authorization: "Bearer xxxx-xxxx-xxxx", "content-type": "application/json"}, {})`
{% endhint %}

#### Let’s take a look at some examples:

```ninox
http("GET", "https://api.example.com/status")
```

Calls the external service and returns a JSON response object or an error object.

```ninox
let url := "https://api.ninoxdb.de/v1/teams/" + teamId() +
           "/databases/" + databaseId() + "/tables/";
let apiKey := "Bearer abcd1234-0000-xxxx-zzzz-1a1aa1aaa1a111";

let response := http("GET", url, {
    Authorization: apiKey
});
response
```

Lists tables from the current database through the Ninox API or an error object.

```ninox
do as server
   let url := "https://api.ninoxdb.de/v1/teams/" + teamId() +
             "/databases/" + databaseId() + "/query";
   let apiKey := "Bearer abcd1234-0000-xxxx-zzzz-1a1aa1aaa1a111";
   
   let response := http("POST", url, {
             Authorization: apiKey, 
             "content-type": "application/json"
   }, {
    query: "select customers where status = 4"
   });
   response
end
```

Sends a POST request and returns matching records or an error object.

<pre class="language-ninox"><code class="lang-ninox"><strong>let response := do as server
</strong>    http("POST",
        "https://example.com/upload",
        { "content-type": "multipart/form-data" },
        null,
        [myFile])
end
</code></pre>

Uploads a file to an external service when file uploads are supported in the current execution context.

Tips:

* `http()` returns a JSON object, not plain text.
* If you access another Ninox database, you need an API key.
* Some endpoints expect a body even for `GET` requests. Use `{}` when the target endpoint requires one and you do not need to send fields.
* File uploads depend on the execution context.
* Test integration scripts against the real service response, not sample output only.

## Transform XML

Use these functions when another system sends or expects XML, especially when the XML must match a defined schema.

### Convert XML text to data with `parseXML()`

Use `parseXML()` to turn XML text into a JSON object you can inspect in Ninox. This is especially useful when you connect Ninox to external services by API and need to process XML responses. XML is a common exchange format alongside JSON.

Use it when you want to:

* Read values from an XML response.
* Extract fields from imported XML.
* Convert XML into structured data for later logic.

`parseXML(string)`

* `string` the XML text you want to convert to a JSON object

#### Let’s take a look at some examples:

```ninox
let xml := "<?xml version=""1.0"" encoding=""UTF-8""?>
<note>
    <to>Jane Doe</to>
    <from>Ninox</from>
    <heading>Save the world!</heading>
    <body>Please save the world!</body>
</note>";
parseXML(xml)
```

Returns a JSON object built from the XML text, for example:

```json
{
  "note": {
    "to": {
      "@": "Jane Doe"
    },
    "from": {
      "@": "Ninox"
    },
    "heading": {
      "@": "Save the world!"
    },
    "body": {
      "@": "Please save the world!"
    }
  }
}
```

Tip:

* If you have an XSD schema, validate external XML before you parse it.

### Create XML text with `formatXML()`

Use `formatXML()` to convert JSON data into XML text.

Use it when you want to:

* Prepare XML for another service.
* Reformat parsed data into readable XML.

`formatXML(JSON)`\
`formatXML(JSON, boolean)`

* `JSON` the structured data you want to convert to XML
* `boolean` whether the output should be visually structured for reading

#### Let’s take a look at some examples:

```ninox
let x := parseXML("<root><item>1</item></root>");
formatXML(x, true)
```

Formats the parsed object back into readable XML text.

```ninox
formatXML({
    contact: {
        @type: "Person",
        firstName: {
            @: "Max"
        },
        lastName: {
            @: "Mustermann"
        },
        phone: [{
            @type: "Mobile",
            @: "(+1) (202) 123 45 67"
        }, {
            @type: "Phone",
            @: "+1.151.11 ++66 14 66"
        }]
    }
}, true)
```

Converts the JSON object into structured XML text. Keys like `@type` become XML attributes. `@` becomes the node text value.

Tips:

* Use the pretty option when humans need to read the result.
* Use compact output when the target system only needs the payload.
* This function is especially useful for API integrations that expect XML instead of JSON.

## Send email messages

Use this function to open an email message from Ninox.

### Work with an email value using `email()`

Use `email()` to convert text into an email value.

Use it when you want to:

* Open your device's email app from an email value.
* Display a formula field as an email field.
* Extract an email address from text and use it with one click.

`email(string)`

* `string` the text value to use as an email address. Include an `@` and a valid domain.

{% hint style="info" %}
Click <i class="fa-envelope">:envelope:</i> in a field or button. Ninox opens your device's default email app.
{% endhint %}

#### Let’s take a look at some examples:

```ninox
email(myEmail)
```

Converts the value in `myEmail` into an email value.

```ninox
email("maria.garcia@company.com")
```

Displays the address as an email value with a clickable mail action.

Tips:

* Keep email addresses correctly formatted. Otherwise, the mail action can return an error.
* A correctly formatted address opens your device's default email app.

{% hint style="info" %}
Integration behavior can depend on your environment, client, and connected services. Confirm HTTP and email workflows in the same setup your users run in production.
{% 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.ninox.com/ninox-scripting/automate-your-workflows/work-with-functions/integration-and-http.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.
