Skip to content

Latest commit

 

History

History
573 lines (480 loc) · 17.2 KB

File metadata and controls

573 lines (480 loc) · 17.2 KB
title API Check Construct
description Learn how to configure API Checks with the Checkly CLI.
sidebarTitle API Check
Learn more about API Checks in [the API Checks overview](/detect/synthetic-monitoring/api-checks/overview).

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.

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.

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",
  },
})
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),
    ],
  },
})

Configuration

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

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
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

ApiCheck Options

The HTTP request configuration that defines the API endpoint to monitor. This is the core component of any API Check.

Usage:

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
`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`.

Examples:

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),
  ],
},
request: {
  method: "GET",
  url: "https://api.example.com/status",
  treatResponseBodyAsText: true,
  assertions: [
    AssertionBuilder.statusCode().equals(200),
    AssertionBuilder.textBody().contains("OK"),
  ],
},
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(),
  ],
},
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"),
  ],
},
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),
  ],
},

Use cases: HTTP endpoint monitoring, REST API testing, GraphQL API validation, authentication testing.

Response time threshold in milliseconds for marking the check as degraded. This provides an early warning before the check fails completely.

Usage:

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.

Maximum response time in milliseconds before marking the check as failed. This sets the absolute threshold for check failure based on response time.

Usage:

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.

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:

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

Examples:

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)],
  },
})
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(),
    ],
  },
})

Use cases: Negative testing, error handling validation, security testing.

Script to run before the API Check execution. Useful for setting up test data or authentication tokens.

Usage:

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",
  },
})
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'
  }
})

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
You must provide either `entrypoint` or `content`, but not both.

Learn more about writing setup and teardown scripts in the setup and teardown scripts documentation.

Use cases: Test data setup, authentication preparation, environment configuration.

Script to run after the API Check execution. Useful for cleaning up test data or resources.

Usage:

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",
  },
})
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",
  },
})

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
You must provide either `entrypoint` or `content`, but not both.

Learn more about writing setup and teardown scripts in the setup and teardown scripts documentation.

Use cases: Test data cleanup, resource cleanup, logging and reporting.

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
  • 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.

Assertion Examples

  • Asserting an HTTP status code
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
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
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

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),
    ],
  },
})
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(),
    ],
  },
})
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"),
    ],
  },
})
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),
    ],
  },
})
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).