Checks

Update a check

Partially updates a monitor using JSON Merge Patch semantics (RFC 7396):

  • Omitted field — the stored value is left unchanged.
  • Explicit null — clears the value. Supported on runaway_ceiling, max_runtime_s, step_timeout_s, blocked_timeout_s, expect_every_s, notify_min_run_s, monitor_from, ci_workflow, ci_branch, tags, agent_id, source_kind and source_ref only — the same thirteen properties typed to allow null in the CheckPatch schema; for tags, explicit null is equivalent to sending []; for blocked_timeout_s, explicit null does not mean "wait forever" — it restores the 24h default, same as omitting the field; for agent_id, explicit null detaches the monitor from its agent without deleting either of them; for the source pair, null must be sent on both keys, since a half-cleared discovery identity reconciles against nothing and is rejected with 400 (SOURCE_INCOMPLETE). failure_threshold is NOT clearable (it always has a value, default 1); a null there is treated as omission.
  • Any other value — replaces the stored value.

Changing failure_threshold does not reset consecutive_failures: lowering it means "that many failures is now enough", so a monitor already at or above the new threshold alerts on its next failure.

tags is replaced wholesale, not merged; send [] or null to remove all tags. slug, monitor_type and ci_secret are immutable and are ignored if present. ci_provider is immutable too, but on a monitor with no CI binding it is now rejected with 400 (FIELD_NOT_IN_SHAPE) rather than accepted and ignored — see the CheckPatch schema.

ci_workflow, ci_branch, source_kind and source_ref deliberately deviate from strict RFC 7396: an explicit empty string "" preserves the stored value, the same as omitting the field. This protects full-body clients (e.g. Terraform) that always send "" for an unset attribute from silently unbinding a live CI filter — or, for the source pair, from destroying a monitor's discovery identity, after which the next scan no longer recognises the source and creates a second monitor for it. Explicit null is the documented way to clear any of these fields.

Sending a complete body remains valid and behaves as a full replace.

patch/api/v1/checks/{id}

Request

  • Base URL: https://app.lastping.dev
  • URL: https://app.lastping.dev/api/v1/checks/{id}
  • Auth: API key in header X-Api-Key

Request body

namestring

Human-readable name for the check. A new name must be at most 200 characters (not bytes) and free of control and invisible characters (400 INVALID_NAME); sending the stored name unchanged is always accepted. Bytes that are not valid UTF-8 are replaced with U+FFFD when the request is decoded, and accepted.

schedule_kind'simple' | 'cron' | 'on_demand'

simple uses a fixed period; cron uses a cron expression; on_demand means the check has no cadence at all — it is driven entirely by run events, never arms an absence deadline, and silence between runs never alerts. Run-scoped detection (max_runtime_s, step_timeout_s) still applies once a run starts, and expect_every_s — the silence floor — is the only way to detect absence between runs. Ignored when the monitor's type is http (schedule is driven by probe_interval_s).

period_sinteger

Expected ping interval in seconds. Applies when schedule_kind is simple.

Must be absent when the resolved schedule_kind is on_demand — sending it in the same request that sets (or leaves) the check at on_demand is rejected with 400 (ON_DEMAND_SCHEDULE_CONFLICT).

cron_exprstring

Cron expression (5-field). Applies when schedule_kind is cron.

Must be absent when the resolved schedule_kind is on_demand — sending it in the same request that sets (or leaves) the check at on_demand is rejected with 400 (ON_DEMAND_SCHEDULE_CONFLICT).

tzstring

IANA timezone for cron evaluation.

grace_sinteger

Grace period in seconds after a ping is due before the check is considered late. For an http monitor the effective grace is derived as 2 × probe_interval_s; a larger explicit grace_s sent in the same request is honoured instead.

grace_s is the silence tolerance and the first-run deadline; the overrun deadline uses max_runtime_s when that is set.

max_runtime_sinteger nullable

