HeimPulse API

Services

The real shape of an endpoint's call and assertions, including the few leaves the reference documents as opaque objects.

View as Markdown

POST/PATCH /v1/services accept full endpoint definitions - most of it is typed exactly in the API reference (see EndpointInput, MonitoringCallInput, and MonitoringAssertionDef). A handful of deeply-nested leaves fall back to opaque objects in the generated schema because they can’t be expressed as fixed OpenAPI types: this page is their real shape.

The call

Today only Http is supported (GRPC/DNS are accepted and rejected with a clear error, not silently ignored):

{
  "url": "https://example.com/health",
  "name": "Health check",
  "call": {
    "Http": {
      "method": "GET",
      "body": null,
      "headers": { "Authorization": { "value": "Bearer secret-token", "sensitive": true } },
      "max_redirects_to_follow": 3,
      "with_dns": true,
      "timeout": null
    }
  },
  "assertions": [{ "StatusCode": { "expected": { "Eq": 200 } } }]
}

Assertions

assertions is an array of tagged objects, one of five kinds:

[
  { "StatusCode": { "expected": { "Eq": 200 } } },
  { "Latency": { "l_type": "TotalLatency", "expected": { "LessThan": { "secs": 1, "nanos": 0 } } } },
  { "DnsResoltion": { "expected": { "LessOrEqual": { "secs": 0, "nanos": 200000000 } } } },
  { "Header": { "name": "content-type", "matcher": { "Contains": "application/json" } } },
  { "Body": { "matcher": { "Regex": "\"status\"\\s*:\\s*\"ok\"" } } }
]

The comparison operators

StatusCode’s expected field is a Comparison - one of:

Variant Shape Meaning
Eq / NotEq {"Eq": 200} equals / does not equal
GreaterThan / GreaterOrEqual / LessThan / LessOrEqual {"GreaterThan": 500} ordering
Between {"Between": [200, 299]} inclusive range (two values)
OneOf {"OneOf": [200, 201, 204]} any of a set

Latency and DnsResoltion use a narrower DurationComparison instead - a status code is a discrete set of legal values (Eq/OneOf make sense there), but a timing measurement is continuous, so only the ordering-style comparisons apply:

Variant Shape
LessThan / LessOrEqual {"LessThan": {"secs": 1, "nanos": 0}}
Between {"Between": [{"secs": 0, "nanos": 0}, {"secs": 2, "nanos": 0}]}

l_type (on Latency only) is one of HeadersLatency, BodyLatency, TotalLatency.

String matching

Header and Body assertions both use a StringMatcher:

Variant Shape
Equals {"Equals": "ok"}
Contains {"Contains": "application/json"}
StartsWith / EndsWith {"StartsWith": "2."}
Regex {"Regex": "^ok$"}

Why these particular pieces are opaque in the reference

The generated OpenAPI spec derives real, named schemas for almost everything above - the one exception is the specific comparison value itself (Comparison<T>’s operand and DurationComparison, both shown as a bare object in the reference). Comparison<T> is a Rust generic used with a single concrete type parameter (u16, for a status code) mixing single-value and array-shaped variants in one enum - a real limitation of the OpenAPI-generation tooling for that specific shape, not a gap in what the API itself accepts. DurationComparison and the raw timeout field both bottom out in std::time::Duration, which has no fixed schema representation of its own beyond the {secs, nanos} shape documented above. Everything else in a service or endpoint definition - including which five assertion kinds exist and every other field on each - is fully typed in the reference itself.