> ## Documentation Index
> Fetch the complete documentation index at: https://checkly-422f444a-angie-api-response-text-override-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API Check Construct

> Learn how to configure API Checks with the Checkly CLI.

<Tip>
  Learn more about API Checks in [the API Checks overview](/detect/synthetic-monitoring/api-checks/overview).
</Tip>

Use API Checks to monitor HTTP endpoints, REST APIs, GraphQL APIs, and other HTTP-based services. The examples below show how to configure monitoring for different types of API endpoints.

<Accordion title="Prerequisites">
  Before creating API Checks, ensure you have:

  * An initialized Checkly CLI project
  * URLs or HTTP endpoints you want to monitor
  * Understanding of HTTP status codes and response behavior
  * Network access to the URLs you want to monitor

  For additional setup information, see [CLI overview](/cli/overview).
</Accordion>

<CodeGroup>
  ```ts Basic Example theme={null}
  import { ApiCheck } from "checkly/constructs"

  new ApiCheck("hello-api-1", {
    name: "Hello API Check",
    description: "Verifies the `/hello` endpoint returns a **successful** response.",
    request: {
      method: "GET",
      url: "https://api.checklyhq.com/hello",
    },
  })
  ```

  ```ts Advanced Example theme={null}
  import { ApiCheck, AssertionBuilder, Frequency } from "checkly/constructs"

  new ApiCheck("advanced-api-check", {
    name: "Advanced API Check",
    description: "User creation succeeds (201) with valid ID.",
    activated: true,
    frequency: Frequency.EVERY_5M,
    locations: ["us-east-1", "eu-west-1"],
    tags: ["api", "critical"],
    maxResponseTime: 10000,
    degradedResponseTime: 5000,
    request: {
      method: "POST",
      url: "https://api.example.com/users",
      headers: [
        { key: "Content-Type", value: "application/json" },
        { key: "Authorization", value: "Bearer {{API_TOKEN}}" },
      ],
      body: JSON.stringify({ name: "Test User" }),
      assertions: [
        AssertionBuilder.statusCode().equals(201),
        AssertionBuilder.jsonBody("$.id").notEmpty(),
        AssertionBuilder.headers(
          "strict-transport-security",
          "max-age=(\\d+)"
        ).greaterThan(10000),
      ],
    },
  })
  ```
</CodeGroup>

## Configuration

The API Check configuration consists of specific API Check options and inherited general check options.

<Tabs>
  <Tab title="API Check">
    | Parameter              | Type      | Required | Default | Description                                                               |
    | ---------------------- | --------- | -------- | ------- | ------------------------------------------------------------------------- |
    | `request`              | `object`  | ✅        | -       | HTTP request configuration object                                         |
    | `degradedResponseTime` | `number`  | ❌        | `10000` | Response time threshold in milliseconds for degraded status               |
    | `maxResponseTime`      | `number`  | ❌        | `20000` | Maximum response time in milliseconds before marking as failed            |
    | `shouldFail`           | `boolean` | ❌        | `false` | Whether a failure should count as a pass (status 400+ reported as passed) |
    | `setupScript`          | `object`  | ❌        | -       | Script to run before the API Check execution                              |
    | `tearDownScript`       | `object`  | ❌        | -       | Script to run after the API Check execution                               |
  </Tab>

  <Tab title="General Check">
    | Property                | Type                    | Required | Default | Description                                                             |
    | ----------------------- | ----------------------- | -------- | ------- | ----------------------------------------------------------------------- |
    | `name`                  | `string`                | ✅        | -       | Friendly name for your check                                            |
    | `description`           | `string`                | ❌        | `null`  | A description of the check. Supports markdown. Max 500 characters       |
    | `activated`             | `boolean`               | ❌        | `true`  | Whether the check is enabled                                            |
    | `alertChannels`         | `AlertChannel[]`        | ❌        | `[]`    | Array of AlertChannel objects for notifications                         |
    | `alertEscalationPolicy` | `AlertEscalationPolicy` | ❌        | -       | Advanced alert settings                                                 |
    | `environmentVariables`  | `object[]`              | ❌        | `[]`    | Check-level environment variables                                       |
    | `frequency`             | `Frequency`             | ❌        | -       | How often to run your check                                             |
    | `group`                 | `CheckGroup`            | ❌        | -       | The CheckGroup this check belongs to                                    |
    | `locations`             | `string[]`              | ❌        | `[]`    | Array of public location codes                                          |
    | `muted`                 | `boolean`               | ❌        | `false` | Whether alert notifications are muted                                   |
    | `privateLocations`      | `string[]`              | ❌        | `[]`    | Array of Private Location slugs                                         |
    | `retryStrategy`         | `RetryStrategy`         | ❌        | -       | Strategy for configuring retries                                        |
    | `runtimeId`             | `string`                | ❌        | -       | The ID of the runtime to use                                            |
    | `runParallel`           | `boolean`               | ❌        | `false` | Run checks in parallel or round-robin                                   |
    | `tags`                  | `string[]`              | ❌        | `[]`    | Array of tags to organize checks                                        |
    | `testOnly`              | `boolean`               | ❌        | `false` | Only run with test, not during deploy                                   |
    | `triggerIncident`       | `IncidentTrigger`       | ❌        | -       | Create and resolve an incident based on the check's alert configuration |
  </Tab>