Run-duration budget in seconds for the overrun deadline only; the silence rule and the first-run seed keep using grace_s. Time a run spends blocked does not count toward it.

Explicit null clears it, restoring the fallback to grace_s; omitting the field leaves it as stored.

Rejected with 400 (MAX_RUNTIME_NOT_SUPPORTED) on an http monitor when sent with a non-null value — an HTTP probe has no start/success pair, so the overrun rule can never fire. An explicit null on an http monitor is accepted as a no-op.

step_timeout_sinteger nullable

Progress budget in seconds for the stall rule only.

Explicit null disables stall detection; omitting the field leaves it as stored.

Stall detection needs your job to call /step: the Claude Code hook and the reporting prompt do not send steps, so leave step_timeout_s unset for them.

The merged value must stay strictly below the merged effective run budget COALESCE(max_runtime_s, grace_s), and this is checked from BOTH directions: a PATCH that only raises grace_s, or only clears max_runtime_s, is rejected with 400 (STEP_TIMEOUT_EXCEEDS_BUDGET) when it would push the stored step_timeout_s out of the window.

Rejected with 400 (STEP_TIMEOUT_NOT_SUPPORTED) on an http monitor when sent with a non-null value. An explicit null on an http monitor is accepted as a no-op.

expect_every_sinteger nullable

Silence floor in seconds: alert if no ping of any kind arrives within this window, regardless of the schedule.

Explicit null turns the floor off; omitting the field leaves it as stored. On an on_demand monitor, clearing it returns the monitor to arming no absence deadlines at all between runs.

Accepted on every monitor_type, including http.

notify_min_run_sinteger nullable

Notification duration floor: a run shorter than this many seconds does not produce an INFO-CLASS notification (success, started, every-run, note). Never suppresses down, fail, recovery or blocked, and never suppresses started or an event whose duration is unknown.

Explicit null turns the floor off; omitting the field leaves it as stored.

Rejected with 400 (NOTIFY_MIN_RUN_NOT_SUPPORTED) on an http monitor when sent with a non-null value — an HTTP probe has no start/success pair, so its run duration is never measured. An explicit null on an http monitor is accepted as a no-op.

blocked_timeout_sinteger nullable

How long (in seconds) a check may sit blocked before a blocked incident opens.

Explicit null does NOT mean "wait forever" — it clears the stored value and falls back to the default (24 hours), same as omitting the field on a check that never set it. There is no way to disable the blocked timeout entirely.

Accepted on every monitor_type, including http.

failure_thresholdinteger

Consecutive explicit failures required before an incident opens. Applies to the fail cause ONLY — silence, overrun, never_started, runaway, stalled and blocked are time- or rate-based and are never gated by it. A run that ends on the model provider's API error (upstream) neither counts toward it nor resets it: those page on their own count of runs in a row, which is 3 or this threshold, whichever is higher.

Not nullable: it always has a value (default 1), so there is no "unset" state to return to. An omitted field (or an explicit null, treated the same as omission) leaves the stored value unchanged.

Changing it does NOT reset consecutive_failures. With the counter at 3 and the threshold lowered from 5 to 2, the very next failure opens an incident. This is deliberate: the counter is a factual record of failures that really happened, and lowering the threshold means "that many is now enough" — resetting would discard true information. Raising it likewise keeps the counter, so a monitor already past the new threshold alerts on its next failure.

monitor_fromstring date-time nullable

RFC 3339 timestamp. Deadlines are not computed before this time. Explicit null clears it.

probe_urlstring uri

Absolute http or https URL for LastPing to probe (http monitors).

probe_method'GET' | 'HEAD' | 'POST'

HTTP method for the probe request.

probe_expected_bodystring

Substring that must appear in the response body for the probe to be considered successful. Send "" to skip body matching.

probe_interval_sinteger

How often (in seconds) LastPing should probe the URL. Must be between 30 and 86400.

probe_expected_statusinteger

HTTP status code the probe must receive to count as success. 0 means "any 2xx response counts as success".

