Skip to main content
Glama

fettle-mcp

Website: fettle.sh · MCP docs: fettle.sh/docs/mcp · Dashboard: dashboard.fettle.sh · Support: support@fettle.sh

MCP server for Fettle — uptime monitoring you can drive from Claude Code, Codex, Claude Desktop, Cursor, Windsurf or anything else that speaks the Model Context Protocol.

Ask your assistant to create a monitor, look up why one went down, acknowledge an incident or pause checks before a deploy — it calls the same public API you would.

"Add an HTTP monitor for https://api.acme.dev, check it every 5 minutes from Europe."
"Which of my monitors had incidents this week?"
"Pause the checkout monitor — we're deploying for the next 20 minutes."

In the official MCP registry this server is sh.fettle/mcp — one entry covering both channels, for clients that install from the registry rather than from a hand-edited config file.

Requirements

  • Node.js 20 or newer

  • A Fettle account and an API key (Settings → API Keys at https://fettle.sh)

An API key belongs to one organization and carries either read or write scope. Read-scope keys can list and inspect; the write tools below need a write-scope key.

Related MCP server: IonHour MCP Server

Install

There is nothing to install — MCP clients run the package with npx on demand. Add one entry to your client's config and restart it.

Claude Code

claude mcp add fettle --env FETTLE_API_KEY=fettle_your_key_here -- npx -y fettle-mcp

Codex

codex mcp add fettle --env FETTLE_API_KEY=fettle_your_key_here -- npx -y fettle-mcp

Or by hand in ~/.codex/config.toml (.codex/config.toml for one trusted project):

[mcp_servers.fettle]
command = "npx"
args = ["-y", "fettle-mcp"]

[mcp_servers.fettle.env]
FETTLE_API_KEY = "fettle_your_key_here"

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "fettle": {
      "command": "npx",
      "args": ["-y", "fettle-mcp"],
      "env": { "FETTLE_API_KEY": "fettle_your_key_here" }
    }
  }
}

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (per project):

{
  "mcpServers": {
    "fettle": {
      "command": "npx",
      "args": ["-y", "fettle-mcp"],
      "env": { "FETTLE_API_KEY": "fettle_your_key_here" }
    }
  }
}

Windsurf

~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "fettle": {
      "command": "npx",
      "args": ["-y", "fettle-mcp"],
      "env": { "FETTLE_API_KEY": "fettle_your_key_here" }
    }
  }
}

Configuration

Variable

Required

Default

What it does

FETTLE_API_KEY

yes

—

Your API key. The server refuses to start without it.

FETTLE_API_URL

no

https://api.fettle.sh

Point the server at a different API. You will not normally set this.

FETTLE_TIMEOUT_MS

no

30000

How long one tool call may take before it is abandoned.

Tools

49 tools, grouped by what they work on. Read-scope keys can call the read ones; everything marked write needs a write-scope key.

Every tool carries the MCP hints readOnlyHint, destructiveHint, idempotentHint and openWorldHint, so a client can tell reads from changes without parsing names and ask for confirmation only where it matters. Only the five delete_* tools are destructive. preview_maintenance_window and check_target are marked read-only although they need a write-scope key: they change nothing. check_now and check_target reach the target host, so they are open-world.

Every tool whose result is a JSON object declares an outputSchema and returns the result as structuredContent as well as text, so a client can read typed fields instead of parsing the text. The four exceptions return the text only: list_monitors (its compact rows) and the three tools whose result is a list — list_active_maintenance, preview_maintenance_window and list_channels.

Monitors

Tool

Scope

What it does

list_monitors

read

List monitors compactly (status, target, tags, SSL expiry), filtered by type, status, tags.

get_monitor

read

Read one monitor's full configuration and current status by id.

check_target

write

Probe a target once from one region before creating a monitor for it.

create_monitor

write

Create a monitor that checks a URL, host or port on a schedule.

bulk_create_monitors

write

Create up to 100 monitors in one call — all of them or none.

update_monitor

write

Change an existing monitor's settings.

bulk_update_monitors

write

Set the same interval, regions, channels or thresholds on up to 100 monitors, all or nothing.

pause_monitor

write

Stop checking a monitor without deleting it — use before planned downtime.

bulk_pause_monitors

write

Pause up to 100 monitors in one call, all or nothing.

resume_monitor

write

Resume checks on a paused monitor.

bulk_resume_monitors

write

Resume up to 100 paused monitors in one call, all or nothing.

delete_monitor

write

Soft-delete a monitor: it stops being checked and leaves the monitor list.

check_now

write

Re-arm a monitor to run on the next scheduler tick instead of waiting out its interval.

get_exposed_ports_preset

read

Database and admin ports that should not be reachable from the internet.

Results and uptime

Tool

Scope

What it does

get_uptime_summary

read

Uptime, average response time and incident counts over 24h / 7d / 30d at once.

get_uptime_daily

read

A monitor's uptime for each UTC day, oldest first.

get_response_time_by_region

read

A monitor's average response time over 24h, 7d or 30d, one series per region.

list_check_results

read

Individual check results of a monitor, newest first, filtered by region, status or period.

Incidents

Tool

Scope

What it does

list_incidents

read

List incidents, optionally filtered by monitor, status, cause or period.

get_incident

read

Read one incident with its cause and every alert attempt.

acknowledge_incident

write

Acknowledge an open incident so repeat notifications stop.

Heartbeats

Tool

Scope

What it does

list_heartbeats

read

List heartbeat (cron / dead-man's-switch) monitors and when each was last pinged.

get_heartbeat

read

Read one heartbeat, including its ping URL and when it will be reported late.

create_heartbeat

write

Create a heartbeat monitor and get the URL a scheduled job should ping.

update_heartbeat

write

Change a heartbeat's name, period, grace, channels or tags.

pause_heartbeat

write

Pause a heartbeat: it is not reported late and its pings are ignored.

resume_heartbeat

write

Resume a paused heartbeat.

delete_heartbeat

write

Delete a heartbeat for good; its ping URL stops working.

Maintenance windows

Tool

Scope

What it does

list_maintenance_windows

read

List maintenance windows (one-time or recurring, organization-wide or per monitor).

list_active_maintenance

read

The maintenance windows in effect right now.

get_maintenance_window

read

Read one maintenance window with its next three occurrences.

preview_maintenance_window

write

Show the next three occurrences a schedule would produce, without saving it.

create_maintenance_window

write

Create a window that silences alerts, once or on an iCal RRULE schedule.

update_maintenance_window

write

Change a maintenance window.

delete_maintenance_window

write

Delete a maintenance window; alerts resume at once.

Tags

Tool

Scope

What it does

list_tags

read

List every tag in the organization with how many monitors and heartbeats carry it.

bulk_update_monitor_tags

write

Add and/or remove tags across up to 300 monitors in one call.

rename_tag

write

Rename a tag on every monitor and heartbeat that carries it.

delete_tag

write

Remove a tag from every monitor and heartbeat that carries it.

Status pages

Tool

Scope

What it does

list_status_pages

read

List status pages, with each page's slug and whether it is published.

get_status_page

read

Read one status page with its groups and components.

list_status_page_incidents

read

List a status page's incidents, posted by a person or opened by Fettle, with their timelines.

create_status_page_incident

write

Open an incident on a status page with a first message.

post_status_page_update

write

Add a message to a status page incident and set its status; RESOLVED closes it.

update_status_page_incident

write

Rename a status page incident; subscribers are not notified.

delete_status_page_incident

write

Remove an incident and its timeline from a status page.

Organization and platform

Tool

Scope

What it does

get_plan_usage

read

The organization's plan, its limits, and how much of each is used.

list_channels

read

List notification channels (id, type, label, verified) to bind to monitors.

list_regions

read

List the check regions and the codes the regions argument takes.

The list is not written by hand. It is generated in the Fettle backend from one registry and served at /public-api/mcp-tools.json; this package vendors that file and builds its tools from it at startup, so the two MCP channels can never offer different tools.

Agent guide

The server sends this guide to the client in initialize (instructions), so an agent connected through either channel already has it. It is reproduced here for humans and for clients that do not surface server instructions.

Fettle is an uptime monitoring service. The tools see only the API key's organization: monitors, heartbeats, maintenance windows, incidents, status page incidents, tags, channels (read), regions. Channels, status pages, members, API keys and billing are managed only in the dashboard (https://dashboard.fettle.sh). Read a tool's description (arguments, limits, errors) before its first call.

FINDING THINGS
- list_monitors gives one short row per monitor; use it to find ids. Filters are JSON arrays. Broken now: status ["DOWN", "DEGRADED"]. Certificates expiring first: type ["SSL"], sort "ssl_expiry".
- tag filters lists; tag_match "all" (default) needs every tag, "any" one of them.
- Lists are paginated: page from 1, size 1..100 (default 25).

PLAN LIMITS
Call get_plan_usage before creating anything: limits (null means none) and usage. A broken limit or an unknown region is a 403 naming it: change the request or tell the user; never retry it unchanged.

CREATING MONITORS
- check_target probes a target once before create_monitor. list_regions names the region codes.
- bulk_create_monitors creates up to 100, all or nothing.
- type and target never change after create.
- channel_ids: ids from list_channels. Empty or omitted on create alerts every verified, active channel. Email is not a channel: every alert also goes to the account email of whoever created the monitor or heartbeat.
- update tools change only the fields you pass. Never send null; omit a field to keep it. A monitor's config is replaced whole: send every config field you want to keep.
- Exposed ports on a server: follow get_exposed_ports_preset.

MANY MONITORS AT ONCE
Find ids with list_monitors, then bulk_pause_monitors, bulk_resume_monitors or bulk_update_monitors (interval, timeout, regions, channels, threshold, cooldown) for up to 100 ids, all or nothing. bulk_update_monitor_tags adds or removes tags on up to 300. There is no bulk delete.

TAGS
Call list_tags first and reuse names. Tags are flat labels such as env:prod, trimmed, lowercased and deduplicated; at most 10 per item. rename_tag and delete_tag act on every monitor and heartbeat.

HEARTBEATS
A job calls ping_url when it succeeds. Job every N seconds, alert after T seconds of silence: period_seconds = N, grace_seconds = T - N. Never late before its first success ping. ping_url + "/start" restarts the clock, ping_url + "/fail" marks it DOWN at once.

MAINTENANCE
Before a deploy or reboot, create_maintenance_window (scope ORG or MONITOR) instead of pausing monitors: checks keep running, but no incident opens and no alert goes out. Not for heartbeats. preview_maintenance_window shows a schedule's next occurrences; list_active_maintenance shows what is silenced now.

OUTAGES
list_monitors status ["DOWN"] -> list_check_results (status code, error, region per check) -> get_incident. acknowledge_incident stops repeat alerts; the recovery alert still goes out. create_status_page_incident and post_status_page_update can email the page's subscribers: confirm the text with the user first.

ERRORS (start of a failed call's text)
- "Authentication failed": the key is missing, revoked or expired, the address is not allowed, or its creator lost access. Do not retry; tell the user.
- "This tool requires/needs an API key with write scope": the key is read-only; tell the user.
- "Invalid argument(s)": names each failing field. "Invalid request:": the rule broken. Fix, retry.
- "Forbidden:": a plan limit, an unknown region, or the key's user lacks the permission; the reason says which.
- "Not found:": no such id in this organization.
- "Rate limited": wait the seconds given, then retry. All API key calls share the organization's per-minute budget.
- "Tool '<name>' failed: the API returned 5xx": server fault, retry once later.
- "Tool '<name>' does not accept argument(s)": drop the ones named.
- "Request failed with status N": read the reason, do not retry unchanged.

The other channel: remote MCP

If your client supports remote MCP servers over HTTP, you do not need this package at all — point it at https://api.fettle.sh/mcp with the same API key as a Bearer token. Same tools, same behaviour, nothing to install or update.

Claude Code adds the remote channel from the command line — a different flag set from the stdio one above, with the key as a header rather than an environment variable:

claude mcp add fettle --transport http https://api.fettle.sh/mcp \
  --header "Authorization: Bearer fettle_your_key_here"

Clients configured through a JSON file take the same two fields:

{
  "mcpServers": {
    "fettle": {
      "url": "https://api.fettle.sh/mcp",
      "headers": { "Authorization": "Bearer fettle_your_key_here" }
    }
  }
}

Codex takes the remote channel in ~/.codex/config.toml and reads the key from an environment variable, so it never sits in the file:

[mcp_servers.fettle]
url = "https://api.fettle.sh/mcp"
bearer_token_env_var = "FETTLE_API_KEY"

Use this package when your client speaks only stdio, or when you would rather the credential stayed in a local config file than in a client's cloud configuration.

There is no OAuth on either channel yet; both authenticate with an API key.

Rate limits and plans

Tool calls spend the same per-organization request budget as the REST API — the plan's limit, not a separate one. A rate-limited call comes back saying how many seconds to wait. check_now also has its own cap of 10 calls per minute per calling address. get_plan_usage shows the organization's request budget as limits.api_rate_limit_per_minute. Plan limits are listed at https://fettle.sh/pricing.

Troubleshooting

FETTLE_API_KEY is not set — the client started the server without the variable. Check the env block of the config above, then fully restart the client: most clients read MCP config only at launch.

Authentication failed — the key is wrong, revoked, or from a deleted organization. Create a fresh one in Settings → API Keys.

This tool requires an API key with write scope — the key is read-only. Create a write-scoped key; there is no way to widen an existing key's scope.

The assistant does not see the tools — restart the client, then confirm Node.js 20+ with node -v. Run npx -y fettle-mcp in a terminal: it should print the missing-key message and exit, which proves the package itself runs.

Development

pnpm install
pnpm run typecheck
pnpm test
pnpm run build
pnpm run contract:check        # vendored contract vs. production

Adding a tool is a change in the backend's registry, not here: regenerate the contract there, then re-vendor it with pnpm run contract:check -- --write and commit the result. No source file in this package describes a tool.

server.json is the entry the official MCP registry serves, and it repeats the version — a test fails if it stops matching package.json, so bump both together.

A release is a version tag: pushing vX.Y.Z runs .github/workflows/publish.yml, which tests, builds and publishes the package to npm with provenance.

License

MIT © Fettle

Available Tools

49 tools
acknowledge_incidentAcknowledge an incidentA
Idempotent
Inspect

Mark an open incident as being handled so its repeat alerts stop; the recovery alert still goes out when it resolves. Use it when someone is working on the outage. It does not close the incident (that happens when the monitor recovers) and it is not for status page incidents (post_status_page_update). Requires a key with the write scope. Acknowledging twice keeps the first acknowledgement; on a resolved incident it succeeds without effect on alerts. Returns the incident in the get_incident shape.

ParametersJSON Schema
NameRequiredDescriptionDefault
incident_idYesThe incident's uuid from list_incidents. An id that is not an incident of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
causeYesKnown values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, HEARTBEAT_MISSED, HEARTBEAT_FAILED, UNKNOWN.
created_atYes
monitor_idNo
started_atYes
updated_atYes
resolved_atYes
cause_detailYes
heartbeat_idNo
renotify_countYes
acknowledged_atYes
acknowledged_byYes
last_notified_atYes
notification_logsNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: explains that only repeat alerts are suppressed while the recovery alert still sends, that the incident is closed by monitor recovery rather than by this call, that a write-scoped key is required, and the exact semantics of double-acknowledgement and acknowledging a resolved incident. These are non-obvious behaviors an agent could not derive from idempotentHint/destructiveHint alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core effect and then layers constraints, auth, and edge-case semantics in four tight sentences. Dense but nearly every clause earns its place; only the trailing return-shape note is arguably redundant given the output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With rich annotations, a fully documented single parameter, and an output schema (the description just points at the get_incident shape), the description covers everything an agent needs: effect, exclusions, auth scope, idempotency, and error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter's uuid origin and 404 failure mode are fully documented in the schema, so the description adds no parameter detail. Baseline 3 is appropriate when the schema carries the parameter burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Mark an open incident as being handled') plus the precise effect (repeat alerts stop, recovery alert still fires). It explicitly disambiguates from the sibling that handles status page incidents, so an agent can route correctly without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('when someone is working on the outage'), when-not ('it does not close the incident'), and names the alternative for the adjacent case ('post_status_page_update'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bulk_create_monitorsCreate several monitorsAInspect

Create 1 to 100 monitors in one call, all or nothing; for a single monitor use create_monitor. Requires a key with the write scope. An invalid item, or a batch that would exceed the plan, rejects the whole call and creates nothing: call get_plan_usage first to check the batch fits. Errors name the failing item. A field that fails validation is named by its path, such as monitors.3.target (index 3 is the fourth item; all such errors are reported at once). Any other item error keeps the status create_monitor would give (403 when its interval or regions break the plan or name an unknown region, 404 for an unknown channel id, 422 for its config or its type's region rules) and its reason starts with monitors[3] (""): — only the first such item is reported. Read the index only from that leading monitors[N] (the pattern ^monitors[(\d+)] after any lead-in such as "Forbidden: " or "Invalid request: "), never from the name, which may itself contain quotes or brackets. A plan-limit 403 without that prefix is about the batch as a whole: together the items would exceed the plan's monitor count or its quota of monitors below 60 seconds. Fix the item or shrink the batch and send the whole call again. Returns monitors: one list_monitors row per created monitor, in request order. Example: {"monitors": [{"name": "db.example.com exposed ports", "type": "TCP", "target": "db.example.com", "interval_seconds": 3600, "timeout_seconds": 10, "regions": ["eu-central"], "config": {"ports": [5432, 6379, 27017], "expected_state": "closed"}}]}

ParametersJSON Schema
NameRequiredDescriptionDefault
monitorsYes1 to 100 monitors, each taking the same fields and rules as create_monitor's arguments. Items with is_active false are created paused and still count toward the plan.

Output Schema

ParametersJSON Schema
NameRequiredDescription
monitorsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: atomicity (nothing is created on any failure), plan-limit behavior, per-item vs batch error discrimination, the exact status codes inherited from create_monitor (403/404/422), and the monitors[N] prefix contract for locating the offending item. This is exactly the kind of operational detail annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the create_monitor alternative are front-loaded, but the long middle paragraph about regex-parsing the monitors[N] prefix ('only the first such item is reported', quoting several lead-in variants) is verbose and could be tightened without losing meaning. It is information-dense rather than padded, but not as lean as it could be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still adds the ordering guarantee ('one list_monitors row per created monitor, in request order'), which the schema alone may not convey. Combined with atomicity, prerequisite checks, and error semantics, an agent has everything needed for a 100-item batch call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the field set and rules. The description adds value with a complete worked example payload (TCP monitor with ports config) and clarifies error-path semantics like monitors.3.target, but does not restate field-level constraints, keeping it modestly above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create 1 to 100 monitors in one call') plus the batch cardinality and all-or-nothing semantics, and explicitly distinguishes from the sibling create_monitor for the single-item case. An agent can identify the tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing ('for a single monitor use create_monitor') and an actionable prerequisite ('call get_plan_usage first to check the batch fits'). The failure-and-retry guidance ('Fix the item or shrink the batch and send the whole call again') tells the agent how to recover, which is rare and genuinely useful.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bulk_pause_monitorsPause many monitorsA
Idempotent
Inspect

Pause up to 100 monitors in one call, all or nothing: no checks run and each open incident closes without an alert. Use it to stop monitoring a whole project or group found with list_monitors; for one monitor use pause_monitor, and to silence alerts around a deploy while checks keep running use create_maintenance_window instead. Requires a key with the write scope. Pausing a paused monitor is not an error. Returns monitors: the list_monitors rows after the change, in request order. Example: {"monitor_ids": ["", ""]}

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idsYes1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
monitorsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: all-or-nothing atomicity, that no checks run and open incidents close without alert, the write-scope requirement, and that re-pausing is not an error. These are behavioral facts the idempotent/destructive hints alone would not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and scope, then routes to alternatives, then states prerequisites and return shape. Dense but every sentence carries distinct information; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still names the return ('list_monitors rows after the change, in request order'), and the auth requirement plus atomicity behavior are covered. Nothing needed to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents the 422 duplicate-id and 404 unknown-id behavior, so the baseline is 3. The description's inline example clarifies invocation format and reinforces the atomic failure semantics ('all or nothing'), adding modest value over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Pause up to 100 monitors in one call'. It also explicitly distinguishes itself from pause_monitor (single) and create_maintenance_window (silence while checks run), so the sibling boundary is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('stop monitoring a whole project or group found with list_monitors') plus two named alternatives with the condition that selects each. No inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bulk_resume_monitorsResume many monitorsA
Idempotent
Inspect

Resume up to 100 paused monitors in one call, all or nothing; each goes back to PENDING and is checked on the next tick. For one monitor use resume_monitor; to run a check right away on a monitor that is already running, use check_now. Requires a key with the write scope. Resuming more monitors than the plan's active limit allows is a 403 and nothing changes (see get_plan_usage). A monitor already running is left as it is. Returns monitors: the list_monitors rows after the change, in request order. Example: {"monitor_ids": ["", ""]}

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idsYes1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
monitorsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (idempotent=true, destructive=false), and the description adds substantial context beyond them: transactionality ('all or nothing'), resulting state (PENDING, checked next tick), the 403 plan-limit behavior with no partial change, and the no-op on already-running monitors. No contradiction with idempotentHint or destructiveHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the batch semantics, then routing, then auth/preconditions, then return shape, then example. Every sentence carries distinct information; no filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter bulk mutation, the description covers scope, alternatives, permissions, failure modes, no-op behavior, and return format — everything an agent needs. An output schema exists, and the description's brief return note is complementary rather than redundant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and already documents the 1-100 distinct-uuid constraint plus 422/404 handling, so baseline is 3. The description adds a concrete invocation example and states the return order is the request order, giving slightly more than the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (resume) plus resource (monitors), with scope stated (up to 100 paused monitors, all-or-nothing). It explicitly distinguishes itself from resume_monitor and check_now, so an agent can route without opening sibling schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names two alternatives with their selecting conditions: resume_monitor for a single monitor, check_now for an immediate check on an already-running monitor. Also states the auth prerequisite (write scope) and the plan-limit failure path with a pointer to get_plan_usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bulk_update_monitorsChange settings of many monitorsA
Idempotent
Inspect

Set the same interval, timeout, regions, channels, threshold or cooldown on up to 100 monitors in one call, all or nothing. For example, move twenty PING monitors to other regions. Not for config or name (use update_monitor, one monitor at a time) or tags (use bulk_update_monitor_tags). Requires a key with the write scope. The plan's rules apply to the result: an interval below the plan minimum, too many fast monitors, too many regions or an unknown region is a 403. A value one monitor cannot take (several regions on an SSL, DNS or port-list TCP monitor, or an interval under 300 on a port-list one) is a 422 that starts with monitors[] (""). Returns monitors: list_monitors rows, which show the interval but not the other settings; read those with get_monitor. Example: {"monitor_ids": ["", ""], "changes": {"regions": ["eu-central", "us-east"], "interval_seconds": 300}}

ParametersJSON Schema
NameRequiredDescriptionDefault
changesYesThe values to set, at least one of: interval_seconds (30 to 86400), timeout_seconds (1 to 120), regions (region codes from limits.allowed_regions in get_plan_usage), channel_ids (channel uuids from list_channels; replaces each binding, [] clears it, an unknown channel is a 404), confirmation_threshold (1 to 10) and notification_cooldown_seconds (60 to 86400). Omit a field to keep it; never send null.
monitor_idsYes1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
monitorsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description adds real behavior beyond them: atomic all-or-nothing semantics, 403 plan-rule failures, 422 per-monitor errors with the monitors[<i>] ("<name>") format, and the caveat that returned list_monitors rows omit most settings so get_monitor is needed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and exclusions are front-loaded, and every sentence carries distinct information (scope, alternatives, auth, limits, error shapes, return caveat, example). It is dense and long, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a 2-param tool with a nested changes object and an output schema, the description covers invocation, gating rules, partial-failure behavior, and result interpretation. An agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the nested changes object is fully documented in the schema, so baseline is 3. The description goes further with a concrete example payload and the semantics of channel_ids replacement/clearing and monitor_ids uniqueness/404 behavior, adding meaning beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ("Set the same interval, timeout, regions...") and bounds scope (up to 100 monitors, all-or-nothing). Explicitly names the siblings it is not (update_monitor, bulk_update_monitor_tags), so an agent can route correctly without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States when-not to use it: not for config or name (use update_monitor) and not for tags (use bulk_update_monitor_tags). Also names the prerequisite (a key with write scope), which is the condition that gates invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bulk_update_monitor_tagsRetag several monitors at onceA
Idempotent
Inspect

Add and/or remove tags across up to 300 monitors in one call, all or nothing: each monitor ends with (its tags | add) - remove. Use it to retag a fleet; to replace one monitor's whole tag list use update_monitor, to rename or drop a tag everywhere (heartbeats too) use rename_tag or delete_tag. Requires a key with the write scope. At least one of add or remove is required, and they must not share a tag (422). A monitor that would end with more than 10 tags rejects the whole call (422). Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates. Returns monitors_updated. Example: {"monitor_ids": ["", ""], "add": ["env:prod"], "remove": ["env:staging"]}

ParametersJSON Schema
NameRequiredDescriptionDefault
addNoTags to add to every listed monitor, up to 10.
removeNoTags to remove from every listed monitor, up to 10.
monitor_idsYes1 to 300 distinct monitor uuids from list_monitors. A repeated id is a 422; an unknown id rejects the whole call with a 404 naming every id not found.

Output Schema

ParametersJSON Schema
NameRequiredDescription
monitors_updatedYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description discloses real behavior: all-or-nothing atomicity, write-scope key requirement, the exact 422 failure conditions (shared tag, >10 tags, duplicate id), tag normalization on write, and the return field monitors_updated. This is far more than the annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is dense but front-loaded with the core contract, then alternatives, then requirements, then an example. Every sentence carries usable information, though the packed constraint list and example make it longer than strictly necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema plus rich annotations already present, the description still covers scope, prerequisites, failure modes, normalization rules and return value, leaving nothing an agent needs to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds constraints the schema omits: at least one of add/remove is required and the two must not share a tag (422), plus a concrete example payload. It adds meaningful semantics beyond the documented fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb pair and resource ('Add and/or remove tags across up to 300 monitors in one call'), states the all-or-nothing scope, and names exactly which siblings handle the adjacent cases (update_monitor, rename_tag, delete_tag). An agent can distinguish this from every bulk_* and tag sibling without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit routing: 'Use it to retag a fleet; to replace one monitor's whole tag list use update_monitor, to rename or drop a tag everywhere (heartbeats too) use rename_tag or delete_tag.' When-to-use and when-to-use-something-else are both spelled out with the selecting condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_nowCheck a monitor nowAInspect

Queue one existing monitor to run on the scheduler's next tick instead of waiting out its interval, for example to confirm a fix. It returns the monitor record, not a check result: call get_monitor or list_check_results a moment later for the outcome. To probe a target that has no monitor yet use check_target; to restart a paused monitor use resume_monitor. Requires a key with the write scope. A repeat call for the same monitor within 30 seconds, or a call on a paused monitor, is a silent no-op that returns it unchanged. Calls are limited to 10 per minute per calling address (not per key or organization); past that it is a 429 with the seconds to wait, so pace a run over many monitors.

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare the safety profile, but the description adds substantial non-structured context: it returns the monitor record rather than a check result, the 30-second and paused-monitor no-op semantics, the write scope requirement, and a per-address rate limit with 429 behavior and a pacing recommendation. This is exactly the operational detail an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and effect, then layered: return-value caveat, sibling routing, auth requirement, no-op conditions, rate limit. Every sentence carries actionable information with no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the gaps an output schema cannot: latency of the result, silent no-op conditions, auth scope, and rate limiting with pacing guidance. The explicit note that the return is the monitor record, not a check result, is the key clarification for correct agent follow-up.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter is fully documented there (uuid source from list_monitors, 404 conditions). The description adds no additional parameter-level syntax or format meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Queue one existing monitor to run on the scheduler's next tick instead of waiting out its interval') and explicitly distinguishes itself from check_target and resume_monitor. The purpose and scope are unambiguous without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit use case ('to confirm a fix'), names two sibling alternatives with the condition that selects each (check_target for no monitor yet, resume_monitor for a paused monitor), and flags the silent no-op cases that make the call pointless. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_targetProbe a target before creating a monitorA
Read-onlyIdempotent
Inspect

Run one real check of a target from one region chosen by Fettle, without creating anything. It reports status (up, down, error or unknown), region, response_time_ms, status_code, error and failure_kind. unknown means no definite answer came back, not a failure. Use it before create_monitor to catch a typo or an unreachable host; a down result does not stop you creating the monitor. For a monitor that already exists use check_now. Requires a key with the write scope. It is rate limited per calling address: a 429 whose retry_after says how many seconds to wait. Example: {"type": "HTTP", "target": "https://api.example.com/health"}

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesHTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value).
configNoAs in create_monitor; TCP and DNS need it. The region, interval and update rules there do not apply to a one-off probe. An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state "open" (default) or "closed", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state "closed", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form.
targetYesWhat to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422.

Output Schema

ParametersJSON Schema
NameRequiredDescription
errorNo
regionYes
statusYesKnown values: up, down, error, unknown.
status_codeNo
failure_kindNo
response_time_msNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnly, idempotent, non-destructive), and the description still adds real operational context: the write-scope auth requirement, per-address rate limiting with a 429/retry_after contract, and the semantic that 'unknown' means no definite answer rather than a failure. That last point is behavior an agent cannot infer from schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: purpose, then outputs, then the confusing 'unknown' semantics, then usage, then auth/rate limits, then the example. Slightly dinged because enumerating the returned fields (region, response_time_ms, status_code, error, failure_kind) duplicates what the output schema already provides.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a probe tool with an output schema in place, the description covers everything an agent needs: auth scope, rate-limit failure mode, the meaning of each status value, and how this call relates to create_monitor and check_now. No gaps remain for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum values and config sub-fields are thoroughly documented in the schema itself, so the baseline is 3. The description only adds a single worked example ({"type": "HTTP", "target": "https://api.example.com/health"}) and a note that TCP/DNS need config; it does not meaningfully extend parameter semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Run one real check of a target') with an explicit scope qualifier ('without creating anything'), and it enumerates the result fields. It also distinguishes itself from both siblings it could be confused with: create_monitor and check_now.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('Use it before create_monitor to catch a typo or an unreachable host'), an explicit non-blocking caveat ('a down result does not stop you creating the monitor'), and the alternative for the other case ('For a monitor that already exists use check_now'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_heartbeatCreate a heartbeat monitorAInspect