</Tabs>

### `ApiCheck` Options

<ResponseField name="request" type="object" required>
  The HTTP request configuration that defines the API endpoint to monitor. This is the core component of any API Check.

  **Usage:**

  ```ts theme={null}
  request: {
    method: 'GET',
    url: 'https://api.example.com/users'
  }
  ```

  **Parameters:**

  | Parameter                 | Type      | Required | Default | Description                                                                                          |
  | ------------------------- | --------- | -------- | ------- | ---------------------------------------------------------------------------------------------------- |
  | `method`                  | `string`  | ✅        | -       | HTTP method: `GET` \| `POST` \| `PUT` \| `PATCH` \| `HEAD` \| `DELETE` \| `OPTIONS`                  |
  | `url`                     | `string`  | ✅        | -       | The target URL for the HTTP request                                                                  |
  | `assertions`              | `array`   | ❌        | `[]`    | Response assertions using `AssertionBuilder`                                                         |
  | `basicAuth`               | `object`  | ❌        | -       | Basic auth credentials: `{ username, password }`                                                     |
  | `body`                    | `string`  | ❌        | -       | HTTP request body content                                                                            |
  | `bodyType`                | `string`  | ❌        | `NONE`  | Body type: `JSON` \| `FORM` \| `RAW` \| `GRAPHQL` \| `NONE`                                          |
  | `followRedirects`         | `boolean` | ❌        | `true`  | Whether to automatically follow 30x redirects                                                        |
  | `headers`                 | `array`   | ❌        | `[]`    | Array of `{ key, value }` objects for HTTP headers                                                   |
  | `skipSSL`                 | `boolean` | ❌        | `false` | Whether to skip SSL certificate validation                                                           |
  | `treatResponseBodyAsText` | `boolean` | ❌        | `false` | Feature-flagged support override for known text responses served with a binary `Content-Type` header |
  | `queryParameters`         | `array`   | ❌        | `[]`    | Array of `{ key, value }` objects for query parameters                                               |

  <Warning>
    `treatResponseBodyAsText` is only available when Checkly has enabled the API response body text override for your account. Use it only for endpoints that return text payloads with misleading binary response headers, such as `application/octet-stream`.
  </Warning>

  **Examples:**

  <CodeGroup>
    ```ts REST API theme={null}
    request: {
      method: "GET",
      url: "https://api.example.com/users",
      headers: [
        { key: "Authorization", value: "Bearer {{API_TOKEN}}" },
        { key: "Content-Type", value: "application/json" },
      ],
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.length").greaterThan(0),
        AssertionBuilder.responseTime().lessThan(1000),
      ],
    },
    ```

    ```ts Binary-labelled text response theme={null}
    request: {
      method: "GET",
      url: "https://api.example.com/status",
      treatResponseBodyAsText: true,
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.textBody().contains("OK"),
      ],
    },
    ```

    ```ts GraphQL API theme={null}
    request: {
      method: "POST",
      url: "https://api.example.com/graphql",
      headers: [{ key: "Content-Type", value: "application/json" }],
      body: JSON.stringify({
        query: `
        query GetUser($id: ID!) {
          user(id: $id) {
            id
            name
            email
          }
        }
      `,
        variables: { id: "1" },
      }),
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.data.user.id").equals("1"),
        AssertionBuilder.jsonBody("$.errors").isEmpty(),
      ],
    },
    ```

    ```ts Form POST theme={null}
    request: {
      method: "POST",
      url: "https://httpbin.org/post",
      headers: [
        { key: "Content-Type", value: "application/x-www-form-urlencoded" },
      ],
      body: "name=John+Doe&email=john%40example.com",
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.form.name").equals("John Doe"),
      ],
    },
    ```

    ```ts API with Authentication theme={null}
    request: {
      method: "GET",
      url: "https://api.example.com/protected-resource",
      basicAuth: {
        username: "admin",
        password: "{{SECRET_PASSWORD}}",
      },
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.headers("x-rate-limit-remaining").greaterThan(0),
      ],
    },
    ```
  </CodeGroup>

  **Use cases**: HTTP endpoint monitoring, REST API testing, GraphQL API validation, authentication testing.