probe_timeout_sinteger

Probe HTTP request timeout in seconds. Must be between 1 and 30.

probe_follow_redirectsboolean

Whether the probe should follow HTTP redirects.

ci_workflowstring nullable

CI workflow name to filter inbound webhooks by (provider-specific). Deliberately deviates from strict RFC 7396: an explicit empty string "" preserves the stored value, the same as omitting the field, so that full-body clients (e.g. Terraform) which always send "" for an unset filter cannot silently unbind a live filter. Explicit null clears it.

ci_branchstring nullable

Branch name to filter inbound webhooks by. Same empty-string preservation rule as ci_workflow; explicit null clears it.

runaway_ceilinginteger nullable

Maximum pings allowed in a rolling 1-hour window. Exceeding it opens a runaway-cause incident, which detects a looping agent or job pinging abnormally fast. Explicit null disables the check; omitting the field leaves it as stored.

tagsstring[] nullable

Labels for namespace scoping and auditing. Replaced wholesale, not merged. Max 20 tags; each tag max 50 characters. Duplicate tags are silently deduplicated. Send [] or null to remove all tags; omitting the field leaves the stored tags alone.

agent_idstring nullable

The agent that owns this monitor, by id or slug. Omitting the field preserves the current attachment; an explicit null detaches the monitor (sets its agent_id to null) without deleting anything; any other non-empty value re-attaches it, resolved fresh on every request. An explicit empty string "" is rejected with 400 — unlike ci_workflow/ci_branch, it is NOT treated as "leave unchanged"; omit the field or send null instead.

An unknown or foreign agent reference is rejected with 400 (UNKNOWN_AGENT) and never implicitly creates the agent.

source_kindstring nullable

The scanner that discovered this monitor. Omitting the field — or sending an explicit empty string "" — leaves the stored value alone; only an explicit null clears it, and only together with source_ref.

The ""-preserves rule matches ci_workflow/ci_branch and exists for the same full-body clients, with a sharper consequence: every other clearable field here is a setting, but this pair is an identity. A source cleared by accident is a monitor the next discovery scan no longer recognises, so the scan reports the source as unmonitored and creates a second monitor for it — the exact duplicate the reconcile key exists to prevent.

PATCH is the only surface that can change a monitor's source after create. That is deliberate: a slug upsert body cannot tell "omitted" from "clear", so allowing it to write here would let a slug collision silently adopt a hand-made monitor into discovery. A PATCH names a specific monitor and a specific field, which makes adoption an explicit act — and is exactly what Terraform's import-then-apply flow performs.

source_refstring nullable

The stable path within source_kind. Same merge-patch rules as source_kind above.

The two are resolved as a pair. Whatever the request and the stored row combine to, the result must be either both set or both empty — {"source_ref": null} alone is rejected with 400 (SOURCE_INCOMPLETE), not applied as a half-cleared identity. Clearing therefore takes an explicit null on both keys.

A pair another monitor in this project already claims is rejected with 409 (SOURCE_ALREADY_MONITORED): two monitors reconciling to one source would make every later discovery run ambiguous.

A PATCH that mentions neither key issues no source write at all, so a discovered monitor cannot lose its identity to an unrelated edit such as a rename.

trace_content'redacted' | 'dropped'