Create a heartbeat: Fettle alerts when a scheduled job stops calling its ping_url. Use it for cron jobs, backups and workers that should report in; to probe a URL, host or port from outside use create_monitor. The job calls ping_url (GET or POST) on success, ping_url + "/start" when it begins (restarts the clock) and ping_url + "/fail" to go DOWN at once. It is never late before its first success ping (a /fail call still marks it DOWN); after that an alert fires period_seconds + grace_seconds after the last ping. Requires a key with the write scope. The plan caps how many heartbeats exist (403 past it; see get_plan_usage). An invalid argument is a 422 naming it. Returns the heartbeat, with ping_url. Example: {"name": "nightly backup", "period_seconds": 86400, "grace_seconds": 3600}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesDisplay name, 1 to 255 characters.
tagsNoFlat labels for grouping and filtering, for example env:prod or service:api, at most 10. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates.
channel_idsNoNotification channel uuids from list_channels. Omit it or pass [] to alert every verified, active channel of the organization. An id that is not an active channel of this organization is a 404.
grace_secondsYesExtra seconds of silence tolerated after the period before the heartbeat is reported late, 0 to 2592000; it may exceed the period.
period_secondsYesHow often the job runs, 60 to 2592000 seconds. To ping every N seconds and be alerted after T seconds of silence, set period_seconds = N and grace_seconds = T - N (T at least N).
notification_cooldown_secondsNo60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
stateYesKnown values: PENDING, UP, DOWN, PAUSED.
ping_urlYes
is_activeYes
created_atYes
overdue_atYes
updated_atYes
channel_idsNo
last_ping_atYes
grace_secondsYes
last_start_atYes
period_secondsYes
last_success_atYes
last_duration_msYes
notification_cooldown_secondsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the mutation safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false). The description adds substantial behavior: the ping_url contract (/start restarts the clock, /fail goes DOWN immediately), the never-late-before-first-ping rule, the period_seconds + grace_seconds alert timing, the write-scope requirement, the plan cap returning 403, and invalid args returning 422. This is exactly the context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single dense paragraph, but it is front-loaded with the purpose and then the ping_url contract, error behavior, and example in a logical order. Every sentence carries distinct information, though the run-on density slightly taxes readability compared to a cleaner separation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter mutation tool with an output schema, the description covers the gaps an agent actually needs: purpose, alternative tool, ping contract, auth scope, plan limits, and error codes. Return values are summarized ('returns the heartbeat, with ping_url') without redundantly re-specifying the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value on top: a worked example tying name/period_seconds/grace_seconds together and the timing rule (alert fires period_seconds + grace_seconds after the last ping), which explains how the two numeric params interact. It does not add detail for tags, channel_ids, or notification_cooldown_seconds beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Create) and resource (a heartbeat), then immediately defines what a heartbeat is: 'Fettle alerts when a scheduled job stops calling its ping_url.' It explicitly distinguishes itself from the sibling create_monitor ('to probe a URL, host or port from outside use create_monitor'), so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use cases (cron jobs, backups, workers that report in) and an explicit alternative with its condition (use create_monitor to probe a URL/host/port from outside). It also routes to get_plan_usage for quota and names the write scope requirement. Nothing about selection is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_maintenance_windowCreate a maintenance windowAInspect

Create a one-time or recurring maintenance window that silences alerts for some or all monitors. While a window is in effect its monitors keep being checked, but no incident opens and no alert goes out. Use it around a deploy or reboot instead of pause_monitor; it does not cover heartbeats (use pause_heartbeat). For a recurring schedule run preview_maintenance_window first. Requires a key with the write scope. The plan caps how many windows exist (403 past it or when the plan has none; see max_maintenance_windows in get_plan_usage). An invalid argument or schedule is a 422 naming it. Returns the window. Example: {"name": "Deploy", "scope": "MONITOR", "monitor_ids": [""], "dtstart": "2026-10-14T22:00:00", "duration_minutes": 30}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesDisplay name, 1 to 255 characters.
rruleNoRepeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused. Omit it for a one-time window.
scopeYesORG covers every monitor of the organization and ignores monitor_ids; MONITOR covers only monitor_ids.
dtstartYesThe first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422.
enabledNoDefault true; false stores the window without effect.
timezoneNoIANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes. Defaults to the organization's timezone.
monitor_idsNoMonitor uuids from list_monitors, at least one when scope is MONITOR. An id that is not a monitor of this organization is a 404.
duration_minutesYesHow long each occurrence lasts, 1 to 40320 minutes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
rruleYes
scopeYesKnown values: MONITOR, ORG.
dtstartYes
enabledYes
timezoneYes
created_atYes
monitor_idsNo
duration_minutesYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnly=false, idempotent=false, destructive=false), and the description adds substantial behavior beyond that: monitors keep being checked but no incident/alert fires, write-scope auth is required, plan caps produce a 403, and invalid args produce a 422 naming the field. Return value is only named, but an output schema exists. Slight gap is that idempotency/duplicate-creation behavior is not discussed, though the annotation hints it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose in sentence one, then behavior, alternatives, auth, error modes, and a worked example in descending priority. Dense but every sentence carries distinct operational information; nothing is redundant with the name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-param write tool with annotations and an output schema, the description supplies the missing pieces an agent needs: effect on monitoring, sibling routing, auth scope, quota failure mode, validation failure mode, and a concrete call. Nothing material is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes modestly beyond by giving a complete example call that demonstrates the MONITOR-scope + monitor_ids + dtstart + duration_minutes combination and pointing at list_monitors as the id source, which helps the agent assemble a valid request rather than just read field docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Create a ... maintenance window') and immediately qualifies scope ('one-time or recurring', 'some or all monitors') and effect ('silences alerts'). It also distinguishes itself from pause_monitor and pause_heartbeat, so an agent can route correctly without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('around a deploy or reboot'), explicit alternative ('instead of pause_monitor'), explicit exclusion ('does not cover heartbeats (use pause_heartbeat)'), and a precondition for the recurring case ('run preview_maintenance_window first'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_monitorCreate a monitorAInspect

Create one monitor that checks a URL, host or port on a schedule from one or more regions, and return it in the get_monitor shape. Use check_target first to catch a typo or an unreachable host; use bulk_create_monitors for several monitors, and create_heartbeat for a job that should report in rather than be probed. Requires a key with the write scope. Plan limits apply (monitor count, minimum interval, monitors faster than 60 seconds, regions per monitor): breaking one is a 403 naming it, so call get_plan_usage first. A paused monitor still counts toward them. An invalid argument is a 422 naming it. Example: {"name": "API", "type": "HTTP", "target": "https://api.example.com/health", "interval_seconds": 300, "timeout_seconds": 10, "regions": ["eu-central"], "config": {"expected_status_codes": [200]}, "tags": ["env:prod"]}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesDisplay name, 1 to 255 characters.
tagsNoFlat labels for grouping and filtering, for example env:prod or service:api, at most 10. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates.
typeYesHTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value). Cannot be changed after create.
configNoAn object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state "open" (default) or "closed", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state "closed", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form. Omit it for HTTP, PING or SSL to take the defaults; a TCP or DNS monitor without it is a 422.
targetYesWhat to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422. Cannot be changed after create.
regionsYesOne or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise).
is_activeNoDefault true. false creates it paused: no check runs until resume_monitor.
channel_idsNoNotification channel uuids from list_channels. Omit it or pass [] to alert every verified, active channel of the organization. An id that is not an active channel of this organization is a 404.
timeout_secondsYesSeconds one check may take before it fails, 1 to 120.
interval_secondsYesSeconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit.
confirmation_thresholdNoHow many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create.
notification_cooldown_secondsNo60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this is a non-read-only, non-destructive create, and the description adds substantial context beyond them: write scope required, plan limits (count, min interval, fast-monitor cap, regions per monitor) failing as a 403 that names the limit, paused monitors still counting, and 422 behavior for invalid arguments.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded with purpose, then alternatives, then error/limit semantics, then an example. It is dense but every clause carries useful information; the single-paragraph format is slightly heavy though not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter create tool with an output schema, the description covers purpose, routing to siblings, required scope, limit/quota failure modes, the get_monitor return shape, and a valid example. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds value by including a full worked example that shows how name, type, target, interval_seconds, timeout_seconds, regions, config and tags combine in a valid call. It does not restate individual field semantics, which the schema handles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Create one monitor'), its scope (checks a URL, host or port on a schedule from one or more regions) and its return shape. It clearly distinguishes itself from bulk_create_monitors and create_heartbeat, which are named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternatives and the condition selecting each: check_target first to catch typos/unreachable hosts, bulk_create_monitors for several, create_heartbeat for report-in jobs, and get_plan_usage before hitting limits. When-to-use routing is fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_status_page_incidentPost an incident on a status pageAInspect

