---
title: "Create Monitor - POST /v1/monitors"
description: "POST /v1/monitors - Create uptime monitors via API. Configure check frequency, monitoring regions, HTTP methods, expected status codes, and alert thresholds."
url: https://hyperping.com/docs/api/monitors/create
---

> Documentation index
> Section index: https://hyperping.com/docs/api/llms.txt
> Full docs index: https://hyperping.com/docs/llms.txt

`POST /v1/monitors`

# Create a monitor

Creates a new monitor: HTTP, port, ping (ICMP), DNS, or a Playwright browser check.

## Request

**Body** (application/json)

-   `name` (string, required): Pronounceable name of the monitor Example: `"My Website"`.

-   `external_id` (string, optional): Your own identifier for the monitor, unique within the project: 1 to 128 letters, digits, ., \_, : or -, starting with a letter or a digit. Creating a second monitor with the same external\_id returns 409 with the uuid of the monitor that has it. To create or update by this identifier, use Create or update a monitor. Example: `"client-42"`.

-   `url` (string, required): The URL of your website, or hostname (for DNS/ICMP/port monitors) you want to check. Optional for a browser check, whose target is in its script: when set, it is shown with the monitor. Example: `"https://acme.com"`.

-   `protocol` (enum, optional): Type of monitor to create. browser creates a browser check that runs the Playwright test in script. To create many of them from one script, see Create browser checks with the API. Options: `http`, `port`, `icmp`, `dns`, `browser`. Default: `http`.

-   `script` (string, required for browser): The Playwright test of a browser check, the same code you would paste in the dashboard editor (@playwright/test, TypeScript or JavaScript). Required when protocol is browser and refused for the other protocols. Up to 100,000 characters. New browser checks run on runtime 2026.05.

-   `env_variables` (array, optional): Variables the script reads as process.env.NAME: credentials, or what changes between checks that share one script, like the URL to open. Objects with name and value. Names use letters, digits and \_ and don't start with a digit; values are up to 4096 bytes. Values are stored encrypted and never returned by the API. Browser checks only, up to 50 variables. Example: `[{ "name": "BASE_URL", "value": "https://help.acme.com" }]`.

-   `dns_record_type` (enum, optional): DNS record type to check. Only used when protocol is dns Options: `A`, `AAAA`, `CNAME`, `MX`, `NS`, `TXT`, `SOA`, `SRV`, `CAA`, `PTR`. Default: `A`.

-   `dns_nameserver` (string, optional): Nameserver to query against (e.g. 8.8.8.8). Leave empty to use default resolvers. Only used when protocol is dns Example: `"8.8.8.8"`.

-   `dns_expected_answer` (string, optional): Expected DNS answer to validate against. Monitor fails if the resolved value does not contain this string. Only used when protocol is dns Example: `"192.0.2.1"`.

-   `regions` (array, optional): Array of region names to monitor from. Browser checks run from frankfurt and sanfrancisco, and use both by default. Options: `sanfrancisco`, `nyc`, `london`, `paris`, `frankfurt`, `seoul`, `mumbai`, `bangalore`, `saopaulo`, `california`, `virginia`, `sydney`, `toronto`, `amsterdam`, `singapore`, `tokyo`, `bahrain`, `capetown`.

-   `check_frequency` (number, optional): Check frequency in seconds. A browser check takes 300, 600, 900, 1800, 3600, 21600, 43200 or 86400, and defaults to 300. Options: `10`, `20`, `30`, `60`, `120`, `180`, `300`, `600`, `1800`, `3600`, `21600`, `43200`, `86400`. Default: `30`.

-   `http_method` (enum, optional): HTTP method for the request Options: `GET`, `POST`, `PUT`, `HEAD`, `DELETE`, `PATCH`, `OPTIONS`. Default: `GET`.

-   `request_body` (string, optional): Request body for POST, PUT, PATCH requests

-   `request_headers` (array, optional): Array of objects with name and value properties for custom HTTP headers

-   `follow_redirects` (boolean, optional): Whether to follow HTTP redirects Default: `true`.

-   `ip_version` (enum, optional): IP version used to reach the target: 4 or 6. An IPv6 monitor is checked over IPv6 only, never IPv4. Available for the http, port and icmp protocols. Checks run only from the selected regions that have an IPv6 probe, and the request is rejected if none of the selected regions has one. See IP version. Options: `4`, `6`. Default: `4`.

-   `port` (number, optional): Port number to check. Required if protocol is port Example: `443`.

-   `expected_status_code` (string, optional): Expected HTTP status code. Use "2xx" for 200-299, "1xx-3xx" for 100-399, or a specific code like "200". Default: `2xx`. Example: `"2xx"`.