</ResponseField>

<ResponseField name="degradedResponseTime" type="number" default="10000">
  Response time threshold in milliseconds for marking the check as degraded. This provides an early warning before the check fails completely.

  **Usage:**

  ```ts highlight={3} theme={null}
  new ApiCheck("performance-check", {
    name: "Performance Monitoring",
    degradedResponseTime: 2000, // Warning at 2 seconds
    maxResponseTime: 5000, // Failure at 5 seconds
    request: {
      method: "GET",
      url: "https://api.example.com/users",
    },
  })
  ```

  **Use cases**: Performance alerting, SLA monitoring, gradual degradation detection.
</ResponseField>

<ResponseField name="maxResponseTime" type="number" default="20000">
  Maximum response time in milliseconds before marking the check as failed. This sets the absolute threshold for check failure based on response time.

  **Usage:**

  ```ts highlight={3} theme={null}
  new ApiCheck("timeout-check", {
    name: "API Timeout Check",
    maxResponseTime: 5000, // Fail if response takes longer than 5 seconds
    request: {
      method: "GET",
      url: "https://api.example.com/slow-endpoint",
    },
  })
  ```

  **Use cases**: Performance monitoring, SLA compliance, timeout management.
</ResponseField>

<ResponseField name="shouldFail" type="boolean">
  Whether a failure should count as a pass. When set to `true`, HTTP status codes 400 and above are reported as passed instead of failed.

  **Usage:**

  ```ts highlight={3} theme={null}
  new ApiCheck("negative-test", {
    name: "Test Error Handling",
    shouldFail: true, // Expect this to fail
    request: {
      method: "GET",
      url: "https://httpbin.org/status/403",
    },
  })
  ```

  **Examples:**

  <CodeGroup>
    ```ts Error Testing theme={null}
    new ApiCheck("error-handling-test", {
      name: "Error Handling Test",
      shouldFail: true, // We expect 4xx/5xx responses
      request: {
        method: "POST",
        url: "https://api.example.com/protected",
        // No auth headers - should return 401
        assertions: [AssertionBuilder.statusCode().equals(401)],
      },
    })
    ```

    ```ts Rate Limit Testing theme={null}
    new ApiCheck("rate-limit-test", {
      name: "Rate Limit Behavior",
      shouldFail: true, // Expecting 429 Too Many Requests
      request: {
        method: "GET",
        url: "https://api.example.com/rate-limited-endpoint",
        assertions: [
          AssertionBuilder.statusCode().equals(429),
          AssertionBuilder.headers("retry-after").isNotNull(),
        ],
      },
    })
    ```
  </CodeGroup>

  **Use cases**: Negative testing, error handling validation, security testing.