Open a new incident on a status page with its first message, to tell the page's visitors about an outage. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Any status but RESOLVED emails every confirmed subscriber at once; RESOLVED records an already closed incident (a postmortem) and emails nobody. To add to an existing incident use post_status_page_update. Requires a key with the write scope. Returns the incident. Example: {"page_id": "", "title": "API errors", "body": "We are investigating elevated error rates."}

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe first message. The message subscribers read, 1 to 5000 characters.
titleYesThe incident's headline, 1 to 255 characters.
statusNoINVESTIGATING, IDENTIFIED, MONITORING or RESOLVED; RESOLVED closes the incident on the page. Default INVESTIGATING.
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.
component_idsNoThe affected components: uuids from get_status_page. An id that is not a component of this page is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
titleYes
statusYesKnown values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.
is_autoYes
updatesYes
started_atYes
notified_atYes
resolved_atYes
component_idsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses that the incident is public, that it emails confirmed subscribers, the exact divergence between RESOLVED (records a closed incident/postmortem, emails nobody) and any other status (emails everyone at once), and the required write-scope key. The annotations only say it is a non-idempotent, non-destructive write; the description supplies the real blast radius.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: purpose, then notification behavior, then the sibling escape hatch, then auth, then an example. Every sentence carries information, though the example is somewhat redundant given a 100%-covered schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a public, notification-triggering mutation with an output schema already present, the description covers purpose, routing, side effects and auth. Nothing material an agent needs to invoke it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, and the description earns an upgrade by explaining the subscriber-notification semantics of the status enum and by showing a concrete call example with page_id, title and body. Component_ids and the length limits are left to the schema, which already documents them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Open a new incident on a status page with its first message') and explicitly distinguishes itself from the sibling post_status_page_update, which adds to an existing incident. An agent can route between these two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the when (tell visitors about an outage), the when-not (adding to an existing incident → post_status_page_update), and a procedural precondition ('confirm the wording with the user before calling'). No inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_heartbeatDelete a heartbeat monitorA
DestructiveIdempotent
Inspect

Delete one heartbeat for good: its ping_url stops working (404) and no tool restores it. Use it only when the user asked for deletion; to stop alerts for a while use pause_heartbeat. Requires a key with the write scope. Returns {"success": true}.

ParametersJSON Schema
NameRequiredDescriptionDefault
heartbeat_idYesThe heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
successYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, yet the description still adds real behavioral context beyond them: the ping_url returns 404 afterward, no tool can restore it, and a write-scoped key is required. The return shape is restated from the output schema but the irreversibility and auth requirements are genuinely additive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, each earning its place: what it does, when to use it versus the alternative, and the auth/return facts. The most consequential fact (permanent deletion) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the destructive nature, the irreversibility, the required scope, and the sibling alternative, while the output schema carries the return value and annotations carry the safety profile. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single heartbeat_id parameter is fully documented in the schema, including the 404 behavior for foreign or already-deleted ids. The description adds no parameter-level detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete one heartbeat') and immediately pins down the scope ('for good'), which distinguishes it from pause/update siblings. An agent can tell this apart from pause_heartbeat or delete_monitor without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('only when the user asked for deletion') and names the alternative for the adjacent case ('to stop alerts for a while use pause_heartbeat'). Both the condition and the routing target are given, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_maintenance_windowDelete a maintenance windowA
DestructiveIdempotent
Inspect

Delete one maintenance window; alerts for its monitors resume at once and no tool restores it. To suspend a window but keep it, use update_maintenance_window with enabled false. Requires a key with the write scope. Returns {"success": true}.

ParametersJSON Schema
NameRequiredDescriptionDefault
window_idYesThe window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
successYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: the effect is immediate ('alerts for its monitors resume at once'), it is unrecoverable ('no tool restores it'), and it requires a key with the write scope. The annotations declare destructiveHint=true, but the description tells the agent what is actually destroyed and that recovery is impossible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight clauses covering effect, alternative, and prerequisites, with the destructive consequence front-loaded. No filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive single-parameter tool, everything needed is present: irreversibility, side effect on monitors, the safer alternative, auth scope, and return shape. The output schema exists, so restating the return value is a minor redundancy rather than a gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter with 100% schema description coverage, so the schema already carries the semantics including the uuid format and the 404 condition. The description adds no additional parameter-level detail, which is the baseline 3 for a fully documented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete one maintenance window') and immediately distinguishes it from the sibling update_maintenance_window by contrasting deletion with suspension. An agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative and the exact condition that selects it: 'To suspend a window but keep it, use update_maintenance_window with enabled false.' This is genuine when-to-use/when-not guidance rather than implied usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_monitorDelete a monitorA
DestructiveIdempotent
Inspect

Delete one monitor: it stops being checked and disappears from the organization's monitors, and no tool restores it. Use it only when the user explicitly asked for deletion; otherwise prefer pause_monitor, which keeps the monitor and its history. There is no bulk delete. Requires a key with the write scope. Returns {"success": true}.

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
successYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=true, but the description adds the irreversibility guarantee ('no tool restores it'), the side effect on monitoring ('stops being checked'), the authorization prerequisite ('Requires a key with the write scope'), and the 404 semantics on unknown/deleted ids. These go meaningfully beyond the annotation flags.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and well front-loaded: the destructive effect and irreversibility come before the alternative and the prerequisite. The trailing 'Returns {"success": true}' restates what the existing output schema already conveys, a minor redundancy that keeps it short of a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool with full annotation coverage and an output schema, the description supplies exactly the missing pieces: reversibility, authorization, sibling routing, and bulk-delete absence. An agent has everything needed to call it correctly and safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single monitor_id parameter is fully documented in the schema (uuid format, source from list_monitors, 404 on invalid/deleted id). The description therefore does not need to compensate and adds no parameter-level detail the schema lacks — baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete one monitor') and immediately describes the effect: it stops being checked and disappears from the organization's monitors, with no restoration path. It also explicitly contrasts with the closest sibling (pause_monitor) and rules out a bulk variant, so an agent can select it confidently without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('only when the user explicitly asked for deletion'), explicit when-not ('otherwise prefer pause_monitor, which keeps the monitor and its history'), and an explicit scope exclusion ('There is no bulk delete'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_status_page_incidentDelete a status page incidentA
DestructiveIdempotent
Inspect

Remove an incident and its timeline from a status page; it stops showing at once, nothing is sent to subscribers, and no tool restores it. Use it for an incident posted by mistake; to close a real one use post_status_page_update with RESOLVED. Requires a key with the write scope. Returns {"success": true}.

ParametersJSON Schema
NameRequiredDescriptionDefault
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.
incident_idYesThe status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
successYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, but the description goes further: it states the effect is immediate, that subscribers are not notified, that it is irreversible ('no tool restores it'), and that a write-scoped key is required. That is exactly the extra context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the destructive outcome and the alternative route in three tight clauses with no filler. The closing 'Returns {"success": true}' is redundant given the output schema exists, a small waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, irreversible mutation the description covers effect, notification behavior, reversibility, auth scope, and the correct alternative tool; return values are already covered by the output schema. An agent has everything needed to call it safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already explains both page_id and incident_id, including the 404 behavior and which list tool supplies each id. The description adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (remove) plus resource (status page incident and its timeline), and it explicitly distinguishes itself from create_status_page_incident and update_status_page_incident by describing the delete-only semantics. An agent can identify the right sibling without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use ('an incident posted by mistake') and an explicit when-not with the named alternative ('to close a real one use post_status_page_update with RESOLVED'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_tagRemove a tag everywhereA
DestructiveIdempotent
Inspect

Remove a tag from every monitor and heartbeat that carries it; the items themselves stay, and no tool restores the tag. Use it to retire a tag across the organization; to take it off chosen monitors only use bulk_update_monitor_tags with remove, and to rename it use rename_tag. Requires a key with the write scope. A tag nothing carries is not an error (both counts are 0). Returns from (the tag), monitors_updated and heartbeats_updated.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagYesThe tag to remove, exactly as list_tags shows it.

Output Schema

ParametersJSON Schema
NameRequiredDescription
fromYes
monitors_updatedYes
heartbeats_updatedYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive=true, idempotent=true, readOnly=false, but the description adds behavior beyond them: the tagged items survive, no tool can restore the tag (irreversibility), a write-scoped key is required, and deleting an unattached tag is not an error (counts 0). These are meaningful operational facts not derivable from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the effect and its scope, then alternatives, then prerequisites, then edge cases and return shape. Every clause carries distinct information with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, single-parameter mutation with an output schema present, the description covers effect, irreversibility, alternatives, auth requirement, and the empty-input edge case. An agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With one parameter at 100% schema coverage, the schema already documents the 'tag' argument and its format ('exactly as list_tags shows it'). The description adds little parameter-level meaning beyond restating that the tag is echoed back in the response, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (remove) and resource (tag) plus the exact scope: 'from every monitor and heartbeat that carries it'. It explicitly contrasts itself with the two nearest siblings (bulk_update_monitor_tags for selective removal, rename_tag for renaming), so an agent can distinguish it without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('retire a tag across the organization') and two when-not cases with named alternatives and their selecting conditions ('take it off chosen monitors only use bulk_update_monitor_tags with remove'; 'to rename it use rename_tag'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_exposed_ports_presetGet the exposed-ports presetA
Read-onlyIdempotent
Inspect

List the ports that should never be reachable from the internet (databases, queues, admin panels). Returns ports, each a port number and the service that usually listens on it. Use it to pick ports when asked to watch a server for exposed services; it creates nothing. Then create one TCP monitor on the server's public hostname or IP with config {"ports": [...], "expected_state": "closed"} (1 to 20 distinct ports, one region, interval_seconds 300 or more; 3600 is plenty) through create_monitor: it counts as one monitor and fails naming every port that answers.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
portsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, so 'it creates nothing' is largely redundant. The description still adds genuine value by describing what the list contains (port number plus the service that usually listens on it) and by warning how the data is consumed downstream (one monitor counted, fails naming every answering port).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose in the first clause, then uses. The final sentence is long and packs create_monitor configuration details that arguably belong in that tool's own docs, though they are actionable for completing the workflow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter preset lookup with rich annotations and an output schema, this is more than sufficient: purpose, return content, safe-to-call status, and the intended downstream workflow are all covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the baseline-4 case; nothing in the description is needed to disambiguate arguments. The mention of the 1-20 distinct ports / interval_seconds constraints pertains to create_monitor's payload, not this tool's schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'List the ports that should never be reachable from the internet (databases, queues, admin panels).' It also names the return content, so an agent knows this is a static preset lookup rather than a scan of any particular server, distinguishing it from siblings like check_target or get_monitor.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use it ('Use it to pick ports when asked to watch a server for exposed services'), what it does not do ('it creates nothing'), and names the follow-up tool with the exact config shape, port/region/interval constraints, and the failure semantics of that call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_heartbeatGet a heartbeat monitorA
Read-onlyIdempotent
Inspect

Read one heartbeat in full, including how long its last run took. It has name, state, period_seconds, grace_seconds, ping_url, last_ping_at, last_success_at, last_start_at, last_duration_ms (how long the last run took, from its /start to its success ping), overdue_at (when it will be reported late), notification_cooldown_seconds, is_active, channel_ids and tags. Use it to answer whether a job ran, how long it took and when it is next due. To find a heartbeat use list_heartbeats; to change it use update_heartbeat; probed monitors are get_monitor.

ParametersJSON Schema
NameRequiredDescriptionDefault
heartbeat_idYesThe heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
stateYesKnown values: PENDING, UP, DOWN, PAUSED.
ping_urlYes
is_activeYes
created_atYes
overdue_atYes
updated_atYes
channel_idsNo
last_ping_atYes
grace_secondsYes
last_start_atYes
period_secondsYes
last_success_atYes
last_duration_msYes
notification_cooldown_secondsYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds genuinely useful semantic context on returned fields such as last_duration_ms being measured from /start to success ping and overdue_at meaning the late-report time. It stops short of discussing pagination or error behavior beyond the schema's 404 note, so a 4 rather than a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and routing are front-loaded in the first and last sentences, which is good structure. However, the long enumeration of returned fields is partly redundant given an output schema exists, so it is not maximally economical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with annotations and a full output schema, the description covers purpose, usage, alternatives, and field interpretation adequately. The field list slightly duplicates the output schema rather than adding new information, leaving a minor gap in efficiency rather than completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema description coverage is 100%, with the schema already documenting that heartbeat_id comes from list_heartbeats and that foreign/deleted ids yield 404. The description adds no parameter-specific meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read one heartbeat in full') and explicitly distinguishes itself from get_monitor ('probed monitors are get_monitor'), so an agent can separate this from the closest sibling without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the use case ('answer whether a job ran, how long it took and when it is next due') plus explicit alternatives for the adjacent tasks: list_heartbeats to find one, update_heartbeat to change it, get_monitor for probed monitors. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_incidentGet an incidentA
Read-onlyIdempotent
Inspect

Read one incident in full, with every alert sent for it. It has id, monitor_id or heartbeat_id (exactly one is set), started_at, resolved_at, cause, cause_detail, last_notified_at, acknowledged_at, acknowledged_by, renotify_count and notification_logs (each alert attempt: id, channel_type, destination, event TRIGGERED, RESOLVED or SSL_EXPIRY, sent_at, status PENDING, SENT or FAILED, and error). Use it to tell who acknowledged an incident and whether its alerts were delivered. destination is an email address, a Telegram chat id, or only scheme://host/… of a webhook. To find incidents use list_incidents; to stop its reminders use acknowledge_incident.

ParametersJSON Schema
NameRequiredDescriptionDefault
incident_idYesThe incident's uuid from list_incidents. An id that is not an incident of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
causeYesKnown values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, HEARTBEAT_MISSED, HEARTBEAT_FAILED, UNKNOWN.
created_atYes
monitor_idNo
started_atYes
updated_atYes
resolved_atYes
cause_detailYes
heartbeat_idNo
renotify_countYes
acknowledged_atYes
acknowledged_byYes
last_notified_atYes
notification_logsNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false. The description adds valuable context beyond annotations: exactly one of monitor_id or heartbeat_id is set, notification_logs fields with event/status/error semantics, and destination formats. Missing only auth or rate-limit details, which are minor for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with core purpose. The long enumeration of return fields is somewhat redundant with the existing output schema, making the description longer than strictly necessary. Still well-structured and every sentence serves a purpose for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with an output schema and rich annotations, the description covers purpose, usage, alternatives, return content, and destination formats. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single required parameter is fully documented in the schema (uuid from list_incidents, 404 for wrong organization). The description adds no parameter-specific syntax or constraints beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb 'Read' and resource 'incident' with scope 'in full, with every alert sent for it'. Explicitly distinguishes from siblings by naming list_incidents and acknowledge_incident, so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the use case: 'Use it to tell who acknowledged an incident and whether its alerts were delivered.' Names alternatives: list_incidents to find incidents and acknowledge_incident to stop reminders. Provides both when-to-use and when-to-use-alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_maintenance_windowGet a maintenance windowA
Read-onlyIdempotent
Inspect

Read one maintenance window with its schedule and its next three occurrences. It has the list_maintenance_windows fields plus next_occurrences, each with start and end. Use it to confirm when a recurring window fires next. To check a schedule before saving it use preview_maintenance_window; to find a window use list_maintenance_windows.

ParametersJSON Schema
NameRequiredDescriptionDefault
window_idYesThe window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
rruleYes
scopeYesKnown values: MONITOR, ORG.
dtstartYes
enabledYes
timezoneYes
created_atYes
monitor_idsNo
duration_minutesYes
next_occurrencesNo

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and closed-world, so the safety profile is fully covered. The description adds the return payload shape (schedule plus next_occurrences with start/end), but with an output schema present this is largely redundant and it says nothing about permissions or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action, then the usage case, then the sibling routing. Every clause earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read with a full output schema and complete annotations, the description covers purpose, usage, and alternatives. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and there is a single required parameter, so the schema already documents window_id fully. The description adds no syntax, format, or sourcing detail beyond what the schema provides, making the baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read one maintenance window') and immediately scopes it against siblings by naming preview_maintenance_window and list_maintenance_windows. An agent can tell it apart from the other maintenance-window tools without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives the selecting condition ('Use it to confirm when a recurring window fires next') and routes to the two alternatives with their own conditions ('to check a schedule before saving it', 'to find a window'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_monitorGet a monitorA
Read-onlyIdempotent
Inspect

Read one monitor's full configuration and current state. It has type, target, interval_seconds, timeout_seconds, regions, config, status, is_active, confirmation_threshold, notification_cooldown_seconds, channel_ids (empty means every verified, active channel is alerted), tags, badge_enabled, last_checked_at, next_run_at, and for SSL monitors ssl_expires_at and ssl_cert_info. Use it before update_monitor, since a config you send replaces the stored one whole. Not for finding a monitor (list_monitors), its uptime (get_uptime_summary) or why it fails (list_check_results).

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool as read-only, idempotent, and non-destructive, but the description adds important operational context beyond those hints. It explains the whole-config replacement behavior of update_monitor, clarifies that an empty channel_ids means all verified active channels are alerted, and notes SSL-specific fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by usage guidance and exclusions in a logical order. The long field list is relevant to understanding what a full configuration includes, though it is somewhat redundant because an output schema exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, the detailed schema, annotations, and presence of an output schema, the description is complete enough for correct invocation. It covers purpose, pre-update usage, field semantics, and sibling routing without needing to explain return formatting.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the monitor_id parameter is already documented as a UUID from list_monitors with 404 semantics for unknown or deleted monitors. The description does not add meaning beyond the schema for this single parameter, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: read one monitor's full configuration and current state. It enumerates the key fields returned and explicitly distinguishes the tool from list_monitors, get_uptime_summary, and list_check_results, so an agent can identify its role without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states a concrete usage condition: call it before update_monitor because update configs replace the stored configuration wholesale. It also names when not to use it and routes the agent to the correct alternatives for listing, uptime, and failure investigation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_plan_usageGet plan usageA
Read-onlyIdempotent
Inspect

Show the organization's plan, its limits and current usage, to check that new monitors, heartbeats or regions fit before creating them or to explain a 403 naming a limit. Region codes and their cities come from list_regions; billing changes happen only in the dashboard. Values are current as of the call. Returns plan (one of FREE, PLUS, PRO, MAX, ENTERPRISE), limits and usage. limits: max_monitors, min_interval_seconds, max_fast_monitors (monitors below fast_interval_threshold_seconds, 60), max_regions per monitor, allowed_regions, max_heartbeats, max_maintenance_windows, history_retention_days, api_rate_limit_per_minute (shared by the whole organization), renotify_interval_seconds and renotify_max_count (how often and how many times an open, unacknowledged incident is alerted again; 0 means no reminders); null means no limit. usage: monitors (paused included), fast_monitors and heartbeats.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
planYesKnown values: FREE, PLUS, PRO, MAX, ENTERPRISE.
usageYes
limitsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial context beyond the annotations: values are current as of the call, null means no limit, API rate limits are shared by the whole organization, and renotify fields describe incident alerting behavior. It also clarifies the output categories plan, limits, and usage in enough detail to support interpretation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage before moving into field-level detail. It is somewhat long and repeats some return-value information that may already be captured by the output schema, but the detail largely earns its place for a tool whose limits and usage values need interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's breadth and the presence of an output schema, the description provides all the context an agent needs: when to call it, what the values mean, how limits should be interpreted, and where related actions belong. No material behavioral or usage gap remains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the baseline is 4. The description does not need to explain parameter meaning, and it does not introduce any parameter-related ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: showing the organization's plan, limits, and current usage. It also distinguishes its scope from related operations by naming list_regions for region codes and the dashboard for billing changes, so an agent can identify it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance: before creating monitors, heartbeats, or regions, and when explaining a 403 that names a limit. It also names alternatives for region data and billing changes, making the selection criteria clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_response_time_by_regionGet a monitor's response time by regionA
Read-onlyIdempotent
Inspect

Chart one monitor's average response time over time, one series per region, to see where it is slow and since when. Returns monitor_id, window, bucket_seconds and regions, each with region, display_name and points (oldest first, the same buckets in every series: bucket_start, avg_response_time_ms, null when the bucket had no successful check, and sample_count). Every configured region has a series, even an empty one, followed by removed regions that still had checks; points start at the window's start or at the monitor's creation. For uptime use get_uptime_summary; for single checks use list_check_results.

ParametersJSON Schema
NameRequiredDescriptionDefault
windowNo24h (the default; up to 24 hourly buckets), 7d (up to 28 six-hourly buckets) or 30d (up to 30 daily buckets).
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
windowYes
regionsYes
monitor_idYes
bucket_secondsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavioral detail beyond the annotations, including the exact return payload shape, bucket alignment across regions, null handling for empty buckets, sample_count, inclusion of empty configured regions, and treatment of removed regions with checks. Annotations already establish read-only safety, but the description goes further by explaining output semantics and data ordering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with its purpose, then moves efficiently through return structure and alternative tools. Despite its length, every sentence carries useful information about output shape, ordering, region inclusion, or routing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not define return values, but it still provides rich return semantics, region inclusion rules, bucket alignment, and alternative-tool guidance. Given the annotations, complete schema coverage, and output schema, it is fully complete for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the window enum and monitor_id UUID semantics. The description does not add parameter-specific syntax or constraints beyond what the schema provides, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: chart one monitor's average response time over time, one series per region. It also names the sibling alternatives get_uptime_summary and list_check_results, so an agent can distinguish this tool from related uptime and check-listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The final sentence gives explicit routing guidance: use get_uptime_summary for uptime and list_check_results for single checks. The opening sentence also clarifies the intended analytical use case of seeing where and since when a monitor is slow by region.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_status_pageGet a status pageA
Read-onlyIdempotent
Inspect

Read one status page with its components. It has the list_status_pages fields, where each component has id, monitor_id, display_name and position. Use it to get the component ids that create_status_page_incident takes as component_ids. To find a page use list_status_pages; for the incidents posted on it use list_status_page_incidents.

ParametersJSON Schema
NameRequiredDescriptionDefault
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
slugYes
groupsYes
created_atYes
descriptionYes
history_daysYes
is_publishedYes
ungrouped_componentsYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so safety behavior is covered. The description adds value beyond that by disclosing the shape of the returned components (id, monitor_id, display_name, position) and the downstream consumer of the ids, which annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the routing guidance, with no filler sentences. The middle sentence describing component fields is slightly dense but earns its place by telling the agent what it will get back for the component_ids use case.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the return values need not be re-explained, yet the description still summarizes component fields relevant to the chained call. Combined with a fully documented parameter and read-only annotations, nothing an agent needs to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter's description already states the UUID source (list_status_pages) and the 404 for foreign ids. The description adds essentially no syntax or format detail beyond the schema, so the baseline 3 for a fully documented single parameter is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read one status page with its components') and immediately differentiates it from the closely related list_status_pages and list_status_page_incidents. An agent can distinguish this from every sibling without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative for discovery ('To find a page use list_status_pages'), the alternative for the related sub-resource ('for the incidents posted on it use list_status_page_incidents'), and states a concrete downstream use case (feeding component_ids into create_status_page_incident). When-to-use is fully spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_uptime_dailyGet a monitor's daily uptimeA
Read-onlyIdempotent
Inspect

Report one monitor's uptime for each UTC day, oldest first and ending today, to find the day an outage or degradation began. Each day has date, uptime_percentage, total_checks, up_checks, down_checks, degraded_checks and maintenance_checks; a degraded check counts as up, and a day with no checks outside maintenance has a null uptime_percentage, not 100. For 24h, 7d and 30d totals use get_uptime_summary. Returns monitor_id and days.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days to return, 1 to 365; default 30. Capped at the plan's limits.history_retention_days (get_plan_usage), so fewer days can come back.
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysYes
monitor_idYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/idempotent profile, and the description adds real behavioral semantics beyond them: degraded checks count as up, days with only maintenance checks yield null uptime_percentage rather than 100, ordering is oldest-first, and results are capped at the plan's history retention. These are exactly the non-obvious traits an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: purpose and ordering first, then field semantics and the null-edge case, then the sibling hand-off. Dense but every clause carries information; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-param read tool with annotations and an output schema, the description covers purpose, ordering, edge cases, retention behavior, and the alternative tool. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are documented, giving a baseline of 3. The description adds value beyond the schema by reinforcing the retention cap and noting that fewer days than requested can be returned, clarifying the effective behavior of 'days'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Report one monitor's uptime for each UTC day') with explicit scope (oldest first, ending today). It distinguishes itself from get_uptime_summary by naming that sibling as the alternative for aggregate totals.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case ('to find the day an outage or degradation began') and explicitly routes the agent to get_uptime_summary for 24h/7d/30d totals. Both when-to-use and the alternative are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_uptime_summaryGet uptime for a monitorA
Read-onlyIdempotent
Inspect

Report one monitor's uptime percentage, average response time and incident count over the last 24 hours, 7 days and 30 days at once, to answer how reliable it has been. For a day-by-day series use get_uptime_daily; for response time per region use get_response_time_by_region; for the individual failures use list_check_results. Returns monitor_id and windows keyed 24h, 7d and 30d, each with uptime_percentage (DEGRADED checks count as up; null when there were no checks), total_checks, up_checks, down_checks, degraded_checks, incident_count and avg_response_time_ms.

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
windowsYes
monitor_idYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, but the description adds real behavioral semantics beyond them: DEGRADED checks count as up, uptime_percentage is null when there were no checks, and incident_count/avg_response_time_ms are surfaced. It omits anything about permissions or rate limits, but the key interpretive caveats are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by routing and then the return shape; every sentence carries information. The long enumeration of return fields is somewhat heavy given an output schema already exists, which is the only reason this isn't a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with full annotations and an output schema present, the description is more than adequate; it even spells out the window keys and metric names. The return-value detail is partly redundant with the output schema, but nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is only one parameter and schema coverage is 100%, so the schema already documents monitor_id fully, including the uuid format and the 404 behavior. The description adds no further parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (uptime percentage, average response time, incident count for one monitor) and scopes it precisely to three fixed windows (24h, 7d, 30d). It also names the sibling tools it is not, so an agent can distinguish it from get_uptime_daily and get_response_time_by_region without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'For a day-by-day series use get_uptime_daily; for response time per region use get_response_time_by_region; for the individual failures use list_check_results.' This is textbook when-to-use/when-not guidance with named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_active_maintenanceList maintenance windows in effect nowA
Read-onlyIdempotent
Inspect

List the enabled maintenance windows in effect at this moment, to tell whether a monitor's alerts are silenced now. An ORG-scope window covers every monitor, a MONITOR-scope one its monitor_ids. For every window, including future and disabled ones, use list_maintenance_windows. Returns a plain array (not a page) of list_maintenance_windows items; empty when nothing is silenced.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: the return is a plain array rather than a page, and it is empty when nothing is silenced. It does not mention sort order or item shape, but that is a minor gap given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, zero waste, and the most decision-relevant information (what it lists, and the sibling to use otherwise) is front-loaded. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description carries the burden of describing returns — and it does, stating the array-vs-page shape and the empty result semantics. Combined with the scope explanation and the sibling routing, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter syntax for the description to compensate for. Baseline 4 applies; the description correctly signals the absence of filters by noting the call is unscoped.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('list the enabled maintenance windows in effect at this moment') plus the scope model (ORG covers every monitor, MONITOR covers its monitor_ids). It explicitly distinguishes itself from the sibling list_maintenance_windows, so an agent can pick between them without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use ('to tell whether a monitor's alerts are silenced now') and an explicit when-not / alternative: 'For every window, including future and disabled ones, use list_maintenance_windows.' Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_channelsList notification channelsA
Read-onlyIdempotent
Inspect

