

# Writing a JSON configuration for Node.js multi Checks blueprint
<a name="CloudWatch_Synthetics_WritingCanary_Multichecks"></a>

The Node.js multi checks blueprint allows you to create canaries that perform multiple validation checks within a single canary run. This blueprint is useful when you want to test multiple endpoints, validate different aspects of your application, or perform a series of related checks in sequence. 

**Topics**
+ [Root configuration structure](#root-configuration-structure)
+ [Global settings](#global-settings)
+ [Variables and data management](#variables-data-management)
+ [Step definitions](#step-definitions)
+ [Check types](#check-types)
+ [Authentication methods](#authentication-methods)
+ [Assertions and validation](#assertions-validation)
+ [Data extraction](#data-extraction)

## Root configuration structure
<a name="root-configuration-structure"></a>

The root configuration defines the overall structure of your advanced API blueprint canary.


**Schema properties**  

| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  globalSettings  | Object | No | Default configurations applied to all steps | 
|  variables  | Object | No | Reusable values across steps (max 10) | 
|  steps  | Object |  Yes  | Collection of monitoring steps (1-10 steps) | 

 **Example** 

```
{
  "globalSettings": {
    "stepTimeout": 30000,
    "userAgent": "CloudWatch-Synthetics-Advanced/1.0"
  },
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiVersion": "v1"
  },
  "steps": {
    "1": {
      "stepName": "healthCheck",
      "checkerType": "HTTP",
      "url": "${baseUrl}/health",
      "httpMethod": "GET"
    }
  }
}
```

 **Validation rules** 
+ Must contain at least one step
+ Maximum 10 steps allowed
+ No additional properties allowed beyond `globalSettings`, ` variables`, and `steps`

## Global settings
<a name="global-settings"></a>

Global settings provide default configurations that apply to all steps unless overridden at the step level.

 **Properties** 


**Global setting properties**  

| Property | Type | Default | Range | Description | 
| --- | --- | --- | --- | --- | 
|  stepTimeout  | integer | 30000 | 5000-300000 | Default timeout for all steps (milliseconds) | 

 **Example** 

```
{
  "globalSettings": {
    "stepTimeout": 60000,
            
  }
}
```

## Variables and data management
<a name="variables-data-management"></a>

Variables allow you to define reusable values that can be referenced throughout your configuration using `${variableName}` syntax.

 **Variable properties** 


| Property | Type | Description | 
| --- | --- | --- | 
| Variable names | string | Must match pattern ^[a-zA-Z][a-zA-Z0-9\$1]\$1\$1 | 
| Variable values | string | Any string value | 

 **Limitations** 
+ Maximum 10 variables per configuration
+ Variable names must start with a letter
+ Variable names can contain letters, numbers, and underscores only
+ Maximum length not specified in schema

 **Example** 

```
{
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiKey": "${AWS_SECRET:my-api-key}",
    "timeout": "30000",
    "userEmail": "test@example.com"
  }
}
```

 **Configuration usage** 

```
{
  "steps": {
    "1": {
      "url": "${baseUrl}/users",
      "timeout": "${timeout}",
      "headers": {
        "Authorization": "Bearer ${apiKey}"
      }
    }
  }
}
```

## Step definitions
<a name="step-definitions"></a>

Steps define individual monitoring operations. Each step is numbered from 1 to 10 and contains a specific type of check.

 *Common step properties* 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  stepName  | string |  Yes  | Unique identifier for the step | 
|  checkerType  | string |  Yes  | Type of check: HTTP, DNS, SSL,  TCP | 
|  extractors  | array | No | Data extraction configuration | 

 *Step name validation* 
+ Pattern - ^[a-zA-Z][a-zA-Z0-9\$1-]\$1\$1
+ Maximum length - 64 characters
+ Must start with a letter

 *Step numbering* 
+ Steps are numbered as string keys: "1", "2", ..., "10"
+ Pattern: ^([1-9]\$110)\$1
+ Minimum 1 step required
+ Maximum 10 steps allowed

 *Example* 

```
{
  "steps": {
    "1": {
      "stepName": "loginAPI",
      "checkerType": "HTTP",
      "url": "https://api.example.com/login",
      "httpMethod": "POST"
    },
    "2": {
      "stepName": "dnsCheck",
      "checkerType": "DNS",
      "domain": "example.com"
    }
  }
}
```

## Check types
<a name="check-types"></a>

### HTTP checks
<a name="http-types"></a>

Monitor web endpoints and APIs with comprehensive request and response validation.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  url  | string | Target URL (must be valid URI format) | 
|  httpMethod  | string | HTTP method: GET, POST, PUT,  PATCH, DELETE, HEAD, OPTIONS | 

 **Optional properties** 


| Property | Type | Default | Range | Description | 
| --- | --- | --- | --- | --- | 
|  timeout  | integer | 30000 | 5000-300000 | Request timeout (milliseconds) | 
|  waitTime  | integer | 0 | 0-60 | Delay before request (seconds) | 
|  headers  | object | - | - | Custom HTTP headers | 
|  body  | string | - | - | Request body for POST/PUT operations | 
|  authentication  | object | - | - | Authentication configuration | 
|  assertions  | array | - | - | Response validation rules | 

 **Example** 

```
{
  "stepName": "createUser",
  "checkerType": "HTTP",
  "url": "https://api.example.com/users",
  "httpMethod": "POST",
  "timeout": 15000,
  "headers": {
    "Content-Type": "application/json",
    "X-API-Version": "v1"
  },
  "body": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}",
  "authentication": {
    "type": "API_KEY",
    "apiKey": "${AWS_SECRET:api-credentials}",
    "headerName": "X-API-Key"
  },
  "assertions": [
    {
      "type": "STATUS_CODE",
      "operator": "EQUALS",
      "value": 201
    }
  ]
}
```

### DNS checks
<a name="dns-types"></a>

Validate DNS resolution and record information.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  domain  | string | Domain name to query (hostname format) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  recordType  | string | "A" | DNS record type: A, CNAME, MX,  TXT, NS | 
|  nameserver  | string | - | Specific DNS server to query | 
|  timeout  | integer | 30000 | Query timeout (5000-300000ms) | 
|  port  | integer | 53 | DNS server port (1-65535) | 
|  protocol  | string | "UDP" | Protocol: UDP or TCP | 
|  assertions  | array | - | DNS response validation rules | 

 **Example** 

```
{
  "stepName": "dnsResolution",
  "checkerType": "DNS",
  "domain": "example.com",
  "recordType": "A",
  "nameserver": "8.8.8.8",
  "timeout": 10000,
  "assertions": [
    {
      "type": "RECORD_VALUE",
      "operator": "CONTAINS",
      "value": "192.168"
    }
  ]
}
```

### SSL checks
<a name="ssl-types"></a>

Monitor SSL certificate health and configuration.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  hostname  | string | Target hostname (hostname format) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  port  | integer | 443 | SSL port (1-65535) | 
|  timeout  | integer | 30000 | Connection timeout (5000-300000ms) | 
|  sni  | boolean | TRUE | Server Name Indication | 
|  verifyHostname  | boolean | TRUE | Hostname verification | 
|  allowSelfSigned  | boolean | FALSE | Accept self-signed certificates | 
|  assertions  | array | - | Certificate validation rules | 

 **Example** 

```
{
  "stepName": "sslCertCheck",
  "checkerType": "SSL",
  "hostname": "secure.example.com",
  "port": 443,
  "sni": true,
  "verifyHostname": true,
  "assertions": [
    {
      "type": "CERTIFICATE_EXPIRY",
      "operator": "GREATER_THAN",
      "value": 30,
      "unit": "DAYS"
    }
  ]
}
```

### TCP checks
<a name="tcp-types"></a>

Test TCP port connectivity and response validation.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  hostname  | string | Target hostname (hostname format) | 
|  port  | integer | Target port (1-65535) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  timeout  | integer | 30000 | Overall timeout (5000-300000ms) | 
|  connectionTimeout  | integer | 3000 | Connection timeout (5000-300000ms) | 
|  readTimeout  | integer | 2000 | Data read timeout (5000-300000ms) | 
|  sendData  | string | - | Data to send after connection | 
|  expectedResponse  | string | - | Expected response data | 
|  encoding  | string | "UTF-8" | Data encoding: UTF-8, ASCII, HEX | 
|  assertions  | array | - | Connection and response validation | 

 **Example** 

```
{
  "stepName": "databaseConnection",
  "checkerType": "TCP",
  "hostname": "db.example.com",
  "port": 3306,
  "connectionTimeout": 5000,
  "sendData": "SELECT 1",
  "expectedResponse": "1",
  "assertions": [
    {
      "type": "CONNECTION_SUCCESSFUL",
      "value": true
    }
  ]
}
```

## Authentication methods
<a name="authentication-methods"></a>

 **No authentication** 

```
{
  "type": "NONE"
}
```

 **Basic authentication** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "BASIC" | 
|  username  | string |  Yes  | Username for authentication | 
|  password  | string |  Yes  | Password for authentication | 

 **Example** 

```
{
  "type": "BASIC",
  "username": "admin",
  "password": "${AWS_SECRET:basic-auth:password}"
}
```

 **API key authentication** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "API\$1KEY" | 
|  apiKey  | string |  Yes  | - | API key value | 
|  headerName  | string | No | "X-API-Key" | Header name for API key | 

 **Example** 

```
{
  "type": "API_KEY",
  "apiKey": "${AWS_SECRET:api-credentials}",
  "headerName": "Authorization"
}
```

 **OAuth client credentials** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "OAUTH\$1CLIENT\$1CREDENTIALS" | 
|  tokenUrl  | string |  Yes  | - | OAuth token endpoint URL | 
|  clientId  | string |  Yes  | - | OAuth client ID | 
|  clientSecret  | string |  Yes  | - | OAuth client secret | 
|  scope  | string | No | - | OAuth scope | 
|  audience  | string | No | - | OAuth audience | 
|  resource  | string | No | - | OAuth resource | 
|  tokenApiAuth  | array | No | - | Token API auth methods: BASIC\$1AUTH\$1HEADER, REQUEST\$1BODY | 
|  tokenCacheTtl  | integer | No | 3600 | Token cache TTL (minimum 60 seconds) | 

 **Example** 

```
{
  "type": "OAUTH_CLIENT_CREDENTIALS",
  "tokenUrl": "https://auth.example.com/oauth/token",
  "clientId": "${AWS_SECRET:oauth-creds:client_id}",
  "clientSecret": "${AWS_SECRET:oauth-creds:client_secret}",
  "scope": "read write",
  "tokenCacheTtl": 7200
}
```

 **AWS Signature (Version 4)** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "SIGV4" | 
|  service  | string |  Yes  | Name of the AWS service (for example, "execute-api") | 
|  region  | string |  Yes  | AWS region | 
|  roleArn  | string |  Yes  | IAM role ARN for signing | 

 **Example** 

```
{
  "type": "SIGV4",
  "service": "execute-api",
  "region": "us-east-1",
  "roleArn": "arn:aws:iam::123456789012:role/SyntheticsRole"
}
```

## Assertions and validation
<a name="assertions-validation"></a>

### HTTP assertions
<a name="http-assertions"></a>

 **Status code assertions** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "STATUS\$1CODE" | 
|  operator  | string |  Yes  | EQUALS, NOT\$1EQUALS, GREATER\$1THAN,  LESS\$1THAN, IN\$1RANGE | 
|  value  | integer | Conditional | HTTP status code (100-599) | 
|  rangeMin  | integer | Conditional | Minimum range value (for IN\$1RANGE) | 
|  rangeMax  | integer | Conditional | Maximum range value (for IN\$1RANGE) | 

```
{
  "type": "STATUS_CODE",
  "operator": "EQUALS",
  "value": 200
}
```

 **Response time assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RESPONSE\$1TIME" | 
|  operator  | string |  Yes  | - | LESS\$1THAN, GREATER\$1THAN, EQUALS | 
|  value  | number |  Yes  | - | Time value (minimum 0) | 
|  unit  | string | No | "MILLISECONDS" | Must be "MILLISECONDS" | 

```
{
  "type": "RESPONSE_TIME",
  "operator": "LESS_THAN",
  "value": 500,
  "unit": "MILLISECONDS"
}
```

 **Head assertions** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "HEADER" | 
|  headerName  | string |  Yes  | Name of header to validate | 
|  operator  | string |  Yes  | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH, EXIST | 
|  value  | string/boolean | Conditional | Expected value (boolean for EXIST operator) | 

```
{
  "type": "HEADER",
  "headerName": "Content-Type",
  "operator": "CONTAINS",
  "value": "application/json"
}
```

 **Body assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "BODY" | 
|  target  | string | No | "JSON" | JSON or TEXT | 
|  path  | string | Conditional | - | JSONPath (required for JSON target) | 
|  operator  | string |  Yes  | - | CONTAINS, NOT\$1CONTAINS, EQUALS,  NOT\$1EQUALS, EXISTS | 
|  value  | string/boolean |  Yes  | - | Expected value (boolean for EXISTS operator) | 

```
{
  "type": "BODY",
  "target": "JSON",
  "path": "$.users[0].name",
  "operator": "EQUALS",
  "value": "John Doe"
}
```

### DNS assertions
<a name="dns-assertions"></a>

 **Record value assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RECORD\$1VALUE" | 
|  operator  | string |  Yes  | - | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH | 
|  value  | string |  Yes  | - | Expected record value | 

 **Record count assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RECORD\$1COUNT" | 
|  operator  | string |  Yes  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | ≥ 0 | Expected count (minimum 0) | 

 **Authoritative assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "AUTHORITATIVE" | 
|  value  | boolean |  Yes  | - | Expected authoritative status | 

 **TTL assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "TTL" | 
|  operator  | string |  Yes  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | ≥ 0 | Expected TTL (minimum 0) | 

### SSL assertions
<a name="ssl-assertions"></a>

 **Certificate expiry assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1EXPIRY" | 
|  operator  | string |  Yes  | - | GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | - | Time value (minimum 0) | 
|  unit  | string | No | "DAYS" | DAYS, HOURS | 

 **Certificate subject assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1SUBJECT" | 
|  field  | string |  Yes  | - | Subject field: CN, O, OU, C , ST, L | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS, REGEX\$1MATCH | 
|  value  | string |  Yes  | - | Expected field value | 

 **Certificate issuer assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1ISSUER" | 
|  field  | string |  Yes  | - | Issuer field: CN, O | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS | 
|  value  | string |  Yes  | - | Expected field value | 

### TCP assertions
<a name="tcp-assertions"></a>

 **Connection success assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CONNECTION\$1SUCCESSFUL" | 
|  value  | boolean |  Yes  | - | Expected connection status | 

 **Response data assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RESPONSE\$1DATA" | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS, NOT\$1CONTAINS,  REGEX\$1MATCH, STARTS\$1WITH, ENDS\$1WITH | 
|  value  | string |  Yes  | - | Expected response data | 
|  encoding  | string | No | "UTF-8" | UTF-8, ASCII, HEX | 

## Data extraction
<a name="data-extraction"></a>

Extractors allows you to capture data from responses for use in subsequent steps or for reporting purposes.

 **Extraction properties** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  name  | string |  Yes  | - | Variable name for extracted data | 
|  type  | string |  Yes  | - | Extraction type: BODY | 
|  path  | string | No | - | JSONPath for body extraction | 
|  regex  | string | No | - | Regular expression pattern | 
|  regexGroup  | integer | No | 0 | Regex capture group (minimum 0) | 

 **Extraction name validation** 
+ Pattern: `^[a-zA-Z][a-zA-Z0-9_]*$`
+ Must start with a letter
+ Can contain letters, numbers, and underscores

**Limitation** – Substitution does not apply for fields in the schema that have specific ENUM values

 **Extraction types** 

```
{
  "name": "userId",
  "type": "BODY",
  "path": "$.user.id"
}
```

```
{
  "stepName": "loginAndExtract",
  "checkerType": "HTTP",
  "url": "https://api.example.com/login",
  "httpMethod": "POST",
  "body": "{\"username\":\"test\",\"password\":\"pass\"}",
  "extractors": [
    {
      "name": "textVariable",
      "type": "BODY",
      "path": "$.myvalue"
    }
  ]
},
{
  "stepName": "substituteVariable",
  "checkerType": "HTTP",
  "url": "https://api.example.com/get/${textVariable}",
  "httpMethod": "GET",
  "assertions": [
    {
    "type": "BODY",
    "target": "JSON",
    "path": "$.users[0].name",
    "operator": "EQUALS",
    "value": "${textVariable}"
    }
  ]
}
```