What this monitor's traces keep of prompt, command and tool content. dropped (the default) removes the content attributes (prompts, completions, commands, tool arguments, results and definitions, retrieved documents, working directories) of every recognised vocabulary entirely; lengths such as user_prompt_length, token counts and cost are kept. Error text (error, error.message, exception.message, exception.stacktrace and the span's status message) is kept at dropped, redacted and then cut to 512 characters, and a cut marks the span or log event truncated. redacted opts in to storing that content, with every secret-shaped value replaced by [REDACTED:<class>] at ingest, before anything is queued or stored: API keys (LastPing, Anthropic, OpenAI, GitHub, GitLab, npm, AWS access key ids, Slack, Stripe, Google, Hugging Face, Perplexity, Fireworks, Supabase, New Relic, Airtable, Terraform Cloud, Firebase), HashiCorp Vault tokens, age secret keys, Discord bot tokens, Slack, Discord and Teams webhook URLs, Authorization header values, JWTs, private key blocks, password=/token=/api_key= style assignments (subscripted ones such as os.environ["API_KEY"] = ... and Dockerfile ENV/ARG lines included), SQL PASSWORD '...' and IDENTIFIED BY clauses, the Redis AUTH command, .netrc passwords, command-line password flags and the argument after them (any secret-named --flag, -p after a login subcommand, redis-cli -a), cookies, credentials in URLs, the value of any attribute or JSON field whose name is secret-named (password, token, api_key, secret, the same word in several other languages, an Authorization or X-Api-Key header and the like; Idempotency-Key and request, correlation and trace ids are not secrets), including JSON carried inside another JSON string such as tool-call arguments, and long high-entropy tokens. A bytes attribute that is valid UTF-8 is scanned and stored as its text. A span that had a value redacted carries lastping.redacted_values. A request whose redaction work exceeds a fixed budget stores [REDACTED:over_budget] for the values it could not scan, never the values themselves. In both modes every remaining value is redacted the same way. There is no setting that stores content unredacted. A change reaches ingest within 60 seconds: ingest caches each monitor's setting for up to a minute, so an export sent just after the change may still be handled the old way.

Absent leaves the stored value alone. null and any other value are rejected with 400 (INVALID_TRACE_CONTENT): the setting has no unset state. A change reaches the ingest host within a minute.

Example request

{
  "name": "Daily backup job",
  "schedule_kind": "simple",
  "period_s": 86400,
  "cron_expr": "0 3 * * *",
  "tz": "Europe/London",
  "grace_s": 600,
  "max_runtime_s": 14400,
  "step_timeout_s": 300,
  "expect_every_s": 900,
  "notify_min_run_s": 300,
  "blocked_timeout_s": 86400,
  "failure_threshold": 3,
  "monitor_from": "2026-01-01T00:00:00Z",
  "probe_url": "https://example.com/healthz",
  "probe_method": "GET",
  "probe_expected_body": "\"status\":\"ok\"",
  "probe_interval_s": 60,
  "probe_expected_status": 200,
  "probe_timeout_s": 10,
  "ci_workflow": "ci.yml",
  "ci_branch": "main",
  "runaway_ceiling": 20,
  "tags": [
    "agent:claude",
    "env:prod"
  ],
  "agent_id": "nightly-etl-bot",
  "source_kind": "github-actions",
  "source_ref": ".github/workflows/nightly.yml#build",
  "trace_content": "redacted"
}

Response

Updated check.

idstring uuid required

Unique check identifier.

namestring required

Human-readable name.

slugstring required

Stable project-scoped identifier (may be empty string if not set).

schedule_kind'simple' | 'cron' | 'on_demand' required

on_demand means the check has no cadence: it never arms an absence deadline, so silence between runs never alerts. Run-scoped detection (max_runtime_s, step_timeout_s) still applies once a run starts, and expect_every_s — the silence floor — is the only way to detect absence between runs.

period_sinteger required

Period in seconds (only meaningful for schedule_kind=simple).

cron_exprstring

Cron expression (only present when schedule_kind=cron).

tzstring required

IANA timezone.

grace_sinteger required

Grace period in seconds — the silence tolerance and the first-run deadline, and the overrun budget when max_runtime_s is unset.

max_runtime_sinteger nullable

Run-duration budget in seconds for the overrun deadline only. Omitted from the response when unset, in which case the overrun rule falls back to grace_s. Never set on http monitors.

step_timeout_sinteger nullable

Progress budget in seconds for the stall rule. Omitted from the response when unset, in which case stall detection is disabled. Never set on http monitors.

expect_every_sinteger nullable