List the organization's notification channels (up to 100), to get the ids that channel_ids of monitors and heartbeats take. Each has id, type (TELEGRAM, WEBHOOK, SLACK or DISCORD), label, is_verified, is_active and destination_hint (a chat id, a masked address, or a webhook's scheme and host). Only a verified, active channel is alerted; an unverified one can be bound but receives nothing yet, and an inactive or unknown id cannot be bound (404). Email is not a channel: every alert also goes to the account email of whoever created the monitor or heartbeat. Channels are added only in the dashboard.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent/non-destructive, and the description adds substantial context beyond them: a 100-item cap, the alerting semantics of verified+active vs. unverified vs. inactive, the 404 on binding an inactive or unknown id, and the clarification that email is not a channel. These are exactly the behavioral facts an agent cannot infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool is and why before enumerating fields, and every sentence carries information. The email aside is slightly tangential but it preempts a plausible agent mistake, so it still earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must carry the return shape, and it does: id, type (with the full enum), label, is_verified, is_active, destination_hint, plus the meaning of each status flag. Nothing needed to call or interpret this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; per the baseline for parameterless tools this is a 4. The description instead spends its budget on return-value semantics, which is the right trade.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('List the organization's notification channels') and immediately explains the reason to call it: to obtain the ids that channel_ids of monitors and heartbeats take. That framing distinguishes it from every sibling list_* tool, which list monitors, incidents, tags, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear purpose-driven context (resolve ids for binding to monitors/heartbeats) and explicitly closes the loop on creation: 'Channels are added only in the dashboard,' telling the agent there is no create tool to reach for. It does not name alternative siblings, but none are genuinely substitutable for this call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_check_resultsList a monitor's check resultsA
Read-onlyIdempotent
Inspect

List one monitor's individual check results, newest first, to find out why it is DOWN: which regions fail and with what status code or error. Each has id, region, checked_at, status, response_time_ms, status_code, error_message, details and maintenance_window_id (set when the check ran inside a window). For totals use get_uptime_summary or get_uptime_daily; for the incident they opened use list_incidents. Returns a page: items plus total (of matching results), page, size and pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
regionNoKeep one region's results: its exact code, up to 64 characters.
statusNoKeep results with this status only.
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.
period_daysNoKeep results of the last N days, 1 to 365; without it every stored result is eligible.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, non-destructive), and the description adds ordering (newest first), the semantics of maintenance_window_id (set when the check ran inside a window), and the paging contract. It does not discuss result retention limits or any rate/volume caveats, so it falls short of the richest disclosure but clearly adds context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the diagnostic purpose, then the returned fields, then routing to alternatives, then the pagination contract — a logical order with near-zero filler. The 'Returns a page: items plus total, page, size and pages' sentence is largely redundant given an output schema exists, which keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter paginated read tool with full schema coverage, an output schema and read-only annotations, the description supplies everything an agent needs: purpose, the diagnostic use case, sibling routing, field-level meaning for maintenance_window_id, and how to page. No material gap remains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so page, size, region, status, monitor_id and period_days are already documented, including enum values and the 404 case. The description adds no filter syntax or semantics beyond the field names it enumerates, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list one monitor's individual check results) plus scope (newest first) and diagnostic intent ('to find out why it is DOWN'). An agent can distinguish it from list_monitors, get_uptime_summary and list_incidents without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the when ('to find out why it is DOWN: which regions fail and with what status code or error') and names two alternatives with their selecting conditions: get_uptime_summary/get_uptime_daily for totals, list_incidents for the incident they opened. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_heartbeatsList heartbeat monitorsA
Read-onlyIdempotent
Inspect

Find heartbeat (cron / dead-man's-switch) monitors. Each has id, name, state (PENDING until a success ping makes it UP or a /fail ping makes it DOWN; later UP, DOWN or PAUSED), period_seconds, grace_seconds, ping_url, last_ping_at, last_success_at, overdue_at, tags and channel_ids. Use it to get a heartbeat's id or ping_url, or to see which jobs are late (sort status puts DOWN first). Probed URLs and hosts are monitors: use list_monitors for those. For one heartbeat's full record, with its last run's duration, use get_heartbeat. Returns a page: items plus total, page, size and pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoCase-insensitive substring of the name, up to 255 characters.
tagNoKeep items carrying these tags: a JSON array of up to 10 tags, each up to 50 characters, lowercased before matching. tag_match decides whether all or any of them must match.
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
sortNostatus (the default: DOWN, PENDING, UP, PAUSED, newest first within each), name, or created_at (newest first).
tag_matchNoall (the default): an item must carry every tag in tag. any: at least one of them.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/idempotent/non-destructive profile, but the description adds real substance beyond them: the PENDING→UP/DOWN/PAUSED state machine, the meaning of last_ping_at/overdue_at, and the paginated return shape ('items plus total, page, size and pages'). It does not discuss rate limits or auth, but for a read-only list tool this is a rich disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and usage before field details, and each sentence carries routing or state information. The long field enumeration is mildly redundant given an output schema exists, but it is compact and not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers filters, sort behavior, sibling disambiguation, and result paging, which is everything an agent needs to call it correctly. Return-value detail slightly overlaps the output schema but does not leave any gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (q, tag, page, size, sort, tag_match) is already fully documented in the schema, including defaults and enum meanings. The description only echoes the sort ordering already in the schema ('sort status puts DOWN first'), adding no new syntax or semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Find heartbeat (cron / dead-man's-switch) monitors') and immediately enumerates the returned fields, so the agent knows exactly what this list yields. It also draws explicit boundaries against the two nearest siblings, list_monitors and get_heartbeat, making selection unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use cases ('get a heartbeat's id or ping_url', 'see which jobs are late'), an explicit when-not ('Probed URLs and hosts are monitors: use list_monitors for those'), and names get_heartbeat for the single-record case. All three routing decisions are stated rather than inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_incidentsList incidentsA
Read-onlyIdempotent
Inspect

List the organization's monitor and heartbeat incidents, newest first, to see what is or was down and which alerts went out. Each item has id, monitor_id or heartbeat_id (exactly one is set), started_at, resolved_at (null while open), cause, cause_detail (the raw check error), acknowledged_at and notification_logs: the alerts sent, oldest first, each with id, channel_type (EMAIL, TELEGRAM, WEBHOOK, SLACK or DISCORD), destination (may be masked), event (TRIGGERED for the first alert and every reminder, RESOLVED for the recovery), sent_at, status (PENDING while a webhook, Slack or Discord delivery is still being tried, then SENT or FAILED) and error (the last delivery error). For one incident's full record use get_incident; for the checks behind it use list_check_results; incidents posted on a status page are list_status_page_incidents. An incident resolves by itself when its monitor or heartbeat recovers. Returns a page: items plus total, page, size and pages. An invalid value is a 422 naming the argument. Example: {"status": "open", "size": 50}

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
causeNoKeep one failure cause, such as TIMEOUT, HTTP_5XX or HEARTBEAT_MISSED.
statusNoopen or resolved (lowercase); omit it for both.
monitor_idNoKeep one monitor's incidents: its uuid from list_monitors.
period_daysNoKeep incidents active within the last N days, 1 to 365. An open incident always qualifies, so with status open it changes nothing: use status resolved, or omit status, to see the window take effect.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint, idempotentHint, non-destructive, closed-world), yet the description adds substantial context: newest-first ordering, the self-resolving lifecycle, the 422 error shape on invalid values, and the notification delivery state machine (PENDING while a webhook/Slack/Discord delivery is retried, then SENT or FAILED with the last error). This goes well beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and alternatives are front-loaded, but the body is one dense run-on paragraph enumerating return fields (id, started_at, resolved_at, cause, notification_logs, channel_type, destination, event, sent_at, status, error) that an output schema already carries. Much of that inventory does not earn its place against a structured output contract.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only filtered list with 6 optional parameters, the description covers scope, ordering, alternatives, resolution semantics, pagination and error behavior. An agent has everything needed to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds a worked example ({'status': 'open', 'size': 50}) showing a valid filter combination and reinforces pagination intent. It does not add per-parameter syntax beyond the schema, so it does not reach 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the organization's monitor and heartbeat incidents, newest first') and immediately bounds the scope to what is or was down. It explicitly distinguishes itself from get_incident, list_check_results and list_status_page_incidents, so an agent can route without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the three alternative tools and the condition selecting each ('For one incident's full record use get_incident; for the checks behind it use list_check_results; incidents posted on a status page are list_status_page_incidents'). It also explains the resolution lifecycle, telling the agent an incident clears itself on monitor/heartbeat recovery.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_maintenance_windowsList maintenance windowsA
Read-onlyIdempotent
Inspect

List every maintenance window of the organization, enabled or not, in effect or not. Each has id, name, enabled, scope (ORG or MONITOR), dtstart, duration_minutes, rrule, timezone, monitor_ids and created_at. Use it to find a window's id. To learn whether alerts are silenced right now use list_active_maintenance; for a window's upcoming occurrences use get_maintenance_window. Returns a page: items plus total, page, size and pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoCase-insensitive substring of the name, up to 255 characters.
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
sortNocreated_at (the default, newest first) or name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description goes beyond that by disclosing that results include both enabled and disabled windows and both active and inactive ones, enumerating the returned fields, and describing the paginated envelope (items plus total, page, size, pages). It stops short of rate-limit or auth notes, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with the purpose and scope front-loaded and the sibling routing immediately after. The field enumeration is somewhat redundant given an output schema exists, which keeps it from a 5, but nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety, a 100%-covered input schema, and an output schema present, the description need not restate return structure in detail yet still does enough to orient the agent. Everything needed to call it correctly — scope, use case, alternatives — is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter (q, page, size, sort) is already documented in the schema, including defaults and paging advice. The description adds nothing about parameter semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (maintenance windows of the organization) with explicit scope: enabled or not, in effect or not. It further separates itself from siblings by naming list_active_maintenance and get_maintenance_window, so an agent can pick it without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case ('Use it to find a window's id') and explicitly routes to alternatives with conditions: list_active_maintenance for current silencing state, get_maintenance_window for upcoming occurrences. This is exactly the when-to-use/when-not guidance the dimension asks for.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_monitorsList monitorsA
Read-onlyIdempotent
Inspect

Find monitors in the organization by name, target, type, status or tag. Each row is short: id, name, type, target, status, is_active, tags, interval_seconds, ssl_expires_at and last_checked_at. Use it first to get a monitor's id, or to answer what is broken now (status ["DOWN", "DEGRADED"]) or which certificates expire first (type ["SSL"], sort ssl_expiry). For one monitor's full settings use get_monitor; for heartbeats use list_heartbeats. Returns a page: items plus total, page, size and pages. An invalid value is a 422 naming the argument. Example: {"status": ["DOWN", "DEGRADED"], "size": 100}

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoCase-insensitive substring of the name or the target, up to 255 characters.
tagNoKeep items carrying these tags: a JSON array of up to 10 tags, each up to 50 characters, lowercased before matching. tag_match decides whether all or any of them must match.
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
sortNostatus (the default: PENDING, DOWN, DEGRADED, UP, PAUSED, then by name), up_first (healthy first), name, newest, oldest, or ssl_expiry (soonest-expiring certificates first; monitors with no known expiry, non-SSL types or not checked yet, last).
typeNoKeep monitors of any of these types: a JSON array.
statusNoKeep monitors in any of these states: a JSON array. PENDING means no verdict yet.
tag_matchNoall (the default): an item must carry every tag in tag. any: at least one of them.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description adds real behavioral context on top: the exact row fields returned, the pagination model (items plus total, page, size, pages), and the 422 error behavior naming the bad argument. It stops short of describing rate limits or ordering guarantees beyond sort, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then usage, then return shape, error behavior, and an example — each sentence carries information. The bare field-list enumeration is slightly dense but earns its place given there is no output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by spelling out the returned row fields and the page envelope, and even notes the error shape. For an 8-parameter read tool with rich annotations, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so baseline is 3. The description still adds cross-parameter meaning the schema lacks: a worked example combining status and size, and the intent mapping (status ['DOWN','DEGRADED'] for outages, type ['SSL'] + sort ssl_expiry for certificates), which helps agents compose parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Find monitors in the organization') plus the filterable dimensions, and explicitly contrasts itself with siblings get_monitor and list_heartbeats. An agent can select this over get_monitor without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete when-to-use cases ('use it first to get a monitor's id', 'answer what is broken now', 'which certificates expire first') and names the alternatives plus the condition that selects them (full settings vs. heartbeats). Exclusions are explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_regionsList check regionsA
Read-onlyIdempotent
Inspect

List every check region of the platform, to show the user where checks can run. Returns regions, each with code (what a regions argument takes), display_name, city, country_code, group and group_display_name. The organization may use only some of them: to choose regions for a monitor read limits.allowed_regions and max_regions from get_plan_usage instead. For one monitor's per-region timings use get_response_time_by_region.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
regionsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds real context by noting the organization may use only some regions, steering the agent to get_plan_usage for the actual allowed set. It does not add further behavioral traits like rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with purpose. The enumerated return fields are somewhat redundant against the output schema, though the note on 'code' justifies inclusion.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't explain returns, yet it covers purpose, alternatives, and the allowed-region caveat. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so the baseline is 4. The description still earns its keep by explaining that the returned 'code' field is what a 'regions' argument elsewhere consumes, linking this tool's output to other tools' inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List every check region of the platform') plus the intent ('to show the user where checks can run'). It also disambiguates from two siblings, so an agent can identify it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent away: use limits.allowed_regions/max_regions from get_plan_usage to choose a monitor's regions, and get_response_time_by_region for per-region timings. Both the when-to-use and clear alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_status_page_incidentsList a status page's incidentsA
Read-onlyIdempotent
Inspect

