Create Website
Creates a new website monitor for a customer.
POST /api/websites
Example (cURL)
BASE_URL="https://uptimeify.io"
TOKEN="<your-api-token>"
curl -X POST "$BASE_URL/api/websites" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"customerId": "059e1469-0f05-4c93-bd4d-89c45bb2afd9",
"name": "New Landing Page",
"url": "https://landing.deinkunde.com",
"monitoringType": "combined",
"checkInterval": 5
}'Example (cURL): Connect target
Measures the origin behind a WAF/CDN by connecting to a different host than the one in url,
while the URL, path, Host header and TLS SNI stay the public hostname:
curl -X POST "$BASE_URL/api/websites" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"customerId":"...","name":"Shop (Origin)","url":"https://shop.example.com","connectHost":"origin.example.com","connectTlsInsecure":true}'Request Body
Core fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
customerId | number|string | Yes | - | Customer public ID (preferred) or legacy numeric ID |
name | string | Yes | - | Display name (1-255 chars) |
url | string | Yes* | - | URL to monitor (max 2048 chars). Required for combined, http_status, ssl_check and dns; optional for heartbeat and playwright. HTTP monitors need a full URL including protocol; DNS monitors take a bare hostname (no protocol, no path). |
monitoringType | string | No | combined | combined, http_status, ssl_check, playwright, heartbeat, dns |
status | string | No | active | active, inactive, maintenance (paused accepted, mapped to inactive) |
checkInterval | number | No | 30 | Check interval in minutes. Actively scheduled monitors accept 1-1440 (24 hours); heartbeat monitors accept 1-43200 (30 days), because the value is the expected ping interval rather than a polling rate. The minimum your organization may set depends on the package. |
timeoutSeconds | number | No | 30 | Request timeout in seconds (1-60) |
expectedStatusCodes | string | No | 200,301,302 | Comma-separated expected HTTP status codes. Digits, commas and spaces only. |
allowedCheckCountryCodes | string[]|null | No | org default | Array of 2-letter country codes to restrict monitoring locations |
searchTerm | string|null | No | null | Keyword to search for in response body (max 255 chars) |
customFields | object|null | No | null | Custom field values as key-value pairs |
allowPaidQuotaUpgrade | boolean | No | false | Consent to a PAID quota upgrade. Only relevant when the organization is at its monitor quota AND has automatic quota upgrading switched on: an agent (MCP) call then needs this set to true, otherwise it is refused with paidQuotaUpgradeNotAuthorized and the message names the tier and the price. Any other caller is unaffected and the field is ignored - a person in the dashboard sees the price, a model does not. It is never stored and never part of duplicate detection. |
managementType | string | No | managed | Ownership class: managed or self_service: see Managed vs. Self-Service. Only organization admins may choose it; customer-scoped creators always get self_service (requires allowSelfService and free quota). |
Authentication
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
authMode | string | No | none | none, authorization_header, basic |
authorizationHeader | string|null | No | null | Required when authMode is authorization_header (1-4096 chars). Encrypted at rest. |
basicAuthUsername | string|null | No | null | Required when authMode is basic (1-255 chars) |
basicAuthPassword | string|null | No | null | Required when authMode is basic (1-4096 chars). Encrypted at rest. |
HTTP Request Configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
httpMethod | string | No | GET | GET, QUERY, POST, PUT, PATCH, DELETE, HEAD, OPTIONS |
customHeaders | object|null | No | null | Custom HTTP headers as key-value pairs. Keys: 1-100 chars, values: max 8192 chars. Encrypted at rest. |
requestBody | string|null | No | null | Request body, max 100KB. Sent with every method except GET and HEAD. Encrypted at rest. |
followRedirects | boolean | No | true | Whether to follow HTTP redirects |
cookieHandling | string | No | none | none or jar (maintain cookie jar across redirects) |
Connect target (Ersatzziel)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
connectHost | string|null | No | null | Connects to this host/IP instead of the one in url, while the URL, path, Host header and TLS SNI stay unchanged - the semantics of curl --resolve. Host only, or host with port; IPv6 in brackets (e.g. [2001:db8::1]:8443); no protocol, no path. Useful for measuring the origin behind a WAF/CDN, or for running two monitors on the same URL that measure the edge and the origin separately. Private, loopback, link-local and otherwise blocked addresses are rejected (connectHostNotPublic). |
connectPort | number|null | No | null | Port to use with connectHost (1-65535). Defaults to a port embedded in connectHost itself, then to the URL's own port. |
connectTlsInsecure | boolean | No | false | Skips certificate verification for the connection to connectHost. Only valid together with connectHost (connectTlsInsecureWithoutHost otherwise). SSL expiry and issuer are still read and reported. |
Not available for playwright scenarios or heartbeat monitors: neither runs the HTTP/SSL check pipeline that connectHost plugs into, so the fields are accepted but have no effect on those monitoring types.
If checkHttpsRedirectEnabled is on, the "does http redirect to https" probe follows connectHost too and therefore measures the origin as well. Because that redirect is usually the WAF's job rather than the origin's, the monitor can rightly turn red for a redirect the public site still serves correctly.
mTLS (Mutual TLS)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
mtlsEnabled | boolean | No | false | Enable mutual TLS authentication |
mtlsClientCert | string|null | No | null | Required when mtlsEnabled is true (1-100000 chars). Encrypted at rest. |
mtlsClientKey | string|null | No | null | Required when mtlsEnabled is true (1-100000 chars). Encrypted at rest. |
Playwright Monitoring
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
playwrightScript | string|null | No* | null | Required when monitoringType is playwright (1-100000 chars) |
playwrightEnv | object|null | No | Environment variables (max 50, keys 1-64 chars and matching ^[A-Z_][A-Z0-9_]*$, values max 2000 chars) | |
playwrightDevice | string|null | No | null | Device emulation preset (1-100 chars) |
playwrightViewportWidth | number|null | No | null | Viewport width (1-3840). Must be set with playwrightViewportHeight. |
playwrightViewportHeight | number|null | No | null | Viewport height (1-3840). Must be set with playwrightViewportWidth. |
playwrightRetries | number|null | No | 0 | Number of retries (0-5) |
playwrightTimeoutMs | number|null | No | 30000 | Timeout in milliseconds (1000-180000) |
Expected Response Validation
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
checkExpectedResponseEnabled | boolean | No | false | Enable response body validation |
expectedResponseMatchType | string|null | No | contains | contains, equals, json_path_equals |
expectedResponseValue | string|null | No | null | Required when checkExpectedResponseEnabled is true (max 10000 chars) |
expectedResponseJsonPath | string|null | No | null | Required when expectedResponseMatchType is json_path_equals (max 500 chars) |
Check Configuration
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
checkSslEnabled | boolean | No | true | Enable SSL certificate checks (disabled for Playwright) |
checkHttpsRedirectEnabled | boolean | No | true | Check HTTPS redirect (disabled for Playwright) |
checkStatusEnabled | boolean | No | true | Check HTTP status (disabled for Playwright) |
checkSizeEnabled | boolean | No | true | Check response size (disabled for Playwright) |
checkResponseTimeEnabled | boolean | No | true | Check response time (disabled for Playwright) |
checkKeywordEnabled | boolean | No | true | Enable keyword search (disabled for Playwright) |
Your organization's package may forbid a given check; sending true for a check the package does not allow silently creates the monitor with that check false.
SSL & Domain Thresholds
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
sslNoticeDays | number | No | 7 | Days before SSL expiry to trigger notice (1-365) |
sslErrorDays | number | No | 0 | Days before SSL expiry to trigger error (0-365, must be ≤ sslNoticeDays) |
checkDomainExpiryEnabled | boolean | No | true | Enable domain expiry checks (disabled for Playwright) |
domainExpiryNoticeDays | number | No | 30 | Days before domain expiry to trigger notice (1-365) |
domainExpiryErrorDays | number | No | 7 | Days before domain expiry to trigger error (0-365, must be ≤ domainExpiryNoticeDays) |
Page Size Limits
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
minPageSize | number|null | No | null | Minimum expected page size in bytes (≥ 0, must be ≤ maxPageSize; disabled for Playwright) |
maxPageSize | number|null | No | null | Maximum expected page size in bytes (≥ 0; disabled for Playwright) |
DNS Monitoring
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
dnsConfig | object | No | DNS query configuration (only for monitoringType: dns) |
Heartbeat
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
heartbeatToken | string|null | No | auto-generated | Custom heartbeat token (max 255 chars) |
heartbeatGracePeriodMinutes | number | No | 5 | Grace period in minutes (1-10080, max 1 week) |
Response
Returns the created website record. Encrypted fields (authorizationHeader, basicAuthPassword, customHeaders, requestBody, mtlsClientCert, mtlsClientKey) are never returned in API responses.
{
"id": 103,
"customerId": 1,
"name": "New Landing Page",
"url": "https://landing.deinkunde.com",
"status": "active",
"monitoringType": "combined",
"checkInterval": 5,
"httpMethod": "GET",
"followRedirects": true,
"cookieHandling": "none",
"mtlsEnabled": false,
"connectHost": null,
"connectPort": null,
"connectTlsInsecure": false,
"createdAt": "2026-02-26T12:05:00.000Z"
}GET /api/websites/:id and GET /api/websites return connectHost, connectPort and connectTlsInsecure the same way.
Common errors
401 Unauthorizedwhen you are not logged in403 Forbiddenwhen you cannot create websites for the organization/customer403 Forbidden(selfServiceNotAllowed) when a customer-scoped caller creates a monitor but the customer's resolvedallowSelfServiceis false403 Forbidden(selfServiceQuotaReached) when the customer's total self-service monitors (across all monitor types) already meetmaxSelfServiceUrls404 Customer not foundwhencustomerIddoes not resolve to an existing customer400 Bad Request(connectHostInvalid) whenconnectHostis not a valid host, or carries a protocol or a path400 Bad Request(connectHostNotPublic) whenconnectHostresolves to a private, loopback, link-local or otherwise blocked address400 Bad Request(connectTlsInsecureWithoutHost) whenconnectTlsInsecureis sent withoutconnectHost403 Forbiddenwithdata.codepaidQuotaUpgradeNotAuthorizedwhen the call comes from an agent (MCP) connection, the organization is at its monitor quota with automatic upgrading switched on, andallowPaidQuotaUpgradewas not set totrue. Creating the monitor would have moved the organization to the next, more expensive quota tier and billed the difference for the rest of the period; the message names that tier and its monthly price. Repeat the call withallowPaidQuotaUpgrade: trueonce a person has agreed to the higher bill, or free up a monitor first.