Skip to content

Make HTTP requests ​

Make HTTP API calls from your flows to set up test data or verify backend state.

maestro-runner includes a built-in JavaScript HTTP client, so you can call external APIs directly from your flows. This is useful for setting up test data, authenticating users, or verifying backend state without navigating through the UI.

Making requests ​

Use the shorthand methods for standard requests:

  • http.get(url, options)
  • http.post(url, options)
  • http.put(url, options)
  • http.delete(url, options)

For other methods (like PATCH), use the generic request function. In maestro-runner the HTTP method is the first argument:

javascript
const response = http.request('PATCH', 'https://example.com', {
    body: JSON.stringify({ status: "active" })
});

Different from Maestro

Maestro documents http.request(url, { method: "PATCH" }). That form does not work in maestro-runner, which expects http.request(method, url, options).

Working with JSON ​

The global json() function parses a JSON string into a JavaScript object. A successful response whose body is a JSON object also exposes it as response.json.

For example, assume that https://api.example.com/user/1 returns:

json
{
  "id": 1,
  "email": "user@example.com",
  "profile": {
    "name": "Jane Doe",
    "age": 32
  }
}

You can parse the response body and access fields directly:

js
// script.js
const response = http.get('https://api.example.com/user/1');

// Parse the body and access fields directly
const userData = json(response.body);
output.username = userData.profile.name;

In this example, the user's name is read from profile.name and assigned to output.username.

Request options ​

The second argument is an options object. These keys are supported:

OptionTypeDescription
headersObjectRequest headers, such as an authorization token.
bodyString or ObjectThe payload. A plain object is sent as JSON with Content-Type: application/json.
timeoutNumberTimeout in milliseconds. The default is 30000.
insecureBooleanSkip TLS certificate verification, for example for a staging server with a self-signed certificate.

Headers ​

javascript
const response = http.get('https://example.com', {
    headers: {
        'Authorization': 'Bearer ' + output.token,
        'Content-Type': 'application/json'
    }
});

Request body ​

For POST, PUT, or PATCH requests, provide the payload in body. Stringify JSON objects yourself so the body is exactly what you expect:

javascript
const response = http.post('https://example.com/login', {
    body: JSON.stringify({
        username: "test_user",
        password: "password123"
    })
});

Multipart uploads are not supported

Maestro's multipartForm option (file uploads) is not available in maestro-runner. If you pass it, it is ignored. Upload through the app's own UI, or through your backend's test endpoints with a JSON body.

The response object ​

Every HTTP call returns a response object with these fields:

Field nameTypeDescription
okBooleantrue if the request was successful (status 200-299).
statusNumberThe HTTP status code (e.g., 200, 404).
bodyStringThe raw string body of the response.
headersObjectHTTP response headers.
jsonObject or nullThe parsed body when it is a JSON object, otherwise null.

Usage example ​

A common pattern is to use the API to seed test data before executing UI interactions. This makes sure the data you need is present without slow and flaky UI setup steps.

In this example, a script creates a new appointment with a POST request and stores the appointmentTitle in the output object for the main flow.

javascript
// create_appointment.js
const response = http.post('https://my-api.com/v1/appointments', {
    body: JSON.stringify({
        title: "Maestro Health Check",
        date: "2026-02-10"
    }),
    headers: { 'Content-Type': 'application/json' }
});

const data = json(response.body);

// Store the title globally so the Flow can assert on it
output.appointmentTitle = data.title;

Once the script has run, the stored values can be used in any later step of the flow:

yaml
# flow.yaml
appId: com.example.app
---
- launchApp
- runScript: create_appointment.js
- tapOn: "My Appointments"
# Assert that the data we just created via API is now visible in the UI
- assertVisible: ${output.appointmentTitle}

Next step ​

Learn how to generate synthetic test data at runtime, making your tests more flexible and less dependent on hard-coded values.