# Using the API Test Step Builder

{% hint style="warning" %}
Due to recent platform-wide naming, navigation, and URL changes in the product, you may notice some discrepancies between the product and the screenshots displayed in our technical documentation. The instructions and actual pages in the product are still valid and haven’t changed. Please bear with us as we update our screenshots to better match the in-product experience. See the full scope of changes on [Naming and Navigation Menu changes - Summary List](https://docs.thousandeyes.com/whats-new/naming-and-nav-phase-2-changes).
{% endhint %}

The Step Builder is where most of the API test configuration occurs.

![](/files/KU8fx5hLY1aiWnminLDP)

You can use the Step Builder to chain together API calls in a series of steps, each with its own API endpoint. You can extract variables from one API call for use in subsequent steps in the test. For example, obtaining a product SKU in one step and then using that SKU to fetch a price.

## Step Builder Settings

Each step corresponds to a single API call. Within each step, you can optionally specify additional information on a series of tabs:

* **Authentication** - Configure either `Basic` ([RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617)) or `Bearer` ([RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750)) HTTP authentication schemes
* **Parameters** - Specify one or more key-value pairs to include in the request's query string
* **Headers** - Add custom headers if the API endpoint requires them.
* **Body** - For POST or PUT methods, you can send a customized payload.
* **Assertion rules** - The default is HTTP response success code 200, but you can actually look for or exclude specific error codes. You can also look for strings in the response such as a product code of “tigers” when the desired response is “kittens”.
* **Post-request options** - Use this feature to extract variables from a response and pass them to subsequent steps within the same test.

### Basic Step Builder Navigation Elements

![](/files/zVVlZNIk7OUKlkqdmAcA)

Each step has a name, a number in the sequence, an API method, and an endpoint.

* **Name:** Enter a short description of what this step in the API test is intended to do.
* **API Methods:** Choose GET (default), POST, PUT, or DELETE.
* **Endpoint:** The endpoint is a URL for the API call, for example `https://api.thousandeyes.com/v6`

### Authentication Tab

![](/files/YJQVhFR47P3Imw8kOXQh)

Authentication Types supported are:

* **None** - default
* **Basic** - enter a username (plain text) and password (obscured) or use the Credentials Repository.
* **Bearer Token** - enter a token (obscured) or use the Credentials Repository.
* **OAuth 2.0** - generates a new token for every test round.

Click the key icon to access your ThousandEyes Credentials Repository, as described in [Working With Secure Credentials](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/working-with-secure-credentials). You can find your ThousandEyes Credentials Repository under **Network & App Synthetics > Test Settings > Credentials Repository**.

Depending on your own environment and whose API you’re testing, you may not need to provide explicit authentication for each step in your test.

Don’t put user credentials in global predefined variables, parameters, or headers. Use the **Authentication** tab and the **Credentials Repository**.

Credentials should only be used in the **Authentication** tab, which automatically configures the `Authorization` HTTP request header. The ThousandEyes platform redacts/obscures the value of the `Authorization` header, whether or not a Credential was used from the **Credentials Repository**.

**Verify SSL Certificate**: By default, certificate-related errors will result in a test error. Uncheck this box to ignore certificate errors during SSL/TLS negotiation.

### Using OAuth 2.0 With the API Test Type

![](/files/LZGPW0mVaxZFsr0RqEVI)

In OAuth 2.0, an HTTP request is sent to an authentication server in order to obtain a uniquely generated one-time token used for each test round, using a client ID and a client secret as credentials.

The Step Builder in ThousandEyes generates two steps for OAuth, each pointing to a different endpoint:

* **Step 1**: Go to the OAuth URL endpoint to get a token, which is saved as a variable.
* **Step 2**: Use that token to connect to the application’s endpoint URL.

The workflow is automated so that as soon as you choose OAuth 2.0 as the authentication method, the Step Builder automatically creates a Step 1 titled **OAuth 2.0**. A second step, which you will name, contains all the input information from both steps.

![](/files/QefP9bhE2nTjv9ZiF0RR)

Most of this is set up on the **Authentication** tab in the Step Builder, and then you’ll use the **Assertion Rules** tab to specify what constitutes success. ThousandEyes automatically creates the variable and shows the variable name on the **Authentication** tab. You don't need to set post-request variables for the "Step 1 OAuth" request.

Note that the default **Step 1** (the "OAuth 2.0" step) includes default assertions. These assertions cannot be modified for the OAuth 2.0 step.

* HTTP response code is 200
* Response body contains "access\_token"

On the **Authentication** tab, provide the following information:

* **Token URL** - Endpoint used for the OAuth authentication server. This endpoint is used to get the access token.
* **Client ID** - Unique identifier for your application, provided by the API service when you register your application (equivalent to a username).
* **Client Secret** - Confidential key that you use to authenticate with the OAuth server (equivalent to a password). Click the key icon to use a secret stored in your organization’s ThousandEyes Credentials Repository. See [Working With Secure Credentials](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/working-with-secure-credentials) for more information.
* **Scope** - A list of permissions that you are requesting. For example, read:org would request organization-wide read permission.
* **Client Authentication** defines how your user credentials, namely your Client ID and Client Secret are sent in the authentication request. This field has two options:
  * Use **Send as Basic Auth Header** to send credentials in the request header.
  * Use **Send Client Credentials in Body** to send credentials in the request body.

### Parameters Tab

![](/files/TlAq4aFhq1Wr2WkSZH7A)

The **Parameters** tab lets you specify a series of one or more key-value pairs to pass in as parameters to the API call defined for this step.

For example, the ThousandEyes API has a parameter named `aid` which is used to set the account group context. You can include this parameter in your API test by creating a parameter with a key of `aid` and the specific value of your choosing.

You can also use variables in parameter keys or values. Continuing with the `aid` parameter example above, you could:

* Use one step to get a list of account groups and extract one account group ID. This ID would be assigned to a variable and passed to a later step to set the account group context of its request.
* In a subsequent step, add a parameter with a key of `aid`, and pass in that `{{aid}}` variable as the value.

Variables can be used in either Key or Value field.

### Headers Tab

![](/files/oThE4vaJr3OfdsIm1sFZ)

The **Headers** tab starts pre-populated with default headers, including a few custom built-in headers required in order for the ThousandEyes Cloud or Enterprise Agent that will be running this API test.

Note that:

* The built-in headers for ThousandEyes can’t be modified.
* You can use variables for header values, but not for header names. For example, you could add `x-custom-header` with `{{my_var}}`.

### Body Tab

![](/files/ME4ACjXZfIHvMQKznOUE)

The **Body** tab is available for steps that use an API method of POST or PUT. Use this tab to send customized information to the test target.

### Assertion Rules Tab

![](/files/N71W2y3oGDZpBe6fiz0w)

Use the **Assertion Rules** tab to define one or more success factors for this one step, formatted as subject – operator – condition. It’s how you define what “good” looks like for this API. All assertion rules are ANDed together. Basically, assertion rules allow validation against HTTP responses to your API calls.

The default assertion rule for every step is a simple HTTP response status code from the API test target, which is 200 (OK). You can define more complicated assertion rules, depending on what API functionality you’re trying to monitor. For example, you might want to test an API and ensure that the API is not only up and responding, but that it’s correctly identifying unauthorized users.

An unsuccessful API test appears in the ThousandEyes test view with an error. These errors are related to the ThousandEyes API test itself, rather than errors issued by the API endpoints. You can set ThousandEyes alert rules to generate alerts, and also surface this test in the Dashboard.

Assertions are important for the Completion metric in the ThousandEyes API test view.

### Post-Request Options Tab

![](/files/SlIdvkDsZNcJqwLITnqF)

The **Post-Request Options** tab defines what happens at the end of this step when the API call is finishing up.

* **Collect response for this API step** is a checkbox that causes the API response to be stored and made available on the ThousandEyes platform in the test view. Un-check if the response contains sensitive data.
* Extract **Variables** using key-value pairs, to use them in subsequent API calls within this test.
* You can add a **Post-API-Call Delay** in milliseconds. This is an arbitrary, artificial delay between this step and the next one. Adding a delay can be helpful if you know that you need a certain latency between one API call and the next, especially if you need to avoid race conditions.

The API test type expects variables to be passed between steps using JSON syntax.

{% hint style="warning" %}
Regarding the checkbox **Collect Response for this API Step**:

If you expect the API response to contain restricted data, de-select this option to keep the response on the ThousandEyes agent, and prevent it from being sent to the ThousandEyes platform. Sensitive data (anything that is subject to heightened regulatory or contractual handling requirements) should never be submitted to the ThousandEyes platform.
{% endhint %}

## About Variables

Variables in the API test type are key-value pairs, similar to credentials in the ThousandEyes [Credentials Repository](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/working-with-secure-credentials), except that ordinary variables are not secret.

Variables apply only to a single API test.The key is a name that you provide, and the value comes from one of the following places:

* Another previous step in the same test
* The **Predefined Variables** under **Environment Setup** in the Step Builder.

### Helper Dropdown Menu

When configuring API tests, you can use `{{` in any text field that allows for variables to open a dropdown list of [predefined variables](###adding-predefined-variables), functions, and [credentials](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/working-with-secure-credentials) that can be used inline:

![](/files/RNl8fkoZlBELlJ1s7Rz7)

You can then scroll through the list, continue typing to filter by name, or manually enter the full name of the variable, function, or credential. Those full names have the following structures:

```
{{myVariableName}}
{{@functionName()}}
{{$credentialName}}
```

You can use `{{@` and `{{$` as well to filter the list by functions or credentials respectively, as shown below:

![](/files/e1YoL7bDdkFBVK5CqrOB)

The table below outlines the available functions:

| Function             | Description                                                                                                                               | Parameter(s)                                                   | Example Return Value |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | -------------------- |
| epochtime()          | Returns the number of seconds since Jan 1, 1970 as an integer                                                                             | -                                                              | 1747235979           |
| timestamp()          | Returns the current datetime as a string, formatted in ISO8601 standard YYYY-MM-DDThh:mm:ssZ format.                                      | -                                                              | 2025-05-14T15:20:23Z |
| timestamp().tz()     | Returns the current datetime as a string, formatted in IS8601 standard YYYY-MM-DDThh:mm:ss+00:00 format with the given timezone’s offset. | Timezone code (for example, PST)                               | 2025-05-14T15:20:23Z |
| timestamp().format() | Returns the current datetime as a string in the given format.                                                                             | Date format (for example, YYYY-MM-DD)                          | 2025-05-14           |
| timestamp().add()    | Returns a datetime with the given offset                                                                                                  | Requires an integer value and a unit (for example, 8, minutes) | -                    |

**Helper Dropdown and Variable FAQ**

Q. In what fields can I use variables, functions, and credentials with the `{{ }}` syntax?

A. The syntax can be used in parameter keys and values, header values, the request body, response body assertions, and the URL.

Q. Can I use the `{{ }}` syntax for content other than in-line variables, functions, and credentials?

A. No. If the `{{ }}` syntax is used, but the text within the brackets is not a valid variable, function, or credential, it will be replaced with an empty string.

Q. What formatting options are available?

A. The helper dropdown list uses the [dayjs](https://www.npmjs.com/package/dayjs) library. The available formats can be found [here](https://day.js.org/docs/en/display/format#list-of-all-available-formats).

Q. Does function order matter when chaining multiple functions together?

A. No, function order does not matter.

Q. Can `.add()` be used with `epochtime()`?

A. No, you can't add time to the `epochtime()` function.

Q. What are the supported units for `add()`?

A. The supported units can be found in the [dayjs library documentation](https://day.js.org/docs/en/manipulate/add#docsNav).

### Adding Predefined Variables

![](/files/ndynHFiTXzABa9f7iYMj)

Use **Predefined Variables** to re-use a value that isn’t actually fetched in an API call. This is helpful when you want to parameterize a value throughout your API test rather than specifying the value over and over again. For example, when using the ThousandEyes API, suppose you are working in the context of an account group with an identifier of `1234`.

Instead of explicitly providing the account group every time for each step:

```
GET /v7/users?aid=1234
GET /v7/tests?aid=1234
GET /v7/agents/?aid=1234&agentTypes=enterprise
```

You could create a predefined variable and name it `my_aid`and then use it in a complex multi-step API test as follows:

```
GET /v7/users?aid={{my_aid}}
GET /v7/tests?aid={{my_aid}}
GET /v7/agents/?aid={{my_aid}}&agentTypes=enterprise

```

### Post-Request Variables

The **Variables** list on the **Post-Request Options** tab allows you to extract data from a step’s HTTP response, turn it into a named variable, and then reference that variable in subsequent steps. This feature is what allows you to chain API calls together.

For example, suppose you’re working with the ThousandEyes API, configuring a step that fetches the first user from a list within your own account group. You might see a response body similar to the one shown below:

![](/files/TOdJAgP0jhy9bOfaFwpn)

The `245` portion from the above response could be extracted into a variable that you name `my_user_id`. You would then specify a value of `users[0].uid`.


---

# 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://docs.thousandeyes.com/product-documentation/tests/api-tests/using-the-step-builder.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.