Silence floor in seconds. Omitted from the response when unset, in which case absence is detected only by the schedule — and, for an on_demand monitor, not at all between runs.

notify_min_run_sinteger nullable

Notification duration floor in seconds. Omitted from the response when unset, in which case every info-class notification (success, started, every-run, note) fires regardless of how short the run was. Never set on http monitors. Never suppresses down, fail, recovery or blocked.

blocked_timeout_sinteger nullable

How long (in seconds) the check may sit blocked before a blocked incident opens. Omitted from the response when unset — that does NOT mean the check waits forever, it means the 24-hour default applies.

failure_thresholdinteger required

Consecutive explicit failures required before an incident opens (fail cause only). Always present; 1 means "open on the first failure", the default.

monitor_fromstring date-time nullable

RFC 3339 timestamp from which deadlines are computed.

status'new' | 'up' | 'late' | 'down' required

Current check status derived from ping history.

last_ping_atstring date-time nullable

RFC 3339 timestamp of the most recent ping received.

due_atstring date-time nullable

RFC 3339 timestamp when the next ping is expected.

alert_afterstring date-time nullable

RFC 3339 timestamp after which an alert is sent if no ping arrives.

pausedboolean required

When true the check does not alert regardless of ping status.

maintenance_untilstring date-time nullable

RFC 3339 timestamp until which the check is snoozed. Alerts are suppressed while this is in the future; null or absent when the check is not snoozed.

created_atstring date-time required

RFC 3339 UTC timestamp when the check was created.

ping_urlstring uri required

The URL your service should HTTP-GET to record a successful ping.

monitor_type'heartbeat' | 'ci' | 'http'

Monitor mode. Omitted on responses when the value is the default heartbeat.

probe_urlstring uri

URL being probed (HTTP monitors only; omitted otherwise).

probe_method'GET' | 'HEAD' | 'POST'

HTTP method used for the probe (HTTP monitors only; omitted otherwise).

probe_expected_bodystring

Expected response body substring (HTTP monitors only; omitted otherwise).

probe_interval_sinteger

Probe interval in seconds (HTTP monitors only; omitted otherwise).

probe_expected_statusinteger

Expected HTTP status code (HTTP monitors only; omitted otherwise).

probe_timeout_sinteger

Probe timeout in seconds (HTTP monitors only; omitted otherwise).

probe_follow_redirectsboolean

Whether the probe follows redirects (HTTP monitors only; omitted otherwise).

next_probe_atstring date-time nullable

RFC 3339 UTC timestamp when the next probe is scheduled (HTTP monitors only; omitted otherwise).

ci_provider'github' | 'gitlab' | 'jenkins'

CI provider bound to this check (omitted when no CI binding is set).

ci_configuredboolean

True when a CI binding is set on this check (omitted when false).

ci_webhook_urlstring uri

Webhook URL for this CI check (omitted when no CI binding is set). POST this URL from your CI provider with the ci_secret as the HMAC secret.

ci_secretstring

WRITE-ONCE — returned ONLY in the 201 create response and the POST /api/v1/checks/{id}/ci/regenerate response. NEVER returned on GET or list. Copy it immediately; it cannot be retrieved again (use regenerate to rotate).

ci_workflowstring

Optional workflow/job name filter narrowing which CI runs this check watches (omitted when unset, which watches every workflow).

ci_branchstring

Optional branch filter narrowing which CI runs this check watches (omitted when unset, which watches every branch).

runaway_ceilinginteger nullable

Maximum pings allowed in a rolling 1-hour window. Exceeding it opens a runaway-cause incident, which detects a looping agent or job pinging abnormally fast. Omitted from the response when disabled for this monitor.

tagsstring[] required

Labels attached to this monitor. Always returned as an array (never null); empty array when no tags are set.

agent_idstring uuid nullable

Id of the agent that owns this monitor. Omitted/null when the monitor is unattached — including right after its owning agent was deleted: DELETE /api/v1/agents/{id} unowns the monitors it owned, it does not delete them.