</ResponseField>

<ResponseField name="setupScript" type="object">
  Script to run before the API Check execution. Useful for setting up test data or authentication tokens.

  **Usage:**

  <CodeGroup>
    ```ts File Reference highlight={3-5} theme={null}
    new ApiCheck("api-with-setup", {
      name: "API with Setup Script",
      setupScript: {
        entrypoint: path.join(__dirname, "scripts/api-setup.ts"),
      },
      request: {
        method: "GET",
        url: "https://api.example.com/users",
      },
    })
    ```

    ```ts Inline Script highlight={3-8} theme={null}
    new ApiCheck('inline-setup', {
      name: 'API with Inline Setup',
      setupScript: {
        content: `
          const token = await getToken()
          request.headers['Authorization'] = \`Bearer \${token}\`
        `
      },
      request: {
        url: 'https://api.example.com/users'
      }
    })
    ```
  </CodeGroup>

  **Parameters:**

  | Parameter    | Type     | Required | Description                                               |
  | ------------ | -------- | -------- | --------------------------------------------------------- |
  | `entrypoint` | `string` | ❌        | Path to a `.js` or `.ts` file containing the setup script |
  | `content`    | `string` | ❌        | Inline JavaScript/TypeScript code as a string             |

  <Info>
    You must provide either `entrypoint` or `content`, but not both.
  </Info>

  <Tip>Learn more about writing setup and teardown scripts in [the setup and teardown scripts documentation](/detect/synthetic-monitoring/api-checks/setup-and-teardown).</Tip>

  **Use cases**: Test data setup, authentication preparation, environment configuration.
</ResponseField>

<ResponseField name="tearDownScript" type="object">
  Script to run after the API Check execution. Useful for cleaning up test data or resources.

  **Usage:**

  <CodeGroup>
    ```ts File Reference highlight={3-5} theme={null}
    new ApiCheck("api-with-teardown", {
      name: "API with Teardown Script",
      tearDownScript: {
        entrypoint: path.join(__dirname, "scripts/api-teardown.ts"),
      },
      request: {
        method: "GET",
        url: "https://api.example.com/users",
      },
    })
    ```

    ```ts Inline Script highlight={3-9} theme={null}
    new ApiCheck("inline-teardown", {
      name: "API with Inline Teardown",
      tearDownScript: {
        content: `
          // Clean up test data
          console.log('Cleaning up test resources');
          // Cleanup logic here
        `,
      },
      request: {
        method: "GET",
        url: "https://api.example.com/users",
      },
    })
    ```
  </CodeGroup>

  **Parameters:**

  | Parameter    | Type     | Required | Description                                                  |
  | ------------ | -------- | -------- | ------------------------------------------------------------ |
  | `entrypoint` | `string` | ❌        | Path to a `.js` or `.ts` file containing the teardown script |
  | `content`    | `string` | ❌        | Inline JavaScript/TypeScript code as a string                |

  <Info>
    You must provide either `entrypoint` or `content`, but not both.
  </Info>

  <Tip>Learn more about writing setup and teardown scripts in [the setup and teardown scripts documentation](/detect/synthetic-monitoring/api-checks/setup-and-teardown).</Tip>

  **Use cases**: Test data cleanup, resource cleanup, logging and reporting.
</ResponseField>

### `ApiCheck` Assertions

To define `assertions` for the `request` of an `ApiCheck` you should use the `AssertionBuilder`. The following sources are available for API check assertions:

* `statusCode()`: Assert the HTTP status code for the HTTP request, e.g. 200 or 404
* `jsonBody(property?)`: Assert the JSON response body. The property argument accepts a [JSON path expression](/detect/assertions/#json-responses-with-json-path)
* `textBody()`: Assert the body as raw text
* `headers(propery?, regex?)`: Assert a set of response headers, takes the header name as the property argument and a regex to tease out a string from the header value
* `responseTime()`: Assert the total response time of the HTTP request

Learn more in our docs on [Assertions](/detect/assertions).

**Assertion Examples**

* Asserting an HTTP status code

```ts theme={null}
AssertionBuilder.statusCode().equals(200)
// Equivalent to:
{ source: 'STATUS_CODE', comparison: 'EQUALS', target: '200' }
```

* Asserting a part of a JSON response body using a JSON path expression

```ts theme={null}
AssertionBuilder.jsonBody('$.data').greaterThan(2000),
// Equivalent to:
{ source: 'JSON_BODY', property: '$.data', comparison: 'GREATER_THAN', target: '2000' }
```

* Asserting the value of a part of an HTTP response header. Note that you can pass in a regex as the second argument

```ts theme={null}
AssertionBuilder.headers('strict-transport-security', 'max-age=(\\d+)').greaterThan(10000),
// Equivalent to:
{ source: 'HEADERS', regex: 'max-age=(\d+)', property: 'strict-transport-security', comparison: 'GREATER_THAN', target: '10000' }
```

## Examples

<CodeGroup>
  ```ts REST API Check theme={null}
  new ApiCheck("users-api-check", {
    name: "Users API Check",
    maxResponseTime: 5000,
    degradedResponseTime: 2000,
    request: {
      method: "GET",
      url: "https://api.example.com/users",
      headers: [
        { key: "Authorization", value: "Bearer {{API_TOKEN}}" },
        { key: "Content-Type", value: "application/json" },
      ],
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.users.length").greaterThan(0),
        AssertionBuilder.responseTime().lessThan(1000),
      ],
    },
  })
  ```

  ```ts GraphQL API Check theme={null}
  new ApiCheck("graphql-api-check", {
    name: "GraphQL API Check",
    request: {
      method: "POST",
      url: "https://api.example.com/graphql",
      headers: [{ key: "Content-Type", value: "application/json" }],
      body: JSON.stringify({
        query: `
          query GetUser($id: ID!) {
            user(id: $id) {
              id
              name
              email
            }
          }
        `,
        variables: { id: "1" },
      }),
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.data.user.id").equals("1"),
        AssertionBuilder.jsonBody("$.errors").isEmpty(),
      ],
    },
  })
  ```

  ```ts Form Submission Check theme={null}
  new ApiCheck("form-api-check", {
    name: "Form Submission Check",
    request: {
      method: "POST",
      url: "https://httpbin.org/post",
      headers: [
        { key: "Content-Type", value: "application/x-www-form-urlencoded" },
      ],
      body: "name=John+Doe&email=john%40example.com",
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.jsonBody("$.form.name").equals("John Doe"),
      ],
    },
  })
  ```

  ```ts Authenticated API Check theme={null}
  new ApiCheck("protected-api-check", {
    name: "Protected API Check",
    request: {
      method: "GET",
      url: "https://api.example.com/protected-resource",
      basicAuth: {
        username: "admin",
        password: "{{SECRET_PASSWORD}}",
      },
      assertions: [
        AssertionBuilder.statusCode().equals(200),
        AssertionBuilder.headers("x-rate-limit-remaining").greaterThan(0),
      ],
    },
  })
  ```
</CodeGroup>

<Warning>
  When using environment variables in your requests (like `{{API_TOKEN}}`), make sure [they are properly configured in your project or check group settings](/platform/variables).
</Warning>
