diff --git a/detect/synthetic-monitoring/api-checks/assertions.mdx b/detect/assertions.mdx similarity index 65% rename from detect/synthetic-monitoring/api-checks/assertions.mdx rename to detect/assertions.mdx index d95e6761..3058a1dd 100644 --- a/detect/synthetic-monitoring/api-checks/assertions.mdx +++ b/detect/assertions.mdx @@ -1,57 +1,46 @@ --- -title: 'Writing assertions for API checks' -description: 'Writing assertions for API checks' +title: 'Defining Assertions' +description: 'Add assertions to validate your check results' sidebarTitle: 'Assertions' --- - - -The response of an API request can be checked for correctness and timeliness by using assertions on the response data. Assertions are flexible statements that combine preset modifiers with custom values to meet the needs of a broad set of use cases. +Uptime monitors and API checks allow you to define assertions to validate a response and check its data for correctness. ## How assertions work -Assertions are statements you create that check one aspect of the HTTP response. You can create multiple assertions for one check that assert various aspects of a response, for example: +Assertions let you validate specific parts of a check's response. For example: -- HTTP response status equals 200. -- HTTP response body equals the text "success". -- HTTP response time is lower than 2000 milliseconds. -- HTTP response header "X-Custom-Header" equals "SomeValue". -- HTTP response JSON object has a key called "accountBalance" with a value greater than 9999 +- **URL monitor**: HTTP response status equals 200. +- **TCP monitor**: Response contains expected string (e.g. OK). +- **DNS monitor**: Resolved IP equals 93.184.216.34. +- **API check**: HTTP response header "X-Custom-Header" equals "SomeValue". + +### Sources In each assertion, a **source** is connected to a **comparison** and a **target**. ![api monitoring assertions example 1](/images/docs/images/api-checks/assertions-1.png) -In some cases a **property** is added, for example when asserting headers or JSON response bodies. +In some cases a [property](#property) is added, for example when asserting API check headers or JSON response bodies. ![api monitoring assertions example 2](/images/docs/images/api-checks/assertions-2.png) Assertions are executed from top to bottom. If one assertion fails, the full check is considered as failed. -## Source - -On each API check assertion, the following sources are available: +Supported assertion sources vary by monitor type. Refer to the documentation of the specific monitor (API, DNS, TCP, etc.) to see which sources are available. -- **Status code:** The HTTP response status, parsed as an integer. -- **JSON body:** The response body parsed as a JSON object. -- **Text body:** The response body as plain text. -- **Headers:** The response headers as an array of key/value pairs. -- **Response time:** The response time of the full API request in milliseconds, parsed as an integer value. +### Property -## Property +The property field is a free-form text input that lets you point to a specific part of the data you want to validate. It’s available for the following types of assertion [sources](#sources): -The property field is a free form text field used to identify the name of a header, the part of a JSON object using JSON path or part of a text body. +- **JSON response bodies**: Use a JSON path expression in the form of dot-separated strings to +target nested properties in an object, i.e. `$.product.size` or an item in an array, i.e. `$.[1].key`. [Learn more](#json-responses-with-json-path). -- With **JSON response bodies**, the property field accepts **JSON path** expressions in the form of dot-separated strings to -target nested properties in an object, i.e. `$.product.size` or an item in an array, i.e. `$.[1].key` +- **Text response bodies**: Provide a regular expression with a capture group to pick out parts, +i.e. ``. [Learn more](#text-body-assertions-with-regular-expressions). -- With **text response bodies**, the property field accepts a **regular expression** with a capture group to pick out parts, -i.e. `` - -- With **headers**, you provide the header you want to assert in the property field, i.e. `Content-Type`. You can even add a -regular expression after that to tease out a specific part of the header. - -Read more about asserting JSON response bodies below. +- **API check headers**: Enter the header name you want to assert on i.e. `Content-Type`. You can even add a +regular expression after that to tease out a specific part of the header. [Learn more](#using-regular-expressions). ## Comparison @@ -75,19 +64,14 @@ Response time is empty? JSON Object is less than? We block out the comparisons w The target field is a free form text field that determines the desired outcome of your assertion. - ## JSON responses with JSON path -You can use **JSON path** to specify which field of a JSON response body should be asserted. JSON path is a query language +For monitors that support JSON body assertions, you can use **JSON path** to specify which field of a JSON response body should be asserted. JSON path is a query language similar to Xpath for XML, but in general a lot more intuitive and simpler to use. -> For Checkly to be able to parse the JSON body, the `Content-Type` header of the response should be set to `application/json`. - ### JSON path primer -JSON path only uses a handful of operators in its queries. Not all of them are useful in the context of assertions. -Here is an adapted set of examples based on [Stefan Goessner's 2007 introduction post](http://goessner.net/articles/JsonPath/). - +The following JSONPath operators are available: JSONPath | Description -----------------|------------ @@ -153,7 +137,6 @@ JSONPath | Description `$.store..price` | The price of everything in the store `$.store.book.length` | The length of the book array `$..book[2]` | The third book -`$..book[(@.length-1)]` | The last book via script subscript `$..book[-1:]` | The last book via slice `$..book[0,1]` | The first two books via subscript union `$..book[:2]` | The first two books via subscript array slice. @@ -163,8 +146,7 @@ JSONPath | Description `$..book[?(@.price<30 && @.category=="fiction")]` | Filter all fiction books cheaper than 30 `$..*` | All members of JSON structure -Use this [online editor to play around](https://jsonpath.com/), or look at the examples below. We use this [jsonpath NPM -module](https://github.com/dchester/jsonpath) under the hood. +Use this [online editor](https://jsonpath.com/) to try out your own JSONPath expressions. For a full description of the syntax and semantics, see [RFC 9535](https://datatracker.ietf.org/doc/rfc9535/). ### Asserting basic types @@ -218,23 +200,24 @@ Regular expressions give you the power to extract specific parts of text from a You can use regular expressions with two assertions sources: 1. **Text body:** Use the property field to add your regex. -2. **Headers:** First select the header you are interested in the property field, then click "add regex". +2. **API check headers:** First select the header you are interested in the property field, then click "add regex". + +Here is an example: -Under the hood, we use the stock Javascript regular expressions implementation. Specifically, we use the [.match()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) -method. We *do not use the `/g` modifier* and return the first matched group the expression finds. +``` +The quick brown fox jumps over the lazy dog. It barked. +``` -Sounds more complicated than it is. Here is an example: +And the following regular expression: -```javascript -const paragraph = 'The quick brown fox jumps over the lazy dog. It barked.' -const regex = /quick (.*) fox/ -const found = paragraph.match(regex) -console.log(found) - -// [ 'quick brown fox', -// 'brown', -// index: 4, -// input: 'The quick brown fox jumps over the lazy dog. It barked.' ] +``` +quick (.*) fox +```` + +The assertion extracts: + +``` +brown ``` In the example above we return the string `brown` because it is the first capture group, the `(.*)` bit. @@ -244,25 +227,18 @@ The first item `quick brown fox` is the full match, which we do not return. ### Text body assertions with regular expressions -If our API returns HTML, there might be a `lang="en"` attribute in the `` element. We can capture the two character -country/language code value of that attribute with the following expression. +When a check returns a text-based response, you can use regular expressions to extract and assert on specific parts of the response body. + +For example, an HTML document might include a `lang="en"` attribute on the `` element. You can capture the two-character language code using the following regular expression: ![api monitoring use regular expression on text body](/images/docs/images/api-checks/assertions-10.png) The expression `lang="(.{2})"` means 'grab any of the first two characters between `lang="` and the next `"`'. If we were sure there are only non-capital characters, we could tighten it up a bit with `lang="([a-z]*)"`. -### Header assertions with regular expressions - -We can use regular expressions with headers too. In this example, we check if the `max-age` property of a `Strict-Transport-Security` -response header is above a `100000` - -![api monitoring use regular expression on http header](/images/docs/images/api-checks/assertions-11.png) - - - - - - +### API check header assertions with regular expressions +We can use regular expressions with [API check headers](/detect/synthetic-monitoring/api-checks/configuration#headers) too. In this example, we check if the `max-age` property of a `Strict-Transport-Security` +response header is above a `100000`. +![api monitoring use regular expression on http header](/images/docs/images/api-checks/assertions-11.png) \ No newline at end of file diff --git a/detect/synthetic-monitoring/api-checks/requests.mdx b/detect/synthetic-monitoring/api-checks/configuration.mdx similarity index 72% rename from detect/synthetic-monitoring/api-checks/requests.mdx rename to detect/synthetic-monitoring/api-checks/configuration.mdx index 575c7e81..d26d7664 100644 --- a/detect/synthetic-monitoring/api-checks/requests.mdx +++ b/detect/synthetic-monitoring/api-checks/configuration.mdx @@ -1,32 +1,25 @@ --- -title: 'Requests' -description: 'Requests' -sidebarTitle: 'Requests' +title: 'Configuration' +description: 'Configure your API checks to validate responses and ensure your endpoints behave as expected.' +sidebarTitle: 'Configuration' --- import GenericRuntimeVariablesTable from '/snippets/generic-runtime-variables-table.mdx'; -A full HTTP request is created by filling out the various parts of the HTTP request settings screen. Not all sections and fields -are mandatory, only a name and URL are required to get going. +While configuring up your API check, you can run the request and its assertions using the **Run request** button. This will run the API check on production infrastructure and help you debug any issues. -While building up your API check, you can run the request and its assertions using the **Run request** button. This will run the -API checks on the production infrastructure and help you debug any issues. +## Basic Setup -## Method & URL +Start by specifying the endpoint you want to track. -An API check starts with creating an HTTP request including a HTTP verb (GET, POST, PUT, etc.) and a URL at the minimum. +![api monitoring request configuration](/images/docs/images/api-checks/api-request-configuration.png) -![api monitoring http request](/images/docs/images/api-checks/http-request-method.png) - -- Available methods are `GET, POST, PUT, HEAD, DELETE, PATCH` -- URL's are checked for correctness and must start with either `http://` or `https://` - -Checking the **"This request should fail"** checkbox allows you to treat HTTP error codes (4xx and 5xx) as correct responses. This comes in handy when testing 404 pages or 500 error handling. - -When enabled: - * ✅ Failed responses (4xx, 5xx) → check passes - * ✅ Successful responses → check passes - * ❌ Failed assertions → check fails +- **URL**: The HTTP(S) URL to monitor (e.g. https://checklyhq.com). URL's are checked for correctness and must start with either `http://` or `https://`. +- **Request methods**: Available methods are `GET, POST, PUT, HEAD, DELETE, PATCH`. +- **IP family**: Defaults to IPv4. +- **Skip SSL**: Skip SSL certificate validation. +- **Follow redirects**: Automatically follow 30x redirects. +- **This request should fail**: Treat HTTP error codes (4xx and 5xx) as passed. Please note that successful responses still pass. Only failed assertions will cause the check to fail. ## Body @@ -48,7 +41,6 @@ JSON bodies are commonly used with REST APIs. ### GraphQL - This option also sets the `Content-Type` request header to `application/json`, but allows you to type GraphQL queries and format them as such, i.e. @@ -93,10 +85,8 @@ This section allows you to add query parameters to the request URL in a structur ## Basic authentication -To add [HTTP basic authentication parameters](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) to your API -request, use the username and password fields in the relevant section. - -![api monitoring basic auth](/images/docs/images/api-checks/http-request-auth.png) +Add [HTTP basic authentication parameters](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) to your API +request by entering a username and password in the Authentication tab. ## Accessing environment variables @@ -167,6 +157,28 @@ parses your spec and prompts you to make some decisions about which requests are - **Add a "group" tag:** Copy the name of you spec to a tag and add it to each imported request. This helps filtering and grouping related checks in the Checkly dashboard. +## Assertions + +The response of an API request can be checked for correctness and timeliness by using assertions on the response data. This allows you to verify things such as: + +- HTTP response status equals 200. +- HTTP response body equals the text "success". +- HTTP response time is lower than 2000 milliseconds. +- HTTP response header "X-Custom-Header" equals "SomeValue". +- HTTP response JSON object has a key called "accountBalance" with a value greater than 9999. + +![api check assertions](/images/docs/images/api-checks/api-check-assertions.png) + +On each API check assertion, the following sources are available: + +- **Status code:** The HTTP response status, parsed as an integer. +- **JSON body:** The response body parsed as a JSON object. To enable parsing, the Content-Type header of the response should be set to application/json. +- **Text body:** The response body as plain text. +- **Headers:** The response headers as an array of key/value pairs. +- **Response time:** The response time of the full API request in milliseconds, parsed as an integer value. + +For more details, see our documentation on [Assertions](/detect/assertions). + ## Responses In almost all cases, you have full access to the HTTP response for assertions. We also store the full response diff --git a/detect/synthetic-monitoring/api-checks/overview.mdx b/detect/synthetic-monitoring/api-checks/overview.mdx index e30f047b..24fffe74 100644 --- a/detect/synthetic-monitoring/api-checks/overview.mdx +++ b/detect/synthetic-monitoring/api-checks/overview.mdx @@ -59,25 +59,14 @@ API checks perform comprehensive endpoint validation: API checks are ideal for testing both internal services and external API dependencies your application relies on. -## Timeouts +## Response Metrics -All API checks are capped at a timeout of **30 seconds**. With each request, we record the most relevant timing phases. This can help you troubleshoot slow responses, e.g. your DNS might be slow. +With each request, we record the most relevant timing phases: -The timing phases correspond to the Node.js request library timing phases: - -- `wait`: Duration of socket initialization - `dns`: Duration of DNS lookup - `tcp`: Duration of TCP connection - `firstByte`: Duration of HTTP server response - `download`: Duration of HTTP download -![api monitoring timing phases](/images/docs/images/api-checks/timing-phases.png) - - -## Interpreting the `wait` metric - -The "wait" time is the time it takes for the underlying Node HTTP module to get a socket from the network layer. -This time can vary quite a bit, usually it goes from 900 microseconds to some milliseconds. Most clients for API / webpage will have this lag too. - - +This can help you troubleshoot slow responses, e.g. your DNS might be slow. diff --git a/detect/uptime-monitoring/dns-monitors/configuration.mdx b/detect/uptime-monitoring/dns-monitors/configuration.mdx index 127ff9c3..099778ea 100644 --- a/detect/uptime-monitoring/dns-monitors/configuration.mdx +++ b/detect/uptime-monitoring/dns-monitors/configuration.mdx @@ -45,9 +45,10 @@ With JSON path assertions, you can: * `$.Answer[0].TTL` → validate TTL values are within expected ranges * `$.Answer[0].data` → check specific IP addresses or record values +* `$.Answer.length` → check how many records were returned * `$.Status` → verify the DNS response status code -Learn more about JSON path assertions: [JSON responses with JSON path](/detect/synthetic-monitoring/api-checks/assertions/#json-responses-with-json-path). +Learn more about JSON path assertions: [JSON responses with JSON path](/detect/assertions#json-responses-with-json-path). ### JSON Response Schemas diff --git a/detect/uptime-monitoring/tcp-monitors/configuration.mdx b/detect/uptime-monitoring/tcp-monitors/configuration.mdx index ae91cec6..26ee455e 100644 --- a/detect/uptime-monitoring/tcp-monitors/configuration.mdx +++ b/detect/uptime-monitoring/tcp-monitors/configuration.mdx @@ -35,6 +35,8 @@ Configure connection timeouts and data transmission assertions: * **Read timeout:** Time to wait for response after connection (default: 10 seconds) * **Data to send:** Optional data to transmit after establishing connection +For more details, see our documentation on [Assertions](/detect/assertions). + ### Response Validation Validate the service response for more precise monitoring: diff --git a/detect/uptime-monitoring/url-monitors/configuration.mdx b/detect/uptime-monitoring/url-monitors/configuration.mdx index e661a938..aa3f71b9 100644 --- a/detect/uptime-monitoring/url-monitors/configuration.mdx +++ b/detect/uptime-monitoring/url-monitors/configuration.mdx @@ -27,6 +27,8 @@ Use assertions to validate the status code of your URL request. When one or more URL monitor assertions interface showing status code configuration +For more details, see our documentation on [Assertions](/detect/assertions). + ### Response Time Limits Set performance thresholds to ensure your application meets speed requirements: diff --git a/docs.json b/docs.json index fa92c7a5..f202b07c 100644 --- a/docs.json +++ b/docs.json @@ -192,11 +192,10 @@ "group": "API Checks", "pages": [ "detect/synthetic-monitoring/api-checks/overview", - "detect/synthetic-monitoring/api-checks/api-structure", - "detect/synthetic-monitoring/api-checks/requests", - "detect/synthetic-monitoring/api-checks/assertions", + "detect/synthetic-monitoring/api-checks/configuration", "detect/synthetic-monitoring/api-checks/set-up-and-tear-down", "detect/synthetic-monitoring/api-checks/snippets", + "detect/synthetic-monitoring/api-checks/api-structure", "detect/synthetic-monitoring/api-checks/troubleshooting" ] }, @@ -251,7 +250,8 @@ "detect/testing/using-env-variables", "detect/testing/playwright-reporter" ] - } + }, + "detect/assertions" ] }, { @@ -1200,7 +1200,14 @@ } }, "redirects": [ - -] + { + "source": "/detect/synthetic-monitoring/api-checks/assertions", + "destination": "/detect/synthetic-monitoring/api-checks/configuration#assertions" + }, + { + "source": "/detect/synthetic-monitoring/api-checks/requests", + "destination": "/detect/synthetic-monitoring/api-checks/configuration" + } + ] } diff --git a/images/docs/images/api-checks/api-check-assertions.png b/images/docs/images/api-checks/api-check-assertions.png new file mode 100644 index 00000000..294f5c96 Binary files /dev/null and b/images/docs/images/api-checks/api-check-assertions.png differ diff --git a/images/docs/images/api-checks/api-request-configuration.png b/images/docs/images/api-checks/api-request-configuration.png new file mode 100644 index 00000000..95ed8a24 Binary files /dev/null and b/images/docs/images/api-checks/api-request-configuration.png differ diff --git a/images/docs/images/api-checks/http-request-auth.png b/images/docs/images/api-checks/http-request-auth.png deleted file mode 100644 index 7d80731d..00000000 Binary files a/images/docs/images/api-checks/http-request-auth.png and /dev/null differ diff --git a/images/docs/images/api-checks/http-request-headers.png b/images/docs/images/api-checks/http-request-headers.png index 143c32ea..be7e5552 100644 Binary files a/images/docs/images/api-checks/http-request-headers.png and b/images/docs/images/api-checks/http-request-headers.png differ diff --git a/images/docs/images/api-checks/http-request-method.png b/images/docs/images/api-checks/http-request-method.png deleted file mode 100644 index 97e008bf..00000000 Binary files a/images/docs/images/api-checks/http-request-method.png and /dev/null differ diff --git a/images/docs/images/api-checks/timing-phases.png b/images/docs/images/api-checks/timing-phases.png deleted file mode 100644 index cc8905e0..00000000 Binary files a/images/docs/images/api-checks/timing-phases.png and /dev/null differ diff --git a/platform/variables.mdx b/platform/variables.mdx index 96f5f6c2..2e7e794c 100644 --- a/platform/variables.mdx +++ b/platform/variables.mdx @@ -86,7 +86,7 @@ be overridden at the check level. How variables are accessed depends on where you're accessing them from: * In [Browser](/detect/synthetic-monitoring/browser-checks/mac-structure#environment-variables), [Multistep](/detect/synthetic-monitoring/multistep-checks/overview#built-in-runtime-variables), and [API Check setup/teardown scripts](/detect/synthetic-monitoring/api-checks/set-up-and-tear-down#built-in-variables), use the standard Node.js `process.env.VARIABLE_NAME` notation. -* In [API Check requests](/detect/synthetic-monitoring/api-checks/requests#accessing-environment-variables), use Handlebars/Moustache templating delimiters, i.e. `{{VARIABLE_NAME}}` +* In [API Check requests](/detect/synthetic-monitoring/api-checks/configuration#accessing-environment-variables), use Handlebars/Moustache templating delimiters, i.e. `{{VARIABLE_NAME}}` * In [webhook alert channels](/integrations/alerts/webhooks#template-variables), also use the Handlebar/Moustache format, i.e. `{{VARIABLE_NAME}}` diff --git a/sitemap-crawl.md b/sitemap-crawl.md index 4a011d19..dd3aa7fa 100644 --- a/sitemap-crawl.md +++ b/sitemap-crawl.md @@ -90,8 +90,8 @@ This file contains all valid URLs extracted from docs.json organized by director - /detect/synthetic-monitoring/api-checks/overview - /detect/synthetic-monitoring/api-checks/creating-your-first-api-check - /detect/synthetic-monitoring/api-checks/api-structure -- /detect/synthetic-monitoring/api-checks/requests -- /detect/synthetic-monitoring/api-checks/assertions +- /detect/synthetic-monitoring/api-checks/configuration +- /detect/assertions - /detect/synthetic-monitoring/api-checks/set-up-and-tear-down - /detect/synthetic-monitoring/api-checks/snippets - /detect/synthetic-monitoring/api-checks/troubleshooting