-   `required_keyword` (string, optional): Triggers downtime if body response is missing this keyword

-   `paused` (boolean, optional): Whether the monitor should be paused Default: `false`.

-   `alerts_wait` (number, optional): Minutes to wait before sending alerts. Use -1 to disable alerts. Options: `-1`, `0`, `1`, `2`, `3`, `5`, `10`, `30`, `60`. Default: `0`.

-   `ssl_alert_days` (number, optional): Days before the TLS certificate expires to send the first expiry alert. -1 = never. When omitted on create, the default applies. Options: `-1`, `1`, `3`, `7`, `15`, `30`, `60`, `90`.

-   `ssl_reminders` (boolean, optional): Also remind at each step below the threshold (30, 15, 7, 3 and 1 days). Default true.

-   `ssl_notify_on_change` (boolean, optional): Notify when the server starts serving a different certificate. Default false.

-   `domain_alert_days` (number, optional): Days before the domain registration expires to alert. -1 = never (default for monitors created through the API). Options: `-1`, `7`, `14`, `30`, `60`, `90`.

-   `group_id` (number, optional): Monitor group to put the monitor in, from the Monitor Groups API. The monitor goes last in the group unless sort\_order is set. Example: `12`.

-   `sort_order` (number, optional): Position of the monitor in its group

-   `escalation_policy` (string, optional): Policy UUID to link. Send null or "none" to unlink. Example: `"policy_123abc"`.

## Response

Returns the newly created monitor object with status code 201, or `409` with `message` and `uuid` when the `external_id` is already used in the project.

RequestcURL

```
curl -X POST https://api.hyperping.io/v1/monitors \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Website",
    "url": "https://acme.com",
    "regions": ["paris", "frankfurt", "amsterdam", "london"],
    "http_method": "GET",
    "check_frequency": 30,
    "request_headers": [
      { "name": "X-Request-Header", "value": "Header value" }
    ],
    "protocol": "http"
  }'
```

201 CreatedJSON

```json
{
  "name": "Website",
  "url": "https://acme.com",
  "paused": false,
  "regions": [
    "paris",
    "frankfurt",
    "amsterdam",
    "london"
  ],
  "http_method": "GET",
  "check_frequency": 30,
  "request_headers": [
    {
      "name": "X-Request-Header",
      "value": "Header value"
    }
  ],
  "protocol": "http",
  "port": null,
  "follow_redirects": true,
  "ip_version": 4,
  "expected_status_code": "2xx",
  "request_body": "",
  "projectUuid": "0109c1f0-b521-44f4-9681-9046aa6f51d8",
  "uuid": "mon_3GhAQMYGEQuyUH",
  "status": "up",
  "ssl_expiration": 90,
  "ssl_alert_days": 30,
  "ssl_reminders": true,
  "ssl_notify_on_change": false,
  "domain_alert_days": 30,
  "domain_expiration": 214,
  "alerts_wait": 0
}
```

Request: browser checkcURL

```
curl -X POST https://api.hyperping.io/v1/monitors \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Help center - Acme",
    "protocol": "browser",
    "url": "https://help.acme.com",
    "check_frequency": 300,
    "group_id": 12,
    "script": "import { test, expect } from \"@playwright/test\";\n\ntest(\"help center loads\", async ({ page }) => {\n  await page.goto(process.env.BASE_URL);\n  await expect(page.getByRole(\"searchbox\")).toBeVisible();\n});\n",
    "env_variables": [
      { "name": "BASE_URL", "value": "https://help.acme.com" }
    ]
  }'
```

201 CreatedJSON

```json
{
  "name": "Help center - Acme",
  "url": "https://help.acme.com",
  "uuid": "mon_7BLzvBqgJYdvpm",
  "protocol": "browser",
  "projectUuid": "0109c1f0-b521-44f4-9681-9046aa6f51d8",
  "paused": false,
  "regions": [
    "frankfurt",
    "sanfrancisco"
  ],
  "check_frequency": 300,
  "status": "up",
  "alerts_wait": 0,
  "group_id": 12,
  "sort_order": 4,
  "escalation_policy": null,
  "env_variables": [
    { "name": "BASE_URL" }
  ],
  "script": "import { test, expect } from \"@playwright/test\";\n\ntest(\"help center loads\", async ({ page }) => {\n  await page.goto(process.env.BASE_URL);\n  await expect(page.getByRole(\"searchbox\")).toBeVisible();\n});\n"
}
```

[← Get a monitor](https://hyperping.com/docs/api/monitors/get)[Update a monitor →](https://hyperping.com/docs/api/monitors/update)

[](https://x.com/hyperping)[](https://www.linkedin.com/company/hyperping)

© 2026 Hyperping