List the incidents shown on one status page, newest first, both posted by a person and opened by Fettle. Each has id, title, status, is_auto (opened by Fettle from a monitor), started_at, resolved_at, notified_at (when subscribers were first emailed; null if never), component_ids and updates (the timeline, oldest first, each with id, status, body, created_by and created_at). Use it to find the incident_id for post_status_page_update. Monitor outages behind the scenes are list_incidents. Returns a page: items plus total, page, size and pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive profile, so the bar is lower. The description adds ordering behavior ('newest first', updates 'oldest first') and field semantics such as is_auto meaning Fettle-opened from a monitor and notified_at being null if never emailed. It does not discuss filtering or rate limits, but the added behavioral context is substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core verb and scope, then the returned fields, then the sibling routing. It is dense and slightly long, but nearly every clause conveys return shape or routing information rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Combined with a 100%-covered schema, full annotations, and an output schema, the description supplies ordering, field semantics, pagination behavior, and sibling routing. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three parameters (page, size, page_id) are fully documented in the schema, including defaults and the 404 case for page_id. The description adds nothing beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the incidents shown on one status page'), scopes it to a single page, and explicitly distinguishes itself from the sibling list_incidents ('Monitor outages behind the scenes are list_incidents'). An agent can route correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both the when-to-use rationale ('Use it to find the incident_id for post_status_page_update') and the when-not/alternative ('Monitor outages behind the scenes are list_incidents'). This is explicit routing guidance, not inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_status_pagesList status pagesA
Read-onlyIdempotent
Inspect

List the organization's public status pages. Each has id, slug, name, description, is_published (publicly visible now), history_days, created_at, groups (each with name, position and its components) and ungrouped_components. Use it to find a page's id before posting an incident on it. For one page use get_status_page; pages are created and edited only in the dashboard. Returns a page of results: items plus total, page, size and pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, 1 or more; default 1.
sizeNoRows per page, 1 to 100; default 25. Keep paging until you have seen total rows.
sortNocreated_at (the default, newest first) or name.

Output Schema

ParametersJSON Schema
NameRequiredDescription
pageYes
sizeYes
itemsYes
pagesYes
totalYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a safe, idempotent, read-only operation, so the description only needs to add context beyond that. It usefully adds that pages are public, lists returned fields, and explains the paginated result shape, though some field detail overlaps with the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded and efficient, with the primary purpose and alternative tool stated early. The returned-field enumeration is somewhat detailed but still relevant to the task.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema and full annotation coverage, the description supplies enough context for an agent to call the tool correctly. It covers purpose, alternative, pagination behavior, and creation/edit constraints.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the parameters page, size, and sort are already documented in the schema. The description does not add syntax or selection guidance beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: listing the organization's public status pages. It also distinguishes this list operation from the sibling get_status_page for a single page.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states the main use case: finding a page's id before posting an incident. It also names get_status_page as the alternative for one page and clarifies that creation and editing happen only in the dashboard.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tagsList tagsA
Read-onlyIdempotent
Inspect

List the tags used in the organization, most-used first, each with monitor_count and heartbeat_count, as items. Call it before tagging anything so you reuse an existing name instead of inventing a near-duplicate. Not a filter: to find the monitors or heartbeats carrying a tag, pass tag to list_monitors or list_heartbeats. Returns every tag at once, not a page.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNomonitor or heartbeat lists only the tags that kind of item uses; all (the default) lists both. Both counts are reported either way.

Output Schema

ParametersJSON Schema
NameRequiredDescription
itemsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive, so the bar is lower, yet the description adds real behavior: result ordering (most-used first), the returned counts, and critically that there is no pagination ('Returns every tag at once, not a page'). It stops short of describing anything about auth scope or what happens with very large tag sets, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, each doing distinct work: purpose, pre-tagging guidance, disambiguation from filtering tools, and pagination behavior. The most decision-relevant information (what it is, when to call it) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description still surfaces the salient ones (counts, ordering, no paging). Combined with full schema coverage and read-only annotations, an agent has everything needed to call this correctly and to avoid misusing it as a filter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum values for 'kind' are fully documented in the schema, so the baseline is 3. The description adds no additional semantics for 'kind' (e.g., which count corresponds to which kind), instead spending its parameter-adjacent text on sibling routing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the tags used in the organization') and goes further by specifying ordering ('most-used first') and the per-item payload ('monitor_count and heartbeat_count'). It also distinguishes itself from siblings like list_monitors/list_heartbeats by clarifying it is not a filter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('Call it before tagging anything so you reuse an existing name') and explicit when-not ('Not a filter'), with the correct alternative named ('pass tag to list_monitors or list_heartbeats'). Nothing about tool selection is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pause_heartbeatPause a heartbeat monitorA
Idempotent
Inspect

Pause one heartbeat: it is no longer reported late, pings to its ping_url are accepted but ignored, and its open incident closes without an alert. Use it when the job is stopped on purpose, such as a runner taken out of service; resume_heartbeat undoes it, while delete_heartbeat removes the heartbeat for good. Maintenance windows do not cover heartbeats. Requires a key with the write scope. Pausing a paused heartbeat changes nothing. Returns the heartbeat.

ParametersJSON Schema
NameRequiredDescriptionDefault
heartbeat_idYesThe heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
stateYesKnown values: PENDING, UP, DOWN, PAUSED.
ping_urlYes
is_activeYes
created_atYes
overdue_atYes
updated_atYes
channel_idsNo
last_ping_atYes
grace_secondsYes
last_start_atYes
period_secondsYes
last_success_atYes
last_duration_msYes
notification_cooldown_secondsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: pings are accepted but ignored, an open incident is closed without an alert, a write-scoped key is required, and pausing an already-paused heartbeat is a no-op. This is exactly the operational context the annotations (idempotentHint, destructiveHint) cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tightly packed sentences, front-loaded with the effect of pausing, then usage, then alternatives and prerequisites. No filler sentences; even the trailing 'Returns the heartbeat' is one short clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Mutation tool with an output schema and full annotation coverage, and the description still covers side effects, auth scope, idempotency, and sibling routing. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single heartbeat_id parameter is already fully documented in the schema (uuid source, 404 semantics). The description adds no parameter-level detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Pause one heartbeat') and immediately qualifies scope by naming the sibling alternatives resume_heartbeat and delete_heartbeat. An agent can distinguish this from resume/delete without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use condition ('when the job is stopped on purpose, such as a runner taken out of service'), plus explicit when-not/alternatives: resume_heartbeat undoes it, delete_heartbeat removes it permanently, and maintenance windows do not cover heartbeats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pause_monitorPause a monitorA
Idempotent
Inspect

Stop checking one monitor without deleting it: its status becomes PAUSED and an open incident on it closes without a recovery alert. Use it when the user wants a monitor off for an open-ended time. For a planned deploy or reboot prefer create_maintenance_window, which keeps checking but silences alerts; for many monitors use bulk_pause_monitors; to restart checks use resume_monitor. Requires a key with the write scope. Pausing a paused monitor changes nothing. Returns the monitor in the get_monitor shape.

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that an open incident closes without a recovery alert, that write scope is required, that pausing a paused monitor is a no-op (consistent with idempotentHint), and what shape the result takes. These are exactly the mutation side effects an agent cannot infer from readOnlyHint/destructiveHint alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action and its state change are front-loaded, followed tightly by routing rules and constraints. Every sentence carries distinct, actionable information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Annotations cover the safety/idempotency profile, the output schema covers the return value, and the description covers semantics, prerequisites, and alternatives. An agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single monitor_id parameter is fully documented in the schema (uuid source plus 404 behavior), so the baseline is 3. The description adds nothing further about the parameter itself, leaving the schema to do the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('stop checking one monitor without deleting it') plus the resulting state (PAUSED) and the side effect on incidents. It explicitly distinguishes itself from create_maintenance_window, bulk_pause_monitors, and resume_monitor by name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use ('monitor off for an open-ended time') and multiple when-not-to-use conditions with named alternatives: planned deploy/reboot -> create_maintenance_window, many monitors -> bulk_pause_monitors, restart checks -> resume_monitor. Routing is fully determined.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

post_status_page_updatePost an update to a status page incidentAInspect

Add a message to an existing status page incident and set its status; RESOLVED closes it. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Every confirmed subscriber gets the update, except that resolving an incident they were never told about stays silent. To open a new incident use create_status_page_incident; to fix only the title, silently, use update_status_page_incident. Requires a key with the write scope. A resolved incident accepts only further RESOLVED updates; any other status is a 409. Returns the incident. Example: {"page_id": "", "incident_id": "", "status": "RESOLVED", "body": "Fixed; error rates are back to normal."}

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYesThe message subscribers read, 1 to 5000 characters.
statusYesINVESTIGATING, IDENTIFIED, MONITORING or RESOLVED; RESOLVED closes the incident on the page.
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.
incident_idYesThe status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
titleYes
statusYesKnown values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.
is_autoYes
updatesYes
started_atYes
notified_atYes
resolved_atYes
component_idsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only provide the generic write profile (readOnly=false, idempotent=false), while the description supplies the traits that actually change agent behavior: the update is public, it emails confirmed subscribers, resolving a never-notified incident stays silent, a write-scope key is required, and a resolved incident only accepts further RESOLVED updates (409 otherwise). None of this is inferable from structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the public/email warning follows immediately on the purpose statement and outranks the alternatives and error semantics that come after. It is one long multi-clause paragraph plus an inline example, which slightly hurts scannability, but essentially every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-param mutation tool with an output schema, the description covers the gaps that matter: side effects, auth scope, conflict behavior, and sibling routing. Return values are covered by the output schema, and no destructive or idempotency surprise is left unexplained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes modestly beyond it by binding each id to its provenance tool (page_id from list_status_pages, incident_id from list_status_page_incidents) and by attaching the 409 constraint to the status value. The worked example clarifies required-field combination but largely restates schema-documented fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add a message to an existing status page incident and set its status') with a crucial scope qualifier: RESOLVED closes it. It also explicitly distinguishes itself from create_status_page_incident and update_status_page_incident, so an agent can route correctly without opening sibling schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names both alternatives with the exact condition that selects each ('To open a new incident use create_status_page_incident; to fix only the title, silently, use update_status_page_incident'). It also gives a pre-call obligation — confirm the wording with the user — which is actionable guidance, not just context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_maintenance_windowPreview a maintenance scheduleA
Read-onlyIdempotent
Inspect

Compute the next three occurrences, each with start and end, that a schedule would produce, without saving anything. Use it to check a recurring schedule before create_maintenance_window or update_maintenance_window; for a saved window's occurrences use get_maintenance_window. Requires a key with the write scope. An invalid schedule is a 422 with the reason. Returns an array. Example: {"dtstart": "2026-10-18T03:00:00", "duration_minutes": 60, "rrule": "FREQ=WEEKLY;BYDAY=SU", "timezone": "Europe/Berlin"}

ParametersJSON Schema
NameRequiredDescriptionDefault
rruleNoRepeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused. Omit it for a one-time window.
dtstartYesThe first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422.
timezoneNoIANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes. Defaults to the organization's timezone.
duration_minutesYesHow long each occurrence lasts, 1 to 40320 minutes.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive, and the description adds context annotations cannot express: it requires a write-scoped key despite being a read, invalid schedules fail as a 422 carrying the reason, and the result is an array of three occurrences with start and end. Auth, error, and return-shape behavior are all disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core behavior, then usage, auth, errors, and return shape in tight sentences. The example earns its place by showing a valid combined payload, though the entry is on the dense side.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does state an array of start/end occurrences, plus error semantics. It is nearly complete, though it could note whether exactly three are always returned or fewer for one-time windows.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents dtstart wall-clock semantics, the RRULE format and refused frequencies, the IANA timezone default, and the duration bounds. The description only echoes this via a sample payload, so baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: computes the next three occurrences a schedule would produce, without saving. It also names the siblings it is not (create_maintenance_window, update_maintenance_window, get_maintenance_window), so an agent can distinguish it from every adjacent tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes: use this to validate a recurring schedule before create/update, and use get_maintenance_window instead for a saved window's occurrences. Both the when-to-use and the alternative-selection condition are stated outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_tagRename a tag everywhereA
Idempotent
Inspect

Rename a tag on every monitor and heartbeat that carries it; an item that already has the new name keeps one copy. Use it to fix a naming scheme across the organization; to change the tags of chosen monitors only use bulk_update_monitor_tags, and to drop a tag use delete_tag. Requires a key with the write scope. A tag nothing carries is not an error (both counts are 0). Returns from, to, monitors_updated and heartbeats_updated. Example: {"from": "prod", "to": "env:prod"}

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesThe new name. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates.
fromYesThe existing tag, as list_tags shows it.

Output Schema

ParametersJSON Schema
NameRequiredDescription
toNo
fromYes
monitors_updatedYes
heartbeats_updatedYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description adds genuinely new context: write-scope auth requirement, the merge behavior ('an item that already has the new name keeps one copy'), and the edge case that a tag nothing carries is not an error (counts are 0).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core behavior, then routes to alternatives, then auth, edge cases, return fields and an example. Every clause carries distinct information with no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a two-parameter mutation: scope, auth, idempotent merge behavior, no-op edge case, alternatives, and example are all present. An output schema exists, so the return-field mention is supplementary rather than required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both parameters including normalization rules, giving a baseline of 3. The description adds a concrete example mapping ('{"from": "prod", "to": "env:prod"}') and clarifies the merge semantics that govern the 'to' behavior, slightly exceeding the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (rename) plus resource (tag) and exact scope: 'on every monitor and heartbeat that carries it.' It also names the sibling tools it is not (bulk_update_monitor_tags, delete_tag), so an agent can distinguish it without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('to fix a naming scheme across the organization') and when-not, with named alternatives: bulk_update_monitor_tags for selected monitors only and delete_tag to drop a tag. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resume_heartbeatResume a heartbeat monitorA
Idempotent
Inspect

Resume one paused heartbeat: it goes back to PENDING with no deadline, so it is not reported late until its next success ping restarts the clock. Use it once the job runs again; to change its timing use update_heartbeat. There is no bulk resume for heartbeats. Requires a key with the write scope. Resuming one that is not paused resets it to PENDING the same way. Returns the heartbeat.

ParametersJSON Schema
NameRequiredDescriptionDefault
heartbeat_idYesThe heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
stateYesKnown values: PENDING, UP, DOWN, PAUSED.
ping_urlYes
is_activeYes
created_atYes
overdue_atYes
updated_atYes
channel_idsNo
last_ping_atYes
grace_secondsYes
last_start_atYes
period_secondsYes
last_success_atYes
last_duration_msYes
notification_cooldown_secondsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by describing the resulting state (back to PENDING with no deadline), the reporting consequence (not late until the next success ping restarts the clock), the auth requirement (write scope), and the return ("Returns the heartbeat"). The idempotentHint is corroborated by the note that resuming an already-active heartbeat behaves the same way.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five short sentences, each carrying distinct information: state effect, timing rule, alternative tool, bulk limitation, auth requirement, edge case, return. Front-loaded with the action and its state consequence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter state-changing tool with an output schema, the description covers everything an agent needs: what changes, what it requires, what it returns, and what happens in the non-obvious case. Return-value detail is correctly delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single heartbeat_id already documents its uuid format and 404 conditions. The description adds no id-specific syntax or sourcing detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb + resource ("Resume one paused heartbeat") and immediately disambiguates from siblings by saying there is no bulk resume for heartbeats, distinguishing it from bulk_resume_monitors and resume_monitor. An agent can route to it without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to use it ("once the job runs again") and names the alternative for a different need ("to change its timing use update_heartbeat"). It also states the negative case (no bulk resume) and the surprising edge case (resuming a non-paused heartbeat still resets it to PENDING).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resume_monitorResume a monitorA
Idempotent
Inspect

