Common Types and Fields¶
Version: v1 Status: Stable
Overview¶
This document defines common types, fields, and concepts shared across all check kinds in Synthetic Open Schema v1.
Time Format¶
Type: Time
Format: ^[0-9]+(ns|ms|s|m|h|d|w|mo|y)?$
Description: A duration value expressed as an integer followed by an optional unit.
Supported Units:
- ns - Nanoseconds (fixed duration)
- ms - Milliseconds (fixed duration)
- s - Seconds (default if no unit specified, fixed duration)
- m - Minutes (fixed duration)
- h - Hours (fixed duration)
- d - Days (fixed duration: 24 hours)
- w - Weeks (fixed duration: 7 days)
- mo - Months (calendar-based: varies 28-31 days)
- y - Years (calendar-based: varies 365-366 days)
Examples:
Validation Rules: - MUST contain at least one digit - Unit is OPTIONAL; defaults to seconds - Value MUST be positive
Calendar-Based Units (mo, y):
Months and years are calendar-based, not fixed durations:
mo(months): Computed based on calendar months from reference timestamp- Example: January 7 + 3mo = April 7 (regardless of actual days elapsed)
-
Handles month-end gracefully: January 31 + 1mo = February 28/29
-
y(years): Computed based on calendar years from reference timestamp - Example: January 7, 2024 + 1y = January 7, 2025
- Leap years handled automatically
Reference Timestamp: The timestamp used for calendar calculation depends on context:
- Scheduling (interval): Last execution or result timestamp
- Assertions (expirationTime): Current time or certificate issue date
Examples:
# Fixed duration - always 30 days
interval: 30d
# Calendar-based - runs on same day each month
interval: 1mo
# Certificate expires in 3 calendar months
value: 3mo # Jan 7 → April 7, Mar 31 → June 30
Usage: Used for fields where defaulting to seconds is intuitive (timeout, interval).
StrictTime Format¶
Type: StrictTime
Format: ^[0-9]+(ns|ms|s|m|h|d|w|mo|y)$
Description: A duration value that REQUIRES an explicit unit suffix. Bare integers are NOT allowed.
Supported Units:
- ns - Nanoseconds (fixed duration)
- ms - Milliseconds (fixed duration)
- s - Seconds (fixed duration)
- m - Minutes (fixed duration)
- h - Hours (fixed duration)
- d - Days (fixed duration: 24 hours)
- w - Weeks (fixed duration: 7 days)
- mo - Months (calendar-based: varies 28-31 days)
- y - Years (calendar-based: varies 365-366 days)
Examples:
# Valid
value: 30d
value: 500ms
value: 5s
# Invalid - unit required
value: 30 # ❌ ERROR: unit suffix required
value: 500 # ❌ ERROR: unit suffix required
Validation Rules: - MUST contain at least one digit - Unit suffix is REQUIRED (not optional) - Value MUST be positive - Bare integers are REJECTED
Calendar-Based Units (mo, y):
Same calendar semantics as Time type:
- 3mo = 3 calendar months from reference date (e.g., Jan 7 → April 7)
- 1y = 1 calendar year from reference date (e.g., Jan 7, 2024 → Jan 7, 2025)
Rationale: Prevents ambiguity in contexts where defaulting to seconds would be confusing. For example, certificate expiration checks measure days, not seconds, so value: 30 would be ambiguous without enforcing the unit.
Usage: Used for assertion values where the appropriate unit may not be obvious (expirationTime, duration in assertions).
Identifiers¶
CaseInsensitiveKey¶
Type: CaseInsensitiveKey
Format: ^[A-Za-z0-9\-]+$
Description: An identifier that is case-insensitive and contains only alphanumeric characters and hyphens.
Constraints: - MUST contain at least one character - MUST match DNS subdomain naming rules - Automatically converted to lowercase - MAY contain hyphens - MUST NOT start or end with hyphen
Examples:
DNSHostname¶
Type: DNSHostname
Format: ^(([a-zA-Z0-9]+|([a-zA-Z0-9]+-*[a-zA-Z0-9]+))\.)*[a-zA-Z0-9]+$
Description: A valid DNS hostname.
Constraints: - MUST be valid DNS format - Automatically converted to lowercase - Minimum length: 1 character - Maximum length: 253 characters
Examples:
Operators¶
Operators define comparison operations used in assertions.
NumericOperator¶
Used for: Status codes, sizes, numeric values
Values:
- equals - Exactly equal to value
- notEquals - Not equal to value
- greaterThan - Greater than value
- lessThan - Less than value
Example:
StringOperator¶
Used for: Body content, headers, text fields
Values:
- equals - Exact string match
- notEquals - Does not match string
- contains - Contains substring
- notContains - Does not contain substring
Example:
BooleanOperator¶
Used for: Boolean and null comparisons (reachable, valid)
Values:
- is - Is exactly (true/false)
- isNot - Is not (true/false)
- equals - Equals (backward compatibility)
- notEquals - Not equals (backward compatibility)
Example:
ListOperator¶
Used for: List/array comparisons (nameservers, multiple values)
Values:
- equals - Exact match (order-independent set equality)
- contains - All assertion values present in result (subset check)
- notContains - No assertion values present in result
Semantics:
equals: Result list MUST exactly match assertion list (order-independent)
- Assertion: [a, b] matches result: [b, a] ✅
- Assertion: [a, b] matches result: [a] ❌ (missing b)
- Assertion: [a, b] matches result: [a, b, c] ❌ (extra c)
contains: Result list MUST contain ALL assertion values (may have more)
- Assertion: [a, b] matches result: [a, b] ✅
- Assertion: [a, b] matches result: [a, b, c] ✅ (extra values ok)
- Assertion: [a, b] matches result: [a] ❌ (missing b)
notContains: Result list MUST NOT contain ANY assertion values
- Assertion: [a, b] matches result: [c, d] ✅ (neither a nor b present)
- Assertion: [a, b] matches result: [a, c] ❌ (a is present)
Examples:
# Single value check (string syntax)
- type: nameservers
operator: contains
value: ns1.cloudflare.com
# Multiple values check (list syntax)
- type: nameservers
operator: contains
value:
- ns1.cloudflare.com
- ns2.cloudflare.com
# Exact match
- type: nameservers
operator: equals
value:
- ns1.cloudflare.com
- ns2.cloudflare.com
# Must NOT contain (single value)
- type: nameservers
operator: notContains
value: ns1.oldprovider.net
# Must NOT contain (multiple values)
- type: nameservers
operator: notContains
value:
- ns1.oldprovider.net
- ns2.badactor.com
Base Assertion Types¶
All check-specific assertions extend these base types.
NumericAssertion¶
Description: Base for numeric value assertions.
Fields:
- operator: NumericOperator (REQUIRED)
- value: integer (REQUIRED)
Used by: statusCode, size, numeric assertions
Example:
Validation: - Value MUST be an integer - Extra fields are FORBIDDEN
TimebasedAssertion¶
Description: Base for time/duration assertions where unit suffix is required.
Fields:
- operator: NumericOperator (REQUIRED)
- value: StrictTime (REQUIRED)
Used by: duration, latency, expirationTime assertions
Example:
Validation:
- Value MUST be StrictTime (unit suffix required)
- Bare integers are REJECTED (e.g., value: 30 is invalid)
- MUST include unit: 30d, 500ms, 5s, etc.
- Extra fields are FORBIDDEN
Rationale: Using StrictTime prevents ambiguity. For example, certificate expiration is measured in days, so value: 30 would be confusing (30 seconds? 30 days?). Requiring value: 30d makes intent clear.
StringAssertion¶
Description: Base for string content assertions.
Fields:
- operator: StringOperator (REQUIRED)
- value: string (REQUIRED)
Used by: body, text content assertions
Example:
Validation: - Value MUST be a string - Extra fields are FORBIDDEN
KeyValueAssertion¶
Description: Base for key-value pair assertions (headers, query params).
Fields:
- operator: StringOperator (REQUIRED)
- name: string (OPTIONAL)
- value: string (REQUIRED)
Behavior:
- If name is NOT specified: Operations are against keys
- If name IS specified: Operations are against the value of that key
Used by: header assertions
Examples:
Check if header exists:
Check header value:
Validation: - Extra fields are FORBIDDEN
BooleanAssertion¶
Description: Base for boolean/null assertions.
Fields:
- operator: BooleanOperator (REQUIRED)
- value: boolean (REQUIRED)
Used by: reachable, valid, boolean checks
Example:
Validation: - Value MUST be boolean (true/false) - Extra fields are FORBIDDEN
ListAssertion¶
Description: Base for list/array value assertions.
Fields:
- operator: ListOperator (REQUIRED)
- value: string | array[string] (REQUIRED)
Used by: nameservers, multi-value assertions
Operators:
- equals - Exact list match (order-independent)
- contains - All assertion values present in result
- notContains - No assertion values present in result
Value Type Handling:
If value is a string (single value):
- Automatically converted to single-element list: "a" → ["a"]
- Syntactic sugar for common single-value checks
- Semantically equivalent to ["a"]
If value is an array (multiple values):
- Used as-is for multi-value checks
- MUST NOT be empty
Examples:
Single nameserver check (string syntax):
type: nameservers
operator: contains
value: ns1.cloudflare.com # String - checks if this ONE nameserver is present
Single nameserver check (list syntax):
Multiple nameservers check:
type: nameservers
operator: contains
value:
- ns1.cloudflare.com
- ns2.cloudflare.com # Checks if BOTH are present
Exact nameserver list match:
Nameserver must NOT be present:
type: nameservers
operator: notContains
value: ns1.oldprovider.net # String - checks if this ONE nameserver is absent
Multiple nameservers must NOT be present:
type: nameservers
operator: notContains
value:
- ns1.oldprovider.net
- ns2.badactor.com # Checks if BOTH are absent
Validation: - Value MUST be a string OR an array of strings - If array, it MUST NOT be empty - If string, it MUST NOT be empty - Duplicate values in assertion list are normalized (treated as set) - Extra fields are FORBIDDEN
Semantics:
String to List Conversion: If value is a string, it is converted to a single-element list before comparison.
- Assertion: value: "a" → internally becomes value: ["a"]
- This is purely syntactic sugar for convenience
Order Independence: List comparison is order-independent. [a, b] equals [b, a].
Comparison Behavior:
- equals: Set equality check
- Result: [ns1.cloudflare.com, ns2.cloudflare.com] matches assertion: [ns2.cloudflare.com, ns1.cloudflare.com] ✅
- Result: [ns1.cloudflare.com] matches assertion: ns1.cloudflare.com ✅ (string converted to [ns1.cloudflare.com])
- Result: [ns1.cloudflare.com] fails assertion: [ns1.cloudflare.com, ns2.cloudflare.com] ❌
- Result: [ns1.cloudflare.com, ns2.cloudflare.com, ns3.cloudflare.com] fails assertion: [ns1.cloudflare.com, ns2.cloudflare.com] ❌
contains: Subset check (assertion ⊆ result)- Result:
[ns1.cloudflare.com, ns2.cloudflare.com]matches assertion:ns1.cloudflare.com✅ (single value present) - Result:
[ns1.cloudflare.com, ns2.cloudflare.com]matches assertion:[ns1.cloudflare.com]✅ - Result:
[ns1.cloudflare.com, ns2.cloudflare.com, ns3.cloudflare.com]matches assertion:[ns1.cloudflare.com, ns2.cloudflare.com]✅ -
Result:
[ns1.cloudflare.com]fails assertion:[ns1.cloudflare.com, ns2.cloudflare.com]❌ (missing ns2) -
notContains: Disjoint check (assertion ∩ result = ∅) - Result:
[ns1.cloudflare.com, ns2.cloudflare.com]matches assertion:ns1.oldprovider.net✅ (single value absent) - Result:
[ns1.cloudflare.com, ns2.cloudflare.com]matches assertion:[ns1.oldprovider.net]✅ - Result:
[ns1.cloudflare.com, ns2.cloudflare.com]fails assertion:ns1.cloudflare.com❌ (value is present) - Result:
[ns1.cloudflare.com, ns2.cloudflare.com]fails assertion:[ns1.cloudflare.com, ns3.other.com]❌ (ns1.cloudflare.com present)
Case Sensitivity: String comparisons are case-sensitive by default. ns1.cloudflare.com ≠ NS1.CLOUDFLARE.COM.
Normalization: Implementations MAY normalize values (e.g., lowercase DNS names) before comparison. If normalization is performed, it MUST be documented.
Scheduling¶
Checks MUST specify exactly one scheduling method: interval OR cron.
Interval¶
Type: Time
Description: Execute check at regular intervals.
Example:
Validation:
- MUST be valid Time format
- MUST NOT be used with cron
Cron¶
Type: string
Description: Execute check based on cron expression.
Format: Standard cron format (5 or 6 fields)
Example:
Validation:
- MUST be valid cron expression
- MUST NOT be used with interval
- Validated using croniter library semantics
Common Spec Fields¶
These fields appear in the spec section of all check kinds.
timeout¶
Type: Time
Default: 1s
OPTIONAL
Description: Maximum duration for check execution.
Example:
retries¶
Type: integer
Default: 1
OPTIONAL
Description: Number of retry attempts on failure.
Example:
Validation: - MUST be positive integer
locations¶
Type: array[string]
Default: []
OPTIONAL
Description: List of geographic locations or execution environments where check should run.
Example:
Semantics: - Empty list means run in default location - Location identifiers are implementation-specific - Check runs independently in each location
channels¶
Type: array[object]
Default: []
OPTIONAL
Description: Notification destinations for check results.
Example:
Fields:
- channel: Identifier for notification channel
- severity: Severity level (implementation-specific)
Semantics: - Empty list means no notifications - Channel configuration is implementation-specific
Validation Rules¶
Extra Fields¶
All models in this specification use strict validation: - Extra fields are FORBIDDEN - Unknown fields MUST cause validation errors - Implementations SHOULD provide clear error messages
Required vs Optional¶
- Fields marked REQUIRED MUST be present
- Fields marked OPTIONAL MAY be omitted
- Default values apply when optional fields are omitted
Mutually Exclusive¶
Some fields are mutually exclusive:
- interval and cron MUST NOT both be specified
- Exactly one MUST be present
Validation Error:
Conformance¶
Implementations claiming conformance with Synthetic Open Schema v1 MUST:
- Support all common types defined in this document
- Validate Time format according to specified pattern
- Enforce identifier constraints (CaseInsensitiveKey, DNSHostname)
- Implement all operators for their respective assertion types
- Validate mutually exclusive fields (interval/cron)
- Reject extra fields in strict mode
- Apply default values for optional fields
Implementations SHOULD: - Provide clear error messages for validation failures - Support all common spec fields (timeout, retries, locations, channels) - Document which operators are supported for each assertion type