source_kindstring

The scanner that discovered this monitor (crontab, github-actions, k8s-cronjob, systemd-timer). Omitted when a human created the monitor, which is the state of every monitor that predates discovery — and such a monitor is never reconciled, so a scan can neither adopt nor delete it.

source_refstring

The stable path within source_kind that identifies exactly what was found. Together with source_kind and the project it is the discovery reconcile key.

source_kind and source_ref are always either both present or both omitted: a half-set identity is never stored.

trace_content'redacted' | 'dropped' required

What this monitor's traces keep of prompt, command and tool content. dropped (the default) removes the content attributes (prompts, completions, commands, tool arguments, results and definitions, retrieved documents, working directories) of every recognised vocabulary entirely; lengths such as user_prompt_length, token counts and cost are kept. Error text (error, error.message, exception.message, exception.stacktrace and the span's status message) is kept at dropped, redacted and then cut to 512 characters, and a cut marks the span or log event truncated. redacted opts in to storing that content, with every secret-shaped value replaced by [REDACTED:<class>] at ingest, before anything is queued or stored: API keys (LastPing, Anthropic, OpenAI, GitHub, GitLab, npm, AWS access key ids, Slack, Stripe, Google, Hugging Face, Perplexity, Fireworks, Supabase, New Relic, Airtable, Terraform Cloud, Firebase), HashiCorp Vault tokens, age secret keys, Discord bot tokens, Slack, Discord and Teams webhook URLs, Authorization header values, JWTs, private key blocks, password=/token=/api_key= style assignments (subscripted ones such as os.environ["API_KEY"] = ... and Dockerfile ENV/ARG lines included), SQL PASSWORD '...' and IDENTIFIED BY clauses, the Redis AUTH command, .netrc passwords, command-line password flags and the argument after them (any secret-named --flag, -p after a login subcommand, redis-cli -a), cookies, credentials in URLs, the value of any attribute or JSON field whose name is secret-named (password, token, api_key, secret, the same word in several other languages, an Authorization or X-Api-Key header and the like; Idempotency-Key and request, correlation and trace ids are not secrets), including JSON carried inside another JSON string such as tool-call arguments, and long high-entropy tokens. A bytes attribute that is valid UTF-8 is scanned and stored as its text. A span that had a value redacted carries lastping.redacted_values. A request whose redaction work exceeds a fixed budget stores [REDACTED:over_budget] for the values it could not scan, never the values themselves. In both modes every remaining value is redacted the same way. There is no setting that stores content unredacted. A change reaches ingest within 60 seconds: ingest caches each monitor's setting for up to a minute, so an export sent just after the change may still be handled the old way.

Always present.

kind'cron' | 'ci' | 'agent' | 'http' required

The console's four-way grouping of this monitor, derived server-side so every surface groups it the same way. agent wins over the rest: an agent's heartbeat is the agent's. A CI monitor is one with a ci_provider, not one with monitor_type: "ci" — nothing in the product writes that value.

uptime_90dnumber double nullable required

Uptime over the last 90 days, or since the monitor was created if that is more recent, as a percentage with two decimals. For an HTTP monitor this is the share of probes that succeeded; for every other type it is derived from incident downtime over the window. Null when an HTTP monitor has no probe history yet, and null for any other monitor that has never been pinged. A monitor created three days ago reports on those three days, not on 90 days of assumed success, so the window varies per monitor and the console says so beside the figure.

latency_msinteger nullable required

The most recent probe's latency. HTTP monitors only; null for every other type and for an HTTP monitor with no probe yet.

routes_countinteger required

How many distinct alert destinations would hear about this monitor FAILING: the destinations routed on down, fail, blocked or every-run. Distinct destinations, not route rows, so one destination routed on both down and fail is one place the alerts go. every-run counts because it fires for every completed run, a failed one included. A route on recovery, success, started or note is not counted: routes are resolved per event with no fallback, and none of those four ever fires for a failure, so a monitor routed only on them has nowhere for its bad news to go. 0 means failures would be silent, which the console flags as "Not routed" and Home counts in overview.alerts.monitors_unrouted.