Restart checks on one paused monitor: its status goes back to PENDING and it is checked on the scheduler's next tick. For many monitors use bulk_resume_monitors; to check a running monitor right away use check_now. Requires a key with the write scope. Resuming an active monitor is a no-op success. A 403 means the organization already has as many active monitors as its plan allows: pause or delete another one first. Returns the monitor in the get_monitor shape.

ParametersJSON Schema
NameRequiredDescriptionDefault
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses the PENDING transition timing ('scheduler's next tick'), the required write scope, that active monitors yield a no-op success (consistent with idempotentHint), and the specific 403 plan-limit cause with a remediation. It does not add much on failure/retry edge cases, but the annotation set plus this text is unusually thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences with zero filler, front-loaded with the core action and its state change, then alternatives, then constraints. Every sentence carries distinct operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the mental model (state transition), authorization requirement, idempotent-success case, a specific plan-limit failure with remedy, and the return shape by reference to get_monitor. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single monitor_id param is fully documented there, including the 404 case. The description adds no new parameter-level syntax or format detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with explicit scope: 'Restart checks on one paused monitor.' The singular 'one' immediately distinguishes it from the bulk sibling, and the state transition (back to PENDING) makes the effect unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes to alternatives with conditions: 'For many monitors use bulk_resume_monitors; to check a running monitor right away use check_now.' That is textbook when-to-use/when-not guidance naming two concrete siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_heartbeatUpdate a heartbeat monitorA
Idempotent
Inspect

Change one heartbeat's name, timing, channels or tags; only the fields you pass change. A new period or grace applies from the next ping: the current deadline (overdue_at) is not recomputed. To stop or restart late alerts use pause_heartbeat or resume_heartbeat instead; ping_url never changes. Requires a key with the write scope. An invalid argument is a 422 naming it; never send null. Returns the heartbeat. Example: {"heartbeat_id": "", "grace_seconds": 7200}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoDisplay name, 1 to 255 characters.
tagsNoReplaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates.
channel_idsNoNotification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404.
heartbeat_idYesThe heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404.
grace_secondsNoExtra seconds of silence tolerated after the period before the heartbeat is reported late, 0 to 2592000; it may exceed the period.
period_secondsNoHow often the job runs, 60 to 2592000 seconds. To ping every N seconds and be alerted after T seconds of silence, set period_seconds = N and grace_seconds = T - N (T at least N).
notification_cooldown_secondsNo60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
stateYesKnown values: PENDING, UP, DOWN, PAUSED.
ping_urlYes
is_activeYes
created_atYes
overdue_atYes
updated_atYes
channel_idsNo
last_ping_atYes
grace_secondsYes
last_start_atYes
period_secondsYes
last_success_atYes
last_duration_msYes
notification_cooldown_secondsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (which only declare non-read-only, idempotent, non-destructive). It discloses the delayed effect of period/grace ('applies from the next ping: the current deadline (overdue_at) is not recomputed'), the required write scope, the 422-on-invalid-argument contract with the offending field named, and the null prohibition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core operation and update semantics, then progressively narrower detail (timing caveat, sibling routing, auth, error contract, example). Every sentence carries distinct operational information with no filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers everything an agent needs: what changes and what does not, side-effect timing, sibling routing, permission requirements, error shape, and a call example. Return values are handled by the existing output schema, so their omission is correct.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema does not state at the tool level: partial-update behavior, the timing interaction (new period/grace only takes effect from the next ping), and a concrete example pairing heartbeat_id with grace_seconds.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Change) and resource (one heartbeat) with the exact field set it touches (name, timing, channels, tags). It also differentiates from adjacent siblings by naming pause_heartbeat and resume_heartbeat as the tools for a different intent, so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use and when-not-to-use: 'only the fields you pass change' defines the partial-update contract, and 'To stop or restart late alerts use pause_heartbeat or resume_heartbeat instead' names the alternatives and the condition that selects them. It further warns that ping_url never changes, removing a plausible mis-selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_maintenance_windowUpdate a maintenance windowA
Idempotent
Inspect

Change one maintenance window's name, schedule, scope or monitors, or switch it off with enabled false; only the fields you pass change. While a window is in effect its monitors keep being checked, but no incident opens and no alert goes out. A recurring window cannot become one-time: delete it with delete_maintenance_window and create a new one. Check a new schedule with preview_maintenance_window first. Requires a key with the write scope. An invalid argument is a 422 and a resulting schedule that is invalid (for example a bad rrule) a 406, each with the reason. Returns the window. Example: {"window_id": "", "enabled": false}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoDisplay name, 1 to 255 characters.
rruleNoRepeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused.
scopeNoORG covers every monitor of the organization and ignores monitor_ids; MONITOR covers only monitor_ids.
dtstartNoThe first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422.
enabledNofalse keeps the window but stops it silencing alerts.
timezoneNoIANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes.
window_idYesThe window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404.
monitor_idsNoReplaces the list when passed. Monitor uuids from list_monitors, at least one when scope is MONITOR. An id that is not a monitor of this organization is a 404.
duration_minutesNoHow long each occurrence lasts, 1 to 40320 minutes.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
rruleYes
scopeYesKnown values: MONITOR, ORG.
dtstartYes
enabledYes
timezoneYes
created_atYes
monitor_idsNo
duration_minutesYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: reveals auth requirement (write scope), the side effect while a window is in effect (monitors still checked but no incident opens and no alert fires), the recurrence-immutability constraint, and error semantics (422 invalid argument, 406 invalid resulting schedule, each with a reason). None of this is derivable from readOnlyHint/idempotentHint/destructiveHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, and nearly every clause carries non-obvious information (partial update, silencing behavior, recurrence constraint, preview step, auth scope, error codes, return, example). The middle is a dense semicolon run-on that could be split into bullets, which is the only reason this is not a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation tool with an output schema, the description covers everything an agent needs: mutation semantics, side effects, prerequisites, auth, failure modes, and a concrete invocation example. Return-value detail is correctly left light since an output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds value: it clarifies that every field other than window_id is optional and only supplied fields change, which reframes the 9-property schema as a patch. The worked example {"window_id": ..., "enabled": false} demonstrates that partial-update pattern concretely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (change one maintenance window's fields or disable it) and enumerates the editable dimensions (name, schedule, scope, monitors, enabled). An agent can distinguish it from create_maintenance_window, delete_maintenance_window, get/list_maintenance_window and preview_maintenance_window without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use and when-not-to-use: recurring windows cannot be converted to one-time, so delete with delete_maintenance_window and recreate; validate a new schedule with preview_maintenance_window first. It also states the partial-update condition (only passed fields change). Alternatives and prerequisites are named outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_monitorUpdate a monitorA
Idempotent
Inspect

Change one monitor's settings and return it in the get_monitor shape. Only the fields you pass change, and at least one besides monitor_id is required (422 otherwise); type and target never change (create a new monitor instead). Not for pausing or resuming (pause_monitor, resume_monitor), for many monitors at once (bulk_update_monitors) or for tags alone across monitors (bulk_update_monitor_tags). Requires a key with the write scope. Plan limits are checked against the result, as on create_monitor (only moving a monitor below 60 seconds takes a fast slot): breaking one is a 403 naming it. Port-list rules are checked against the result too, so changing only the interval or regions of a port-list TCP monitor can be a 422. Omit a field to keep it; never send null. Example: {"monitor_id": "", "interval_seconds": 600}

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoDisplay name, 1 to 255 characters.
tagsNoReplaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates.
configNoReplaces the monitor's whole config, not just the keys you send: a field of the type's schema you leave out resets to its default (read the current one with get_monitor first). Sending only port on a TCP monitor whose expected_state is closed resets it to open. A port-list TCP monitor cannot switch to a single port (422). An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state "open" (default) or "closed", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state "closed", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form.
regionsNoOne or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise).
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.
channel_idsNoNotification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404.
badge_enabledNoTurns the monitor's public status badge on or off. A monitor on a published status page has a badge even when it is false.
timeout_secondsNoSeconds one check may take before it fails, 1 to 120.
interval_secondsNoSeconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit.
confirmation_thresholdNoHow many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create.
notification_cooldown_secondsNo60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotency and non-destructiveness; the description goes further with PATCH-like semantics (omitted fields retained, null forbidden), 422/403/404 failure conditions, plan-limit checks against the result, and the config-wholesale-replacement warning. This is substantial behavioral disclosure beyond the structured hints, though it does not restate the safety profile itself.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core mutation semantics, immutability constraint, and routing alternatives before the operational caveats. It is long and dense, but the length is earned by the complexity of an 11-parameter tool with nested config; a few clauses (e.g. the port-list/plan-limit details) could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description needn't explain return values, and it focuses correctly on update semantics, error paths, and plan-limit interactions. For a complex nested-config mutation tool, the coverage of edge cases (null handling, config replacement, region/interval constraints) is thorough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-field meaning the schema cannot: 'omit a field to keep it; never send null', the requires-one-field-beyond-monitor_id rule, and a concrete usage example. These clarify how parameters interact rather than merely restating individual field docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Change one monitor's settings') plus the scope (single monitor) and return shape ('get_monitor shape'). It explicitly distinguishes itself from bulk_update_monitors, pause_monitor/resume_monitor, and bulk_update_monitor_tags, so an agent can route correctly without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the excluded use cases and their alternatives explicitly (pause/resume, bulk updates, tag-only bulk edits) and tells the agent to use create_monitor for immutable type/target changes. It also states the write-scope prerequisite and the minimum-field requirement, covering when and when-not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_status_page_incidentRename a status page incidentA
Idempotent
Inspect

