Synthetics
Synthetics allow you to proactively monitor the health, availability, and performance of your endpoints. By simulating requests from your infrastructure, you can verify that your critical services are reachable and returning correct data, even when no real user traffic is active.
Overview
groundcover Synthetics execute checks from your installed groundcover backend, working on BYOC deployments only.
Source: Checks run from within your backend, when having multiple groundcover backends you can select the specific backend to use. We will support region selection for running tests from specific locations.
Supported Protocols: HTTP/HTTPS is fully supported from the UI. SSL/TLS, TCP, and DNS checks are supported via the Terraform provider while the UI is being rolled out. Additional protocols (gRPC, ICMP/Ping, UDP, WebSocket) are coming soon.
Alerting: Creating a Synthetic test automatically creates a corresponding Monitor (See: Monitors). Using monitors you can get alerted on failed synthetic tests, see: Notification Channels . The monitor is uneditable.
Trace Integration: We generate traces for all synthetic tests, which you can see as first-class citizens in groundcover platform. You can query these traces by using
source:syntheticsin traces page.
Creating a Synthetic Test
Navigate to Monitors > Synthetics and click + Create Synthetic Test .
Only Editors can create/edit/delete synthetic tests, see Default Policies
Request Configuration
Define the endpoint and parameters for the test. The available settings depend on the selected synthetic type.
Common settings (all types)
Synthetic Test Name: A descriptive name for the test.
Interval: Frequency of the check (e.g., every 60s). Must be at least 15s and less than 1h. The interval must also be greater than the total worker timeout (including retries).
Custom Labels: Add custom labels that will exist on traces generated by checks. You can use these labels to filter traces.
HTTP settings
Target: Select the HTTP method and URL. Include HTTP scheme (
http://orhttps://), for example:https://api.groundcover.com/api/backends/list. Supported methods:GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS.Tip: Use Import from cURL to paste a command and auto-fill these fields.
Follow redirects: Whether the test should follow 3xx responses. Defaults to
true. When disabled, the test returns the 3xx response as the result set for assertions.Allow insecure: Disables SSL/TLS certificate verification. Defaults to
false. Use this only for internal testing or self-signed certificates — it exposes you to Man-in-the-Middle attacks on production endpoints.HTTP Version: The UI exposes
HTTP/1.0,HTTP/1.1andHTTP/2.0; default isHTTP/1.1.Timeout: Max duration to wait before marking an attempt as failed. Required for HTTP checks (e.g.,
30s,60s). The interval must be greater than the total worker timeout (timeout × retry count + retry intervals).Payload: Set the body type and content if your request requires data (e.g., POST/PUT). Supported body types:
json,text,raw. Omit the body entirely to send no payload.Headers: Custom headers as key/value pairs.
Authentication: Supported types:
none(default),basic(requires username and password),bearer(requires a token).
SSL settings
Host: Hostname to connect to (e.g.,
example.com).Port: Port to connect to (typically
443). Must be between 1 and 65535.Verify: Verify the certificate chain. Set to
falseto accept self-signed or invalid certificates.Min Version: Minimum accepted TLS version (e.g.,
1.2,1.3).SNI: Server Name Indication override.
Timeout: Max duration for the TLS handshake. Default is 10s.
TCP settings
Host: Hostname or IP to connect to.
Port: TCP port to connect to. Must be between 1 and 65535.
Send: Optional string payload to send after connecting.
Expect Response: Whether to read a response back.
Receive Max Bytes: Maximum bytes to read from the response.
Timeout: Max duration for the connection and read. Default is 10s.
DNS settings
Domain: Domain name to query (e.g.,
example.com).Record Type: One of
A,AAAA,CNAME,TXT,MX,NS,SOA,PTR.Resolver: Optional DNS resolver to use. Defaults to the system resolver.
Port: Optional DNS port. Must be between 1 and 65535 when set.
DNSSEC: Whether to enable DNSSEC validation.
Timeout: Max duration to wait for the DNS response. Default is 10s.
Assertions (Validation Logic)
Assertions are the rules that determine the outcome of a check. You can add multiple assertions to a single test. Each assertion evaluates independently to either pass or fail. The overall check outcome depends on the severity of the assertions that evaluate to fail:
If any assertion with
severity: criticalevaluates to fail, the check outcome is failed. This triggers the auto-generated monitor alert.If no critical assertions fail but any assertion with
severity: degradedevaluates to fail, the check outcome is degraded. This does not trigger the auto-generated monitor alert.If all assertions pass, the check outcome is passed.
An assertion has the following fields:
source— which part of the response to inspect (e.g.,statusCode,jsonBody,certificateValid,tcpConnection).property— required forresponseHeader(header name) andjsonBody(dot-notation JSON path). Not used by other sources.operator— how to compare thesourcevalue against thetarget(e.g.,eq,contains,gt).target— the expected value. Required for most operators exceptexists/notExists.severity(optional) —critical(default) ordegraded. Controls how a failed assertion affects the check outcome:criticalfailures fail the check;degradedfailures mark it as degraded without failing it.
Assertion Sources per Synthetic Type
The source field must be compatible with the synthetic type. The table below lists every valid source, the synthetic types it applies to, and the operators the worker currently validates.
statusCode
HTTP
not used
eq, ne, gt, lt
HTTP status code as a numeric string (e.g. "200", "404")
responseHeader
HTTP
Header name (case-insensitive), e.g. Content-Type
exists, notExists, eq, ne, contains
Expected header value (required for eq/ne/contains)
responseBody
HTTP
not used
contains, eq, ne, exists, notExists
Substring or full body to match against. exists/notExists check whether the body is non-empty.
jsonBody
HTTP
Dot-notation JSON path (e.g. data.user.name). Required.
exists, notExists, eq, ne, contains
Expected value at the JSON path. For eq, values that look like JSON ({…}, […], "..."), numbers, or booleans are auto-parsed; anything else is compared as a string.
responseTime
HTTP, SSL, TCP, DNS
not used
gt, lt
Threshold in milliseconds as a string (e.g. "5000")
certificateValid
SSL
not used
eq
"true" or "false"
certificateExpiresIn
SSL
not used
gt, lt
Days until expiry as a string (e.g. "30")
tlsVersion
SSL
not used
eq, gt, lt
TLS version string (e.g. "1.2", "1.3")
chainValid
SSL
not used
eq
"true" or "false"
cipherSuite
SSL
not used
eq, contains
Cipher name (e.g. "AES256")
tcpConnection
TCP
not used
exists, notExists, eq, ne
"true"/"false" for eq/ne
responseContains
TCP
not used
contains
Substring to match in received payload (requires send + expectResponse in the TCP request)
dnsAnswer
DNS
not used
exists/notExists (does DNS resolve at all), eq, ne, contains (match a record value)
Expected DNS record value (e.g. an IP for A records). Not used for exists/notExists.
The target field is always a JSON string, even when the value represents a number or boolean. The API rejects native JSON numbers and booleans (e.g., "target": 200 returns 400). Use quoted values: "target": "200", "target": "true". The worker coerces numeric and boolean strings automatically for sources that require them (statusCode, responseTime, certificateExpiresIn, tlsVersion, certificateValid, chainValid). For jsonBody with operator eq, string targets that look like JSON, numbers, or booleans ("true", "false", "123", "{...}") are auto-parsed before comparison.
The API schema also accepts the operators startsWith, endsWith, regex, and oneOf, and the sources udp and websocket. These are reserved for future use — the worker does not currently validate them and assertions using them will fail with an "Unsupported operator" or "Unknown assertion source" result.
Assertion Operators
The operator defines the logic applied to the source/property.
eq
Equals. Numeric compare for statusCode, responseTime, tlsVersion, certificateExpiresIn; otherwise string equality (case-sensitive).
statusCode eq 200
ne
Not equal.
statusCode ne 500
gt
Numeric greater-than. Used with statusCode, responseTime, certificateExpiresIn, tlsVersion.
responseTime gt 100
lt
Numeric less-than. Same sources as gt.
responseTime lt 5000
contains
Checks if a substring exists within the source value.
responseBody contains "error"
exists
Checks that the field/resource is present. For dnsAnswer, checks that DNS resolves. For tcpConnection, checks that the TCP connection succeeded.
responseHeader (set-cookie) exists
notExists
Opposite of exists.
jsonBody (error_message) notExists
Examples
All examples below represent the JSON payload accepted by the POST /api/synthetics/v1/rules endpoint. HTTP checks can also be created via the UI, which renders this structure as form fields. SSL/TLS, TCP, and DNS checks are currently supported via the Terraform provider while UI support is being rolled out. For Terraform HCL examples, see the provider documentation.
HTTP — health check with multiple assertions
Validates that an API endpoint returns 200, completes within 5 seconds, exposes a Content-Type header, and that the JSON body's status field equals "ok".
SSL — certificate validity and expiration
Checks that the certificate served by example.com:443 is valid, its chain is valid, and it expires in more than 30 days.
TCP — connectivity and response
Opens a TCP connection to db.example.com:5432, asserts the connection succeeded, and asserts the handshake completed in under 1 second.
DNS — A record resolution
Queries example.com for its A record and asserts the answer contains the expected IP.
Assertion severity and retries
Assertions with severity: critical (the default) that evaluate to fail mark the check as failed. Assertions with severity: degraded that evaluate to fail mark the check as degraded — a warning state that does not count as a failure. Use retries to re-attempt the check before settling on the final outcome, avoiding false alerts on transient failures.
In the example below, if the status code assertion (severity: critical) evaluates to fail the check is failed; if only the response time assertion (severity: degraded) evaluates to fail the check is degraded but not failed.
Auto-Generated Monitors
When you create a Synthetic Test, groundcover eliminates the need to manually configure separate alert rules. A Monitor is automatically generated and permanently bound to your test. See: Monitors .
Managed Logic: The monitor queries for checks with outcome
failed(i.e., aseverity: criticalassertion evaluated to fail). Checks with outcomedegraded(onlyseverity: degradedassertions failed) do not trigger the monitor.Lifecycle: The monitor transitions between
Pending,Firing(when the test outcome isfailed), andResolved(when the test passes or is only degraded).Zero Maintenance: You do not need to edit this monitor's query. Any changes you make to the Synthetic Test (such as changing the target URL or assertions) are automatically synced to the Monitor.
Note: To prevent configuration drift, these auto-generated monitors are read-only. You cannot edit their query logic directly; you simply edit the Synthetic Test itself.
Last updated