recent_outcomesstring[] required

This monitor's last 20 run outcomes, newest first, for the console's run strip. Always an array, empty when the monitor has not completed a run yet. Only terminal outcomes appear: a start says a run began and is not one.

hook_versioninteger nullable required

Version of the Claude Code hook script last seen on a start ping; null when no hook that reports a version has sent a start. Older than hook_version_current means re-run set-up.

hook_version_currentinteger required

The hook script version set-up installs today. Compare it with hook_version.

hook_seen_atstring date-time nullable required

When hook_version was last recorded, from a start ping. Refreshed at most once an hour while the version is unchanged. Null when no hook that reports a version has sent a start.

claude_code_seen_atstring date-time nullable required

Latest time this monitor received a Claude Code run (a hook start that reported a version, or a trace whose source is Claude Code). With hook_version null and a recent value here, the machine runs an older hook or none.

Example response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Daily backup job",
  "slug": "daily-backup",
  "schedule_kind": "simple",
  "period_s": 86400,
  "cron_expr": "0 3 * * *",
  "tz": "UTC",
  "grace_s": 600,
  "max_runtime_s": 14400,
  "step_timeout_s": 300,
  "expect_every_s": 900,
  "notify_min_run_s": 300,
  "blocked_timeout_s": 86400,
  "failure_threshold": 3,
  "monitor_from": "2026-01-01T00:00:00Z",
  "status": "up",
  "last_ping_at": "2026-07-10T03:00:05Z",
  "due_at": "2026-07-11T03:00:00Z",
  "alert_after": "2026-07-11T03:10:00Z",
  "maintenance_until": "2026-07-11T09:00:00Z",
  "created_at": "2026-07-01T12:00:00Z",
  "ping_url": "https://ingest.lastping.dev/550e8400-e29b-41d4-a716-446655440000",
  "monitor_type": "http",
  "probe_url": "https://example.com/healthz",
  "probe_method": "GET",
  "probe_expected_body": "\"status\":\"ok\"",
  "probe_interval_s": 60,
  "probe_expected_status": 200,
  "probe_timeout_s": 10,
  "next_probe_at": "2026-07-13T03:01:00Z",
  "ci_provider": "github",
  "ci_configured": true,
  "ci_webhook_url": "https://ingest.lastping.dev/ci/github/550e8400-e29b-41d4-a716-446655440000",
  "ci_secret": "a3f8c2d1e4b7a9f0c3d2e1b4a7f8c0d3e2b1a4f7",
  "ci_workflow": "ci.yml",
  "ci_branch": "main",
  "ci_ignored": {
    "count": 12,
    "last_at": "2026-10-08T14:02:11Z",
    "last_workflow": "CI",
    "last_branch": "feature/login",
    "last_matched_at": "2026-10-01T09:00:00Z",
    "filters_changed_at": "2026-09-20T12:00:00Z",
    "same_workflow_count": 3,
    "same_workflow_last_at": "2026-10-08T11:40:00Z",
    "same_workflow_last_branch": "release/2.4",
    "new_workflow": "Deploy prod",
    "new_workflow_first_at": "2026-10-06T09:12:00Z",
    "new_workflow_count": 2
  },
  "runaway_ceiling": 20,
  "tags": [
    "agent:claude",
    "env:prod"
  ],
  "agent_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "source_kind": "github-actions",
  "source_ref": ".github/workflows/nightly.yml#build",
  "trace_content": "dropped",
  "kind": "cron",
  "uptime_90d": 99.67,
  "latency_ms": 142,
  "routes_count": 2,
  "recent_outcomes": [
    "succeeded",
    "succeeded",
    "failed"
  ],
  "hook_version": 2,
  "hook_version_current": 2
}

Changes

No recorded changes to this operation across all 2 revisions of this API.