Change a status page incident's title without telling anyone: nothing is sent to subscribers. To change its status or add a message use post_status_page_update. Requires a key with the write scope. Returns the incident. Example: {"page_id": "", "incident_id": "", "title": "API errors in eu-central"}

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesThe new headline, 1 to 255 characters.
page_idYesThe status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404.
incident_idYesThe status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
titleYes
statusYesKnown values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.
is_autoYes
updatesYes
started_atYes
notified_atYes
resolved_atYes
component_idsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false), but the description adds behavior the annotations cannot express: no subscriber notification is sent, and a key with the write scope is required. It also states the return value. This is meaningful side-effect and auth context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences: the action and its silent side effect come first, then the alternative tool, then auth, then a compact example. Every sentence carries a distinct fact and none is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter, fully-required mutation with an output schema present, the description supplies the missing pieces: silent notification behavior, required write scope, the competing sibling tool, and ID provenance. Nothing an agent needs to call it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter already documents its source and error behavior ('from list_status_pages', 404 on unknown id), so the baseline is 3. The example restates the same ID provenance rather than adding new semantics such as title constraints or conflict behavior, so no credit above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — renaming a status page incident's title — and immediately clarifies the scope ('without telling anyone: nothing is sent to subscribers'). It explicitly distinguishes itself from the sibling post_status_page_update, which handles status changes and messages, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative tool (post_status_page_update) and the exact condition that selects it ('to change its status or add a message'). It also states the positive condition for this tool: a silent title-only change. Nothing about when-to-use is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 47 tool updatesv0.6.1
    • Changedacknowledge_incident2 fields changed
      • addedInput schema / properties / incident_id / description
        Added value: +"The incident's uuid from list_incidents. An id that is not an incident of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "acknowledged_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "acknowledged_by": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "cause": {
        +      "description": "Known values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, HEARTBEAT_MISSED, HEARTBEAT_FAILED, UNKNOWN.",
        +      "type": "string"
        +    },
        +    "cause_detail": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "heartbeat_id": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "last_notified_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "monitor_id": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_logs": {
        +      "items": {
        +        "properties": {
        +          "channel_type": {
        +            "description": "Known values: EMAIL, TELEGRAM, WEBHOOK, SLACK, DISCORD.",
        +            "type": "string"
        +          },
        +          "destination": {
        +            "type": "string"
        +          },
        +          "error": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "event": {
        +            "description": "Known values: TRIGGERED, RESOLVED, SSL_EXPIRY.",
        +            "type": "string"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "sent_at": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, SENT, FAILED.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "channel_type",
        +          "destination",
        +          "event",
        +          "sent_at",
        +          "status",
        +          "error"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "renotify_count": {
        +      "type": "integer"
        +    },
        +    "resolved_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "started_at": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "started_at",
        +    "resolved_at",
        +    "cause",
        +    "cause_detail",
        +    "last_notified_at",
        +    "acknowledged_at",
        +    "acknowledged_by",
        +    "renotify_count",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedbulk_create_monitors2 fields changed
      • changedInput schema / properties / monitors / description
        Previous value: -"Monitors to create, each shaped like a single create request."New value: +"1 to 100 monitors, each taking the same fields and rules as create_monitor's arguments. Items with is_active false are created paused and still count toward the plan."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitors": {
        +      "items": {
        +        "properties": {
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "interval_seconds": {
        +            "type": "integer"
        +          },
        +          "is_active": {
        +            "type": "boolean"
        +          },
        +          "last_checked_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "ssl_expires_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +            "type": "string"
        +          },
        +          "tags": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "target": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "type",
        +          "target",
        +          "status",
        +          "is_active",
        +          "interval_seconds",
        +          "ssl_expires_at",
        +          "last_checked_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "monitors"
        +  ],
        +  "type": "object"
        +}
    • Changedbulk_pause_monitors2 fields changed
      • changedInput schema / properties / monitor_ids / description
        Previous value: -"Monitors to act on. Every id must belong to the active organization."New value: +"1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitors": {
        +      "items": {
        +        "properties": {
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "interval_seconds": {
        +            "type": "integer"
        +          },
        +          "is_active": {
        +            "type": "boolean"
        +          },
        +          "last_checked_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "ssl_expires_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +            "type": "string"
        +          },
        +          "tags": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "target": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "type",
        +          "target",
        +          "status",
        +          "is_active",
        +          "interval_seconds",
        +          "ssl_expires_at",
        +          "last_checked_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "monitors"
        +  ],
        +  "type": "object"
        +}
    • Changedbulk_resume_monitors2 fields changed
      • changedInput schema / properties / monitor_ids / description
        Previous value: -"Monitors to act on. Every id must belong to the active organization."New value: +"1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitors": {
        +      "items": {
        +        "properties": {
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "interval_seconds": {
        +            "type": "integer"
        +          },
        +          "is_active": {
        +            "type": "boolean"
        +          },
        +          "last_checked_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "ssl_expires_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +            "type": "string"
        +          },
        +          "tags": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "target": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "type",
        +          "target",
        +          "status",
        +          "is_active",
        +          "interval_seconds",
        +          "ssl_expires_at",
        +          "last_checked_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "monitors"
        +  ],
        +  "type": "object"
        +}
    • Changedbulk_update_monitor_tags4 fields changed
      • changedInput schema / properties / add / description
        Previous value: -"Tags to add to every listed monitor."New value: +"Tags to add to every listed monitor, up to 10."
      • changedInput schema / properties / monitor_ids / description
        Previous value: -"Monitors to retag. Every id must belong to the active organization."New value: +"1 to 300 distinct monitor uuids from list_monitors. A repeated id is a 422; an unknown id rejects the whole call with a 404 naming every id not found."
      • changedInput schema / properties / remove / description
        Previous value: -"Tags to remove from every listed monitor."New value: +"Tags to remove from every listed monitor, up to 10."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitors_updated": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "monitors_updated"
        +  ],
        +  "type": "object"
        +}
    • Changedbulk_update_monitors3 fields changed
      • addedInput schema / properties / changes / description
        Added value: +"The values to set, at least one of: interval_seconds (30 to 86400), timeout_seconds (1 to 120), regions (region codes from limits.allowed_regions in get_plan_usage), channel_ids (channel uuids from list_channels; replaces each binding, [] clears it, an unknown channel is a 404), confirmation_threshold (1 to 10) and notification_cooldown_seconds (60 to 86400). Omit a field to keep it; never send null."
      • changedInput schema / properties / monitor_ids / description
        Previous value: -"Monitors to act on. Every id must belong to the active organization."New value: +"1 to 100 distinct monitor uuids from list_monitors. A repeated id is a 422; an id that is not a monitor of this organization is a 404 naming it, and then nothing changes."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitors": {
        +      "items": {
        +        "properties": {
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "interval_seconds": {
        +            "type": "integer"
        +          },
        +          "is_active": {
        +            "type": "boolean"
        +          },
        +          "last_checked_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "ssl_expires_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +            "type": "string"
        +          },
        +          "tags": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "target": {
        +            "type": "string"
        +          },
        +          "type": {
        +            "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "type",
        +          "target",
        +          "status",
        +          "is_active",
        +          "interval_seconds",
        +          "ssl_expires_at",
        +          "last_checked_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "monitors"
        +  ],
        +  "type": "object"
        +}
    • Changedcheck_now2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedcheck_target4 fields changed
      • addedInput schema / properties / config / description
        Added value: +"As in create_monitor; TCP and DNS need it. The region, interval and update rules there do not apply to a one-off probe. An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state \"open\" (default) or \"closed\", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state \"closed\", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form."
      • addedInput schema / properties / target / description
        Added value: +"What to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422."
      • addedInput schema / properties / type / description
        Added value: +"HTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "error": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "failure_kind": {
        +      "anyOf": [
        +        {
        +          "description": "Known values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, UNKNOWN.",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "region": {
        +      "type": "string"
        +    },
        +    "response_time_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: up, down, error, unknown.",
        +      "type": "string"
        +    },
        +    "status_code": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    }
        +  },
        +  "required": [
        +    "status",
        +    "region"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_heartbeat7 fields changed
      • addedInput schema / properties / channel_ids / description
        Added value: +"Notification channel uuids from list_channels. Omit it or pass [] to alert every verified, active channel of the organization. An id that is not an active channel of this organization is a 404."
      • addedInput schema / properties / grace_seconds / description
        Added value: +"Extra seconds of silence tolerated after the period before the heartbeat is reported late, 0 to 2592000; it may exceed the period."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / notification_cooldown_seconds / description
        Added value: +"60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back."
      • addedInput schema / properties / period_seconds / description
        Added value: +"How often the job runs, 60 to 2592000 seconds. To ping every N seconds and be alerted after T seconds of silence, set period_seconds = N and grace_seconds = T - N (T at least N)."
      • addedInput schema / properties / tags / description
        Added value: +"Flat labels for grouping and filtering, for example env:prod or service:api, at most 10. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "grace_seconds": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_duration_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_ping_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_start_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_success_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "overdue_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "period_seconds": {
        +      "type": "integer"
        +    },
        +    "ping_url": {
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "state",
        +    "period_seconds",
        +    "grace_seconds",
        +    "ping_url",
        +    "last_ping_at",
        +    "last_success_at",
        +    "last_start_at",
        +    "last_duration_ms",
        +    "overdue_at",
        +    "notification_cooldown_seconds",
        +    "is_active",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_maintenance_window9 fields changed
      • addedInput schema / properties / dtstart / description
        Added value: +"The first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422."
      • addedInput schema / properties / duration_minutes / description
        Added value: +"How long each occurrence lasts, 1 to 40320 minutes."
      • addedInput schema / properties / enabled / description
        Added value: +"Default true; false stores the window without effect."
      • addedInput schema / properties / monitor_ids / description
        Added value: +"Monitor uuids from list_monitors, at least one when scope is MONITOR. An id that is not a monitor of this organization is a 404."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / rrule / description
        Added value: +"Repeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused. Omit it for a one-time window."
      • addedInput schema / properties / scope / description
        Added value: +"ORG covers every monitor of the organization and ignores monitor_ids; MONITOR covers only monitor_ids."
      • addedInput schema / properties / timezone / description
        Added value: +"IANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes. Defaults to the organization's timezone."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "dtstart": {
        +      "type": "string"
        +    },
        +    "duration_minutes": {
        +      "type": "integer"
        +    },
        +    "enabled": {
        +      "type": "boolean"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "monitor_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "rrule": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "scope": {
        +      "description": "Known values: MONITOR, ORG.",
        +      "type": "string"
        +    },
        +    "timezone": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "enabled",
        +    "scope",
        +    "dtstart",
        +    "duration_minutes",
        +    "rrule",
        +    "timezone",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_monitor13 fields changed
      • addedInput schema / properties / channel_ids / description
        Added value: +"Notification channel uuids from list_channels. Omit it or pass [] to alert every verified, active channel of the organization. An id that is not an active channel of this organization is a 404."
      • addedInput schema / properties / config / description
        Added value: +"An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state \"open\" (default) or \"closed\", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state \"closed\", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form. Omit it for HTTP, PING or SSL to take the defaults; a TCP or DNS monitor without it is a 422."
      • addedInput schema / properties / confirmation_threshold / description
        Added value: +"How many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create."
      • addedInput schema / properties / interval_seconds / description
        Added value: +"Seconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit."
      • addedInput schema / properties / is_active / description
        Added value: +"Default true. false creates it paused: no check runs until resume_monitor."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / notification_cooldown_seconds / description
        Added value: +"60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back."
      • addedInput schema / properties / regions / description
        Added value: +"One or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise)."
      • addedInput schema / properties / tags / description
        Added value: +"Flat labels for grouping and filtering, for example env:prod or service:api, at most 10. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates."
      • addedInput schema / properties / target / description
        Added value: +"What to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422. Cannot be changed after create."
      • addedInput schema / properties / timeout_seconds / description
        Added value: +"Seconds one check may take before it fails, 1 to 120."
      • addedInput schema / properties / type / description
        Added value: +"HTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value). Cannot be changed after create."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_status_page_incident6 fields changed
      • addedInput schema / properties / body / description
        Added value: +"The first message. The message subscribers read, 1 to 5000 characters."
      • addedInput schema / properties / component_ids / description
        Added value: +"The affected components: uuids from get_status_page. An id that is not a component of this page is a 404."
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • addedInput schema / properties / status / description
        Added value: +"INVESTIGATING, IDENTIFIED, MONITORING or RESOLVED; RESOLVED closes the incident on the page. Default INVESTIGATING."
      • addedInput schema / properties / title / description
        Added value: +"The incident's headline, 1 to 255 characters."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "component_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_auto": {
        +      "type": "boolean"
        +    },
        +    "notified_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "resolved_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "started_at": {
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +      "type": "string"
        +    },
        +    "title": {
        +      "type": "string"
        +    },
        +    "updates": {
        +      "items": {
        +        "properties": {
        +          "body": {
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "created_by": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "status",
        +          "body",
        +          "created_by",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "title",
        +    "status",
        +    "is_auto",
        +    "started_at",
        +    "resolved_at",
        +    "notified_at",
        +    "component_ids",
        +    "updates"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_heartbeat2 fields changed
      • addedInput schema / properties / heartbeat_id / description
        Added value: +"The heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "success": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_maintenance_window2 fields changed
      • addedInput schema / properties / window_id / description
        Added value: +"The window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "success": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_monitor2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "success": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_status_page_incident3 fields changed
      • addedInput schema / properties / incident_id / description
        Added value: +"The status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404."
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "success": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changeddelete_tag2 fields changed
      • addedInput schema / properties / tag / description
        Added value: +"The tag to remove, exactly as list_tags shows it."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "from": {
        +      "type": "string"
        +    },
        +    "heartbeats_updated": {
        +      "type": "integer"
        +    },
        +    "monitors_updated": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "from",
        +    "monitors_updated",
        +    "heartbeats_updated"
        +  ],
        +  "type": "object"
        +}
    • Changedget_exposed_ports_preset1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "ports": {
        +      "items": {
        +        "properties": {
        +          "port": {
        +            "type": "integer"
        +          },
        +          "service": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "port",
        +          "service"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "ports"
        +  ],
        +  "type": "object"
        +}
    • Changedget_heartbeat2 fields changed
      • addedInput schema / properties / heartbeat_id / description
        Added value: +"The heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "grace_seconds": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_duration_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_ping_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_start_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_success_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "overdue_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "period_seconds": {
        +      "type": "integer"
        +    },
        +    "ping_url": {
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "state",
        +    "period_seconds",
        +    "grace_seconds",
        +    "ping_url",
        +    "last_ping_at",
        +    "last_success_at",
        +    "last_start_at",
        +    "last_duration_ms",
        +    "overdue_at",
        +    "notification_cooldown_seconds",
        +    "is_active",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedget_incident2 fields changed
      • addedInput schema / properties / incident_id / description
        Added value: +"The incident's uuid from list_incidents. An id that is not an incident of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "acknowledged_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "acknowledged_by": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "cause": {
        +      "description": "Known values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, HEARTBEAT_MISSED, HEARTBEAT_FAILED, UNKNOWN.",
        +      "type": "string"
        +    },
        +    "cause_detail": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "heartbeat_id": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "last_notified_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "monitor_id": {
        +      "anyOf": [
        +        {
        +          "format": "uuid",
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_logs": {
        +      "items": {
        +        "properties": {
        +          "channel_type": {
        +            "description": "Known values: EMAIL, TELEGRAM, WEBHOOK, SLACK, DISCORD.",
        +            "type": "string"
        +          },
        +          "destination": {
        +            "type": "string"
        +          },
        +          "error": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "event": {
        +            "description": "Known values: TRIGGERED, RESOLVED, SSL_EXPIRY.",
        +            "type": "string"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "sent_at": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: PENDING, SENT, FAILED.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "channel_type",
        +          "destination",
        +          "event",
        +          "sent_at",
        +          "status",
        +          "error"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "renotify_count": {
        +      "type": "integer"
        +    },
        +    "resolved_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "started_at": {
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "started_at",
        +    "resolved_at",
        +    "cause",
        +    "cause_detail",
        +    "last_notified_at",
        +    "acknowledged_at",
        +    "acknowledged_by",
        +    "renotify_count",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedget_maintenance_window2 fields changed
      • addedInput schema / properties / window_id / description
        Added value: +"The window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "dtstart": {
        +      "type": "string"
        +    },
        +    "duration_minutes": {
        +      "type": "integer"
        +    },
        +    "enabled": {
        +      "type": "boolean"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "monitor_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_occurrences": {
        +      "items": {
        +        "properties": {
        +          "end": {
        +            "type": "string"
        +          },
        +          "start": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "start",
        +          "end"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "rrule": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "scope": {
        +      "description": "Known values: MONITOR, ORG.",
        +      "type": "string"
        +    },
        +    "timezone": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "enabled",
        +    "scope",
        +    "dtstart",
        +    "duration_minutes",
        +    "rrule",
        +    "timezone",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedget_monitor2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedget_plan_usage1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "limits": {
        +      "properties": {
        +        "allowed_channel_types": {
        +          "items": {
        +            "description": "Known values: EMAIL, TELEGRAM, WEBHOOK, SLACK, DISCORD.",
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "allowed_regions": {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "api_rate_limit_per_minute": {
        +          "type": "integer"
        +        },
        +        "fast_interval_threshold_seconds": {
        +          "type": "integer"
        +        },
        +        "history_retention_days": {
        +          "type": "integer"
        +        },
        +        "max_api_keys": {
        +          "type": "integer"
        +        },
        +        "max_channels": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_fast_monitors": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_heartbeats": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_maintenance_windows": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_monitors": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_regions": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_status_page_subscribers": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "max_status_pages": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "min_interval_seconds": {
        +          "type": "integer"
        +        },
        +        "renotify_interval_seconds": {
        +          "type": "integer"
        +        },
        +        "renotify_max_count": {
        +          "type": "integer"
        +        },
        +        "tier": {
        +          "description": "Known values: FREE, PLUS, PRO, MAX, ENTERPRISE.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "tier",
        +        "max_monitors",
        +        "min_interval_seconds",
        +        "max_fast_monitors",
        +        "fast_interval_threshold_seconds",
        +        "max_regions",
        +        "history_retention_days",
        +        "allowed_channel_types",
        +        "max_channels",
        +        "max_heartbeats",
        +        "max_maintenance_windows",
        +        "max_status_pages",
        +        "max_status_page_subscribers",
        +        "renotify_interval_seconds",
        +        "renotify_max_count",
        +        "max_api_keys",
        +        "api_rate_limit_per_minute",
        +        "allowed_regions"
        +      ],
        +      "type": "object"
        +    },
        +    "plan": {
        +      "description": "Known values: FREE, PLUS, PRO, MAX, ENTERPRISE.",
        +      "type": "string"
        +    },
        +    "usage": {
        +      "properties": {
        +        "fast_monitors": {
        +          "description": "Monitors with an interval below the fast threshold.",
        +          "type": "integer"
        +        },
        +        "heartbeats": {
        +          "type": "integer"
        +        },
        +        "monitors": {
        +          "description": "Monitors, paused ones included.",
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "monitors",
        +        "fast_monitors",
        +        "heartbeats"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "plan",
        +    "limits",
        +    "usage"
        +  ],
        +  "type": "object"
        +}
    • Changedget_response_time_by_region3 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • addedInput schema / properties / window / description
        Added value: +"24h (the default; up to 24 hourly buckets), 7d (up to 28 six-hourly buckets) or 30d (up to 30 daily buckets)."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "bucket_seconds": {
        +      "type": "integer"
        +    },
        +    "monitor_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "regions": {
        +      "items": {
        +        "properties": {
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "points": {
        +            "items": {
        +              "properties": {
        +                "avg_response_time_ms": {
        +                  "anyOf": [
        +                    {
        +                      "type": "integer"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ]
        +                },
        +                "bucket_start": {
        +                  "type": "string"
        +                },
        +                "sample_count": {
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "bucket_start",
        +                "sample_count"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "region": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "display_name",
        +          "points"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "window": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "monitor_id",
        +    "window",
        +    "bucket_seconds",
        +    "regions"
        +  ],
        +  "type": "object"
        +}
    • Changedget_status_page2 fields changed
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "description": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "groups": {
        +      "items": {
        +        "properties": {
        +          "components": {
        +            "items": {
        +              "properties": {
        +                "display_name": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ]
        +                },
        +                "id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "monitor_id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "position": {
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "monitor_id",
        +                "display_name",
        +                "position"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "position": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "position",
        +          "components"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "history_days": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_published": {
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "slug": {
        +      "type": "string"
        +    },
        +    "ungrouped_components": {
        +      "items": {
        +        "properties": {
        +          "display_name": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "monitor_id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "position": {
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "monitor_id",
        +          "display_name",
        +          "position"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "slug",
        +    "name",
        +    "description",
        +    "is_published",
        +    "history_days",
        +    "created_at",
        +    "groups",
        +    "ungrouped_components"
        +  ],
        +  "type": "object"
        +}
    • Changedget_uptime_daily3 fields changed
      • addedInput schema / properties / days / description
        Added value: +"How many days to return, 1 to 365; default 30. Capped at the plan's limits.history_retention_days (get_plan_usage), so fewer days can come back."
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "days": {
        +      "items": {
        +        "properties": {
        +          "date": {
        +            "type": "string"
        +          },
        +          "degraded_checks": {
        +            "type": "integer"
        +          },
        +          "down_checks": {
        +            "type": "integer"
        +          },
        +          "maintenance_checks": {
        +            "type": "integer"
        +          },
        +          "total_checks": {
        +            "type": "integer"
        +          },
        +          "up_checks": {
        +            "type": "integer"
        +          },
        +          "uptime_percentage": {
        +            "anyOf": [
        +              {
        +                "type": "number"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          }
        +        },
        +        "required": [
        +          "date",
        +          "uptime_percentage",
        +          "total_checks",
        +          "up_checks",
        +          "down_checks"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "monitor_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "monitor_id",
        +    "days"
        +  ],
        +  "type": "object"
        +}
    • Changedget_uptime_summary2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "monitor_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "windows": {
        +      "additionalProperties": {
        +        "properties": {
        +          "avg_response_time_ms": {
        +            "anyOf": [
        +              {
        +                "type": "integer"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "degraded_checks": {
        +            "type": "integer"
        +          },
        +          "down_checks": {
        +            "type": "integer"
        +          },
        +          "incident_count": {
        +            "type": "integer"
        +          },
        +          "total_checks": {
        +            "type": "integer"
        +          },
        +          "up_checks": {
        +            "type": "integer"
        +          },
        +          "uptime_percentage": {
        +            "anyOf": [
        +              {
        +                "type": "number"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          }
        +        },
        +        "required": [
        +          "uptime_percentage",
        +          "total_checks",
        +          "up_checks",
        +          "down_checks",
        +          "incident_count",
        +          "avg_response_time_ms"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "monitor_id",
        +    "windows"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_check_results7 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / period_days / description
        Added value: +"Keep results of the last N days, 1 to 365; without it every stored result is eligible."
      • addedInput schema / properties / region / description
        Added value: +"Keep one region's results: its exact code, up to 64 characters."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • addedInput schema / properties / status / description
        Added value: +"Keep results with this status only."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "details": {
        +            "anyOf": [
        +              {
        +                "additionalProperties": true,
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "error_message": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "job_id": {
        +            "type": "string"
        +          },
        +          "maintenance_window_id": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "monitor_id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "response_time_ms": {
        +            "anyOf": [
        +              {
        +                "type": "integer"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          },
        +          "status_code": {
        +            "anyOf": [
        +              {
        +                "type": "integer"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "monitor_id",
        +          "region",
        +          "checked_at",
        +          "status",
        +          "response_time_ms",
        +          "status_code",
        +          "error_message",
        +          "details",
        +          "job_id"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_heartbeats7 fields changed
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / q / description
        Added value: +"Case-insensitive substring of the name, up to 255 characters."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • addedInput schema / properties / sort / description
        Added value: +"status (the default: DOWN, PENDING, UP, PAUSED, newest first within each), name, or created_at (newest first)."
      • addedInput schema / properties / tag / description
        Added value: +"Keep items carrying these tags: a JSON array of up to 10 tags, each up to 50 characters, lowercased before matching. tag_match decides whether all or any of them must match."
      • addedInput schema / properties / tag_match / description
        Added value: +"all (the default): an item must carry every tag in tag. any: at least one of them."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "channel_ids": {
        +            "items": {
        +              "format": "uuid",
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "grace_seconds": {
        +            "type": "integer"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "is_active": {
        +            "type": "boolean"
        +          },
        +          "last_duration_ms": {
        +            "anyOf": [
        +              {
        +                "type": "integer"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "last_ping_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "last_start_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "last_success_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "notification_cooldown_seconds": {
        +            "type": "integer"
        +          },
        +          "overdue_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "period_seconds": {
        +            "type": "integer"
        +          },
        +          "ping_url": {
        +            "type": "string"
        +          },
        +          "state": {
        +            "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +            "type": "string"
        +          },
        +          "tags": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "updated_at": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "state",
        +          "period_seconds",
        +          "grace_seconds",
        +          "ping_url",
        +          "last_ping_at",
        +          "last_success_at",
        +          "last_start_at",
        +          "last_duration_ms",
        +          "overdue_at",
        +          "notification_cooldown_seconds",
        +          "is_active",
        +          "created_at",
        +          "updated_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_incidents7 fields changed
      • changedInput schema / properties / cause / description
        Previous value: -"Filter by structured failure cause."New value: +"Keep one failure cause, such as TIMEOUT, HTTP_5XX or HEARTBEAT_MISSED."
      • addedInput schema / properties / monitor_id / description
        Added value: +"Keep one monitor's incidents: its uuid from list_monitors."
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • changedInput schema / properties / period_days / description
        Previous value: -"Only incidents that were active within the last N days. An incident still open is always included, whenever it started. Combined with status=open this makes period_days a no-op, since every open incident already satisfies that arm — use status=resolved or omit status to see the window take effect."New value: +"Keep incidents active within the last N days, 1 to 365. An open incident always qualifies, so with status open it changes nothing: use status resolved, or omit status, to see the window take effect."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • changedInput schema / properties / status / description
        Previous value: -"Filter by open or resolved; omit for both."New value: +"open or resolved (lowercase); omit it for both."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "acknowledged_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "acknowledged_by": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "cause": {
        +            "description": "Known values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, HEARTBEAT_MISSED, HEARTBEAT_FAILED, UNKNOWN.",
        +            "type": "string"
        +          },
        +          "cause_detail": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "heartbeat_id": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "last_notified_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "monitor_id": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "notification_logs": {
        +            "items": {
        +              "properties": {
        +                "channel_type": {
        +                  "description": "Known values: EMAIL, TELEGRAM, WEBHOOK, SLACK, DISCORD.",
        +                  "type": "string"
        +                },
        +                "destination": {
        +                  "type": "string"
        +                },
        +                "error": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ]
        +                },
        +                "event": {
        +                  "description": "Known values: TRIGGERED, RESOLVED, SSL_EXPIRY.",
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "sent_at": {
        +                  "type": "string"
        +                },
        +                "status": {
        +                  "description": "Known values: PENDING, SENT, FAILED.",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "channel_type",
        +                "destination",
        +                "event",
        +                "sent_at",
        +                "status",
        +                "error"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "renotify_count": {
        +            "type": "integer"
        +          },
        +          "resolved_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "started_at": {
        +            "type": "string"
        +          },
        +          "updated_at": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "started_at",
        +          "resolved_at",
        +          "cause",
        +          "cause_detail",
        +          "last_notified_at",
        +          "acknowledged_at",
        +          "acknowledged_by",
        +          "renotify_count",
        +          "created_at",
        +          "updated_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_maintenance_windows5 fields changed
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / q / description
        Added value: +"Case-insensitive substring of the name, up to 255 characters."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • addedInput schema / properties / sort / description
        Added value: +"created_at (the default, newest first) or name."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "dtstart": {
        +            "type": "string"
        +          },
        +          "duration_minutes": {
        +            "type": "integer"
        +          },
        +          "enabled": {
        +            "type": "boolean"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "monitor_ids": {
        +            "items": {
        +              "format": "uuid",
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "rrule": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "scope": {
        +            "description": "Known values: MONITOR, ORG.",
        +            "type": "string"
        +          },
        +          "timezone": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "enabled",
        +          "scope",
        +          "dtstart",
        +          "duration_minutes",
        +          "rrule",
        +          "timezone",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_monitors8 fields changed
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / q / description
        Added value: +"Case-insensitive substring of the name or the target, up to 255 characters."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • addedInput schema / properties / sort / description
        Added value: +"status (the default: PENDING, DOWN, DEGRADED, UP, PAUSED, then by name), up_first (healthy first), name, newest, oldest, or ssl_expiry (soonest-expiring certificates first; monitors with no known expiry, non-SSL types or not checked yet, last)."
      • addedInput schema / properties / status / description
        Added value: +"Keep monitors in any of these states: a JSON array. PENDING means no verdict yet."
      • addedInput schema / properties / tag / description
        Added value: +"Keep items carrying these tags: a JSON array of up to 10 tags, each up to 50 characters, lowercased before matching. tag_match decides whether all or any of them must match."
      • addedInput schema / properties / tag_match / description
        Added value: +"all (the default): an item must carry every tag in tag. any: at least one of them."
      • addedInput schema / properties / type / description
        Added value: +"Keep monitors of any of these types: a JSON array."
    • Changedlist_regions1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "regions": {
        +      "items": {
        +        "properties": {
        +          "city": {
        +            "type": "string"
        +          },
        +          "code": {
        +            "type": "string"
        +          },
        +          "country_code": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "group": {
        +            "type": "string"
        +          },
        +          "group_display_name": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "code",
        +          "display_name",
        +          "city",
        +          "country_code",
        +          "group",
        +          "group_display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "regions"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_status_page_incidents4 fields changed
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "component_ids": {
        +            "items": {
        +              "format": "uuid",
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "is_auto": {
        +            "type": "boolean"
        +          },
        +          "notified_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "resolved_at": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "started_at": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +            "type": "string"
        +          },
        +          "title": {
        +            "type": "string"
        +          },
        +          "updates": {
        +            "items": {
        +              "properties": {
        +                "body": {
        +                  "type": "string"
        +                },
        +                "created_at": {
        +                  "type": "string"
        +                },
        +                "created_by": {
        +                  "anyOf": [
        +                    {
        +                      "format": "uuid",
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ]
        +                },
        +                "id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "status": {
        +                  "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "status",
        +                "body",
        +                "created_by",
        +                "created_at"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "title",
        +          "status",
        +          "is_auto",
        +          "started_at",
        +          "resolved_at",
        +          "notified_at",
        +          "component_ids",
        +          "updates"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_status_pages4 fields changed
      • addedInput schema / properties / page / description
        Added value: +"Page number, 1 or more; default 1."
      • addedInput schema / properties / size / description
        Added value: +"Rows per page, 1 to 100; default 25. Keep paging until you have seen total rows."
      • addedInput schema / properties / sort / description
        Added value: +"created_at (the default, newest first) or name."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "description": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "groups": {
        +            "items": {
        +              "properties": {
        +                "components": {
        +                  "items": {
        +                    "properties": {
        +                      "display_name": {
        +                        "anyOf": [
        +                          {
        +                            "type": "string"
        +                          },
        +                          {
        +                            "type": "null"
        +                          }
        +                        ]
        +                      },
        +                      "id": {
        +                        "format": "uuid",
        +                        "type": "string"
        +                      },
        +                      "monitor_id": {
        +                        "format": "uuid",
        +                        "type": "string"
        +                      },
        +                      "position": {
        +                        "type": "integer"
        +                      }
        +                    },
        +                    "required": [
        +                      "id",
        +                      "monitor_id",
        +                      "display_name",
        +                      "position"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "type": "array"
        +                },
        +                "id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "type": "string"
        +                },
        +                "position": {
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "name",
        +                "position",
        +                "components"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "history_days": {
        +            "type": "integer"
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "is_published": {
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "type": "string"
        +          },
        +          "slug": {
        +            "type": "string"
        +          },
        +          "ungrouped_components": {
        +            "items": {
        +              "properties": {
        +                "display_name": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ]
        +                },
        +                "id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "monitor_id": {
        +                  "format": "uuid",
        +                  "type": "string"
        +                },
        +                "position": {
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "monitor_id",
        +                "display_name",
        +                "position"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "slug",
        +          "name",
        +          "description",
        +          "is_published",
        +          "history_days",
        +          "created_at",
        +          "groups",
        +          "ungrouped_components"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "page": {
        +      "type": "integer"
        +    },
        +    "pages": {
        +      "type": "integer"
        +    },
        +    "size": {
        +      "type": "integer"
        +    },
        +    "total": {
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "items",
        +    "total",
        +    "page",
        +    "size",
        +    "pages"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_tags2 fields changed
      • addedInput schema / properties / kind / description
        Added value: +"monitor or heartbeat lists only the tags that kind of item uses; all (the default) lists both. Both counts are reported either way."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "items": {
        +      "items": {
        +        "properties": {
        +          "heartbeat_count": {
        +            "type": "integer"
        +          },
        +          "monitor_count": {
        +            "type": "integer"
        +          },
        +          "tag": {
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "tag",
        +          "monitor_count",
        +          "heartbeat_count"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "items"
        +  ],
        +  "type": "object"
        +}
    • Changedpause_heartbeat2 fields changed
      • addedInput schema / properties / heartbeat_id / description
        Added value: +"The heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "grace_seconds": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_duration_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_ping_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_start_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_success_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "overdue_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "period_seconds": {
        +      "type": "integer"
        +    },
        +    "ping_url": {
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "state",
        +    "period_seconds",
        +    "grace_seconds",
        +    "ping_url",
        +    "last_ping_at",
        +    "last_success_at",
        +    "last_start_at",
        +    "last_duration_ms",
        +    "overdue_at",
        +    "notification_cooldown_seconds",
        +    "is_active",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedpause_monitor2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedpost_status_page_update5 fields changed
      • addedInput schema / properties / body / description
        Added value: +"The message subscribers read, 1 to 5000 characters."
      • addedInput schema / properties / incident_id / description
        Added value: +"The status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404."
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • addedInput schema / properties / status / description
        Added value: +"INVESTIGATING, IDENTIFIED, MONITORING or RESOLVED; RESOLVED closes the incident on the page."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "component_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_auto": {
        +      "type": "boolean"
        +    },
        +    "notified_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "resolved_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "started_at": {
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +      "type": "string"
        +    },
        +    "title": {
        +      "type": "string"
        +    },
        +    "updates": {
        +      "items": {
        +        "properties": {
        +          "body": {
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "created_by": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "status",
        +          "body",
        +          "created_by",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "title",
        +    "status",
        +    "is_auto",
        +    "started_at",
        +    "resolved_at",
        +    "notified_at",
        +    "component_ids",
        +    "updates"
        +  ],
        +  "type": "object"
        +}
    • Changedpreview_maintenance_window4 fields changed
      • addedInput schema / properties / dtstart / description
        Added value: +"The first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422."
      • addedInput schema / properties / duration_minutes / description
        Added value: +"How long each occurrence lasts, 1 to 40320 minutes."
      • addedInput schema / properties / rrule / description
        Added value: +"Repeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused. Omit it for a one-time window."
      • addedInput schema / properties / timezone / description
        Added value: +"IANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes. Defaults to the organization's timezone."
    • Changedrename_tag3 fields changed
      • addedInput schema / properties / from / description
        Added value: +"The existing tag, as list_tags shows it."
      • addedInput schema / properties / to / description
        Added value: +"The new name. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "from": {
        +      "type": "string"
        +    },
        +    "heartbeats_updated": {
        +      "type": "integer"
        +    },
        +    "monitors_updated": {
        +      "type": "integer"
        +    },
        +    "to": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    }
        +  },
        +  "required": [
        +    "from",
        +    "monitors_updated",
        +    "heartbeats_updated"
        +  ],
        +  "type": "object"
        +}
    • Changedresume_heartbeat2 fields changed
      • addedInput schema / properties / heartbeat_id / description
        Added value: +"The heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "grace_seconds": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_duration_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_ping_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_start_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_success_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "overdue_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "period_seconds": {
        +      "type": "integer"
        +    },
        +    "ping_url": {
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "state",
        +    "period_seconds",
        +    "grace_seconds",
        +    "ping_url",
        +    "last_ping_at",
        +    "last_success_at",
        +    "last_start_at",
        +    "last_duration_ms",
        +    "overdue_at",
        +    "notification_cooldown_seconds",
        +    "is_active",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedresume_monitor2 fields changed
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedupdate_heartbeat8 fields changed
      • addedInput schema / properties / channel_ids / description
        Added value: +"Notification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404."
      • addedInput schema / properties / grace_seconds / description
        Added value: +"Extra seconds of silence tolerated after the period before the heartbeat is reported late, 0 to 2592000; it may exceed the period."
      • addedInput schema / properties / heartbeat_id / description
        Added value: +"The heartbeat's uuid from list_heartbeats. An id that is not a heartbeat of this organization, or a deleted one, is a 404."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / notification_cooldown_seconds / description
        Added value: +"60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back."
      • addedInput schema / properties / period_seconds / description
        Added value: +"How often the job runs, 60 to 2592000 seconds. To ping every N seconds and be alerted after T seconds of silence, set period_seconds = N and grace_seconds = T - N (T at least N)."
      • addedInput schema / properties / tags / description
        Added value: +"Replaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "grace_seconds": {
        +      "type": "integer"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_duration_ms": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_ping_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_start_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "last_success_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "overdue_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "period_seconds": {
        +      "type": "integer"
        +    },
        +    "ping_url": {
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "Known values: PENDING, UP, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "state",
        +    "period_seconds",
        +    "grace_seconds",
        +    "ping_url",
        +    "last_ping_at",
        +    "last_success_at",
        +    "last_start_at",
        +    "last_duration_ms",
        +    "overdue_at",
        +    "notification_cooldown_seconds",
        +    "is_active",
        +    "created_at",
        +    "updated_at"
        +  ],
        +  "type": "object"
        +}
    • Changedupdate_maintenance_window10 fields changed
      • addedInput schema / properties / dtstart / description
        Added value: +"The first start, an ISO 8601 date-time in the wall-clock time of timezone, for example 2026-10-14T22:00:00. A UTC offset or Z is a 422."
      • addedInput schema / properties / duration_minutes / description
        Added value: +"How long each occurrence lasts, 1 to 40320 minutes."
      • addedInput schema / properties / enabled / description
        Added value: +"false keeps the window but stops it silencing alerts."
      • addedInput schema / properties / monitor_ids / description
        Added value: +"Replaces the list when passed. Monitor uuids from list_monitors, at least one when scope is MONITOR. An id that is not a monitor of this organization is a 404."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / rrule / description
        Added value: +"Repeats the window: one iCal RRULE without the RRULE: prefix, at most 1024 characters, for example FREQ=WEEKLY;BYDAY=SU;BYHOUR=3. Hourly, minutely and secondly frequencies are refused."
      • addedInput schema / properties / scope / description
        Added value: +"ORG covers every monitor of the organization and ignores monitor_ids; MONITOR covers only monitor_ids."
      • addedInput schema / properties / timezone / description
        Added value: +"IANA zone name such as Europe/Berlin, at most 64 characters. The schedule repeats in it, so a weekly 03:00 stays 03:00 across daylight-saving changes."
      • addedInput schema / properties / window_id / description
        Added value: +"The window's uuid from list_maintenance_windows. An id that is not a window of this organization is a 404."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "dtstart": {
        +      "type": "string"
        +    },
        +    "duration_minutes": {
        +      "type": "integer"
        +    },
        +    "enabled": {
        +      "type": "boolean"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "monitor_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "rrule": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "scope": {
        +      "description": "Known values: MONITOR, ORG.",
        +      "type": "string"
        +    },
        +    "timezone": {
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "enabled",
        +    "scope",
        +    "dtstart",
        +    "duration_minutes",
        +    "rrule",
        +    "timezone",
        +    "created_at"
        +  ],
        +  "type": "object"
        +}
    • Changedupdate_monitor12 fields changed
      • addedInput schema / properties / badge_enabled / description
        Added value: +"Turns the monitor's public status badge on or off. A monitor on a published status page has a badge even when it is false."
      • addedInput schema / properties / channel_ids / description
        Added value: +"Notification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404."
      • addedInput schema / properties / config / description
        Added value: +"Replaces the monitor's whole config, not just the keys you send: a field of the type's schema you leave out resets to its default (read the current one with get_monitor first). Sending only port on a TCP monitor whose expected_state is closed resets it to open. A port-list TCP monitor cannot switch to a single port (422). An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state \"open\" (default) or \"closed\", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state \"closed\", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form."
      • addedInput schema / properties / confirmation_threshold / description
        Added value: +"How many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create."
      • addedInput schema / properties / interval_seconds / description
        Added value: +"Seconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit."
      • addedInput schema / properties / monitor_id / description
        Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
      • addedInput schema / properties / name / description
        Added value: +"Display name, 1 to 255 characters."
      • addedInput schema / properties / notification_cooldown_seconds / description
        Added value: +"60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back."
      • addedInput schema / properties / regions / description
        Added value: +"One or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise)."
      • addedInput schema / properties / tags / description
        Added value: +"Replaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates."
      • addedInput schema / properties / timeout_seconds / description
        Added value: +"Seconds one check may take before it fails, 1 to 120."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "badge_enabled": {
        +      "type": "boolean"
        +    },
        +    "channel_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "config": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "confirmation_threshold": {
        +      "type": "integer"
        +    },
        +    "created_at": {
        +      "type": "string"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "interval_seconds": {
        +      "type": "integer"
        +    },
        +    "is_active": {
        +      "type": "boolean"
        +    },
        +    "last_checked_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "name": {
        +      "type": "string"
        +    },
        +    "next_run_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "notification_cooldown_seconds": {
        +      "type": "integer"
        +    },
        +    "region_statuses": {
        +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
        +      "items": {
        +        "properties": {
        +          "checked_at": {
        +            "type": "string"
        +          },
        +          "display_name": {
        +            "type": "string"
        +          },
        +          "region": {
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "region",
        +          "status",
        +          "checked_at",
        +          "display_name"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regions": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "ssl_cert_info": {
        +      "anyOf": [
        +        {
        +          "properties": {
        +            "issuer": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_after": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "not_before": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "subject": {
        +              "anyOf": [
        +                {
        +                  "type": "string"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "valid": {
        +              "anyOf": [
        +                {
        +                  "type": "boolean"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            }
        +          },
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "ssl_expires_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "status": {
        +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "target": {
        +      "type": "string"
        +    },
        +    "timeout_seconds": {
        +      "type": "integer"
        +    },
        +    "type": {
        +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
        +      "type": "string"
        +    },
        +    "updated_at": {
        +      "type": "string"
        +    },
        +    "user_id": {
        +      "format": "uuid",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "user_id",
        +    "name",
        +    "type",
        +    "target",
        +    "interval_seconds",
        +    "timeout_seconds",
        +    "regions",
        +    "config",
        +    "status",
        +    "last_checked_at",
        +    "next_run_at",
        +    "confirmation_threshold",
        +    "notification_cooldown_seconds",
        +    "ssl_expires_at",
        +    "is_active",
        +    "created_at",
        +    "updated_at",
        +    "region_statuses"
        +  ],
        +  "type": "object"
        +}
    • Changedupdate_status_page_incident4 fields changed
      • addedInput schema / properties / incident_id / description
        Added value: +"The status page incident's uuid from list_status_page_incidents (not from list_incidents). An unknown id is a 404."
      • addedInput schema / properties / page_id / description
        Added value: +"The status page's uuid from list_status_pages. An id that is not a status page of this organization is a 404."
      • addedInput schema / properties / title / description
        Added value: +"The new headline, 1 to 255 characters."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "component_ids": {
        +      "items": {
        +        "format": "uuid",
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "id": {
        +      "format": "uuid",
        +      "type": "string"
        +    },
        +    "is_auto": {
        +      "type": "boolean"
        +    },
        +    "notified_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "resolved_at": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "started_at": {
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +      "type": "string"
        +    },
        +    "title": {
        +      "type": "string"
        +    },
        +    "updates": {
        +      "items": {
        +        "properties": {
        +          "body": {
        +            "type": "string"
        +          },
        +          "created_at": {
        +            "type": "string"
        +          },
        +          "created_by": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "id": {
        +            "format": "uuid",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Known values: INVESTIGATING, IDENTIFIED, MONITORING, RESOLVED.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "status",
        +          "body",
        +          "created_by",
        +          "created_at"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "title",
        +    "status",
        +    "is_auto",
        +    "started_at",
        +    "resolved_at",
        +    "notified_at",
        +    "component_ids",
        +    "updates"
        +  ],
        +  "type": "object"
        +}
  2. 49 tool updatesv0.5.4
    • First observedacknowledge_incident
    • First observedbulk_create_monitors
    • First observedbulk_pause_monitors
    • First observedbulk_resume_monitors
    • First observedbulk_update_monitor_tags
    • First observedbulk_update_monitors
    • First observedcheck_now
    • First observedcheck_target
    • First observedcreate_heartbeat
    • First observedcreate_maintenance_window
    • First observedcreate_monitor
    • First observedcreate_status_page_incident
    • First observeddelete_heartbeat
    • First observeddelete_maintenance_window
    • First observeddelete_monitor
    • First observeddelete_status_page_incident
    • First observeddelete_tag
    • First observedget_exposed_ports_preset
    • First observedget_heartbeat
    • First observedget_incident
    • First observedget_maintenance_window
    • First observedget_monitor
    • First observedget_plan_usage
    • First observedget_response_time_by_region
    • First observedget_status_page
    • First observedget_uptime_daily
    • First observedget_uptime_summary
    • First observedlist_active_maintenance
    • First observedlist_channels
    • First observedlist_check_results
    • First observedlist_heartbeats
    • First observedlist_incidents
    • First observedlist_maintenance_windows
    • First observedlist_monitors
    • First observedlist_regions
    • First observedlist_status_page_incidents
    • First observedlist_status_pages
    • First observedlist_tags
    • First observedpause_heartbeat
    • First observedpause_monitor
    • First observedpost_status_page_update
    • First observedpreview_maintenance_window
    • First observedrename_tag
    • First observedresume_heartbeat
    • First observedresume_monitor
    • First observedupdate_heartbeat
    • First observedupdate_maintenance_window
    • First observedupdate_monitor
    • First observedupdate_status_page_incident

TDQS

A4.4/5.0

Scored across 49 tools

Disambiguation5/5

Despite the large number of tools, each has a clearly distinct resource and action, and descriptions explicitly contrast similar operations (e.g., list_active_maintenance vs list_maintenance_windows, check_target vs check_now, list_incidents vs list_status_page_incidents). Overlap is minimal, so an agent can reliably select the right tool.

Naming Consistency5/5

All tool names use snake_case with a predictable verb_noun pattern (list_, get_, create_, update_, delete_, bulk_, pause_, resume_, check_, post_, preview_). Minor variations like bulk_ and post_ are consistent within their families and do not break the pattern.

Tool Count2/5

49 tools is far beyond the typical well-scoped range and places a heavy cognitive load on agents, even though many tools are logically grouped. The server covers a broad domain, but the surface could be consolidated with fewer, more general tools.

Completeness5/5

The surface covers full lifecycle operations for monitors, heartbeats, maintenance windows, incidents, status pages, tags, channels, regions, and check actions, including bulk operations and plan/usage introspection. Missing pieces (e.g., channel/status-page creation) are explicitly delegated to the dashboard, so no critical dead ends remain.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects AI assistants to IonHour uptime monitoring workspaces to manage projects, monitoring checks, and incident responses. It enables users to view reliability metrics, send heartbeats, and manage status pages through natural language.
    8 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to query and monitor service status, latency, and performance through configurable checks (HTTP, TCP, SSL, keyword, JSON-path) and exposes tools for listing services, retrieving metrics, and running on-demand checks.
    Apache 2.0