+ {/* px-2 like a ghost control so the dot sits on the text column */}
+
{postmortem ? (
-
+
+
{approved ? "Approved" : "Draft"}
-
+
) : null}
- {hint ? {hint} : null}
+ {hint ? {hint} : null}
-
-
- save.mutate({ id: incident.id, content, draftedBy: "user" })
- }
- >
- Save
-
- {canApprove ? (
- <>
-
approve.mutate({ id: incident.id })}
+
+
+
+ {postmortem ? (
+
+ copy(content, { withToast: "Postmortem copied" })
+ }
>
- Approve
-
- setConfirmClose(true)}
+ {isCopied ? : }
+
+ ) : null}
+ {showAgent ? (
+ draftWithAgent.mutate({ id: incident.id })}
>
- Approve & close
-
-
- approve.mutate({ id: incident.id, close: true })
- }
- />
- >
- ) : null}
-
+ {draftWithAgent.isPending ? (
+
+ ) : (
+
+ )}
+
+ ) : null}
+
+ {/* Three verbs that differ in consequence; icons alone would not tell them apart. */}
+
+
+ save.mutate({ id: incident.id, content, draftedBy: "user" })
+ }
+ >
+ Save
+
+ {canApprove ? (
+ <>
+ approve.mutate({ id: incident.id })}
+ >
+ Approve
+
+ setConfirmClose(true)}
+ >
+ Approve & close
+
+
+ approve.mutate({ id: incident.id, close: true })
+ }
+ />
+ >
+ ) : null}
+
+
);
diff --git a/apps/dashboard/src/components/incidents/incident-timeline.tsx b/apps/dashboard/src/components/incidents/incident-timeline.tsx
index 0992b8650..933d46808 100644
--- a/apps/dashboard/src/components/incidents/incident-timeline.tsx
+++ b/apps/dashboard/src/components/incidents/incident-timeline.tsx
@@ -2,7 +2,6 @@
import type { RouterOutputs } from "@openstatus/api";
import {
- type IncidentEventType,
type IncidentSeverity,
type IncidentStatus,
incidentSeverity,
@@ -18,177 +17,326 @@ import {
FileText,
type IconType,
Impact,
+ Incident,
Linked,
Lock,
Plug,
Unlinked,
- Warning,
} from "@openstatus/icons";
import { SlackIcon } from "@openstatus/icons/brand";
import { personName } from "@openstatus/utils";
+import { format } from "date-fns";
+import Link from "next/link";
-import type { StatusVariant } from "@/components/common/status-dot";
import { ProcessMessage } from "@/components/content/process-message";
import {
TimelineActor,
- TimelineActorTooltip,
- TimelineAvatar,
- TimelineAvatarBadge,
TimelineBody,
- TimelineContent,
+ TimelineCard,
TimelineHeader,
+ TimelineHighlight,
TimelineIndicator,
TimelineItem,
- TimelineMeta,
TimelineTime,
- TimelineTitle,
} from "@/components/content/timeline";
-import { severityConfig, statusConfig } from "@/data/managed-incidents.client";
import { IncidentSeverityBadge, IncidentStatusBadge } from "./incident-badge";
type Event = NonNullable
[number];
+type Incident = NonNullable;
-const eventConfig: Record<
- IncidentEventType,
- { label: string; icon: IconType; variant?: StatusVariant }
-> = {
- declared: { label: "Declared", icon: Warning, variant: "warning" },
- severity_changed: { label: "Severity changed", icon: Impact },
- status_changed: { label: "Status changed", icon: Compare },
- commander_changed: { label: "Commander changed", icon: Account },
- started_at_changed: { label: "Start time changed", icon: Clock },
- note: { label: "Note", icon: Chat },
- status_report_linked: { label: "Status report linked", icon: Linked },
- status_report_unlinked: { label: "Status report unlinked", icon: Unlinked },
- slack_channel_bound: { label: "Slack channel bound", icon: Plug },
- slack_channel_unbound: { label: "Slack channel unbound", icon: Plug },
- mitigated: { label: "Mitigated", icon: Check, variant: "warning" },
- resolved: { label: "Resolved", icon: Check, variant: "success" },
- canceled: { label: "Canceled", icon: Close },
- postmortem_drafted: { label: "Postmortem drafted", icon: FileText },
- postmortem_updated: { label: "Postmortem updated", icon: FileText },
- postmortem_approved: {
- label: "Postmortem approved",
- icon: FileText,
- variant: "success",
- },
- closed: { label: "Closed", icon: Lock },
-};
+// `team` is optional for app_redirect; without it Slack uses the signed-in one.
+function slackChannelUrl(teamId: string | null, channelId: string): string {
+ const params = new URLSearchParams({ channel: channelId });
+ if (teamId) params.set("team", teamId);
+ return `https://slack.com/app_redirect?${params}`;
+}
const TRANSITION = /^\w+ changed from \w+ to (\w+)(?:\n\n([\s\S]+))?$/;
const DECLARED = /^Declared as (\w+): /;
+const COMMANDER = /^Commander set to (.+)$/;
+const STARTED_AT = /^Start time changed to (\S+)$/;
+const REPORT = /^(?:Linked|Unlinked) status report #(\d+)$/;
+const CHANNEL = /<#([A-Z0-9]+)>/;
// Slack-mirrored notes end with a permalink line appended by the bot.
const FROM_SLACK = /\n\n\[From Slack\]\((https?:\/\/\S+)\)$/;
+// Events without a user come from the service itself.
+const SYSTEM = { name: "System", email: null };
+// Service placeholders when a transition carried no note.
+const DEFAULT_NOTES = new Set(["Incident resolved", "Incident canceled"]);
-// Events carry no structured payload, so the target of a transition is read
-// from the service's own message. An unknown shape falls back to the raw text.
-function parseEvent(event: Event): {
+type Parsed = {
+ icon: IconType;
+ /** The sentence after the actor; `null` for a bare post. */
+ phrase: React.ReactNode;
+ /** Id read from a linked/unlinked message. */
+ reportId?: number;
status?: IncidentStatus;
severity?: IncidentSeverity;
+ /** Authored text, rendered as a card. */
message: string | null;
slackUrl?: string;
-} {
- const message = event.message;
- if (!message) return { message: null };
+ /** Channel id read from a bound/unbound message. */
+ channelId?: string;
+ /** Message text that already carries the actor's name. */
+ agent?: boolean;
+};
- if (event.type === "note") {
- const match = FROM_SLACK.exec(message);
- if (match) {
- return { message: message.replace(FROM_SLACK, ""), slackUrl: match[1] };
+// Events carry no structured payload, so the subject of a change is read back
+// from the service's own message. An unknown shape falls back to the raw text.
+function parseEvent(event: Event): Parsed {
+ const message = event.message;
+ switch (event.type) {
+ case "note": {
+ const match = message ? FROM_SLACK.exec(message) : null;
+ return {
+ icon: Chat,
+ phrase: null,
+ message: message?.replace(FROM_SLACK, "") ?? null,
+ slackUrl: match?.[1],
+ };
}
+ case "declared": {
+ const severity = incidentSeverity.find(
+ (s) => s === (message ? DECLARED.exec(message)?.[1] : undefined),
+ );
+ return {
+ icon: Incident,
+ phrase: severity ? "declared the incident as" : "declared the incident",
+ severity,
+ message: severity ? null : message,
+ };
+ }
+ case "status_changed":
+ case "mitigated": {
+ const match = message ? TRANSITION.exec(message) : null;
+ const status = incidentStatus.find((s) => s === match?.[1]);
+ return {
+ icon: Compare,
+ phrase: "marked",
+ status:
+ status ?? (event.type === "mitigated" ? "mitigated" : undefined),
+ message: match ? (match[2] ?? null) : message,
+ };
+ }
+ case "resolved":
+ case "canceled":
+ return {
+ icon: event.type === "resolved" ? Check : Close,
+ phrase: "marked",
+ status: event.type,
+ message: message && !DEFAULT_NOTES.has(message) ? message : null,
+ };
+ case "severity_changed": {
+ const match = message ? TRANSITION.exec(message) : null;
+ const severity = incidentSeverity.find((s) => s === match?.[1]);
+ return {
+ icon: Impact,
+ phrase: "changed the severity to",
+ severity,
+ message: match ? (match[2] ?? null) : message,
+ };
+ }
+ case "commander_changed": {
+ const name = message ? COMMANDER.exec(message)?.[1] : undefined;
+ return {
+ icon: Account,
+ phrase: name ? (
+ <>
+ set the commander to {name}
+ >
+ ) : (
+ "removed the commander"
+ ),
+ message: null,
+ };
+ }
+ case "started_at_changed": {
+ const iso = message ? STARTED_AT.exec(message)?.[1] : undefined;
+ const date = iso ? new Date(iso) : null;
+ return {
+ icon: Clock,
+ phrase:
+ date && !Number.isNaN(date.getTime()) ? (
+ <>
+ changed the start time to{" "}
+
+ {format(date, "LLL dd, HH:mm")}
+
+ >
+ ) : (
+ "changed the start time"
+ ),
+ message: null,
+ };
+ }
+ case "status_report_linked":
+ case "status_report_unlinked": {
+ const id = message ? REPORT.exec(message)?.[1] : undefined;
+ const verb =
+ event.type === "status_report_linked" ? "linked" : "unlinked";
+ return {
+ icon: event.type === "status_report_linked" ? Linked : Unlinked,
+ phrase: `${verb} status report`,
+ reportId: id ? Number(id) : undefined,
+ message: null,
+ };
+ }
+ // The message names the channel; the link follows it rather than the
+ // incident's current binding, which may be gone or a different channel.
+ case "slack_channel_bound":
+ case "slack_channel_unbound": {
+ const channelId = message ? CHANNEL.exec(message)?.[1] : undefined;
+ return {
+ icon: Plug,
+ phrase:
+ event.type === "slack_channel_bound" ? "bound the" : "unbound the",
+ message: null,
+ channelId,
+ };
+ }
+ case "postmortem_drafted":
+ case "postmortem_updated":
+ case "postmortem_approved": {
+ const agent = message?.includes("by the agent") ?? false;
+ const verb =
+ event.type === "postmortem_approved"
+ ? "approved"
+ : event.type === "postmortem_updated"
+ ? "edited"
+ : agent
+ ? "drafted"
+ : message?.startsWith("Postmortem draft updated")
+ ? "edited"
+ : "drafted";
+ return {
+ icon: FileText,
+ phrase: (
+ <>
+ {verb} the postmortem
+ >
+ ),
+ message: null,
+ agent,
+ };
+ }
+ case "closed":
+ return { icon: Lock, phrase: "closed the incident", message: null };
}
-
- // The message only repeats the label around a raw Slack channel id.
- if (
- event.type === "slack_channel_bound" ||
- event.type === "slack_channel_unbound"
- ) {
- return { message: null };
- }
- if (event.type === "status_changed") {
- const match = TRANSITION.exec(message);
- const status = incidentStatus.find((s) => s === match?.[1]);
- if (status) return { status, message: match?.[2] ?? null };
- }
- if (event.type === "severity_changed") {
- const match = TRANSITION.exec(message);
- const severity = incidentSeverity.find((s) => s === match?.[1]);
- if (severity) return { severity, message: match?.[2] ?? null };
- }
- if (event.type === "declared") {
- const severity = incidentSeverity.find(
- (s) => s === DECLARED.exec(message)?.[1],
- );
- if (severity) return { severity, message: null };
- }
- return { message };
}
-/** One event as a `TimelineItem`; the page composes the `Timeline` around it. */
-export function IncidentTimelineItem({ event }: { event: Event }) {
- const config = eventConfig[event.type];
- const { status, severity, message, slackUrl } = parseEvent(event);
- const variant = status
- ? statusConfig[status].variant
- : event.type === "declared" && severity
- ? severityConfig[severity].variant
- : config.variant;
+/**
+ * One event as a `TimelineItem`; the page composes the `Timeline` around it.
+ * `incident` resolves a report id in the message to the report still linked
+ * today (older ones stay as plain ids) and supplies the Slack team for the
+ * channel link, whose channel id is read from the event message.
+ */
+export function IncidentTimelineItem({
+ event,
+ incident,
+}: {
+ event: Event;
+ incident: Pick;
+}) {
+ const {
+ icon: Icon,
+ phrase,
+ status,
+ severity,
+ message,
+ slackUrl,
+ channelId,
+ agent,
+ reportId,
+ } = parseEvent(event);
const user = event.createdByUser;
const actor = user
? { name: personName(user), email: user.email, photoUrl: user.photoUrl }
- : null;
- // Notes are authored, so the author leads the row; state changes keep the
- // colored indicator and show the actor inline.
- const authored = event.type === "note" && actor;
- return (
-
- {authored ? (
-
-
-
-
-
-
-
+ : SYSTEM;
+ const compact = message === null;
+ const report =
+ reportId !== undefined && incident.statusReport?.id === reportId
+ ? incident.statusReport
+ : null;
+ const channelUrl =
+ event.type === "slack_channel_bound" ||
+ event.type === "slack_channel_unbound"
+ ? channelId
+ ? slackChannelUrl(incident.slackTeamId, channelId)
+ : null
+ : undefined;
+
+ const sentence = (
+ <>
+ {agent ? (
+
+ Agent
+
) : (
-
-
-
+
)}
-
-
-
- {config.label}
- {status ? : null}
- {severity ? : null}
- {authored ? null : actor ? (
-
- ) : (
- System
- )}
- {slackUrl ? (
-
-
-
- via Slack
-
-
- ) : null}
-
-
-
- {message ? (
-
-
-
- ) : null}
-
+ {phrase ?? "posted"}
+ {report ? (
+
+
+ #{report.id}
+
+
+ ) : reportId !== undefined ? (
+ #{reportId}
+ ) : null}
+ {channelUrl === undefined ? null : channelUrl ? (
+
+
+ Slack channel
+
+
+ ) : (
+ Slack channel
+ )}
+ {status ? : null}
+ {severity ? (
+
+ ) : null}
+
+ >
+ );
+
+ if (compact) {
+ return (
+
+
+
+
+ {sentence}
+
+ );
+ }
+ return (
+
+
+ {sentence}
+
+
+
+
);
}
diff --git a/apps/dashboard/src/components/maintenances/maintenance-components.tsx b/apps/dashboard/src/components/maintenances/maintenance-components.tsx
index 28b67bc87..828df6bd1 100644
--- a/apps/dashboard/src/components/maintenances/maintenance-components.tsx
+++ b/apps/dashboard/src/components/maintenances/maintenance-components.tsx
@@ -50,7 +50,7 @@ export function MaintenanceComponents({
@@ -71,7 +71,6 @@ export function MaintenanceComponents({
)}
(null);
@@ -71,61 +71,40 @@ export function MaintenanceUpdateComposer({
return (
-
-
-
+
setMessage(e.target.value)}
onSubmit={() => submit().catch(console.error)}
/>
- Posted
+ Posted
-
-
- setNotifyChecked(value === true)}
- />
-
- Notify subscribers
-
-
-
+
+
+ submit().catch(console.error)}
- >
- Publish update
-
-
+ />
+
diff --git a/apps/dashboard/src/components/maintenances/maintenance-update-timeline.tsx b/apps/dashboard/src/components/maintenances/maintenance-update-timeline.tsx
index f6fae2163..8c8e2cb35 100644
--- a/apps/dashboard/src/components/maintenances/maintenance-update-timeline.tsx
+++ b/apps/dashboard/src/components/maintenances/maintenance-update-timeline.tsx
@@ -3,24 +3,26 @@
import type { RouterOutputs } from "@openstatus/api";
import { Maintenance as MaintenanceIcon } from "@openstatus/icons";
import { useMutation } from "@tanstack/react-query";
+import { format } from "date-fns";
import { useState } from "react";
import { ProcessMessage } from "@/components/content/process-message";
import {
+ TimelineActions,
TimelineActor,
TimelineBody,
- TimelineContent,
+ TimelineCard,
TimelineHeader,
+ TimelineHighlight,
TimelineIndicator,
TimelineItem,
- TimelineMeta,
TimelineTime,
- TimelineTitle,
} from "@/components/content/timeline";
import { QuickActions } from "@/components/dropdowns/quick-actions";
import { FormSheetMaintenanceUpdate } from "@/components/forms/maintenance-update/sheet";
import { distinctEditor } from "@/data/attribution.client";
import { getActions } from "@/data/maintenances.client";
+import { useHydrated } from "@/hooks/use-hydrated";
import { useTRPC } from "@/lib/trpc/client";
import { useInvalidateMaintenance } from "./use-invalidate-maintenance";
@@ -52,38 +54,43 @@ export function MaintenanceUpdateTimelineItem({
return (
-
-
-
-
+
-
- Update
- {author ? : null}
- {editor ? (
-
- edited by
-
- ) : null}
-
+ {author ? (
+ <>
+ posted
+ >
+ ) : (
+ "Posted"
+ )}
+ {editor ? (
+ <>
+ · edited by
+ >
+ ) : null}
+
+ #{index}
+ setEditing(true) })}
+ deleteAction={
+ // a maintenance keeps at least one update; delete it instead
+ maintenance.updates.length > 1
+ ? {
+ description: `Permanently remove update #${index} from the status page.`,
+ submitAction: async () => {
+ await remove.mutateAsync({ id: update.id });
+ },
+ }
+ : undefined
+ }
+ />
+
-
+
-
- #{index}
- setEditing(true) })}
- deleteAction={{
- description: `Permanently remove update #${index} from the status page.`,
- submitAction: async () => {
- await remove.mutateAsync({ id: update.id });
- },
- }}
- />
-
-
+
);
}
+
+/** Closing row: who scheduled the window, and when it runs. */
+export function MaintenanceScheduledTimelineItem({
+ maintenance,
+}: {
+ maintenance: Maintenance;
+}) {
+ // local-time text differs between server and browser
+ const hydrated = useHydrated();
+ return (
+
+
+
+
+
+ {maintenance.createdByUser ? (
+ <>
+ scheduled the
+ maintenance for
+ >
+ ) : (
+ "Maintenance scheduled for"
+ )}
+
+ {hydrated
+ ? `${format(maintenance.from, "LLL dd, HH:mm")} – ${format(maintenance.to, "LLL dd, HH:mm")}`
+ : null}
+
+ {maintenance.createdAt ? (
+
+ ) : null}
+
+
+ );
+}
diff --git a/apps/dashboard/src/components/status-reports/status-report-composer.tsx b/apps/dashboard/src/components/status-reports/status-report-composer.tsx
index dd7183cc3..c39ccb907 100644
--- a/apps/dashboard/src/components/status-reports/status-report-composer.tsx
+++ b/apps/dashboard/src/components/status-reports/status-report-composer.tsx
@@ -7,10 +7,22 @@ import {
pageComponentImpact,
} from "@openstatus/db/src/schema/page_components/constants";
import { statusReportStatus } from "@openstatus/db/src/schema/status_reports/constants";
-import { Close } from "@openstatus/icons";
+import { Close, Components } from "@openstatus/icons";
import { Button } from "@openstatus/ui/components/ui/button";
-import { Checkbox } from "@openstatus/ui/components/ui/checkbox";
-import { Label } from "@openstatus/ui/components/ui/label";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+ CommandSeparator,
+} from "@openstatus/ui/components/ui/command";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@openstatus/ui/components/ui/popover";
import {
Select,
SelectContent,
@@ -18,8 +30,12 @@ import {
SelectTrigger,
SelectValue,
} from "@openstatus/ui/components/ui/select";
-import { personName } from "@openstatus/utils";
-import { useQuery } from "@tanstack/react-query";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@openstatus/ui/components/ui/tooltip";
+import { cn } from "@openstatus/ui/lib/utils";
import { useState } from "react";
import { toast } from "sonner";
@@ -29,44 +45,46 @@ import {
ComponentImpact,
ComponentList,
ComponentListActions,
- ComponentListAdd,
ComponentListItem,
ComponentListName,
ComponentListSelectTrigger,
} from "@/components/content/component-list";
import {
Composer,
+ ComposerActions,
ComposerFooter,
- ComposerHeader,
+ ComposerIconButton,
+ composerControlClassName,
+ ComposerNotifyToggle,
ComposerPreview,
+ ComposerPreviewToggle,
ComposerSection,
+ ComposerSubmit,
ComposerTextarea,
+ useComposerDraft,
} from "@/components/content/composer";
-import { TimelineAvatar, TimelineItem } from "@/components/content/timeline";
-import { toGroupNameLookup } from "@/data/page-components.client";
+import { TimelineItem } from "@/components/content/timeline";
+import {
+ type OrderedComponent,
+ toComponentSections,
+ toGroupNameLookup,
+} from "@/data/page-components.client";
import {
getNextStatus,
statusVariants,
toCreateStatusReportUpdateInput,
+ impactDisplay,
} from "@/data/status-report-updates.client";
-import { useTRPC } from "@/lib/trpc/client";
import { errorMessage } from "@/lib/trpc/error";
import { usePublishUpdate } from "./use-publish-update";
type StatusReport = NonNullable;
-type Component = {
- id: number;
- name: string;
- groupId?: number | null;
- order?: number | null;
- groupOrder?: number | null;
-};
/**
* Publishes a status report update. Impact rows default to "No change"
- * (carry the current impact; all operational once resolved); switching
- * status resets the overrides.
+ * (carry the current impact; all operational once resolved); a picked value
+ * reads in the foreground. Switching status resets the overrides.
*/
export function StatusReportComposer({
report,
@@ -78,14 +96,12 @@ export function StatusReportComposer({
report: StatusReport;
currentImpacts: Map;
/** Every component on the page; the ones not on the report can be added. */
- pageComponents: Component[];
+ pageComponents: OrderedComponent[];
groups: { id: number; name: string }[];
/** Whether the plan includes subscriber notifications. */
canNotify: boolean;
}) {
- const trpc = useTRPC();
- const { data: user } = useQuery(trpc.user.get.queryOptions());
- const [message, setMessage] = useState("");
+ const [message, setMessage] = useComposerDraft(`status-report:${report.id}`);
const [notifyChecked, setNotifyChecked] = useState(true);
const [selected, setSelected] = useState(null);
// null = now, resolved at publish time so an open composer never backdates.
@@ -104,7 +120,7 @@ export function StatusReportComposer({
const invalidDate = date !== null && date > new Date();
const disabled = publish.isPending || !message.trim() || invalidDate;
- const byId = new Map(
+ const byId = new Map(
[...report.pageComponents, ...pageComponents].map((c) => [c.id, c]),
);
const componentIds = ids ?? report.pageComponents.map((c) => c.id);
@@ -158,60 +174,61 @@ export function StatusReportComposer({
return (
-
-
-
+
setMessage(e.target.value)}
onSubmit={() => submit().catch(console.error)}
/>
- {pageComponents.length ? (
+ {components.length ? (
-
-
- Affected components
-
-
- setOverrides(
- new Map(components.map((c) => [c.id, "operational"])),
- )
- }
- >
- Mark all operational
-
-
{components.map((component) => {
+ const current = currentImpacts.get(component.id);
const override = overrides.get(component.id);
+ const effective = impactFor(component.id);
+ // a legacy row (no current impact) only changes once a value is picked
+ const changed = current
+ ? effective !== current
+ : override !== undefined;
+ // legacy rows stay unselected until picked, see "No change"
+ const selectValue = current ? effective : (override ?? "");
+ const value = changed ? (
+
+ ) : current ? (
+
+ ) : (
+
+
+ No change
+
+ );
return (
+ {/* where the component stands now; the picker on the right is where it goes */}
+
{component.name}
-
{
const impact = pageComponentImpact.find(
(i) => i === value,
@@ -224,25 +241,10 @@ export function StatusReportComposer({
>
-
- ) : (
-
-
- No change
-
- )
- }
- />
+ {value}
{pageComponentImpact.map((impact) => (
@@ -252,11 +254,8 @@ export function StatusReportComposer({
))}
-
setIds(
componentIds.filter((id) => id !== component.id),
@@ -264,32 +263,16 @@ export function StatusReportComposer({
}
>
-
+
);
})}
- {
- setIds([...componentIds, id]);
- // a component joins the report with a concrete impact
- if (!report.pageComponents.some((c) => c.id === id)) {
- setOverrides((prev) =>
- new Map(prev).set(id, "degraded_performance"),
- );
- }
- }}
- />
) : null}
- {/* phones: label column + field column so both fields share a left edge */}
-
-
Status
+
{
@@ -302,7 +285,7 @@ export function StatusReportComposer({
@@ -315,47 +298,158 @@ export function StatusReportComposer({
))}
- at
-
-
-
-
- setNotifyChecked(value === true)}
+ {/* "at" wraps together with its date on phones */}
+
+ at
+
-
+
+
+
+ {
+ setIds([...componentIds, id]);
+ // a component joins the report with a concrete impact
+ if (!report.pageComponents.some((c) => c.id === id)) {
+ setOverrides((prev) =>
+ new Map(prev).set(id, "degraded_performance"),
+ );
}
- >
- Notify subscribers
-
-
-
1 &&
+ components.some((c) => impactFor(c.id) !== "operational")
+ ? () =>
+ setOverrides(
+ new Map(components.map((c) => [c.id, "operational"])),
+ )
+ : undefined
+ }
+ />
+
+ submit().catch(console.error)}
- >
- Publish update
-
-
+ />
+
);
}
+
+/**
+ * Footer icon button for the affected components: a searchable picker of
+ * the page's components not yet on the update, plus the bulk restore when
+ * the composer offers one. Disabled with nothing to offer; always titled.
+ */
+function ComponentsMenu({
+ addable,
+ groups,
+ onAdd,
+ onMarkAllOperational,
+}: {
+ addable: OrderedComponent[];
+ groups: { id: number; name: string }[];
+ onAdd: (id: number) => void;
+ onMarkAllOperational?: () => void;
+}) {
+ const [open, setOpen] = useState(false);
+ const sections = toComponentSections(addable, groups);
+ const disabled = addable.length === 0 && !onMarkAllOperational;
+ const label = addable.length
+ ? "Add component"
+ : onMarkAllOperational
+ ? "Affected components"
+ : "All components added";
+
+ return (
+
+
+
+
+ {/* aria-disabled (not disabled) so the tooltip still explains why */}
+ {
+ if (disabled) e.preventDefault();
+ }}
+ >
+
+
+
+
+ {label}
+
+
+
+ {addable.length ? (
+
+ ) : null}
+
+ No components found.
+ {onMarkAllOperational ? (
+
+ {
+ onMarkAllOperational();
+ setOpen(false);
+ }}
+ >
+
+ Mark all operational
+
+
+ ) : null}
+ {onMarkAllOperational && sections.length ? (
+
+ ) : null}
+ {sections.map((section, i) => (
+
+ {section.items.map((c) => (
+ {
+ onAdd(c.id);
+ setOpen(false);
+ }}
+ >
+ {c.name}
+
+ ))}
+
+ ))}
+
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/components/status-reports/status-report-timeline.tsx b/apps/dashboard/src/components/status-reports/status-report-timeline.tsx
index 4ef95cc1d..9dfe7fd34 100644
--- a/apps/dashboard/src/components/status-reports/status-report-timeline.tsx
+++ b/apps/dashboard/src/components/status-reports/status-report-timeline.tsx
@@ -1,15 +1,8 @@
"use client";
import type { RouterOutputs } from "@openstatus/api";
-import {
- type PageComponentImpact,
- worstImpact,
-} from "@openstatus/db/src/schema/page_components/constants";
-import {
- HoverCard,
- HoverCardContent,
- HoverCardTrigger,
-} from "@openstatus/ui/components/ui/hover-card";
+import type { PageComponentImpact } from "@openstatus/db/src/schema/page_components/constants";
+import { Report } from "@openstatus/icons";
import { useMutation } from "@tanstack/react-query";
import { useState } from "react";
@@ -19,76 +12,54 @@ import {
} from "@/components/content/component-list";
import { ProcessMessage } from "@/components/content/process-message";
import {
+ TimelineActions,
TimelineActor,
TimelineBody,
- TimelineContent,
+ TimelineCard,
+ TimelineFooter,
TimelineHeader,
+ TimelineHighlight,
TimelineIndicator,
TimelineItem,
- TimelineMeta,
TimelineTime,
- TimelineTitle,
} from "@/components/content/timeline";
import { QuickActions } from "@/components/dropdowns/quick-actions";
import { FormSheetStatusReportUpdate } from "@/components/forms/status-report-update/sheet";
import { distinctEditor } from "@/data/attribution.client";
-import { icons } from "@/data/icons";
-import {
- getActions,
- impactsEqual,
- statusVariants,
-} from "@/data/status-report-updates.client";
+import { getActions, impactsEqual } from "@/data/status-report-updates.client";
+import { reportStartedAt } from "@/data/status-reports.client";
import { useTRPC } from "@/lib/trpc/client";
-import { StatusReportImpactBadge } from "./status-report-badge";
+import { StatusReportStatusBadge } from "./status-report-badge";
import { useInvalidateStatusReport } from "./use-invalidate-status-report";
type StatusReport = NonNullable;
type StatusReportUpdate = StatusReport["updates"][number];
-/** Worst impact of the update; hover lists each component's own impact. */
-function TimelineImpact({
- impacts,
-}: {
- impacts: {
- id: number;
- name: string;
- group?: string;
- impact: PageComponentImpact;
- }[];
-}) {
- const worst = worstImpact(impacts.map((i) => i.impact));
- return (
-
-
-
-
-
-
- {impacts.map((ci) => (
-
- {ci.name}
-
-
- ))}
-
-
-
+// Components whose impact this update moved against `before`, the state the
+// older updates left behind (an omitted component keeps its last impact). A
+// page starts operational, so the first update lists everything it degraded
+// and a resolve lists what it restored. Legacy updates carry no rows.
+function changedImpacts(
+ update: StatusReportUpdate,
+ before: ReadonlyMap,
+): { pageComponentId: number; impact: PageComponentImpact }[] {
+ return update.componentImpacts.filter(
+ (ci) => ci.impact !== (before.get(ci.pageComponentId) ?? "operational"),
);
}
export function StatusReportTimelineItem({
report,
update,
+ before,
index,
groupOf,
}: {
report: StatusReport;
update: StatusReportUpdate;
+ /** Impact per component as the older updates left it. */
+ before: ReadonlyMap;
/** 1-based, counted from the oldest update. */
index: number;
/** component id → group name, for disambiguating same-named components */
@@ -109,62 +80,70 @@ export function StatusReportTimelineItem({
id: c.id,
name: c.name,
}));
- const Icon = icons.status[update.status];
- // Every update is a status change, so the colored indicator keeps the rail
- // and the author sits inline, as on incident state-change rows.
const author = update.createdByUser;
const editor = distinctEditor(update);
- const impacts = update.componentImpacts.flatMap((ci) => {
+ const changes = changedImpacts(update, before).flatMap((ci) => {
const component = components.find((c) => c.id === ci.pageComponentId);
- return component
- ? [
- {
- id: component.id,
- name: component.name,
- group: groupOf?.get(component.id),
- impact: ci.impact,
- },
- ]
- : [];
+ return component ? [{ ...component, impact: ci.impact }] : [];
});
return (
-
-
-
-
+
-
- {update.status}
- {impacts.length ? : null}
- {author ? : null}
- {editor ? (
-
- edited by
-
- ) : null}
-
+ {author ? (
+ <>
+ posted
+ >
+ ) : (
+ "Posted"
+ )}
+
+ {editor ? (
+ <>
+ · edited by
+ >
+ ) : null}
+
+ #{index}
+ setEditing(true) })}
+ deleteAction={
+ // a report keeps at least one update; delete the report instead
+ report.updates.length > 1
+ ? {
+ description: `Permanently remove update #${index}. The report status is recomputed from the remaining updates.`,
+ submitAction: async () => {
+ await remove.mutateAsync({ id: update.id });
+ },
+ }
+ : undefined
+ }
+ />
+
{update.message ? (
-
+
) : null}
-
- #{index}
- setEditing(true) })}
- deleteAction={{
- description: `Permanently remove update #${index}. The report status is recomputed from the remaining updates.`,
- submitAction: async () => {
- await remove.mutateAsync({ id: update.id });
- },
- }}
- />
-
-
+ {changes.length ? (
+
+ {changes.map((c) => (
+
+
+ {c.name}
+
+
+
+ ))}
+
+ ) : null}
+
);
}
+
+/** Closing row: who opened the report, and on which page. */
+export function StatusReportOpenedTimelineItem({
+ report,
+}: {
+ report: StatusReport;
+}) {
+ return (
+
+
+
+
+
+ {report.createdByUser ? (
+ <>
+ opened the report on
+ >
+ ) : (
+ "Report opened on"
+ )}
+ {report.page.title}
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/data/page-components.client.ts b/apps/dashboard/src/data/page-components.client.ts
index 3beeb7bad..c97fc4f31 100644
--- a/apps/dashboard/src/data/page-components.client.ts
+++ b/apps/dashboard/src/data/page-components.client.ts
@@ -20,7 +20,8 @@ export const getActions = (
}));
};
-type OrderedComponent = {
+/** A page component with enough ordering info to list it in page order. */
+export type OrderedComponent = {
id: number;
name: string;
groupId?: number | null;
diff --git a/apps/server/src/routes/mcp/evals/run.ts b/apps/server/src/routes/mcp/evals/run.ts
index 13eeac008..0a96425e6 100644
--- a/apps/server/src/routes/mcp/evals/run.ts
+++ b/apps/server/src/routes/mcp/evals/run.ts
@@ -156,7 +156,7 @@ const tools = {
}),
list_incidents: tool({
description:
- "List managed incidents in this workspace (declared by the team, not monitor downtime), open ones first.",
+ "List managed incidents in this workspace (declared by the team, not monitor downtime), newest declared first. Filter by `status` to see only open ones.",
inputSchema: z.object({
status: z
.array(z.enum(["open", "mitigated", "resolved", "canceled"]))
diff --git a/apps/server/src/routes/mcp/handler.test.ts b/apps/server/src/routes/mcp/handler.test.ts
index d843a3576..c4a86c77a 100644
--- a/apps/server/src/routes/mcp/handler.test.ts
+++ b/apps/server/src/routes/mcp/handler.test.ts
@@ -127,6 +127,7 @@ describe("MCP transport", () => {
"create_status_report",
"declare_incident",
"delete_maintenance_update",
+ "delete_status_report_update",
"draft_postmortem",
"get_audit_log",
"get_content_page",
@@ -137,6 +138,7 @@ describe("MCP transport", () => {
"get_monitor_summary",
"get_postmortem",
"get_response_log",
+ "get_status_report",
"list_audit_logs",
"list_incidents",
"list_maintenances",
@@ -155,6 +157,7 @@ describe("MCP transport", () => {
"update_incident",
"update_maintenance_update",
"update_status_report",
+ "update_status_report_update",
]);
});
diff --git a/apps/server/src/routes/mcp/tools/status-report.ts b/apps/server/src/routes/mcp/tools/status-report.ts
index ca5f7a450..b712cadcf 100644
--- a/apps/server/src/routes/mcp/tools/status-report.ts
+++ b/apps/server/src/routes/mcp/tools/status-report.ts
@@ -6,9 +6,12 @@ import type { ServiceContext } from "@openstatus/services";
import {
addStatusReportUpdateTool,
createStatusReportTool,
+ deleteStatusReportUpdateTool,
+ getStatusReportTool,
listStatusReportsTool,
resolveStatusReportTool,
updateStatusReportTool,
+ updateStatusReportUpdateTool,
} from "@openstatus/services/agent-tools";
import { registerRegistryTools } from "./registry-adapter";
@@ -19,9 +22,12 @@ export function registerStatusReportTools(
): Map {
return registerRegistryTools(server, ctx, [
listStatusReportsTool,
+ getStatusReportTool,
createStatusReportTool,
addStatusReportUpdateTool,
updateStatusReportTool,
resolveStatusReportTool,
+ updateStatusReportUpdateTool,
+ deleteStatusReportUpdateTool,
]);
}
diff --git a/apps/server/src/routes/mcp/tools/tools.test.ts b/apps/server/src/routes/mcp/tools/tools.test.ts
index 6755d1874..deb3d239f 100644
--- a/apps/server/src/routes/mcp/tools/tools.test.ts
+++ b/apps/server/src/routes/mcp/tools/tools.test.ts
@@ -236,6 +236,133 @@ describe("list_status_reports", () => {
expect(ids).not.toContain(resolved.id);
});
});
+
+ test("returns the full timeline newest-first with update ids", async () => {
+ await withTestTransaction(async (tx) => {
+ const sr = await tx
+ .insert(statusReport)
+ .values({
+ workspaceId: teamWorkspace.id,
+ pageId: testPageId,
+ title: `${TEST_PREFIX}-timeline`,
+ status: "identified",
+ })
+ .returning()
+ .get();
+ // RETURNING order is unspecified, so pick the rows by date
+ const rows = await tx
+ .insert(statusReportUpdate)
+ .values([
+ {
+ statusReportId: sr.id,
+ status: "investigating",
+ message: "first",
+ date: new Date("2026-01-01T00:00:00Z"),
+ },
+ {
+ statusReportId: sr.id,
+ status: "identified",
+ message: "second",
+ date: new Date("2026-01-02T00:00:00Z"),
+ },
+ ])
+ .returning()
+ .all();
+ const [older, newer] = [...rows].sort(
+ (a, b) => a.date.getTime() - b.date.getTime(),
+ );
+
+ const ctx = makeMcpToolCtx(teamWorkspace, { db: tx });
+ const tools = registered("status-report", ctx);
+ const result = await callTool(tools, "list_status_reports", {});
+ expect(result.isError).toBeUndefined();
+ const items = (
+ result.structuredContent as {
+ items: {
+ id: number;
+ latestUpdate: { id: number } | null;
+ updates: { id: number; status: string; message: string }[];
+ }[];
+ }
+ ).items;
+ const item = items.find((i) => i.id === sr.id);
+ expect(item?.updates.map((u) => u.id)).toEqual([newer.id, older.id]);
+ expect(item?.updates[0].status).toBe("identified");
+ expect(item?.latestUpdate?.id).toBe(newer.id);
+ });
+ });
+});
+
+describe("get_status_report", () => {
+ test("returns every update id, past the list cap", async () => {
+ await withTestTransaction(async (tx) => {
+ const sr = await tx
+ .insert(statusReport)
+ .values({
+ workspaceId: teamWorkspace.id,
+ pageId: testPageId,
+ title: `${TEST_PREFIX}-long`,
+ status: "investigating",
+ })
+ .returning()
+ .get();
+ const rows = await tx
+ .insert(statusReportUpdate)
+ .values(
+ Array.from({ length: 12 }, (_, i) => ({
+ statusReportId: sr.id,
+ status: "investigating" as const,
+ message: `update ${i}`,
+ date: new Date(Date.UTC(2026, 0, 1 + i)),
+ })),
+ )
+ .returning()
+ .all();
+ const newestFirst = [...rows]
+ .sort((a, b) => b.date.getTime() - a.date.getTime())
+ .map((u) => u.id);
+
+ const ctx = makeMcpToolCtx(teamWorkspace, { db: tx });
+ const tools = registered("status-report", ctx);
+ const listed = await callTool(tools, "list_status_reports", {});
+ const item = (
+ listed.structuredContent as {
+ items: { id: number; updates: { id: number }[] }[];
+ }
+ ).items.find((i) => i.id === sr.id);
+ expect(item?.updates.map((u) => u.id)).toEqual(newestFirst.slice(0, 10));
+
+ const result = await callTool(tools, "get_status_report", { id: sr.id });
+ expect(result.isError).toBeUndefined();
+ const report = result.structuredContent as {
+ id: number;
+ updates: { id: number }[];
+ };
+ expect(report.id).toBe(sr.id);
+ expect(report.updates.map((u) => u.id)).toEqual(newestFirst);
+ });
+ });
+
+ test("errors for a report outside the workspace", async () => {
+ await withTestTransaction(async (tx) => {
+ const other = await tx
+ .insert(statusReport)
+ .values({
+ workspaceId: SEEDED_WORKSPACE_FREE_ID,
+ title: `${TEST_PREFIX}-other-ws-report`,
+ status: "investigating",
+ })
+ .returning()
+ .get();
+
+ const ctx = makeMcpToolCtx(teamWorkspace, { db: tx });
+ const tools = registered("status-report", ctx);
+ const result = await callTool(tools, "get_status_report", {
+ id: other.id,
+ });
+ expect(result.isError).toBe(true);
+ });
+ });
});
describe("create_status_report", () => {
@@ -487,6 +614,133 @@ describe("resolve_status_report", () => {
});
});
+describe("update_status_report_update / delete_status_report_update", () => {
+ async function seedReport(tx: ServiceContext["db"]) {
+ const ctx = makeMcpToolCtx(teamWorkspace, { db: tx });
+ const tools = registered("status-report", ctx);
+ const created = await callTool(tools, "create_status_report", {
+ title: `${TEST_PREFIX}-edit-updates`,
+ status: "investigating",
+ message: "first",
+ pageId: testPageId,
+ pageComponentIds: [testPageComponentId],
+ notify: false,
+ });
+ expect(created.isError).toBeUndefined();
+ const { statusReport: sr, initialUpdateId } = created.structuredContent as {
+ statusReport: { id: number };
+ initialUpdateId: number;
+ };
+ return { tools, reportId: sr.id, firstUpdateId: initialUpdateId };
+ }
+
+ test("edits an entry and re-derives the report status", async () => {
+ await withTestTransaction(async (tx) => {
+ const { tools, reportId, firstUpdateId } = await seedReport(tx);
+ const added = await callTool(tools, "add_status_report_update", {
+ statusReportId: reportId,
+ status: "identified",
+ message: "second",
+ notify: false,
+ });
+ const { statusReportUpdateId } = added.structuredContent as {
+ statusReportUpdateId: number;
+ };
+
+ const edited = await callTool(tools, "update_status_report_update", {
+ id: statusReportUpdateId,
+ status: "monitoring",
+ message: "second, corrected",
+ });
+ expect(edited.isError).toBeUndefined();
+ const out = edited.structuredContent as {
+ id: number;
+ statusReportId: number;
+ status: string;
+ message: string;
+ };
+ expect(out.id).toBe(statusReportUpdateId);
+ expect(out.statusReportId).toBe(reportId);
+ expect(out.status).toBe("monitoring");
+ expect(out.message).toBe("second, corrected");
+
+ const report = await tx
+ .select()
+ .from(statusReport)
+ .where(eq(statusReport.id, reportId))
+ .get();
+ expect(report?.status).toBe("monitoring");
+ expect(firstUpdateId).toBeGreaterThan(0);
+ });
+ });
+
+ test("setting the latest entry to 'resolved' resolves the report", async () => {
+ await withTestTransaction(async (tx) => {
+ const { tools, reportId, firstUpdateId } = await seedReport(tx);
+ const result = await callTool(tools, "update_status_report_update", {
+ id: firstUpdateId,
+ status: "resolved",
+ });
+ expect(result.isError).toBeUndefined();
+ expect((result.structuredContent as { status: string }).status).toBe(
+ "resolved",
+ );
+
+ const report = await tx
+ .select()
+ .from(statusReport)
+ .where(eq(statusReport.id, reportId))
+ .get();
+ expect(report?.status).toBe("resolved");
+ });
+ });
+
+ test("deletes a non-last entry and refuses the last one", async () => {
+ await withTestTransaction(async (tx) => {
+ const { tools, reportId, firstUpdateId } = await seedReport(tx);
+ const added = await callTool(tools, "add_status_report_update", {
+ statusReportId: reportId,
+ status: "identified",
+ message: "second",
+ notify: false,
+ });
+ const { statusReportUpdateId } = added.structuredContent as {
+ statusReportUpdateId: number;
+ };
+
+ const deleted = await callTool(tools, "delete_status_report_update", {
+ id: statusReportUpdateId,
+ });
+ expect(deleted.isError).toBeUndefined();
+ expect(deleted.structuredContent).toEqual({
+ id: statusReportUpdateId,
+ success: true,
+ });
+ const rows = await readAuditLog({
+ workspaceId: teamWorkspace.id,
+ entityType: "status_report_update",
+ entityId: statusReportUpdateId,
+ db: tx,
+ });
+ expect(rows.some((r) => r.action === "status_report_update.delete")).toBe(
+ true,
+ );
+
+ const last = await callTool(tools, "delete_status_report_update", {
+ id: firstUpdateId,
+ });
+ expect(last.isError).toBe(true);
+ expect(JSON.stringify(last.content)).toContain("at least one update");
+ const remaining = await tx
+ .select()
+ .from(statusReportUpdate)
+ .where(eq(statusReportUpdate.statusReportId, reportId))
+ .all();
+ expect(remaining).toHaveLength(1);
+ });
+ });
+});
+
describe("list_maintenances", () => {
test("returns items and pagination metadata", async () => {
await withTestTransaction(async (tx) => {
@@ -652,6 +906,8 @@ describe("scope filter", () => {
expect(reportTools.has("add_status_report_update")).toBe(false);
expect(reportTools.has("update_status_report")).toBe(false);
expect(reportTools.has("resolve_status_report")).toBe(false);
+ expect(reportTools.has("update_status_report_update")).toBe(false);
+ expect(reportTools.has("delete_status_report_update")).toBe(false);
expect(maintenanceTools.has("create_maintenance")).toBe(false);
expect(maintenanceTools.has("add_maintenance_update")).toBe(false);
expect(maintenanceTools.has("update_maintenance_update")).toBe(false);
diff --git a/apps/server/src/routes/rpc/handlers/maintenance/index.ts b/apps/server/src/routes/rpc/handlers/maintenance/index.ts
index 10ce4a2ba..16da7ea2a 100644
--- a/apps/server/src/routes/rpc/handlers/maintenance/index.ts
+++ b/apps/server/src/routes/rpc/handlers/maintenance/index.ts
@@ -39,13 +39,15 @@ const DECIMAL_ID = /^\d+$/;
function parseId(value: string, label: string): number {
const trimmed = value.trim();
- if (!DECIMAL_ID.test(trimmed)) {
+ // past 2^53 the digits round to a neighbouring id
+ const id = Number(trimmed);
+ if (!DECIMAL_ID.test(trimmed) || !Number.isSafeInteger(id)) {
throw new ConnectError(
`Invalid ${label}: "${value}"`,
Code.InvalidArgument,
);
}
- return Number(trimmed);
+ return id;
}
function parsePageComponentIds(ids: ReadonlyArray): number[] {
diff --git a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts
index 17d66d80f..5d87a419d 100644
--- a/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts
+++ b/apps/server/src/routes/rpc/handlers/status-report/__tests__/status-report.test.ts
@@ -779,6 +779,18 @@ describe("StatusReportService.GetStatusReport", () => {
expect(res.status).toBe(400);
});
+
+ test("rejects a report id beyond the safe integer range", async () => {
+ const res = await connectRequest(
+ "GetStatusReport",
+ { id: "9007199254740993" },
+ { "x-openstatus-key": "1" },
+ );
+
+ expect(res.status).toBe(400);
+ const data = await res.json();
+ expect(data.message).toContain("Invalid status report id");
+ });
});
describe("StatusReportService.ListStatusReports", () => {
@@ -1161,6 +1173,18 @@ describe("StatusReportService.UpdateStatusReport", () => {
expect(res.status).toBe(404);
});
+ test("rejects an update id beyond the safe integer range", async () => {
+ const res = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: "9007199254740993", message: "rounded" },
+ { "x-openstatus-key": "1" },
+ );
+
+ expect(res.status).toBe(400);
+ const data = await res.json();
+ expect(data.message).toContain("Invalid status report update id");
+ });
+
test("rejects a malformed page component id on update", async () => {
const res = await connectRequest(
"UpdateStatusReport",
@@ -1726,6 +1750,305 @@ describe("StatusReportService.AddStatusReportUpdate", () => {
});
});
+describe("StatusReportService status report update CRUD", () => {
+ const AUTH = { "x-openstatus-key": "1" };
+
+ type WireUpdate = {
+ id: string;
+ status: string;
+ message: string;
+ date: string;
+ componentImpacts: { pageComponentId: string; impact: string }[];
+ };
+
+ async function createReport(suffix: string) {
+ const res = await connectRequest(
+ "CreateStatusReport",
+ {
+ title: `${TEST_PREFIX}-${suffix}`,
+ status: "STATUS_REPORT_STATUS_INVESTIGATING",
+ message: "first entry",
+ date: new Date(Date.now() - 60_000).toISOString(),
+ pageId: "1",
+ pageComponentIds: [String(testPageComponentId)],
+ },
+ AUTH,
+ );
+ expect(res.status).toBe(200);
+ const { statusReport: report } = await res.json();
+ return report as { id: string; updates: WireUpdate[] };
+ }
+
+ async function addUpdate(reportId: string, message: string) {
+ const res = await connectRequest(
+ "AddStatusReportUpdate",
+ {
+ statusReportId: reportId,
+ status: "STATUS_REPORT_STATUS_IDENTIFIED",
+ message,
+ date: new Date().toISOString(),
+ },
+ AUTH,
+ );
+ expect(res.status).toBe(200);
+ const { statusReport: report } = await res.json();
+ const created = (report.updates as WireUpdate[]).find(
+ (u) => u.message === message,
+ );
+ if (!created) throw new Error("update not returned");
+ return created;
+ }
+
+ async function getReport(reportId: string) {
+ const res = await connectRequest("GetStatusReport", { id: reportId }, AUTH);
+ expect(res.status).toBe(200);
+ const { statusReport: report } = await res.json();
+ return report as { status: string; updates: WireUpdate[] };
+ }
+
+ async function cleanupReport(reportId: string) {
+ await connectRequest("DeleteStatusReport", { id: reportId }, AUTH);
+ }
+
+ test("edits and removes timeline entries, re-deriving the report status", async () => {
+ const report = await createReport("update-crud");
+ try {
+ const second = await addUpdate(report.id, "second entry");
+ expect((await getReport(report.id)).status).toBe(
+ "STATUS_REPORT_STATUS_IDENTIFIED",
+ );
+
+ // dates persist at second precision
+ const editedDate = new Date(
+ Math.floor(Date.now() / 1000) * 1000,
+ ).toISOString();
+ const edited = await connectRequest(
+ "UpdateStatusReportUpdate",
+ {
+ id: second.id,
+ status: "STATUS_REPORT_STATUS_MONITORING",
+ message: "corrected entry",
+ date: editedDate,
+ },
+ AUTH,
+ );
+ expect(edited.status).toBe(200);
+ const { statusReportUpdate: row } = await edited.json();
+ expect(row.id).toBe(second.id);
+ expect(row.status).toBe("STATUS_REPORT_STATUS_MONITORING");
+ expect(row.message).toBe("corrected entry");
+ expect(new Date(row.date).toISOString()).toBe(editedDate);
+
+ // editing the latest update's status re-derives the report
+ let full = await getReport(report.id);
+ expect(full.status).toBe("STATUS_REPORT_STATUS_MONITORING");
+ expect(full.updates).toHaveLength(2);
+
+ const deleted = await connectRequest(
+ "DeleteStatusReportUpdate",
+ { id: second.id },
+ AUTH,
+ );
+ expect(deleted.status).toBe(200);
+ expect(await deleted.json()).toEqual({ success: true });
+
+ full = await getReport(report.id);
+ expect(full.updates).toHaveLength(1);
+ expect(full.status).toBe("STATUS_REPORT_STATUS_INVESTIGATING");
+ } finally {
+ await cleanupReport(report.id);
+ }
+ });
+
+ test("replaces component impacts only when updateComponentImpacts is set", async () => {
+ const report = await createReport("update-impacts");
+ const updateId = report.updates[0].id;
+ try {
+ const set = await connectRequest(
+ "UpdateStatusReportUpdate",
+ {
+ id: updateId,
+ componentImpacts: [
+ {
+ pageComponentId: String(testPageComponentId),
+ impact: "PAGE_COMPONENT_IMPACT_MAJOR_OUTAGE",
+ },
+ ],
+ updateComponentImpacts: true,
+ },
+ AUTH,
+ );
+ expect(set.status).toBe(200);
+ expect((await set.json()).statusReportUpdate.componentImpacts).toEqual([
+ {
+ pageComponentId: String(testPageComponentId),
+ impact: "PAGE_COMPONENT_IMPACT_MAJOR_OUTAGE",
+ },
+ ]);
+
+ // no flag ⇒ impacts untouched even though the list is empty on the wire
+ const untouched = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: updateId, message: "message only" },
+ AUTH,
+ );
+ expect(untouched.status).toBe(200);
+ const kept = (await untouched.json()).statusReportUpdate;
+ expect(kept.message).toBe("message only");
+ expect(kept.componentImpacts).toHaveLength(1);
+
+ const cleared = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: updateId, componentImpacts: [], updateComponentImpacts: true },
+ AUTH,
+ );
+ expect(cleared.status).toBe(200);
+ // an empty repeated field is omitted on the JSON wire
+ expect(
+ (await cleared.json()).statusReportUpdate.componentImpacts ?? [],
+ ).toEqual([]);
+ const rows = await db
+ .select()
+ .from(statusReportUpdateToPageComponents)
+ .where(
+ eq(
+ statusReportUpdateToPageComponents.statusReportUpdateId,
+ Number(updateId),
+ ),
+ )
+ .all();
+ expect(rows).toHaveLength(0);
+ } finally {
+ await cleanupReport(report.id);
+ }
+ });
+
+ test("refuses to delete the last update", async () => {
+ const report = await createReport("last-update");
+ try {
+ expect(report.updates).toHaveLength(1);
+ const res = await connectRequest(
+ "DeleteStatusReportUpdate",
+ { id: report.updates[0].id },
+ AUTH,
+ );
+ expect(res.status).toBe(400);
+ expect((await res.json()).message).toContain("at least one update");
+ expect((await getReport(report.id)).updates).toHaveLength(1);
+ } finally {
+ await cleanupReport(report.id);
+ }
+ });
+
+ test("rejects an UNSPECIFIED status and a malformed date", async () => {
+ const report = await createReport("update-validation");
+ const updateId = report.updates[0].id;
+ try {
+ const status = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: updateId, status: "STATUS_REPORT_STATUS_UNSPECIFIED" },
+ AUTH,
+ );
+ expect(status.status).toBe(400);
+
+ const date = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: updateId, date: "not-a-date" },
+ AUTH,
+ );
+ expect(date.status).toBe(400);
+ } finally {
+ await cleanupReport(report.id);
+ }
+ });
+
+ test("returns 401 when no auth key provided", async () => {
+ const edit = await connectRequest("UpdateStatusReportUpdate", {
+ id: "1",
+ message: "x",
+ });
+ expect(edit.status).toBe(401);
+ const del = await connectRequest("DeleteStatusReportUpdate", { id: "1" });
+ expect(del.status).toBe(401);
+ });
+
+ test("rejects empty, blank and non-decimal ids", async () => {
+ for (const method of [
+ "UpdateStatusReportUpdate",
+ "DeleteStatusReportUpdate",
+ ]) {
+ for (const id of ["", " ", "abc", "1e3"]) {
+ const res = await connectRequest(method, { id }, AUTH);
+ expect(res.status).toBe(400);
+ }
+ }
+ });
+
+ test("returns 404 for an unknown update", async () => {
+ const edit = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: "999999", message: "x" },
+ AUTH,
+ );
+ expect(edit.status).toBe(404);
+ const del = await connectRequest(
+ "DeleteStatusReportUpdate",
+ { id: "999999" },
+ AUTH,
+ );
+ expect(del.status).toBe(404);
+ });
+
+ test("scopes update mutations to the authenticated workspace", async () => {
+ const otherReport = await db
+ .insert(statusReport)
+ .values({
+ workspaceId: OTHER_WORKSPACE_ID,
+ title: `${TEST_PREFIX}-other-workspace-update`,
+ status: "investigating",
+ })
+ .returning()
+ .get();
+ const otherUpdate = await db
+ .insert(statusReportUpdate)
+ .values({
+ statusReportId: otherReport.id,
+ status: "investigating",
+ date: new Date(),
+ message: "foreign",
+ })
+ .returning()
+ .get();
+ try {
+ // the update lookup answers with ForbiddenError, not NotFoundError
+ const edit = await connectRequest(
+ "UpdateStatusReportUpdate",
+ { id: String(otherUpdate.id), message: "hijacked" },
+ AUTH,
+ );
+ expect(edit.status).toBe(403);
+ const del = await connectRequest(
+ "DeleteStatusReportUpdate",
+ { id: String(otherUpdate.id) },
+ AUTH,
+ );
+ expect(del.status).toBe(403);
+
+ const still = await db
+ .select()
+ .from(statusReportUpdate)
+ .where(eq(statusReportUpdate.id, otherUpdate.id))
+ .get();
+ expect(still?.message).toBe("foreign");
+ } finally {
+ await db
+ .delete(statusReportUpdate)
+ .where(eq(statusReportUpdate.statusReportId, otherReport.id));
+ await db.delete(statusReport).where(eq(statusReport.id, otherReport.id));
+ }
+ });
+});
+
describe("StatusReportService component impacts", () => {
async function cleanupReport(id: number) {
// update deletion cascades the impact join rows
diff --git a/apps/server/src/routes/rpc/handlers/status-report/errors.ts b/apps/server/src/routes/rpc/handlers/status-report/errors.ts
index 39fe7fbe0..b33afd39c 100644
--- a/apps/server/src/routes/rpc/handlers/status-report/errors.ts
+++ b/apps/server/src/routes/rpc/handlers/status-report/errors.ts
@@ -6,6 +6,7 @@ import { Code, ConnectError } from "@connectrpc/connect";
export const ErrorReason = {
STATUS_REPORT_NOT_FOUND: "STATUS_REPORT_NOT_FOUND",
STATUS_REPORT_ID_REQUIRED: "STATUS_REPORT_ID_REQUIRED",
+ STATUS_REPORT_UPDATE_ID_REQUIRED: "STATUS_REPORT_UPDATE_ID_REQUIRED",
STATUS_REPORT_CREATE_FAILED: "STATUS_REPORT_CREATE_FAILED",
STATUS_REPORT_UPDATE_FAILED: "STATUS_REPORT_UPDATE_FAILED",
PAGE_COMPONENT_NOT_FOUND: "PAGE_COMPONENT_NOT_FOUND",
@@ -67,6 +68,17 @@ export function statusReportIdRequiredError(): ConnectError {
);
}
+/**
+ * Creates a "status report update ID required" error.
+ */
+export function statusReportUpdateIdRequiredError(): ConnectError {
+ return createError(
+ "Status report update ID is required",
+ Code.InvalidArgument,
+ ErrorReason.STATUS_REPORT_UPDATE_ID_REQUIRED,
+ );
+}
+
/**
* Creates a "failed to create status report" error.
*/
diff --git a/apps/server/src/routes/rpc/handlers/status-report/index.ts b/apps/server/src/routes/rpc/handlers/status-report/index.ts
index e50d07dd5..6cb5105d1 100644
--- a/apps/server/src/routes/rpc/handlers/status-report/index.ts
+++ b/apps/server/src/routes/rpc/handlers/status-report/index.ts
@@ -8,10 +8,12 @@ import {
addStatusReportUpdate,
createStatusReport,
deleteStatusReport,
+ deleteStatusReportUpdate,
getStatusReport,
listStatusReports,
notifyStatusReport,
updateStatusReport,
+ updateStatusReportUpdate,
} from "@openstatus/services/status-report";
import { toConnectError, toServiceCtx } from "../../adapter";
@@ -19,10 +21,15 @@ import { getRpcContext } from "../../interceptors";
import {
dbReportToProto,
dbReportToProtoSummary,
+ dbUpdateToProto,
protoImpactToDb,
protoStatusToDb,
} from "./converters";
-import { invalidDateFormatError, statusReportIdRequiredError } from "./errors";
+import {
+ invalidDateFormatError,
+ statusReportIdRequiredError,
+ statusReportUpdateIdRequiredError,
+} from "./errors";
function parseDate(dateString: string): Date {
const date = new Date(dateString);
@@ -35,19 +42,23 @@ function parseDate(dateString: string): Date {
// Match the digits explicitly: `Number("")` is 0 (finite!), so a blank id used
// to slip through and target component 0, and `Number.parseInt("1.5")` is 1, so
// swapping in parseInt alone would still truncate a malformed id silently.
-const PAGE_COMPONENT_ID = /^\d+$/;
+const DECIMAL_ID = /^\d+$/;
+
+function parseId(value: string, label: string): number {
+ const trimmed = value.trim();
+ // past 2^53 the digits round to a neighbouring id
+ const id = Number(trimmed);
+ if (!DECIMAL_ID.test(trimmed) || !Number.isSafeInteger(id)) {
+ throw new ConnectError(
+ `Invalid ${label}: "${value}"`,
+ Code.InvalidArgument,
+ );
+ }
+ return id;
+}
function parsePageComponentIds(ids: ReadonlyArray): number[] {
- return ids.map((id) => {
- const trimmed = id.trim();
- if (!PAGE_COMPONENT_ID.test(trimmed)) {
- throw new ConnectError(
- `Invalid page component id: "${id}"`,
- Code.InvalidArgument,
- );
- }
- return Number(trimmed);
- });
+ return ids.map((id) => parseId(id, "page component id"));
}
// empty list ⇒ undefined: an old client omitting the field must produce a
@@ -59,7 +70,7 @@ function parseComponentImpacts(
| undefined {
if (impacts.length === 0) return undefined;
return impacts.map((ci) => ({
- pageComponentId: parsePageComponentIds([ci.pageComponentId])[0],
+ pageComponentId: parseId(ci.pageComponentId, "page component id"),
impact: protoImpactToDb(ci.impact),
}));
}
@@ -71,10 +82,10 @@ export const statusReportServiceImpl: ServiceImpl =
const rpcCtx = getRpcContext(ctx);
const sCtx = toServiceCtx(rpcCtx);
- const pageId = req.pageId?.trim() ? Number(req.pageId.trim()) : null;
- if (pageId === null) {
+ if (!req.pageId?.trim()) {
throw statusReportIdRequiredError();
}
+ const pageId = parseId(req.pageId, "page id");
const { statusReport, initialUpdate } = await createStatusReport({
ctx: sCtx,
@@ -121,7 +132,7 @@ export const statusReportServiceImpl: ServiceImpl =
const full = await getStatusReport({
ctx: toServiceCtx(rpcCtx),
- input: { id: Number(req.id) },
+ input: { id: parseId(req.id, "status report id") },
});
return {
statusReport: dbReportToProto(
@@ -175,7 +186,7 @@ export const statusReportServiceImpl: ServiceImpl =
throw statusReportIdRequiredError();
}
- const id = Number(req.id);
+ const id = parseId(req.id, "status report id");
await updateStatusReport({
ctx: sCtx,
input: {
@@ -211,7 +222,7 @@ export const statusReportServiceImpl: ServiceImpl =
}
await deleteStatusReport({
ctx: toServiceCtx(rpcCtx),
- input: { id: Number(req.id) },
+ input: { id: parseId(req.id, "status report id") },
});
return { success: true };
} catch (err) {
@@ -227,7 +238,7 @@ export const statusReportServiceImpl: ServiceImpl =
throw statusReportIdRequiredError();
}
- const statusReportId = Number(req.statusReportId);
+ const statusReportId = parseId(req.statusReportId, "status report id");
const { statusReport: updatedReport, statusReportUpdate: newUpdate } =
await addStatusReportUpdate({
ctx: sCtx,
@@ -262,4 +273,62 @@ export const statusReportServiceImpl: ServiceImpl =
toConnectError(err);
}
},
+
+ async updateStatusReportUpdate(req, ctx) {
+ try {
+ const rpcCtx = getRpcContext(ctx);
+ const sCtx = toServiceCtx(rpcCtx);
+ if (!req.id?.trim()) {
+ throw statusReportUpdateIdRequiredError();
+ }
+ const id = parseId(req.id, "status report update id");
+ const edited = await updateStatusReportUpdate({
+ ctx: sCtx,
+ input: {
+ id,
+ status:
+ req.status !== undefined
+ ? protoStatusToDb(req.status)
+ : undefined,
+ message: req.message,
+ date: req.date ? parseDate(req.date) : undefined,
+ // repeated can't distinguish empty from absent, so the flag decides
+ componentImpacts: req.updateComponentImpacts
+ ? (parseComponentImpacts(req.componentImpacts) ?? [])
+ : undefined,
+ },
+ });
+ // the row alone has no impact rows; re-read through the report
+ const full = await getStatusReport({
+ ctx: sCtx,
+ input: { id: edited.statusReportId },
+ });
+ const update = full.updates.find((u) => u.id === id);
+ if (!update) {
+ throw new ConnectError(
+ `Status report update ${id} was deleted concurrently`,
+ Code.NotFound,
+ );
+ }
+ return { statusReportUpdate: dbUpdateToProto(update) };
+ } catch (err) {
+ toConnectError(err);
+ }
+ },
+
+ async deleteStatusReportUpdate(req, ctx) {
+ try {
+ const rpcCtx = getRpcContext(ctx);
+ if (!req.id?.trim()) {
+ throw statusReportUpdateIdRequiredError();
+ }
+ await deleteStatusReportUpdate({
+ ctx: toServiceCtx(rpcCtx),
+ input: { id: parseId(req.id, "status report update id") },
+ });
+ return { success: true };
+ } catch (err) {
+ toConnectError(err);
+ }
+ },
};
diff --git a/apps/server/src/routes/slack/system-prompt.ts b/apps/server/src/routes/slack/system-prompt.ts
index 170c81ead..b2acbc120 100644
--- a/apps/server/src/routes/slack/system-prompt.ts
+++ b/apps/server/src/routes/slack/system-prompt.ts
@@ -39,7 +39,7 @@ REPLY STYLE — this is Slack, not a document. Be brief and direct.
- Include only the details that answer the question. Skip caveats and background nobody asked for.
HOW APPROVAL WORKS HERE — read this before any write tool:
-Calling a write tool (create_status_report, add_status_report_update, update_status_report, resolve_status_report, create_maintenance, add_maintenance_update, update_maintenance_update, delete_maintenance_update) does NOT execute it. It renders an approval card in Slack with Approve/Cancel buttons, and nothing is created, published, or notified until the user clicks Approve. The card IS how you ask.
+Calling a write tool (create_status_report, add_status_report_update, update_status_report, resolve_status_report, update_status_report_update, delete_status_report_update, create_maintenance, add_maintenance_update, update_maintenance_update, delete_maintenance_update) does NOT execute it. It renders an approval card in Slack with Approve/Cancel buttons, and nothing is created, published, or notified until the user clicks Approve. The card IS how you ask.
- Call the tool as soon as you have the ids it needs. That is the ONLY way the user gets a card.
- NEVER write the draft out as message text (a "**Title:** … **Message:** …" block) instead of calling the tool.
- NEVER end your turn with "shall I go ahead?", "want me to publish this?", or any other request for permission to call a write tool. The buttons already ask that question; a prose question leaves the user with nothing to click.
@@ -49,7 +49,7 @@ Calling a write tool (create_status_report, add_status_report_update, update_sta
IMPORTANT: You have NO knowledge of this workspace's data. NEVER guess or make up IDs (page, component, report, maintenance, monitor, notification, response log, audit log IDs). You MUST call the appropriate tool first to get real data.
- Questions about pages or components -> call list_status_pages FIRST
-- Questions about reports -> call list_status_reports FIRST
+- Questions about reports -> call list_status_reports FIRST; it stops at the 10 most recent updates, so use get_status_report for the full timeline or to find an older update's id
- Questions about maintenances -> call list_maintenances FIRST
- Questions about a monitor, including by name ("the API monitor") -> call list_monitors FIRST to get its id
- Questions about a notification channel, including by name ("PagerDuty") -> call list_notifications FIRST
@@ -68,6 +68,7 @@ Status pages and incidents (write tools render an approval card):
- Publish progress updates to existing reports (add_status_report_update)
- Edit report metadata like title or components (update_status_report)
- Resolve active reports (resolve_status_report)
+- Edit or remove an existing report update (update_status_report_update, delete_status_report_update); get the update id from get_status_report
- Schedule maintenance windows (create_maintenance)
- Post, edit or remove dated updates on a maintenance window (add_maintenance_update, update_maintenance_update, delete_maintenance_update)
- List status pages, page components, status reports, and maintenance windows (list_status_pages, list_page_components, list_status_reports, list_maintenances)
diff --git a/apps/server/static/openapi-yaml.ts b/apps/server/static/openapi-yaml.ts
index 864e9db38..1b983c4f3 100644
--- a/apps/server/static/openapi-yaml.ts
+++ b/apps/server/static/openapi-yaml.ts
@@ -1,2 +1,2 @@
// Generated from openapi.yaml — run `pnpm --filter @openstatus/server openapi:json`.
-export default "openapi: 3.1.0\ninfo:\n description: OpenStatus is a open-source status page platform with global uptime monitoring. The OpenStatus API allows you to interact with the OpenStatus platform programmatically. To get started you need to create an account on https://www.openstatus.dev/ and create an api token in your settings. Requests are rate limited per API key or token (600 per minute, 100 per 10 seconds); exceeding a limit returns HTTP 429 with a Retry-After header. See https://www.openstatus.dev/docs/reference/api-rate-limits.\n title: OpenStatus API\n version: v2.0.0\n contact:\n email: ping@openstatus.dev\n url: https://www.openstatus.dev\nservers:\n - url: https://api.openstatus.dev\n description: Production\nexternalDocs:\n description: OpenStatus Documentation\n url: https://www.openstatus.dev/docs\ncomponents:\n responses:\n RateLimited:\n description: Rate limit exceeded (Connect code resource_exhausted). Retry after the number of seconds in the Retry-After header. See https://www.openstatus.dev/docs/reference/api-rate-limits.\n headers:\n Retry-After:\n description: Seconds to wait before retrying.\n schema:\n type: integer\n example: 7\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n securitySchemes:\n ApiKeyAuth:\n type: apiKey\n in: header\n name: x-openstatus-key\n schemas:\n connect.error:\n type: object\n properties:\n code:\n type: string\n examples:\n - not_found\n enum:\n - canceled\n - unknown\n - invalid_argument\n - deadline_exceeded\n - not_found\n - already_exists\n - permission_denied\n - resource_exhausted\n - failed_precondition\n - aborted\n - out_of_range\n - unimplemented\n - internal\n - unavailable\n - data_loss\n - unauthenticated\n description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].\n message:\n type: string\n description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.\n details:\n type: array\n items:\n $ref: '#/components/schemas/connect.error_details.Any'\n description: A list of messages that carry the error details. There is no limit on the number of messages.\n title: Connect Error\n additionalProperties: true\n description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation'\n connect.error_details.Any:\n type: object\n properties:\n type:\n type: string\n description: 'A URL that acts as a globally unique identifier for the type of the serialized message. For example: `type.googleapis.com/google.rpc.ErrorInfo`. This is used to determine the schema of the data in the `value` field and is the discriminator for the `debug` field.'\n value:\n type: string\n format: binary\n description: The Protobuf message, serialized as bytes and base64-encoded. The specific message type is identified by the `type` field.\n debug:\n oneOf:\n - type: object\n title: Any\n additionalProperties: true\n description: Detailed error information.\n discriminator:\n propertyName: type\n title: Debug\n description: Deserialized error detail payload. The 'type' field indicates the schema. This field is for easier debugging and should not be relied upon for application logic.\n additionalProperties: true\n description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message, with an additional debug field for ConnectRPC error details.\n openstatus.health.v1.CheckRequest:\n type: object\n properties:\n service:\n type: string\n title: service\n description: Optional service name to check. If empty, checks overall service health.\n title: CheckRequest\n additionalProperties: false\n description: CheckRequest is the request message for health checks.\n openstatus.health.v1.CheckResponse:\n type: object\n properties:\n status:\n title: status\n description: The serving status of the service.\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse.ServingStatus'\n title: CheckResponse\n additionalProperties: false\n description: CheckResponse is the response message for health checks.\n openstatus.health.v1.CheckResponse.ServingStatus:\n type: string\n title: ServingStatus\n enum:\n - SERVING_STATUS_UNSPECIFIED\n - SERVING_STATUS_SERVING\n - SERVING_STATUS_NOT_SERVING\n description: ServingStatus represents the health status of the service.\n openstatus.maintenance.v1.AddMaintenanceUpdateRequest:\n type: object\n properties:\n maintenanceId:\n type: string\n title: maintenance_id\n minLength: 1\n description: ID of the maintenance to update (required).\n message:\n type: string\n title: message\n minLength: 1\n description: Public update message (required).\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Optional date for the update (RFC 3339 format). Defaults to current time.\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this update.\n title: AddMaintenanceUpdateRequest\n additionalProperties: false\n description: AddMaintenanceUpdateRequest is the request to append a maintenance update.\n openstatus.maintenance.v1.AddMaintenanceUpdateResponse:\n type: object\n properties:\n maintenanceUpdate:\n title: maintenance_update\n description: The created update.\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: AddMaintenanceUpdateResponse\n additionalProperties: false\n description: AddMaintenanceUpdateResponse is the response after appending an update.\n openstatus.maintenance.v1.CreateMaintenanceRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - Database Migration\n title: title\n maxLength: 256\n minLength: 1\n description: Title of the maintenance (required, 1-256 characters).\n message:\n type: string\n title: message\n minLength: 1\n description: |-\n Message describing the maintenance (required). Posted as the first\n maintenance update.\n from:\n type: string\n examples:\n - \"2024-03-01T02:00:00Z\"\n title: from\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Start time of the maintenance window (RFC 3339 format, required).\n to:\n type: string\n examples:\n - \"2024-03-01T06:00:00Z\"\n title: to\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: End time of the maintenance window (RFC 3339 format, required).\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: Page ID to associate with this maintenance (required).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: Page component IDs to associate with this maintenance (optional).\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this maintenance (optional, defaults to false).\n title: CreateMaintenanceRequest\n additionalProperties: false\n description: CreateMaintenanceRequest is the request to create a new maintenance window.\n openstatus.maintenance.v1.CreateMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The created maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: CreateMaintenanceResponse\n additionalProperties: false\n description: CreateMaintenanceResponse is the response after creating a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to delete (required).\n title: DeleteMaintenanceRequest\n additionalProperties: false\n description: DeleteMaintenanceRequest is the request to delete a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMaintenanceResponse\n additionalProperties: false\n description: DeleteMaintenanceResponse is the response after deleting a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to remove (required).\n title: DeleteMaintenanceUpdateRequest\n additionalProperties: false\n description: DeleteMaintenanceUpdateRequest is the request to remove an update.\n openstatus.maintenance.v1.DeleteMaintenanceUpdateResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMaintenanceUpdateResponse\n additionalProperties: false\n description: DeleteMaintenanceUpdateResponse is the response after removing an update.\n openstatus.maintenance.v1.GetMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to retrieve (required).\n title: GetMaintenanceRequest\n additionalProperties: false\n description: GetMaintenanceRequest is the request to get a maintenance window by ID.\n openstatus.maintenance.v1.GetMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The requested maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: GetMaintenanceResponse\n additionalProperties: false\n description: GetMaintenanceResponse is the response containing the maintenance window.\n openstatus.maintenance.v1.ListMaintenancesRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of maintenances to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of maintenances to skip for pagination (defaults to 0).\n pageId:\n type:\n - string\n - \"null\"\n title: page_id\n description: Filter by page ID (optional).\n title: ListMaintenancesRequest\n additionalProperties: false\n description: ListMaintenancesRequest is the request to list maintenance windows.\n openstatus.maintenance.v1.ListMaintenancesResponse:\n type: object\n properties:\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: List of maintenances.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of maintenances matching the filter.\n title: ListMaintenancesResponse\n additionalProperties: false\n description: ListMaintenancesResponse is the response containing maintenance window summaries.\n openstatus.maintenance.v1.Maintenance:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the maintenance.\n title:\n type: string\n title: title\n description: Title of the maintenance.\n message:\n type: string\n title: message\n description: Message of the newest maintenance update.\n from:\n type: string\n title: from\n description: Start time of the maintenance window (RFC 3339 format).\n to:\n type: string\n title: to\n description: End time of the maintenance window (RFC 3339 format).\n pageId:\n type: string\n title: page_id\n description: ID of the page this maintenance is associated with.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the maintenance was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the maintenance was last updated (RFC 3339 format).\n updates:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: updates\n description: Full maintenance update timeline, newest first.\n title: Maintenance\n additionalProperties: false\n description: Maintenance represents a maintenance window with full details.\n openstatus.maintenance.v1.MaintenanceSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the maintenance.\n title:\n type: string\n title: title\n description: Title of the maintenance.\n message:\n type: string\n title: message\n description: Message of the newest maintenance update.\n from:\n type: string\n title: from\n description: Start time of the maintenance window (RFC 3339 format).\n to:\n type: string\n title: to\n description: End time of the maintenance window (RFC 3339 format).\n pageId:\n type: string\n title: page_id\n description: ID of the page this maintenance is associated with.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the maintenance was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the maintenance was last updated (RFC 3339 format).\n title: MaintenanceSummary\n additionalProperties: false\n description: MaintenanceSummary represents metadata for a maintenance window (used in list responses).\n openstatus.maintenance.v1.MaintenanceUpdate:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the update.\n message:\n type: string\n title: message\n description: Public update message.\n date:\n type: string\n title: date\n description: Date of the update (RFC 3339 format).\n maintenanceId:\n type: string\n title: maintenance_id\n description: ID of the maintenance this update belongs to.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the update was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the update was last updated (RFC 3339 format).\n title: MaintenanceUpdate\n additionalProperties: false\n description: MaintenanceUpdate represents a timeline entry for a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n maxLength: 256\n minLength: 1\n description: New title for the maintenance (optional).\n message:\n type:\n - string\n - \"null\"\n title: message\n description: Replaces the message of the newest maintenance update (optional).\n from:\n type:\n - string\n - \"null\"\n title: from\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New start time (RFC 3339 format, optional).\n to:\n type:\n - string\n - \"null\"\n title: to\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New end time (RFC 3339 format, optional).\n pageId:\n type:\n - string\n - \"null\"\n title: page_id\n description: 'Deprecated: page_id is now derived from page_component_ids.'\n deprecated: true\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: New list of page component IDs (optional, replaces existing list).\n updatePageComponentIds:\n type:\n - boolean\n - \"null\"\n title: update_page_component_ids\n description: |-\n Set to true to update page component associations.\n When true, page_component_ids replaces the existing list (empty clears all).\n When false or unset, page_component_ids is ignored and existing associations are preserved.\n title: UpdateMaintenanceRequest\n additionalProperties: false\n description: UpdateMaintenanceRequest is the request to update a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The updated maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: UpdateMaintenanceResponse\n additionalProperties: false\n description: UpdateMaintenanceResponse is the response after updating a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to edit (required).\n message:\n type:\n - string\n - \"null\"\n title: message\n minLength: 1\n description: New public message.\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New update date (RFC 3339 format).\n title: UpdateMaintenanceUpdateRequest\n additionalProperties: false\n description: UpdateMaintenanceUpdateRequest is the request to edit an update.\n openstatus.maintenance.v1.UpdateMaintenanceUpdateResponse:\n type: object\n properties:\n maintenanceUpdate:\n title: maintenance_update\n description: The updated timeline entry.\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: UpdateMaintenanceUpdateResponse\n additionalProperties: false\n description: UpdateMaintenanceUpdateResponse is the response after editing an update.\n openstatus.monitor.v1.BodyAssertion:\n type: object\n properties:\n target:\n type: string\n title: target\n description: Target value to compare against.\n comparator:\n not:\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.StringComparator'\n title: BodyAssertion\n additionalProperties: false\n description: BodyAssertion defines an assertion for response body content.\n openstatus.monitor.v1.CreateDNSMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: CreateDNSMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateDNSMonitorRequest is the request to create a new DNS monitor.\n openstatus.monitor.v1.CreateDNSMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: CreateDNSMonitorResponse\n additionalProperties: false\n description: CreateDNSMonitorResponse is the response after creating a DNS monitor.\n openstatus.monitor.v1.CreateGRPCMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: CreateGRPCMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateGRPCMonitorRequest is the request to create a new gRPC monitor.\n openstatus.monitor.v1.CreateGRPCMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: CreateGRPCMonitorResponse\n additionalProperties: false\n description: CreateGRPCMonitorResponse is the response after creating a gRPC monitor.\n openstatus.monitor.v1.CreateHTTPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: CreateHTTPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateHTTPMonitorRequest is the request to create a new HTTP monitor.\n openstatus.monitor.v1.CreateHTTPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: CreateHTTPMonitorResponse\n additionalProperties: false\n description: CreateHTTPMonitorResponse is the response after creating an HTTP monitor.\n openstatus.monitor.v1.CreateICMPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: CreateICMPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateICMPMonitorRequest is the request to create a new ICMP monitor.\n openstatus.monitor.v1.CreateICMPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: CreateICMPMonitorResponse\n additionalProperties: false\n description: CreateICMPMonitorResponse is the response after creating an ICMP monitor.\n openstatus.monitor.v1.CreateTCPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: CreateTCPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateTCPMonitorRequest is the request to create a new TCP monitor.\n openstatus.monitor.v1.CreateTCPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: CreateTCPMonitorResponse\n additionalProperties: false\n description: CreateTCPMonitorResponse is the response after creating a TCP monitor.\n openstatus.monitor.v1.DNSMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - DNS Resolution Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - example.com\n title: uri\n maxLength: 2048\n minLength: 1\n description: Domain to resolve (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n recordAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.RecordAssertion'\n title: record_assertions\n maxItems: 10\n description: DNS record assertions for validation.\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: DNSMonitor\n additionalProperties: false\n description: DNSMonitor defines the configuration for a DNS monitor.\n openstatus.monitor.v1.DeleteMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to delete (required).\n title: DeleteMonitorRequest\n additionalProperties: false\n description: DeleteMonitorRequest is the request to delete a monitor.\n openstatus.monitor.v1.DeleteMonitorResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMonitorResponse\n additionalProperties: false\n description: DeleteMonitorResponse is the response after deleting a monitor.\n openstatus.monitor.v1.GRPCMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Checkout gRPC\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - api.example.com:443\n title: uri\n maxLength: 2048\n minLength: 1\n pattern: ^(\\[[0-9a-fA-F:]+\\]|[^:/\\s]+):[0-9]{1,5}$\n description: Target in \"host:port\" form. IPv6 addresses must be bracketed.\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n service:\n type:\n - string\n - \"null\"\n examples:\n - checkout.v1.CheckoutService\n title: service\n maxLength: 512\n description: Service name passed to Health/Check. Empty means overall server health.\n tlsMode:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.GRPCTlsMode'\n - type: \"null\"\n title: tls_mode\n description: How the connection to the target is secured. Defaults to TLS.\n metadata:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: metadata\n maxItems: 20\n description: Metadata sent with the health check request.\n title: GRPCMonitor\n additionalProperties: false\n description: |-\n GRPCMonitor defines the configuration for a gRPC health check monitor.\n The probe calls grpc.health.v1.Health/Check on the target.\n openstatus.monitor.v1.GRPCTlsMode:\n type: string\n title: GRPCTlsMode\n enum:\n - GRPC_TLS_MODE_UNSPECIFIED\n - GRPC_TLS_MODE_TLS\n - GRPC_TLS_MODE_PLAINTEXT\n - GRPC_TLS_MODE_TLS_INSECURE\n description: GRPCTlsMode selects how the probe secures its connection to the target.\n openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get a response log for (required).\n logId:\n type: string\n title: log_id\n minLength: 1\n description: Response log ID to retrieve (required).\n title: GetMonitorHTTPResponseLogRequest\n additionalProperties: false\n description: GetMonitorHTTPResponseLogRequest is the request to get one response log.\n openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse:\n type: object\n properties:\n log:\n title: log\n description: Response log details.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogDetail'\n title: GetMonitorHTTPResponseLogResponse\n additionalProperties: false\n description: GetMonitorHTTPResponseLogResponse is the response containing one response log.\n openstatus.monitor.v1.GetMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to retrieve (required).\n title: GetMonitorRequest\n additionalProperties: false\n description: GetMonitorRequest is the request to get a single monitor by ID.\n openstatus.monitor.v1.GetMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The monitor configuration (one of HTTP, TCP, DNS, ICMP, or gRPC).\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorConfig'\n title: GetMonitorResponse\n additionalProperties: false\n description: GetMonitorResponse is the response containing the monitor.\n openstatus.monitor.v1.GetMonitorStatusRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get status for (required).\n title: GetMonitorStatusRequest\n additionalProperties: false\n description: GetMonitorStatusRequest is the request to get the status of all regions for a monitor.\n openstatus.monitor.v1.GetMonitorStatusResponse:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Monitor ID.\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.RegionStatus'\n title: regions\n description: Status for each region.\n title: GetMonitorStatusResponse\n additionalProperties: false\n description: GetMonitorStatusResponse is the response containing the status of all regions for a monitor.\n openstatus.monitor.v1.GetMonitorSummaryRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get summary for (required).\n timeRange:\n title: time_range\n description: Time range for metrics aggregation (defaults to 1 day if unspecified).\n $ref: '#/components/schemas/openstatus.monitor.v1.TimeRange'\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Optional filter by regions. If empty, returns metrics for all regions.\n title: GetMonitorSummaryRequest\n additionalProperties: false\n description: GetMonitorSummaryRequest is the request to get aggregated metrics for a monitor.\n openstatus.monitor.v1.GetMonitorSummaryResponse:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Monitor ID.\n lastPingAt:\n type: string\n title: last_ping_at\n description: Timestamp of the last check in RFC 3339 format.\n totalSuccessful:\n type:\n - integer\n - string\n title: total_successful\n format: int64\n description: Total number of successful requests.\n totalDegraded:\n type:\n - integer\n - string\n title: total_degraded\n format: int64\n description: Total number of degraded requests.\n totalFailed:\n type:\n - integer\n - string\n title: total_failed\n format: int64\n description: Total number of failed requests.\n p50:\n type:\n - integer\n - string\n title: p50\n format: int64\n description: 50th percentile (median) latency in milliseconds.\n p75:\n type:\n - integer\n - string\n title: p75\n format: int64\n description: 75th percentile latency in milliseconds.\n p90:\n type:\n - integer\n - string\n title: p90\n format: int64\n description: 90th percentile latency in milliseconds.\n p95:\n type:\n - integer\n - string\n title: p95\n format: int64\n description: 95th percentile latency in milliseconds.\n p99:\n type:\n - integer\n - string\n title: p99\n format: int64\n description: 99th percentile latency in milliseconds.\n timeRange:\n title: time_range\n description: Time range used for the metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.TimeRange'\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n description: Regions included in the metrics.\n title: GetMonitorSummaryResponse\n additionalProperties: false\n description: GetMonitorSummaryResponse is the response containing aggregated metrics for a monitor.\n openstatus.monitor.v1.HTTPMethod:\n type: string\n title: HTTPMethod\n enum:\n - HTTP_METHOD_UNSPECIFIED\n - HTTP_METHOD_GET\n - HTTP_METHOD_POST\n - HTTP_METHOD_HEAD\n - HTTP_METHOD_PUT\n - HTTP_METHOD_PATCH\n - HTTP_METHOD_DELETE\n - HTTP_METHOD_TRACE\n - HTTP_METHOD_CONNECT\n - HTTP_METHOD_OPTIONS\n description: HTTP methods supported for monitors.\n openstatus.monitor.v1.HTTPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Production API Health Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n url:\n type: string\n examples:\n - https://api.example.com/health\n title: url\n maxLength: 2048\n minLength: 1\n format: uri\n description: URL to monitor (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n method:\n not:\n enum:\n - HTTP_METHOD_UNSPECIFIED\n title: method\n description: HTTP method to use (defaults to GET).\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMethod'\n body:\n type: string\n examples:\n - map[key:value]\n title: body\n description: Request body (optional).\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n followRedirects:\n type:\n - boolean\n - \"null\"\n title: follow_redirects\n description: Whether to follow HTTP redirects (defaults to true when not specified).\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: headers\n maxItems: 20\n description: Custom headers for the request.\n statusCodeAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.StatusCodeAssertion'\n title: status_code_assertions\n maxItems: 10\n description: Status code assertions for the response.\n bodyAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.BodyAssertion'\n title: body_assertions\n maxItems: 10\n description: Body content assertions for the response.\n headerAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HeaderAssertion'\n title: header_assertions\n maxItems: 10\n description: Header assertions for the response.\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: HTTPMonitor\n additionalProperties: false\n description: HTTPMonitor defines the configuration for an HTTP monitor.\n openstatus.monitor.v1.HTTPResponseLogDetail:\n type: object\n properties:\n log:\n title: log\n description: Compact response log fields.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogListItem'\n url:\n type: string\n title: url\n description: Checked URL.\n error:\n type: boolean\n title: error\n description: Whether the check errored.\n message:\n type:\n - string\n - \"null\"\n title: message\n description: Error message, when present.\n headers:\n type: object\n title: headers\n additionalProperties:\n type: string\n title: value\n description: Redacted response headers.\n assertions:\n type:\n - string\n - \"null\"\n title: assertions\n description: Serialized assertions used for the check.\n title: HTTPResponseLogDetail\n additionalProperties: false\n description: HTTPResponseLogDetail contains full response log debugging data.\n openstatus.monitor.v1.HTTPResponseLogDetail.HeadersEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: HeadersEntry\n additionalProperties: false\n openstatus.monitor.v1.HTTPResponseLogListItem:\n type: object\n properties:\n id:\n type:\n - string\n - \"null\"\n title: id\n description: Response log ID.\n latency:\n type: integer\n title: latency\n format: int32\n description: Latency in milliseconds.\n statusCode:\n type:\n - integer\n - \"null\"\n title: status_code\n format: int32\n description: HTTP status code.\n monitorId:\n type: string\n title: monitor_id\n description: Monitor ID.\n requestStatus:\n title: request_status\n description: Request status classification.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogRequestStatus'\n region:\n title: region\n description: Region where the check ran.\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n cronTimestamp:\n type:\n - integer\n - string\n title: cron_timestamp\n format: int64\n description: Cron bucket timestamp in Unix milliseconds.\n trigger:\n title: trigger\n description: Check trigger.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogTrigger'\n timestamp:\n type:\n - integer\n - string\n title: timestamp\n format: int64\n description: Response timestamp in Unix milliseconds.\n timing:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogTiming'\n - type: \"null\"\n title: timing\n description: Timing phases.\n title: HTTPResponseLogListItem\n additionalProperties: false\n description: HTTPResponseLogListItem is a compact response log entry.\n openstatus.monitor.v1.HTTPResponseLogPagination:\n type: object\n properties:\n limit:\n type: integer\n title: limit\n format: int32\n description: Requested page size.\n offset:\n type: integer\n title: offset\n format: int32\n description: Requested offset.\n hasMore:\n type: boolean\n title: has_more\n description: Whether more logs are available.\n nextOffset:\n type:\n - integer\n - \"null\"\n title: next_offset\n format: int32\n description: Next offset if more logs are available.\n title: HTTPResponseLogPagination\n additionalProperties: false\n description: HTTPResponseLogPagination contains offset pagination metadata.\n openstatus.monitor.v1.HTTPResponseLogRequestStatus:\n type: string\n title: HTTPResponseLogRequestStatus\n enum:\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_UNSPECIFIED\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_SUCCESS\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_ERROR\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_DEGRADED\n description: HTTPResponseLogRequestStatus is the result classification for an HTTP response log.\n openstatus.monitor.v1.HTTPResponseLogTiming:\n type: object\n properties:\n dns:\n type: integer\n title: dns\n format: int32\n description: DNS lookup duration.\n connect:\n type: integer\n title: connect\n format: int32\n description: TCP connection duration.\n tls:\n type: integer\n title: tls\n format: int32\n description: TLS handshake duration.\n ttfb:\n type: integer\n title: ttfb\n format: int32\n description: Time to first byte duration.\n transfer:\n type: integer\n title: transfer\n format: int32\n description: Response transfer duration.\n title: HTTPResponseLogTiming\n additionalProperties: false\n description: HTTPResponseLogTiming contains calculated timing phases in milliseconds.\n openstatus.monitor.v1.HTTPResponseLogTrigger:\n type: string\n title: HTTPResponseLogTrigger\n enum:\n - HTTP_RESPONSE_LOG_TRIGGER_UNSPECIFIED\n - HTTP_RESPONSE_LOG_TRIGGER_CRON\n - HTTP_RESPONSE_LOG_TRIGGER_API\n description: HTTPResponseLogTrigger describes what started the monitor check.\n openstatus.monitor.v1.HeaderAssertion:\n type: object\n properties:\n target:\n type: string\n title: target\n description: Target value to compare against.\n comparator:\n not:\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.StringComparator'\n key:\n type: string\n title: key\n minLength: 1\n description: Header key to check (required).\n title: HeaderAssertion\n additionalProperties: false\n description: HeaderAssertion defines an assertion for response headers.\n openstatus.monitor.v1.Headers:\n type: object\n properties:\n key:\n type: string\n examples:\n - Authorization\n title: key\n minLength: 1\n description: Header name.\n value:\n type: string\n examples:\n - Bearer token123\n title: value\n description: Header value.\n title: Headers\n additionalProperties: false\n description: Headers represents a key-value pair for HTTP headers.\n openstatus.monitor.v1.ICMPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Ping Gateway\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - 1.1.1.1\n title: uri\n maxLength: 2048\n minLength: 1\n description: URI to monitor in format \"host or IP\" (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: ICMPMonitor\n additionalProperties: false\n description: ICMPMonitor defines the configuration for a ICMP monitor.\n openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to list response logs for (required).\n fromTimestamp:\n type:\n - integer\n - string\n - \"null\"\n title: from_timestamp\n format: int64\n description: Start of the response log window as Unix milliseconds within the 14-day retention window.\n toTimestamp:\n type:\n - integer\n - string\n - \"null\"\n title: to_timestamp\n format: int64\n description: End of the response log window as Unix milliseconds within the 14-day retention window.\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of logs to return (1-100, defaults to 25).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of logs to skip for pagination (defaults to 0).\n title: ListMonitorHTTPResponseLogsRequest\n additionalProperties: false\n description: ListMonitorHTTPResponseLogsRequest is the request to list response logs within the 14-day HTTP response-log window.\n openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse:\n type: object\n properties:\n logs:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogListItem'\n title: logs\n description: Response logs.\n pagination:\n title: pagination\n description: Pagination metadata.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogPagination'\n title: ListMonitorHTTPResponseLogsResponse\n additionalProperties: false\n description: ListMonitorHTTPResponseLogsResponse is the response containing response logs.\n openstatus.monitor.v1.ListMonitorsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of monitors to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of monitors to skip for pagination (defaults to 0).\n title: ListMonitorsRequest\n additionalProperties: false\n description: ListMonitorsRequest is the request to list monitors.\n openstatus.monitor.v1.ListMonitorsResponse:\n type: object\n properties:\n httpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: http_monitors\n description: HTTP monitors in the workspace.\n tcpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: tcp_monitors\n description: TCP monitors in the workspace.\n dnsMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: dns_monitors\n description: DNS monitors in the workspace.\n icmpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: icmp_monitors\n description: ICMP monitors in the workspace.\n grpcMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: grpc_monitors\n description: gRPC monitors in the workspace.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of monitors across all types.\n title: ListMonitorsResponse\n additionalProperties: false\n description: ListMonitorsResponse is the response containing a list of monitors.\n openstatus.monitor.v1.MonitorConfig:\n type: object\n oneOf:\n - type: object\n properties:\n dns:\n title: dns\n description: DNS monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: dns\n required:\n - dns\n - type: object\n properties:\n grpc:\n title: grpc\n description: gRPC monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: grpc\n required:\n - grpc\n - type: object\n properties:\n http:\n title: http\n description: HTTP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: http\n required:\n - http\n - type: object\n properties:\n icmp:\n title: icmp\n description: ICMP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: icmp\n required:\n - icmp\n - type: object\n properties:\n tcp:\n title: tcp\n description: TCP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: tcp\n required:\n - tcp\n title: MonitorConfig\n additionalProperties: false\n description: MonitorConfig represents the type-specific configuration for a monitor.\n openstatus.monitor.v1.MonitorStatus:\n type: string\n title: MonitorStatus\n enum:\n - MONITOR_STATUS_UNSPECIFIED\n - MONITOR_STATUS_ACTIVE\n - MONITOR_STATUS_DEGRADED\n - MONITOR_STATUS_ERROR\n description: MonitorStatus represents the operational status of a monitor.\n openstatus.monitor.v1.NumberComparator:\n type: string\n title: NumberComparator\n enum:\n - NUMBER_COMPARATOR_UNSPECIFIED\n - NUMBER_COMPARATOR_EQUAL\n - NUMBER_COMPARATOR_NOT_EQUAL\n - NUMBER_COMPARATOR_GREATER_THAN\n - NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL\n - NUMBER_COMPARATOR_LESS_THAN\n - NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL\n description: NumberComparator defines comparison operations for numeric values.\n openstatus.monitor.v1.OpenTelemetryConfig:\n type: object\n properties:\n endpoint:\n type: string\n title: endpoint\n maxLength: 2048\n description: OTEL endpoint URL.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: headers\n maxItems: 20\n description: Custom headers for OTEL requests.\n title: OpenTelemetryConfig\n additionalProperties: false\n description: OpenTelemetry configuration for exporting metrics.\n openstatus.monitor.v1.Periodicity:\n type: string\n title: Periodicity\n enum:\n - PERIODICITY_UNSPECIFIED\n - PERIODICITY_30S\n - PERIODICITY_1M\n - PERIODICITY_5M\n - PERIODICITY_10M\n - PERIODICITY_30M\n - PERIODICITY_1H\n description: Monitor periodicity options.\n openstatus.monitor.v1.RecordAssertion:\n type: object\n properties:\n record:\n type: string\n title: record\n enum:\n - A\n - AAAA\n - CNAME\n - MX\n - TXT\n description: DNS record type (e.g., \"A\", \"AAAA\", \"CNAME\", \"MX\", \"TXT\").\n comparator:\n not:\n enum:\n - RECORD_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.RecordComparator'\n target:\n type: string\n title: target\n description: Target value to compare against.\n title: RecordAssertion\n additionalProperties: false\n description: RecordAssertion defines an assertion for DNS records.\n openstatus.monitor.v1.RecordComparator:\n type: string\n title: RecordComparator\n enum:\n - RECORD_COMPARATOR_UNSPECIFIED\n - RECORD_COMPARATOR_EQUAL\n - RECORD_COMPARATOR_NOT_EQUAL\n - RECORD_COMPARATOR_CONTAINS\n - RECORD_COMPARATOR_NOT_CONTAINS\n description: RecordComparator defines comparison operations for DNS records.\n openstatus.monitor.v1.Region:\n type: string\n title: Region\n enum:\n - REGION_UNSPECIFIED\n - REGION_FLY_AMS\n - REGION_FLY_ARN\n - REGION_FLY_BOM\n - REGION_FLY_CDG\n - REGION_FLY_DFW\n - REGION_FLY_EWR\n - REGION_FLY_FRA\n - REGION_FLY_GRU\n - REGION_FLY_IAD\n - REGION_FLY_JNB\n - REGION_FLY_LAX\n - REGION_FLY_LHR\n - REGION_FLY_NRT\n - REGION_FLY_ORD\n - REGION_FLY_SJC\n - REGION_FLY_SIN\n - REGION_FLY_SYD\n - REGION_FLY_YYZ\n - REGION_KOYEB_FRA\n - REGION_KOYEB_PAR\n - REGION_KOYEB_SFO\n - REGION_KOYEB_SIN\n - REGION_KOYEB_TYO\n - REGION_KOYEB_WAS\n - REGION_RAILWAY_US_WEST2\n - REGION_RAILWAY_US_EAST4\n - REGION_RAILWAY_EUROPE_WEST4\n - REGION_RAILWAY_ASIA_SOUTHEAST1\n description: |-\n Geographic regions where monitors can run checks from.\n REGION_FLY_BOM is deprecated and rejected on create/update; use REGION_FLY_SIN.\n openstatus.monitor.v1.RegionStatus:\n type: object\n properties:\n region:\n title: region\n description: The region identifier.\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n status:\n title: status\n description: The status of the monitor in this region.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n title: RegionStatus\n additionalProperties: false\n description: RegionStatus represents the status of a monitor in a specific region.\n openstatus.monitor.v1.StatusCodeAssertion:\n type: object\n properties:\n target:\n type:\n - integer\n - string\n title: target\n maximum: 599\n minimum: 100\n format: int64\n description: Target status code to compare against (100-599).\n comparator:\n not:\n enum:\n - NUMBER_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.NumberComparator'\n title: StatusCodeAssertion\n additionalProperties: false\n description: StatusCodeAssertion defines an assertion for HTTP status codes.\n openstatus.monitor.v1.StringComparator:\n type: string\n title: StringComparator\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n - STRING_COMPARATOR_CONTAINS\n - STRING_COMPARATOR_NOT_CONTAINS\n - STRING_COMPARATOR_EQUAL\n - STRING_COMPARATOR_NOT_EQUAL\n - STRING_COMPARATOR_EMPTY\n - STRING_COMPARATOR_NOT_EMPTY\n - STRING_COMPARATOR_GREATER_THAN\n - STRING_COMPARATOR_GREATER_THAN_OR_EQUAL\n - STRING_COMPARATOR_LESS_THAN\n - STRING_COMPARATOR_LESS_THAN_OR_EQUAL\n description: StringComparator defines comparison operations for string values.\n openstatus.monitor.v1.TCPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Database Connection Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - tcp://db.example.com:5432\n title: uri\n maxLength: 2048\n minLength: 1\n description: URI to monitor in format \"host:port\" (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: TCPMonitor\n additionalProperties: false\n description: TCPMonitor defines the configuration for a TCP monitor.\n openstatus.monitor.v1.TimeRange:\n type: string\n title: TimeRange\n enum:\n - TIME_RANGE_UNSPECIFIED\n - TIME_RANGE_1D\n - TIME_RANGE_7D\n - TIME_RANGE_14D\n description: TimeRange represents the time period for metrics aggregation.\n openstatus.monitor.v1.TriggerMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to trigger (required).\n title: TriggerMonitorRequest\n additionalProperties: false\n description: TriggerMonitorRequest is the request to trigger a monitor check.\n openstatus.monitor.v1.TriggerMonitorResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the trigger was successful.\n title: TriggerMonitorResponse\n additionalProperties: false\n description: TriggerMonitorResponse is the response after triggering a monitor.\n openstatus.monitor.v1.UpdateDNSMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateDNSMonitorRequest\n additionalProperties: false\n description: UpdateDNSMonitorRequest is the request to update an existing DNS monitor.\n openstatus.monitor.v1.UpdateDNSMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: UpdateDNSMonitorResponse\n additionalProperties: false\n description: UpdateDNSMonitorResponse is the response after updating a DNS monitor.\n openstatus.monitor.v1.UpdateGRPCMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateGRPCMonitorRequest\n additionalProperties: false\n description: UpdateGRPCMonitorRequest is the request to update an existing gRPC monitor.\n openstatus.monitor.v1.UpdateGRPCMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: UpdateGRPCMonitorResponse\n additionalProperties: false\n description: UpdateGRPCMonitorResponse is the response after updating a gRPC monitor.\n openstatus.monitor.v1.UpdateHTTPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateHTTPMonitorRequest\n additionalProperties: false\n description: UpdateHTTPMonitorRequest is the request to update an existing HTTP monitor.\n openstatus.monitor.v1.UpdateHTTPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: UpdateHTTPMonitorResponse\n additionalProperties: false\n description: UpdateHTTPMonitorResponse is the response after updating an HTTP monitor.\n openstatus.monitor.v1.UpdateICMPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateICMPMonitorRequest\n additionalProperties: false\n description: UpdateICMPMonitorRequest is the request to update an existing ICMP monitor.\n openstatus.monitor.v1.UpdateICMPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: UpdateICMPMonitorResponse\n additionalProperties: false\n description: UpdateICMPMonitorResponse is the response after updating an ICMP monitor.\n openstatus.monitor.v1.UpdateTCPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateTCPMonitorRequest\n additionalProperties: false\n description: UpdateTCPMonitorRequest is the request to update an existing TCP monitor.\n openstatus.monitor.v1.UpdateTCPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: UpdateTCPMonitorResponse\n additionalProperties: false\n description: UpdateTCPMonitorResponse is the response after updating a TCP monitor.\n openstatus.notification.v1.CheckNotificationLimitRequest:\n type: object\n title: CheckNotificationLimitRequest\n additionalProperties: false\n description: CheckNotificationLimitRequest is the request to check notification limits.\n openstatus.notification.v1.CheckNotificationLimitResponse:\n type: object\n properties:\n limitReached:\n type: boolean\n title: limit_reached\n description: Whether the workspace has reached its notification limit.\n currentCount:\n type: integer\n title: current_count\n format: int32\n description: Current number of notification channels.\n maxCount:\n type: integer\n title: max_count\n format: int32\n description: Maximum allowed notification channels.\n title: CheckNotificationLimitResponse\n additionalProperties: false\n description: CheckNotificationLimitResponse is the response containing limit information.\n openstatus.notification.v1.CreateNotificationRequest:\n type: object\n properties:\n name:\n type: string\n examples:\n - Slack Ops Channel\n title: name\n minLength: 1\n description: Display name for the notification channel.\n provider:\n not:\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors to associate with this notification.\n title: CreateNotificationRequest\n required:\n - data\n additionalProperties: false\n description: CreateNotificationRequest is the request to create a new notification channel.\n openstatus.notification.v1.CreateNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The created notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: CreateNotificationResponse\n additionalProperties: false\n description: CreateNotificationResponse is the response after creating a notification channel.\n openstatus.notification.v1.DeleteNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to delete (required).\n title: DeleteNotificationRequest\n additionalProperties: false\n description: DeleteNotificationRequest is the request to delete a notification channel.\n openstatus.notification.v1.DeleteNotificationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteNotificationResponse\n additionalProperties: false\n description: DeleteNotificationResponse is the response after deleting a notification channel.\n openstatus.notification.v1.DiscordData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://discord.com/api/webhooks/123/abc\n title: webhook_url\n format: uri\n description: Discord webhook URL.\n title: DiscordData\n additionalProperties: false\n description: DiscordData contains configuration for Discord notifications.\n openstatus.notification.v1.EmailData:\n type: object\n properties:\n email:\n type: string\n examples:\n - ops-team@example.com\n title: email\n format: email\n description: Email address to send notifications to.\n title: EmailData\n additionalProperties: false\n description: EmailData contains configuration for email notifications.\n openstatus.notification.v1.GetNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to retrieve (required).\n title: GetNotificationRequest\n additionalProperties: false\n description: GetNotificationRequest is the request to get a notification channel.\n openstatus.notification.v1.GetNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: GetNotificationResponse\n additionalProperties: false\n description: GetNotificationResponse is the response containing the notification channel.\n openstatus.notification.v1.GoogleChatData:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n format: uri\n description: Google Chat webhook URL.\n title: GoogleChatData\n additionalProperties: false\n description: GoogleChatData contains configuration for Google Chat notifications.\n openstatus.notification.v1.GrafanaOncallData:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n format: uri\n description: Grafana OnCall webhook URL.\n title: GrafanaOncallData\n additionalProperties: false\n description: GrafanaOncallData contains configuration for Grafana OnCall notifications.\n openstatus.notification.v1.ListNotificationsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of notifications to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of notifications to skip for pagination (defaults to 0).\n title: ListNotificationsRequest\n additionalProperties: false\n description: ListNotificationsRequest is the request to list notification channels.\n openstatus.notification.v1.ListNotificationsResponse:\n type: object\n properties:\n notifications:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationSummary'\n title: notifications\n description: Notification channel summaries.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of notification channels.\n title: ListNotificationsResponse\n additionalProperties: false\n description: ListNotificationsResponse is the response containing notification channels.\n openstatus.notification.v1.MsTeamsData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://prod-00.westeurope.logic.azure.com:443/workflows/abc/triggers/manual/paths/invoke\n title: webhook_url\n format: uri\n description: Microsoft Teams webhook URL (Power Automate Workflows).\n title: MsTeamsData\n additionalProperties: false\n description: MsTeamsData contains configuration for Microsoft Teams notifications.\n openstatus.notification.v1.Notification:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the notification.\n name:\n type: string\n title: name\n description: Display name for the notification channel.\n provider:\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors associated with this notification.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the notification was created (RFC 3339).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the notification was last updated (RFC 3339).\n title: Notification\n additionalProperties: false\n description: Notification represents a notification channel with full details.\n openstatus.notification.v1.NotificationData:\n type: object\n oneOf:\n - type: object\n properties:\n discord:\n title: discord\n description: Discord configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.DiscordData'\n title: discord\n required:\n - discord\n - type: object\n properties:\n email:\n title: email\n description: Email configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.EmailData'\n title: email\n required:\n - email\n - type: object\n properties:\n googleChat:\n title: google_chat\n description: Google Chat configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.GoogleChatData'\n title: google_chat\n required:\n - googleChat\n - type: object\n properties:\n grafanaOncall:\n title: grafana_oncall\n description: Grafana OnCall configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.GrafanaOncallData'\n title: grafana_oncall\n required:\n - grafanaOncall\n - type: object\n properties:\n msTeams:\n title: ms_teams\n description: Microsoft Teams configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.MsTeamsData'\n title: ms_teams\n required:\n - msTeams\n - type: object\n properties:\n ntfy:\n title: ntfy\n description: Ntfy configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NtfyData'\n title: ntfy\n required:\n - ntfy\n - type: object\n properties:\n opsgenie:\n title: opsgenie\n description: Opsgenie configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.OpsgenieData'\n title: opsgenie\n required:\n - opsgenie\n - type: object\n properties:\n pagerduty:\n title: pagerduty\n description: PagerDuty configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.PagerDutyData'\n title: pagerduty\n required:\n - pagerduty\n - type: object\n properties:\n slack:\n title: slack\n description: Slack configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.SlackData'\n title: slack\n required:\n - slack\n - type: object\n properties:\n sms:\n title: sms\n description: 'Deprecated: SMS is no longer offered; use whatsapp.'\n deprecated: true\n $ref: '#/components/schemas/openstatus.notification.v1.SmsData'\n title: sms\n required:\n - sms\n - type: object\n properties:\n telegram:\n title: telegram\n description: Telegram configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.TelegramData'\n title: telegram\n required:\n - telegram\n - type: object\n properties:\n webhook:\n title: webhook\n description: Webhook configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.WebhookData'\n title: webhook\n required:\n - webhook\n - type: object\n properties:\n whatsapp:\n title: whatsapp\n description: WhatsApp configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.WhatsappData'\n title: whatsapp\n required:\n - whatsapp\n title: NotificationData\n additionalProperties: false\n description: NotificationData is a union of provider-specific configuration.\n openstatus.notification.v1.NotificationProvider:\n type: string\n title: NotificationProvider\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n - NOTIFICATION_PROVIDER_DISCORD\n - NOTIFICATION_PROVIDER_EMAIL\n - NOTIFICATION_PROVIDER_GOOGLE_CHAT\n - NOTIFICATION_PROVIDER_GRAFANA_ONCALL\n - NOTIFICATION_PROVIDER_NTFY\n - NOTIFICATION_PROVIDER_PAGERDUTY\n - NOTIFICATION_PROVIDER_OPSGENIE\n - NOTIFICATION_PROVIDER_SLACK\n - NOTIFICATION_PROVIDER_SMS\n - NOTIFICATION_PROVIDER_TELEGRAM\n - NOTIFICATION_PROVIDER_WEBHOOK\n - NOTIFICATION_PROVIDER_WHATSAPP\n - NOTIFICATION_PROVIDER_MS_TEAMS\n description: NotificationProvider represents the supported notification channel types.\n openstatus.notification.v1.NotificationSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the notification.\n name:\n type: string\n title: name\n description: Display name for the notification channel.\n provider:\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n monitorCount:\n type: integer\n title: monitor_count\n format: int32\n description: Number of monitors associated with this notification.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the notification was created (RFC 3339).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the notification was last updated (RFC 3339).\n title: NotificationSummary\n additionalProperties: false\n description: NotificationSummary represents a notification channel summary for list responses.\n openstatus.notification.v1.NtfyData:\n type: object\n properties:\n topic:\n type: string\n examples:\n - openstatus-alerts\n title: topic\n minLength: 1\n description: Ntfy topic to publish to.\n serverUrl:\n type: string\n title: server_url\n description: Ntfy server URL (defaults to https://ntfy.sh).\n token:\n type:\n - string\n - \"null\"\n title: token\n description: Optional authentication token.\n title: NtfyData\n additionalProperties: false\n description: NtfyData contains configuration for Ntfy notifications.\n openstatus.notification.v1.OpsgenieData:\n type: object\n properties:\n apiKey:\n type: string\n title: api_key\n minLength: 1\n description: Opsgenie API key.\n region:\n title: region\n description: Opsgenie region.\n $ref: '#/components/schemas/openstatus.notification.v1.OpsgenieRegion'\n title: OpsgenieData\n additionalProperties: false\n description: OpsgenieData contains configuration for Opsgenie notifications.\n openstatus.notification.v1.OpsgenieRegion:\n type: string\n title: OpsgenieRegion\n enum:\n - OPSGENIE_REGION_UNSPECIFIED\n - OPSGENIE_REGION_US\n - OPSGENIE_REGION_EU\n description: OpsgenieRegion represents the Opsgenie API region.\n openstatus.notification.v1.PagerDutyData:\n type: object\n properties:\n integrationKey:\n type: string\n examples:\n - a1b2c3d4e5f6g7h8i9j0\n title: integration_key\n minLength: 1\n description: PagerDuty integration key.\n title: PagerDutyData\n additionalProperties: false\n description: PagerDutyData contains configuration for PagerDuty notifications.\n openstatus.notification.v1.SendTestNotificationRequest:\n type: object\n properties:\n provider:\n not:\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n title: SendTestNotificationRequest\n required:\n - data\n additionalProperties: false\n description: SendTestNotificationRequest is the request to send a test notification.\n openstatus.notification.v1.SendTestNotificationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the test was successful.\n errorMessage:\n type:\n - string\n - \"null\"\n title: error_message\n description: Optional error message if the test failed.\n title: SendTestNotificationResponse\n additionalProperties: false\n description: SendTestNotificationResponse is the response after sending a test notification.\n openstatus.notification.v1.SlackData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://hooks.slack.com/services/T00/B00/xxx\n title: webhook_url\n format: uri\n description: Slack webhook URL.\n title: SlackData\n additionalProperties: false\n description: SlackData contains configuration for Slack notifications.\n openstatus.notification.v1.SmsData:\n type: object\n properties:\n phoneNumber:\n type: string\n examples:\n - \"+14155551234\"\n title: phone_number\n minLength: 1\n description: Phone number to send SMS to.\n title: SmsData\n additionalProperties: false\n description: 'Deprecated: SMS is no longer offered; use WhatsappData. Kept for existing channels.'\n deprecated: true\n openstatus.notification.v1.TelegramData:\n type: object\n properties:\n chatId:\n type: string\n examples:\n - \"-1001234567890\"\n title: chat_id\n minLength: 1\n description: Telegram chat ID.\n title: TelegramData\n additionalProperties: false\n description: TelegramData contains configuration for Telegram notifications.\n openstatus.notification.v1.UpdateNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n description: Updated display name.\n data:\n oneOf:\n - $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n - type: \"null\"\n title: data\n description: Updated provider-specific configuration.\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: Updated monitor IDs to associate.\n updateMonitorIds:\n type:\n - boolean\n - \"null\"\n title: update_monitor_ids\n description: |-\n Set to true to update monitor associations.\n When true, monitor_ids replaces the existing list (empty clears all).\n When false or unset, monitor_ids is ignored and existing associations are preserved.\n title: UpdateNotificationRequest\n additionalProperties: false\n description: UpdateNotificationRequest is the request to update a notification channel.\n openstatus.notification.v1.UpdateNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The updated notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: UpdateNotificationResponse\n additionalProperties: false\n description: UpdateNotificationResponse is the response after updating a notification channel.\n openstatus.notification.v1.WebhookData:\n type: object\n properties:\n endpoint:\n type: string\n examples:\n - https://api.example.com/webhooks/openstatus\n title: endpoint\n format: uri\n description: Webhook endpoint URL.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.notification.v1.WebhookHeader'\n title: headers\n description: Optional custom headers.\n title: WebhookData\n additionalProperties: false\n description: WebhookData contains configuration for custom webhook notifications.\n openstatus.notification.v1.WebhookHeader:\n type: object\n properties:\n key:\n type: string\n title: key\n minLength: 1\n description: Header name.\n value:\n type: string\n title: value\n description: Header value.\n title: WebhookHeader\n additionalProperties: false\n description: WebhookHeader represents a custom header for webhook requests.\n openstatus.notification.v1.WhatsappData:\n type: object\n properties:\n phoneNumber:\n type: string\n title: phone_number\n minLength: 1\n description: Phone number to send WhatsApp messages to.\n title: WhatsappData\n additionalProperties: false\n description: WhatsappData contains configuration for WhatsApp notifications.\n openstatus.private_location.v1.CreatePrivateLocationRequest:\n type: object\n properties:\n name:\n type: string\n examples:\n - eu-west-agent\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the private location (required, 1-256 characters).\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors this private location should run (optional).\n metadata:\n type: object\n title: metadata\n maxProperties: 20\n additionalProperties:\n type: string\n title: value\n maxLength: 256\n description: User-defined key/value labels (optional, up to 20 entries).\n title: CreatePrivateLocationRequest\n additionalProperties: false\n description: CreatePrivateLocationRequest is the request to create a new private location.\n openstatus.private_location.v1.CreatePrivateLocationRequest.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.CreatePrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The created private location, including its generated agent token.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: CreatePrivateLocationResponse\n additionalProperties: false\n description: CreatePrivateLocationResponse is the response after creating a private location.\n openstatus.private_location.v1.DeletePrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to delete (required).\n title: DeletePrivateLocationRequest\n additionalProperties: false\n description: DeletePrivateLocationRequest is the request to delete a private location.\n openstatus.private_location.v1.DeletePrivateLocationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeletePrivateLocationResponse\n additionalProperties: false\n description: DeletePrivateLocationResponse is the response after deleting a private location.\n openstatus.private_location.v1.GetPrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to retrieve (required).\n title: GetPrivateLocationRequest\n additionalProperties: false\n description: GetPrivateLocationRequest is the request to get a private location by ID.\n openstatus.private_location.v1.GetPrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The requested private location.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: GetPrivateLocationResponse\n additionalProperties: false\n description: GetPrivateLocationResponse is the response containing the private location.\n openstatus.private_location.v1.ListPrivateLocationsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of private locations to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of private locations to skip for pagination (defaults to 0).\n title: ListPrivateLocationsRequest\n additionalProperties: false\n description: ListPrivateLocationsRequest is the request to list private locations.\n openstatus.private_location.v1.ListPrivateLocationsResponse:\n type: object\n properties:\n privateLocations:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationSummary'\n title: private_locations\n description: List of private locations.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of private locations in the workspace.\n title: ListPrivateLocationsResponse\n additionalProperties: false\n description: ListPrivateLocationsResponse is the response containing private location summaries.\n openstatus.private_location.v1.PrivateLocation:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the private location.\n name:\n type: string\n title: name\n description: Display name for the private location.\n token:\n type: string\n title: token\n description: |-\n Agent credential. Generated by the server on creation and used by the\n agent to authenticate; treat it as a secret.\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors this private location runs.\n lastSeenAt:\n type: string\n title: last_seen_at\n description: Last time the agent reported a result (RFC 3339), empty if it never has.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the private location was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the private location was last updated (RFC 3339 format).\n metadata:\n type: object\n title: metadata\n additionalProperties:\n type: string\n title: value\n description: User-defined key/value labels attached to this private location.\n status:\n title: status\n description: Computed health of the agent. Read-only.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationStatus'\n title: PrivateLocation\n additionalProperties: false\n description: PrivateLocation represents a self-hosted checker agent with full details.\n openstatus.private_location.v1.PrivateLocation.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.PrivateLocationStatus:\n type: string\n title: PrivateLocationStatus\n enum:\n - PRIVATE_LOCATION_STATUS_UNSPECIFIED\n - PRIVATE_LOCATION_STATUS_ACTIVE\n - PRIVATE_LOCATION_STATUS_ERROR\n description: |-\n PrivateLocationStatus is the computed health of a private location, derived\n from the agent heartbeat. Read-only — it cannot be set through the API.\n openstatus.private_location.v1.PrivateLocationSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the private location.\n name:\n type: string\n title: name\n description: Display name for the private location.\n monitorCount:\n type: integer\n title: monitor_count\n format: int32\n description: Number of monitors this private location runs.\n lastSeenAt:\n type: string\n title: last_seen_at\n description: Last time the agent reported a result (RFC 3339), empty if it never has.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the private location was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the private location was last updated (RFC 3339 format).\n status:\n title: status\n description: Computed health of the agent. Read-only.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationStatus'\n metadata:\n type: object\n title: metadata\n additionalProperties:\n type: string\n title: value\n description: User-defined key/value labels attached to this private location.\n title: PrivateLocationSummary\n additionalProperties: false\n description: |-\n PrivateLocationSummary represents metadata for a private location (used in\n list responses). The agent token is intentionally omitted.\n openstatus.private_location.v1.PrivateLocationSummary.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.UpdatePrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n minLength: 1\n description: New display name for the private location (optional).\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: New list of monitor IDs. Only applied when update_monitor_ids is true.\n updateMonitorIds:\n type:\n - boolean\n - \"null\"\n title: update_monitor_ids\n description: |-\n When true, monitor_ids replaces the current associations (an empty list\n clears all). When false or unset, monitor_ids is ignored and existing\n associations are preserved.\n metadata:\n type: object\n title: metadata\n maxProperties: 20\n additionalProperties:\n type: string\n title: value\n maxLength: 256\n description: New key/value labels. Only applied when update_metadata is true.\n updateMetadata:\n type:\n - boolean\n - \"null\"\n title: update_metadata\n description: |-\n When true, metadata replaces the current labels (an empty map clears all).\n When false or unset, metadata is ignored and existing labels are preserved.\n title: UpdatePrivateLocationRequest\n additionalProperties: false\n description: UpdatePrivateLocationRequest is the request to update a private location.\n openstatus.private_location.v1.UpdatePrivateLocationRequest.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.UpdatePrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The updated private location.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: UpdatePrivateLocationResponse\n additionalProperties: false\n description: UpdatePrivateLocationResponse is the response after updating a private location.\n openstatus.status_page.v1.AddMonitorComponentRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to add the component to (required).\n monitorId:\n type: string\n title: monitor_id\n minLength: 1\n description: ID of the monitor to associate with this component (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n description: Display name for the component (optional, defaults to monitor name).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: Display order of the component (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: ID of the group to add this component to (optional).\n title: AddMonitorComponentRequest\n additionalProperties: false\n description: AddMonitorComponentRequest is the request to add a monitor-based component to a status page.\n openstatus.status_page.v1.AddMonitorComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The created component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: AddMonitorComponentResponse\n additionalProperties: false\n description: AddMonitorComponentResponse is the response after adding a monitor component.\n openstatus.status_page.v1.AddStaticComponentRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to add the component to (required).\n name:\n type: string\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the component (required).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: Display order of the component (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: ID of the group to add this component to (optional).\n title: AddStaticComponentRequest\n additionalProperties: false\n description: AddStaticComponentRequest is the request to add a static component to a status page.\n openstatus.status_page.v1.AddStaticComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The created component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: AddStaticComponentResponse\n additionalProperties: false\n description: AddStaticComponentResponse is the response after adding a static component.\n openstatus.status_page.v1.ComponentDayBucket:\n type: object\n properties:\n day:\n type: string\n title: day\n description: Day in RFC 3339 format (UTC midnight).\n count:\n type:\n - integer\n - string\n title: count\n format: int64\n description: Total checks that day.\n ok:\n type:\n - integer\n - string\n title: ok\n format: int64\n description: Successful checks.\n degraded:\n type:\n - integer\n - string\n title: degraded\n format: int64\n description: Degraded checks.\n error:\n type:\n - integer\n - string\n title: error\n format: int64\n description: Failed checks.\n status:\n title: status\n description: Convenience resolved status for the day.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentDayStatus'\n impact:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n - type: \"null\"\n title: impact\n description: Worst status-report impact overlapping the day (absent when none).\n title: ComponentDayBucket\n additionalProperties: false\n description: ComponentDayBucket is one day of status data for a component.\n openstatus.status_page.v1.ComponentDayStatus:\n type: string\n title: ComponentDayStatus\n enum:\n - COMPONENT_DAY_STATUS_UNSPECIFIED\n - COMPONENT_DAY_STATUS_OPERATIONAL\n - COMPONENT_DAY_STATUS_DEGRADED\n - COMPONENT_DAY_STATUS_DOWN\n - COMPONENT_DAY_STATUS_MAINTENANCE\n - COMPONENT_DAY_STATUS_EMPTY\n description: ComponentDayStatus is the resolved status of a component on a given day.\n openstatus.status_page.v1.ComponentEvent:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Identifier of the underlying event.\n name:\n type: string\n title: name\n description: Human-readable name (incident \"Downtime\", maintenance / report title).\n type:\n title: type\n description: Kind of event.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEventType'\n status:\n title: status\n description: Projected status this event contributes.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEventStatus'\n from:\n type: string\n title: from\n description: Start time (RFC 3339).\n to:\n type:\n - string\n - \"null\"\n title: to\n description: End time (RFC 3339); absent while the event is ongoing.\n impact:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n - type: \"null\"\n title: impact\n description: Worst impact over the event (reports only; absent otherwise).\n title: ComponentEvent\n additionalProperties: false\n description: ComponentEvent is a single incident / maintenance / report affecting a component.\n openstatus.status_page.v1.ComponentEventStatus:\n type: string\n title: ComponentEventStatus\n enum:\n - COMPONENT_EVENT_STATUS_UNSPECIFIED\n - COMPONENT_EVENT_STATUS_OPERATIONAL\n - COMPONENT_EVENT_STATUS_DEGRADED\n - COMPONENT_EVENT_STATUS_DOWN\n - COMPONENT_EVENT_STATUS_MAINTENANCE\n description: ComponentEventStatus is the projected status an event contributes.\n openstatus.status_page.v1.ComponentEventType:\n type: string\n title: ComponentEventType\n enum:\n - COMPONENT_EVENT_TYPE_UNSPECIFIED\n - COMPONENT_EVENT_TYPE_MAINTENANCE\n - COMPONENT_EVENT_TYPE_INCIDENT\n - COMPONENT_EVENT_TYPE_REPORT\n description: ComponentEventType is the kind of timeline event affecting a component.\n openstatus.status_page.v1.ComponentStatus:\n type: object\n properties:\n componentId:\n type: string\n title: component_id\n description: ID of the component.\n status:\n title: status\n description: Current status of the component.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n title: ComponentStatus\n additionalProperties: false\n description: ComponentStatus represents the status of a single component.\n openstatus.status_page.v1.CreateComponentGroupRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to create the group in (required).\n name:\n type: string\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the group (required).\n defaultOpen:\n type:\n - boolean\n - \"null\"\n title: default_open\n description: Whether the group should be expanded by default on the status page (optional, defaults to false).\n title: CreateComponentGroupRequest\n additionalProperties: false\n description: CreateComponentGroupRequest is the request to create a new component group.\n openstatus.status_page.v1.CreateComponentGroupResponse:\n type: object\n properties:\n group:\n title: group\n description: The created component group.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: CreateComponentGroupResponse\n additionalProperties: false\n description: CreateComponentGroupResponse is the response after creating a component group.\n openstatus.status_page.v1.CreatePageSubscriptionRequest:\n type: object\n allOf:\n - properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 255\n description: Optional human-readable label.\n componentIds:\n type: array\n items:\n type: string\n title: component_ids\n description: Component scope. Empty = entire page.\n - oneOf:\n - type: object\n properties:\n emailChannel:\n title: email_channel\n $ref: '#/components/schemas/openstatus.status_page.v1.EmailChannel'\n title: email_channel\n required:\n - emailChannel\n - type: object\n properties:\n webhookChannel:\n title: webhook_channel\n $ref: '#/components/schemas/openstatus.status_page.v1.WebhookChannel'\n title: webhook_channel\n required:\n - webhookChannel\n title: CreatePageSubscriptionRequest\n additionalProperties: false\n description: CreatePageSubscriptionRequest is the request to add a vendor-managed subscriber to a status page.\n openstatus.status_page.v1.CreatePageSubscriptionResponse:\n type: object\n properties:\n subscriber:\n title: subscriber\n description: The created subscriber.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: CreatePageSubscriptionResponse\n additionalProperties: false\n description: CreatePageSubscriptionResponse is the response after creating a vendor-managed subscription.\n openstatus.status_page.v1.CreateStatusPageRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - Acme Corp Status\n title: title\n maxLength: 256\n minLength: 1\n description: Title of the status page (required).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the status page (optional).\n slug:\n type: string\n examples:\n - my-status-page\n title: slug\n maxLength: 256\n minLength: 1\n pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$\n description: URL-friendly slug for the status page (required). Must be lowercase alphanumeric with hyphens.\n homepageUrl:\n type:\n - string\n - \"null\"\n examples:\n - https://www.example.com\n title: homepage_url\n description: URL to the homepage (optional).\n contactUrl:\n type:\n - string\n - \"null\"\n title: contact_url\n description: URL to the contact page (optional).\n defaultLocale:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n - type: \"null\"\n title: default_locale\n description: Default locale for the status page (optional, defaults to EN).\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: Enabled locales for the status page (optional).\n icon:\n type:\n - string\n - \"null\"\n title: icon\n maxLength: 1024\n description: Icon URL for the status page (optional).\n customDomain:\n type:\n - string\n - \"null\"\n title: custom_domain\n maxLength: 256\n description: Custom domain for the status page (optional).\n theme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n - type: \"null\"\n title: theme\n description: Visual theme for the status page (optional, defaults to SYSTEM).\n accessType:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n - type: \"null\"\n title: access_type\n description: Access type for the status page (optional, defaults to PUBLIC).\n password:\n type:\n - string\n - \"null\"\n title: password\n maxLength: 256\n minLength: 1\n description: Password for the status page (required when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: Email domains allowed to access the page (used when access_type is AUTHENTICATED).\n allowIndex:\n type:\n - boolean\n - \"null\"\n title: allow_index\n description: Whether search engines are allowed to index this status page (optional, defaults to true).\n allowedIpRanges:\n type:\n - string\n - \"null\"\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (required when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: |-\n Per-mode CSS variable overrides merged over the theme (optional).\n Only supported variable names are accepted. Requires the custom-theme plan feature.\n title: CreateStatusPageRequest\n additionalProperties: false\n description: CreateStatusPageRequest is the request to create a new status page.\n openstatus.status_page.v1.CreateStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The created status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: CreateStatusPageResponse\n additionalProperties: false\n description: CreateStatusPageResponse is the response after creating a status page.\n openstatus.status_page.v1.CustomTheme:\n type: object\n properties:\n light:\n type: object\n title: light\n additionalProperties:\n type: string\n title: value\n description: 'CSS variable overrides applied in light mode, keyed by variable name (e.g. \"--primary\": \"hsl(24 94% 50%)\").'\n dark:\n type: object\n title: dark\n additionalProperties:\n type: string\n title: value\n description: CSS variable overrides applied in dark mode, keyed by variable name.\n title: CustomTheme\n additionalProperties: false\n description: CustomTheme holds per-mode CSS variable overrides merged over the page theme.\n openstatus.status_page.v1.CustomTheme.DarkEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: DarkEntry\n additionalProperties: false\n openstatus.status_page.v1.CustomTheme.LightEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: LightEntry\n additionalProperties: false\n openstatus.status_page.v1.DeleteComponentGroupRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component group to delete (required).\n title: DeleteComponentGroupRequest\n additionalProperties: false\n description: DeleteComponentGroupRequest is the request to delete a component group.\n openstatus.status_page.v1.DeleteComponentGroupResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteComponentGroupResponse\n additionalProperties: false\n description: DeleteComponentGroupResponse is the response after deleting a component group.\n openstatus.status_page.v1.DeleteStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to delete (required).\n title: DeleteStatusPageRequest\n additionalProperties: false\n description: DeleteStatusPageRequest is the request to delete a status page.\n openstatus.status_page.v1.DeleteStatusPageResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteStatusPageResponse\n additionalProperties: false\n description: DeleteStatusPageResponse is the response after deleting a status page.\n openstatus.status_page.v1.EmailChannel:\n type: object\n properties:\n email:\n type: string\n title: email\n format: email\n description: Email address of the subscriber (required).\n title: EmailChannel\n additionalProperties: false\n description: EmailChannel carries the email-channel fields for CreatePageSubscription.\n openstatus.status_page.v1.GetOverallStatusRequest:\n type: object\n oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetOverallStatusRequest\n additionalProperties: false\n description: GetOverallStatusRequest is the request to get the overall status of a status page.\n openstatus.status_page.v1.GetOverallStatusResponse:\n type: object\n properties:\n overallStatus:\n title: overall_status\n description: Aggregated status across all components.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n componentStatuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentStatus'\n title: component_statuses\n description: Status of individual components.\n title: GetOverallStatusResponse\n additionalProperties: false\n description: GetOverallStatusResponse is the response containing the overall status and individual component statuses.\n openstatus.status_page.v1.GetPageComponentDailySummaryRequest:\n type: object\n allOf:\n - properties:\n componentIds:\n type: array\n items:\n type: string\n minLength: 1\n title: component_ids\n description: Restrict the result to these component ids (optional, defaults to all components).\n days:\n type:\n - integer\n - \"null\"\n title: days\n maximum: 45\n minimum: 1\n format: int32\n description: Number of days to return (1-45, defaults to 45 if unspecified).\n - oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetPageComponentDailySummaryRequest\n additionalProperties: false\n description: GetPageComponentDailySummaryRequest is the request for per-component daily summaries.\n openstatus.status_page.v1.GetPageComponentDailySummaryResponse:\n type: object\n properties:\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentDailySummary'\n title: components\n description: Per-component daily summaries, in page order.\n title: GetPageComponentDailySummaryResponse\n additionalProperties: false\n description: GetPageComponentDailySummaryResponse is the response containing per-component summaries.\n openstatus.status_page.v1.GetPageComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to retrieve (required).\n title: GetPageComponentRequest\n additionalProperties: false\n description: GetPageComponentRequest is the request to fetch a single component by ID.\n openstatus.status_page.v1.GetPageComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The requested component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: GetPageComponentResponse\n additionalProperties: false\n description: GetPageComponentResponse is the response containing the component.\n openstatus.status_page.v1.GetStatusPageContentRequest:\n type: object\n oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetStatusPageContentRequest\n additionalProperties: false\n description: GetStatusPageContentRequest is the request to get the full content of a status page.\n openstatus.status_page.v1.GetStatusPageContentResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The status page details.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: components\n description: Components on the status page.\n groups:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: groups\n description: Component groups on the status page.\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: status_reports\n description: Active and recent status reports.\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: Scheduled maintenances.\n title: GetStatusPageContentResponse\n additionalProperties: false\n description: GetStatusPageContentResponse is the response containing the full status page content.\n openstatus.status_page.v1.GetStatusPageOverviewRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page (required, workspace-scoped).\n title: GetStatusPageOverviewRequest\n additionalProperties: false\n description: GetStatusPageOverviewRequest requests the full overview of a status page by id.\n openstatus.status_page.v1.GetStatusPageOverviewResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The status page details.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n configuration:\n title: configuration\n description: Rich rendering configuration of the page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageConfiguration'\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: components\n description: Components on the status page.\n groups:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: groups\n description: Component groups on the status page.\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: status_reports\n description: Active and recent status reports.\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: Scheduled maintenances.\n overallStatus:\n title: overall_status\n description: Aggregated status across all components.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n componentStatuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentStatus'\n title: component_statuses\n description: Status of individual components.\n title: GetStatusPageOverviewResponse\n additionalProperties: false\n description: GetStatusPageOverviewResponse bundles all data for a single status page.\n openstatus.status_page.v1.GetStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to retrieve (required).\n title: GetStatusPageRequest\n additionalProperties: false\n description: GetStatusPageRequest is the request to get a status page by ID.\n openstatus.status_page.v1.GetStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The requested status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: GetStatusPageResponse\n additionalProperties: false\n description: GetStatusPageResponse is the response containing the status page.\n openstatus.status_page.v1.ListStatusPagesRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of pages to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of pages to skip for pagination (defaults to 0).\n title: ListStatusPagesRequest\n additionalProperties: false\n description: ListStatusPagesRequest is the request to list status pages.\n openstatus.status_page.v1.ListStatusPagesResponse:\n type: object\n properties:\n statusPages:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPageSummary'\n title: status_pages\n description: List of status pages (metadata only).\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of status pages.\n title: ListStatusPagesResponse\n additionalProperties: false\n description: ListStatusPagesResponse is the response containing status page summaries.\n openstatus.status_page.v1.ListSubscribersRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to list subscribers for (required).\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of subscribers to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of subscribers to skip for pagination (defaults to 0).\n includeUnsubscribed:\n type:\n - boolean\n - \"null\"\n title: include_unsubscribed\n description: Whether to include unsubscribed users (defaults to false).\n title: ListSubscribersRequest\n additionalProperties: false\n description: ListSubscribersRequest is the request to list subscribers of a status page.\n openstatus.status_page.v1.ListSubscribersResponse:\n type: object\n properties:\n subscribers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: subscribers\n description: List of subscribers.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of subscribers matching the filter.\n title: ListSubscribersResponse\n additionalProperties: false\n description: ListSubscribersResponse is the response containing status page subscribers.\n openstatus.status_page.v1.Locale:\n type: string\n title: Locale\n enum:\n - LOCALE_UNSPECIFIED\n - LOCALE_EN\n - LOCALE_FR\n - LOCALE_DE\n - LOCALE_TR\n - LOCALE_HI\n - LOCALE_KO\n - LOCALE_JA\n description: Locale defines the supported languages for a status page.\n openstatus.status_page.v1.OverallStatus:\n type: string\n title: OverallStatus\n enum:\n - OVERALL_STATUS_UNSPECIFIED\n - OVERALL_STATUS_OPERATIONAL\n - OVERALL_STATUS_DEGRADED\n - OVERALL_STATUS_PARTIAL_OUTAGE\n - OVERALL_STATUS_MAJOR_OUTAGE\n - OVERALL_STATUS_MAINTENANCE\n - OVERALL_STATUS_UNKNOWN\n description: OverallStatus represents the aggregated status of all components on a page.\n openstatus.status_page.v1.PageAccessType:\n type: string\n title: PageAccessType\n enum:\n - PAGE_ACCESS_TYPE_UNSPECIFIED\n - PAGE_ACCESS_TYPE_PUBLIC\n - PAGE_ACCESS_TYPE_PASSWORD_PROTECTED\n - PAGE_ACCESS_TYPE_AUTHENTICATED\n - PAGE_ACCESS_TYPE_IP_RESTRICTED\n description: PageAccessType defines who can access the status page.\n openstatus.status_page.v1.PageBarType:\n type: string\n title: PageBarType\n enum:\n - PAGE_BAR_TYPE_UNSPECIFIED\n - PAGE_BAR_TYPE_ABSOLUTE\n - PAGE_BAR_TYPE_MANUAL\n description: PageBarType mirrors page.configuration.type (how the status bar is computed).\n openstatus.status_page.v1.PageComponent:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the component.\n pageId:\n type: string\n title: page_id\n description: ID of the status page this component belongs to.\n name:\n type: string\n title: name\n description: Display name of the component.\n description:\n type: string\n title: description\n description: Description of the component (optional).\n type:\n title: type\n description: Type of the component (monitor or static).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentType'\n monitorId:\n type: string\n title: monitor_id\n description: ID of the monitor if type is MONITOR (optional).\n order:\n type: integer\n title: order\n format: int32\n description: Display order of the component.\n groupId:\n type: string\n title: group_id\n description: ID of the group this component belongs to (optional).\n groupOrder:\n type: integer\n title: group_order\n format: int32\n description: Order within the group if grouped.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the component was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the component was last updated (RFC 3339 format).\n title: PageComponent\n additionalProperties: false\n description: PageComponent represents a component displayed on a status page.\n openstatus.status_page.v1.PageComponentDailySummary:\n type: object\n properties:\n componentId:\n type: string\n title: component_id\n description: ID of the component.\n type:\n title: type\n description: Component type (monitor or static).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentType'\n monitorId:\n type:\n - string\n - \"null\"\n title: monitor_id\n description: Monitor id backing the component (absent for static components).\n name:\n type: string\n title: name\n description: Display name of the component.\n buckets:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentDayBucket'\n title: buckets\n description: Per-day buckets, oldest first.\n events:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEvent'\n title: events\n description: Events affecting the component within the window.\n title: PageComponentDailySummary\n additionalProperties: false\n description: PageComponentDailySummary is the per-day buckets + event timeline for one component.\n openstatus.status_page.v1.PageComponentGroup:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the group.\n pageId:\n type: string\n title: page_id\n description: ID of the status page this group belongs to.\n name:\n type: string\n title: name\n description: Display name of the group.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the group was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the group was last updated (RFC 3339 format).\n defaultOpen:\n type: boolean\n title: default_open\n description: Whether the group should be expanded by default on the status page.\n title: PageComponentGroup\n additionalProperties: false\n description: PageComponentGroup represents a group of components on a status page.\n openstatus.status_page.v1.PageComponentType:\n type: string\n title: PageComponentType\n enum:\n - PAGE_COMPONENT_TYPE_UNSPECIFIED\n - PAGE_COMPONENT_TYPE_MONITOR\n - PAGE_COMPONENT_TYPE_STATIC\n description: PageComponentType defines the type of a component on a status page.\n openstatus.status_page.v1.PageConfiguration:\n type: object\n properties:\n metricType:\n title: metric_type\n description: Which metric the status bars represent (configuration.value).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageMetricType'\n barType:\n title: bar_type\n description: How the status bar is computed (configuration.type).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageBarType'\n showUptime:\n type: boolean\n title: show_uptime\n description: Whether to show the uptime percentage (configuration.uptime).\n themeKey:\n type: string\n title: theme_key\n description: |-\n Theme key from the theme store (configuration.theme), e.g. \"default\".\n Free-form string rather than an enum because the theme catalog is dynamic.\n days:\n type: integer\n title: days\n format: int32\n description: 'Number of uptime-bar days rendered on the page (configuration.days): 30 or 45.'\n title: PageConfiguration\n additionalProperties: false\n description: PageConfiguration is the rich rendering config stored in page.configuration.\n openstatus.status_page.v1.PageMetricType:\n type: string\n title: PageMetricType\n enum:\n - PAGE_METRIC_TYPE_UNSPECIFIED\n - PAGE_METRIC_TYPE_DURATION\n - PAGE_METRIC_TYPE_REQUESTS\n - PAGE_METRIC_TYPE_MANUAL\n description: PageMetricType mirrors page.configuration.value (which metric the status bars represent).\n openstatus.status_page.v1.PageSubscriber:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the subscriber.\n pageId:\n type: string\n title: page_id\n description: ID of the status page the user is subscribed to.\n email:\n type: string\n title: email\n description: Email address of the subscriber (empty for webhook channels).\n acceptedAt:\n type: string\n title: accepted_at\n description: Timestamp when the subscription was accepted/confirmed (RFC 3339 format, optional).\n unsubscribedAt:\n type: string\n title: unsubscribed_at\n description: Timestamp when the user unsubscribed (RFC 3339 format, optional).\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the subscription was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the subscription was last updated (RFC 3339 format).\n source:\n title: source\n description: How the subscription was created. Vendor-added rows skip verification.\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscriberSource'\n name:\n type:\n - string\n - \"null\"\n title: name\n description: 'Optional human-readable label (e.g. \"Supabase #incidents\").'\n channelType:\n type: string\n title: channel_type\n description: 'Channel type: \"email\" or \"webhook\".'\n webhookUrl:\n type:\n - string\n - \"null\"\n title: webhook_url\n description: Webhook URL (populated only for channel_type = \"webhook\").\n channelConfig:\n type:\n - string\n - \"null\"\n title: channel_config\n description: JSON-encoded channel config (e.g. custom headers). Populated for webhook channels.\n componentIds:\n type: array\n items:\n type: string\n title: component_ids\n description: IDs of components this subscription is scoped to. Empty = entire page.\n title: PageSubscriber\n additionalProperties: false\n description: PageSubscriber represents a subscriber to a status page.\n openstatus.status_page.v1.PageTheme:\n type: string\n title: PageTheme\n enum:\n - PAGE_THEME_UNSPECIFIED\n - PAGE_THEME_SYSTEM\n - PAGE_THEME_LIGHT\n - PAGE_THEME_DARK\n description: PageTheme defines the visual theme of the status page.\n openstatus.status_page.v1.RemoveComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to remove (required).\n title: RemoveComponentRequest\n additionalProperties: false\n description: RemoveComponentRequest is the request to remove a component from a status page.\n openstatus.status_page.v1.RemoveComponentResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the removal was successful.\n title: RemoveComponentResponse\n additionalProperties: false\n description: RemoveComponentResponse is the response after removing a component.\n openstatus.status_page.v1.StatusPage:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status page.\n title:\n type: string\n title: title\n description: Title of the status page.\n description:\n type: string\n title: description\n description: Description of the status page.\n slug:\n type: string\n examples:\n - acme-corp\n title: slug\n description: URL-friendly slug for the status page.\n customDomain:\n type: string\n examples:\n - status.example.com\n title: custom_domain\n description: Custom domain for the status page (optional).\n published:\n type: boolean\n title: published\n description: Whether the status page is published and visible.\n accessType:\n title: access_type\n description: Access type for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n theme:\n title: theme\n description: Visual theme for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n homepageUrl:\n type: string\n title: homepage_url\n description: URL to the homepage (optional).\n contactUrl:\n type: string\n title: contact_url\n description: URL to the contact page (optional).\n icon:\n type: string\n title: icon\n description: Icon URL for the status page (optional).\n createdAt:\n type: string\n examples:\n - \"2024-01-15T09:00:00Z\"\n title: created_at\n description: Timestamp when the page was created (RFC 3339 format).\n updatedAt:\n type: string\n examples:\n - \"2024-06-20T14:30:00Z\"\n title: updated_at\n description: Timestamp when the page was last updated (RFC 3339 format).\n defaultLocale:\n title: default_locale\n description: Default locale for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: Enabled locales for the status page.\n password:\n type: string\n title: password\n description: Password for the status page (only set when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: Email domains allowed to access the page (only set when access_type is AUTHENTICATED).\n allowIndex:\n type: boolean\n title: allow_index\n description: Whether search engines are allowed to index this status page.\n allowedIpRanges:\n type: string\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (only set when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: Per-mode CSS variable overrides merged over the theme (only set when configured).\n title: StatusPage\n additionalProperties: false\n description: StatusPage represents a full status page with all details.\n openstatus.status_page.v1.StatusPageSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status page.\n title:\n type: string\n title: title\n description: Title of the status page.\n slug:\n type: string\n title: slug\n description: URL-friendly slug for the status page.\n published:\n type: boolean\n title: published\n description: Whether the status page is published and visible.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the page was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the page was last updated (RFC 3339 format).\n customDomain:\n type: string\n examples:\n - status.example.com\n title: custom_domain\n description: Custom domain for the status page (optional).\n title: StatusPageSummary\n additionalProperties: false\n description: StatusPageSummary represents metadata for a status page (used in list responses).\n openstatus.status_page.v1.SubscribeToPageRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to subscribe to (required).\n email:\n type: string\n examples:\n - user@example.com\n title: email\n format: email\n description: Email address to subscribe (required).\n title: SubscribeToPageRequest\n additionalProperties: false\n description: SubscribeToPageRequest is the request to subscribe an email to a status page.\n openstatus.status_page.v1.SubscribeToPageResponse:\n type: object\n properties:\n subscriber:\n title: subscriber\n description: The created subscriber.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: SubscribeToPageResponse\n additionalProperties: false\n description: SubscribeToPageResponse is the response after subscribing to a status page.\n openstatus.status_page.v1.SubscriberSource:\n type: string\n title: SubscriberSource\n enum:\n - SUBSCRIBER_SOURCE_UNSPECIFIED\n - SUBSCRIBER_SOURCE_SELF_SIGNUP\n - SUBSCRIBER_SOURCE_VENDOR\n - SUBSCRIBER_SOURCE_IMPORT\n description: SubscriberSource indicates how the subscription was created.\n openstatus.status_page.v1.UnsubscribeFromPageRequest:\n type: object\n allOf:\n - properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to unsubscribe from (required).\n - oneOf:\n - type: object\n properties:\n email:\n type: string\n title: email\n description: Email address to unsubscribe.\n title: email\n required:\n - email\n - type: object\n properties:\n id:\n type: string\n title: id\n description: Subscriber ID.\n title: id\n required:\n - id\n title: UnsubscribeFromPageRequest\n additionalProperties: false\n description: UnsubscribeFromPageRequest is the request to unsubscribe from a status page.\n openstatus.status_page.v1.UnsubscribeFromPageResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the unsubscription was successful.\n title: UnsubscribeFromPageResponse\n additionalProperties: false\n description: UnsubscribeFromPageResponse is the response after unsubscribing from a status page.\n openstatus.status_page.v1.UpdateComponentGroupRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component group to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n minLength: 1\n description: New display name for the group (optional).\n defaultOpen:\n type:\n - boolean\n - \"null\"\n title: default_open\n description: Whether the group should be expanded by default on the status page (optional).\n title: UpdateComponentGroupRequest\n additionalProperties: false\n description: UpdateComponentGroupRequest is the request to update a component group.\n openstatus.status_page.v1.UpdateComponentGroupResponse:\n type: object\n properties:\n group:\n title: group\n description: The updated component group.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: UpdateComponentGroupResponse\n additionalProperties: false\n description: UpdateComponentGroupResponse is the response after updating a component group.\n openstatus.status_page.v1.UpdateComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n description: New display name for the component (optional).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: New description for the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: New display order (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: New group ID (optional, set to empty string to remove from group).\n groupOrder:\n type:\n - integer\n - \"null\"\n title: group_order\n format: int32\n description: New order within the group (optional).\n title: UpdateComponentRequest\n additionalProperties: false\n description: UpdateComponentRequest is the request to update a component.\n openstatus.status_page.v1.UpdateComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The updated component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: UpdateComponentResponse\n additionalProperties: false\n description: UpdateComponentResponse is the response after updating a component.\n openstatus.status_page.v1.UpdateStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n maxLength: 256\n minLength: 1\n description: New title for the status page (optional).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: New description for the status page (optional).\n slug:\n type:\n - string\n - \"null\"\n title: slug\n maxLength: 256\n minLength: 1\n pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$\n description: New slug for the status page (optional).\n homepageUrl:\n type:\n - string\n - \"null\"\n title: homepage_url\n description: New homepage URL (optional).\n contactUrl:\n type:\n - string\n - \"null\"\n title: contact_url\n description: New contact URL (optional).\n defaultLocale:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n - type: \"null\"\n title: default_locale\n description: New default locale for the status page (optional).\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: New enabled locales for the status page (optional).\n icon:\n type:\n - string\n - \"null\"\n title: icon\n maxLength: 1024\n description: New icon URL for the status page (optional).\n customDomain:\n type:\n - string\n - \"null\"\n title: custom_domain\n maxLength: 256\n description: New custom domain (optional).\n theme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n - type: \"null\"\n title: theme\n description: New visual theme (optional).\n accessType:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n - type: \"null\"\n title: access_type\n description: New access type (optional).\n password:\n type:\n - string\n - \"null\"\n title: password\n maxLength: 256\n minLength: 1\n description: New password (optional, required when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: New email domains (optional, required when access_type is AUTHENTICATED).\n allowIndex:\n type:\n - boolean\n - \"null\"\n title: allow_index\n description: Whether search engines are allowed to index this status page (optional).\n allowedIpRanges:\n type:\n - string\n - \"null\"\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (required when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: |-\n New per-mode CSS variable overrides (optional). Omit to keep the current\n value; send an empty message to clear. Requires the custom-theme plan feature.\n title: UpdateStatusPageRequest\n additionalProperties: false\n description: UpdateStatusPageRequest is the request to update a status page.\n openstatus.status_page.v1.UpdateStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The updated status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: UpdateStatusPageResponse\n additionalProperties: false\n description: UpdateStatusPageResponse is the response after updating a status page.\n openstatus.status_page.v1.WebhookChannel:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n maxLength: 2048\n minLength: 1\n format: uri\n description: Webhook URL (required). Payload flavor (Slack / Discord / generic) is auto-detected from the URL prefix.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.WebhookChannelHeader'\n title: headers\n description: Optional custom HTTP headers attached to every dispatch.\n title: WebhookChannel\n additionalProperties: false\n description: WebhookChannel carries the webhook-channel fields for CreatePageSubscription.\n openstatus.status_page.v1.WebhookChannelHeader:\n type: object\n properties:\n key:\n type: string\n title: key\n minLength: 1\n value:\n type: string\n title: value\n title: WebhookChannelHeader\n additionalProperties: false\n description: WebhookChannelHeader is a single custom HTTP header.\n openstatus.status_report.v1.AddStatusReportUpdateRequest:\n type: object\n properties:\n statusReportId:\n type: string\n title: status_report_id\n minLength: 1\n description: ID of the status report to update (required).\n status:\n title: status\n description: New status for the report (required).\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n message:\n type: string\n title: message\n minLength: 1\n description: Message describing what changed (required).\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Optional date for the update (RFC 3339 format). Defaults to current time if not provided.\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this update (optional, defaults to false).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: |-\n Per-component impacts this update sets (optional). Components named here\n are added to the report's affected set; omitted components keep their\n prior impact.\n title: AddStatusReportUpdateRequest\n additionalProperties: false\n description: AddStatusReportUpdateRequest is the request to add a new update to a status report.\n openstatus.status_report.v1.AddStatusReportUpdateResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The updated status report with the new update included.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: AddStatusReportUpdateResponse\n additionalProperties: false\n description: AddStatusReportUpdateResponse is the response after adding an update to a status report.\n openstatus.status_report.v1.ComponentImpact:\n type: object\n properties:\n pageComponentId:\n type: string\n title: page_component_id\n description: ID of the affected page component.\n impact:\n title: impact\n description: Impact set for the component.\n $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n title: ComponentImpact\n additionalProperties: false\n description: ComponentImpact pairs a page component with the impact an update set for it.\n openstatus.status_report.v1.CreateStatusReportRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - API Degradation Investigation\n title: title\n minLength: 1\n description: Title of the status report (required).\n status:\n title: status\n description: Initial status (required).\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n message:\n type: string\n examples:\n - We are investigating reports of increased API latency.\n title: message\n minLength: 1\n description: Initial message describing the incident (required).\n date:\n type: string\n examples:\n - \"2024-03-15T10:30:00Z\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Date when the event occurred (RFC 3339 format, required).\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: Page ID to associate with this report (required).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: Page component IDs to associate with this report (optional).\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this status report (optional, defaults to false).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: |-\n Per-component impacts set by the initial update (optional). When provided,\n the named components are added to the report's affected set. Omitting this\n field creates a legacy report without impact tracking.\n title: CreateStatusReportRequest\n additionalProperties: false\n description: CreateStatusReportRequest is the request to create a new status report.\n openstatus.status_report.v1.CreateStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The created status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: CreateStatusReportResponse\n additionalProperties: false\n description: CreateStatusReportResponse is the response after creating a status report.\n openstatus.status_report.v1.DeleteStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to delete (required).\n title: DeleteStatusReportRequest\n additionalProperties: false\n description: DeleteStatusReportRequest is the request to delete a status report.\n openstatus.status_report.v1.DeleteStatusReportResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteStatusReportResponse\n additionalProperties: false\n description: DeleteStatusReportResponse is the response after deleting a status report.\n openstatus.status_report.v1.GetStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to retrieve (required).\n title: GetStatusReportRequest\n additionalProperties: false\n description: GetStatusReportRequest is the request to get a status report by ID.\n openstatus.status_report.v1.GetStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The requested status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: GetStatusReportResponse\n additionalProperties: false\n description: GetStatusReportResponse is the response containing the status report with its full update timeline.\n openstatus.status_report.v1.ListStatusReportsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of reports to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of reports to skip for pagination (defaults to 0).\n statuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title: statuses\n description: Filter by status (optional). If empty, returns all statuses.\n title: ListStatusReportsRequest\n additionalProperties: false\n description: ListStatusReportsRequest is the request to list status reports.\n openstatus.status_report.v1.ListStatusReportsResponse:\n type: object\n properties:\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportSummary'\n title: status_reports\n description: List of status reports (metadata only, use GetStatusReport for full details).\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of reports matching the filter.\n title: ListStatusReportsResponse\n additionalProperties: false\n description: ListStatusReportsResponse is the response containing status report summaries.\n openstatus.status_report.v1.PageComponentImpact:\n type: string\n title: PageComponentImpact\n enum:\n - PAGE_COMPONENT_IMPACT_UNSPECIFIED\n - PAGE_COMPONENT_IMPACT_OPERATIONAL\n - PAGE_COMPONENT_IMPACT_DEGRADED_PERFORMANCE\n - PAGE_COMPONENT_IMPACT_PARTIAL_OUTAGE\n - PAGE_COMPONENT_IMPACT_MAJOR_OUTAGE\n description: |-\n PageComponentImpact is the per-component impact a status report update sets.\n UNSPECIFIED means the caller doesn't speak impact (legacy) — it is NOT operational.\n openstatus.status_report.v1.StatusReport:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status report.\n status:\n title: status\n description: Current status of the report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title:\n type: string\n title: title\n description: Title of the status report.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n updates:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportUpdate'\n title: updates\n description: Timeline of updates for this report (only included in GetStatusReport).\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the report was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the report was last updated (RFC 3339 format).\n title: StatusReport\n additionalProperties: false\n description: StatusReport represents an incident or maintenance report with full details.\n openstatus.status_report.v1.StatusReportStatus:\n type: string\n title: StatusReportStatus\n enum:\n - STATUS_REPORT_STATUS_UNSPECIFIED\n - STATUS_REPORT_STATUS_INVESTIGATING\n - STATUS_REPORT_STATUS_IDENTIFIED\n - STATUS_REPORT_STATUS_MONITORING\n - STATUS_REPORT_STATUS_RESOLVED\n description: StatusReportStatus represents the current state of a status report.\n openstatus.status_report.v1.StatusReportSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status report.\n status:\n title: status\n description: Current status of the report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title:\n type: string\n title: title\n description: Title of the status report.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the report was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the report was last updated (RFC 3339 format).\n title: StatusReportSummary\n additionalProperties: false\n description: StatusReportSummary represents metadata for a status report (used in list responses).\n openstatus.status_report.v1.StatusReportUpdate:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the update.\n status:\n title: status\n description: Status at the time of this update.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n date:\n type: string\n title: date\n description: Timestamp when this update occurred (RFC 3339 format).\n message:\n type: string\n title: message\n description: Message describing the update.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the update was created (RFC 3339 format).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: Per-component impacts this update set (empty for legacy reports).\n title: StatusReportUpdate\n additionalProperties: false\n description: StatusReportUpdate represents a single update entry in a status report timeline.\n openstatus.status_report.v1.UpdateStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n description: New title for the report (optional).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: New list of page component IDs (optional, replaces existing list).\n updatePageComponentIds:\n type:\n - boolean\n - \"null\"\n title: update_page_component_ids\n description: |-\n Set to true to update page component associations.\n When true, page_component_ids replaces the existing list (empty clears all).\n When false or unset, page_component_ids is ignored and existing associations are preserved.\n title: UpdateStatusReportRequest\n additionalProperties: false\n description: UpdateStatusReportRequest is the request to update a status report's metadata.\n openstatus.status_report.v1.UpdateStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The updated status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: UpdateStatusReportResponse\n additionalProperties: false\n description: UpdateStatusReportResponse is the response after updating a status report.\nsecurity:\n - ApiKeyAuth: []\ntags:\n - name: MonitorService\n description: |\n Create, update, delete, and query monitors. Supports HTTP, TCP, and DNS monitor types\n with configurable check intervals, regions, assertions, and alerting thresholds.\n - name: StatusPageService\n description: |\n Manage public status pages with components, component groups, and email subscribers.\n Includes endpoints for retrieving full page content and aggregated status.\n - name: NotificationService\n description: |\n Configure notification channels (Slack, Discord, PagerDuty, email, webhooks, etc.)\n and associate them with monitors. Supports 12 notification providers.\n - name: StatusReportService\n description: |\n Create and manage incident reports with status updates. Reports follow a lifecycle:\n investigating -> identified -> monitoring -> resolved.\n - name: MaintenanceService\n description: |\n Schedule maintenance windows for status page components. Subscribers can be\n notified automatically when maintenance is created.\n - name: HealthService\n description: Health check endpoint for load balancer probes. No authentication required.\n - name: PrivateLocationService\n description: |-\n PrivateLocationService provides CRUD operations for private locations —\n self-hosted checker agents that run monitors from your own network.\npaths:\n /rpc/openstatus.health.v1.HealthService/Check:\n get:\n tags:\n - HealthService\n summary: Check\n description: Check returns the current serving status of the service.\n operationId: HealthService_Check.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse'\n post:\n tags:\n - HealthService\n summary: Check\n description: Check returns the current serving status of the service.\n operationId: HealthService_Check\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/AddMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: AddMaintenanceUpdate\n description: AddMaintenanceUpdate appends a public update to a maintenance timeline.\n operationId: MaintenanceService_AddMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.AddMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.AddMaintenanceUpdateResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/CreateMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: CreateMaintenance\n description: CreateMaintenance creates a new maintenance window.\n operationId: MaintenanceService_CreateMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.CreateMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.CreateMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/DeleteMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: DeleteMaintenance\n description: DeleteMaintenance removes a maintenance window.\n operationId: MaintenanceService_DeleteMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/DeleteMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: DeleteMaintenanceUpdate\n description: DeleteMaintenanceUpdate removes an existing maintenance update.\n operationId: MaintenanceService_DeleteMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceUpdateResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/GetMaintenance:\n get:\n tags:\n - MaintenanceService\n summary: GetMaintenance\n description: GetMaintenance retrieves a specific maintenance window by ID.\n operationId: MaintenanceService_GetMaintenance.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceResponse'\n post:\n tags:\n - MaintenanceService\n summary: GetMaintenance\n description: GetMaintenance retrieves a specific maintenance window by ID.\n operationId: MaintenanceService_GetMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/ListMaintenances:\n get:\n tags:\n - MaintenanceService\n summary: ListMaintenances\n description: ListMaintenances returns all maintenance windows for the workspace.\n operationId: MaintenanceService_ListMaintenances.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesResponse'\n post:\n tags:\n - MaintenanceService\n summary: ListMaintenances\n description: ListMaintenances returns all maintenance windows for the workspace.\n operationId: MaintenanceService_ListMaintenances\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/UpdateMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: UpdateMaintenance\n description: UpdateMaintenance updates a maintenance window.\n operationId: MaintenanceService_UpdateMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/UpdateMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: UpdateMaintenanceUpdate\n description: UpdateMaintenanceUpdate edits an existing maintenance update.\n operationId: MaintenanceService_UpdateMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceUpdateResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateDNSMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateDNSMonitor\n description: CreateDNSMonitor creates a new DNS monitor.\n operationId: MonitorService_CreateDNSMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateDNSMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateDNSMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateGRPCMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateGRPCMonitor\n description: CreateGRPCMonitor creates a new gRPC health check monitor.\n operationId: MonitorService_CreateGRPCMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateGRPCMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateGRPCMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateHTTPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateHTTPMonitor\n description: Creates a new HTTP monitor in the authenticated workspace. Configure the target URL, HTTP method, request headers and body, response assertions (status code, body content, headers), check periodicity, geographic regions, and optional OpenTelemetry export. The monitor starts checking immediately if set to active.\n operationId: MonitorService_CreateHTTPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateHTTPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateHTTPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateICMPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateICMPMonitor\n description: CreateICMPMonitor creates a new ICMP monitor.\n operationId: MonitorService_CreateICMPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateICMPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateICMPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateTCPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateTCPMonitor\n description: CreateTCPMonitor creates a new TCP monitor.\n operationId: MonitorService_CreateTCPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateTCPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateTCPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/DeleteMonitor:\n post:\n tags:\n - MonitorService\n summary: DeleteMonitor\n description: DeleteMonitor removes a monitor.\n operationId: MonitorService_DeleteMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.DeleteMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.DeleteMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitor:\n get:\n tags:\n - MonitorService\n summary: GetMonitor\n description: |-\n GetMonitor returns a single monitor by ID within the authenticated workspace.\n Returns the monitor configuration (HTTP, TCP, DNS, ICMP, or gRPC) using the MonitorConfig oneof type.\n operationId: MonitorService_GetMonitor.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitor\n description: |-\n GetMonitor returns a single monitor by ID within the authenticated workspace.\n Returns the monitor configuration (HTTP, TCP, DNS, ICMP, or gRPC) using the MonitorConfig oneof type.\n operationId: MonitorService_GetMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorHTTPResponseLog:\n get:\n tags:\n - MonitorService\n summary: GetMonitorHTTPResponseLog\n description: GetMonitorHTTPResponseLog returns one response log for an HTTP monitor.\n operationId: MonitorService_GetMonitorHTTPResponseLog.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorHTTPResponseLog\n description: GetMonitorHTTPResponseLog returns one response log for an HTTP monitor.\n operationId: MonitorService_GetMonitorHTTPResponseLog\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorStatus:\n get:\n tags:\n - MonitorService\n summary: GetMonitorStatus\n description: GetMonitorStatus returns the current status of all regions for a monitor.\n operationId: MonitorService_GetMonitorStatus.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorStatus\n description: GetMonitorStatus returns the current status of all regions for a monitor.\n operationId: MonitorService_GetMonitorStatus\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorSummary:\n get:\n tags:\n - MonitorService\n summary: GetMonitorSummary\n description: Returns aggregated metrics for a monitor including latency percentiles (p50, p75, p90, p95, p99), request counts by status (successful, degraded, failed), and the timestamp of the last check. Metrics can be scoped to a time range (1 day, 7 days, or 14 days) and filtered by specific regions.\n operationId: MonitorService_GetMonitorSummary.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorSummary\n description: Returns aggregated metrics for a monitor including latency percentiles (p50, p75, p90, p95, p99), request counts by status (successful, degraded, failed), and the timestamp of the last check. Metrics can be scoped to a time range (1 day, 7 days, or 14 days) and filtered by specific regions.\n operationId: MonitorService_GetMonitorSummary\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryResponse'\n /rpc/openstatus.monitor.v1.MonitorService/ListMonitorHTTPResponseLogs:\n get:\n tags:\n - MonitorService\n summary: ListMonitorHTTPResponseLogs\n description: ListMonitorHTTPResponseLogs returns paginated response logs for an HTTP monitor from the 14-day HTTP response-log window.\n operationId: MonitorService_ListMonitorHTTPResponseLogs.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse'\n post:\n tags:\n - MonitorService\n summary: ListMonitorHTTPResponseLogs\n description: ListMonitorHTTPResponseLogs returns paginated response logs for an HTTP monitor from the 14-day HTTP response-log window.\n operationId: MonitorService_ListMonitorHTTPResponseLogs\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse'\n /rpc/openstatus.monitor.v1.MonitorService/ListMonitors:\n get:\n tags:\n - MonitorService\n summary: ListMonitors\n description: ListMonitors returns a paginated list of all monitors in the workspace.\n operationId: MonitorService_ListMonitors.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsResponse'\n post:\n tags:\n - MonitorService\n summary: ListMonitors\n description: ListMonitors returns a paginated list of all monitors in the workspace.\n operationId: MonitorService_ListMonitors\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsResponse'\n /rpc/openstatus.monitor.v1.MonitorService/TriggerMonitor:\n post:\n tags:\n - MonitorService\n summary: TriggerMonitor\n description: Manually triggers an immediate check for the specified monitor across all configured regions. This operation is rate-limited under the synthetic-checks quota. A monitor run record is created and the check is dispatched to the checker service.\n operationId: MonitorService_TriggerMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.TriggerMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.TriggerMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateDNSMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateDNSMonitor\n description: UpdateDNSMonitor updates an existing DNS monitor.\n operationId: MonitorService_UpdateDNSMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateDNSMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateDNSMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateGRPCMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateGRPCMonitor\n description: UpdateGRPCMonitor updates an existing gRPC monitor.\n operationId: MonitorService_UpdateGRPCMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateGRPCMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateGRPCMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateHTTPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateHTTPMonitor\n description: UpdateHTTPMonitor updates an existing HTTP monitor.\n operationId: MonitorService_UpdateHTTPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateHTTPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateHTTPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateICMPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateICMPMonitor\n description: UpdateICMPMonitor updates an existing ICMP monitor.\n operationId: MonitorService_UpdateICMPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateICMPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateICMPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateTCPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateTCPMonitor\n description: UpdateTCPMonitor updates an existing TCP monitor.\n operationId: MonitorService_UpdateTCPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateTCPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateTCPMonitorResponse'\n /rpc/openstatus.notification.v1.NotificationService/CheckNotificationLimit:\n get:\n tags:\n - NotificationService\n summary: CheckNotificationLimit\n description: CheckNotificationLimit checks if the workspace has reached its notification limit.\n operationId: NotificationService_CheckNotificationLimit.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitResponse'\n post:\n tags:\n - NotificationService\n summary: CheckNotificationLimit\n description: CheckNotificationLimit checks if the workspace has reached its notification limit.\n operationId: NotificationService_CheckNotificationLimit\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitResponse'\n /rpc/openstatus.notification.v1.NotificationService/CreateNotification:\n post:\n tags:\n - NotificationService\n summary: CreateNotification\n description: CreateNotification creates a new notification channel.\n operationId: NotificationService_CreateNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CreateNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CreateNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/DeleteNotification:\n post:\n tags:\n - NotificationService\n summary: DeleteNotification\n description: DeleteNotification removes a notification channel.\n operationId: NotificationService_DeleteNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.DeleteNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.DeleteNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/GetNotification:\n get:\n tags:\n - NotificationService\n summary: GetNotification\n description: GetNotification retrieves a notification channel by ID.\n operationId: NotificationService_GetNotification.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationResponse'\n post:\n tags:\n - NotificationService\n summary: GetNotification\n description: GetNotification retrieves a notification channel by ID.\n operationId: NotificationService_GetNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/ListNotifications:\n get:\n tags:\n - NotificationService\n summary: ListNotifications\n description: ListNotifications returns a list of notification channels.\n operationId: NotificationService_ListNotifications.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsResponse'\n post:\n tags:\n - NotificationService\n summary: ListNotifications\n description: ListNotifications returns a list of notification channels.\n operationId: NotificationService_ListNotifications\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsResponse'\n /rpc/openstatus.notification.v1.NotificationService/SendTestNotification:\n post:\n tags:\n - NotificationService\n summary: SendTestNotification\n description: Sends a test notification to the specified provider to verify that the configuration is correct. This does not require an existing notification channel - just provide the provider type and its configuration data. Returns success status and an error message if the test failed.\n operationId: NotificationService_SendTestNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.SendTestNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.SendTestNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/UpdateNotification:\n post:\n tags:\n - NotificationService\n summary: UpdateNotification\n description: UpdateNotification updates an existing notification channel.\n operationId: NotificationService_UpdateNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.UpdateNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.UpdateNotificationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/CreatePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: CreatePrivateLocation\n description: Creates a private location. The agent token is generated by the server and returned in the response - it cannot be supplied by the caller. Use the token to configure the agent so it can pull its monitors and report results.\n operationId: PrivateLocationService_CreatePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.CreatePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.CreatePrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/DeletePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: DeletePrivateLocation\n description: DeletePrivateLocation removes a private location.\n operationId: PrivateLocationService_DeletePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.DeletePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.DeletePrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/GetPrivateLocation:\n get:\n tags:\n - PrivateLocationService\n summary: GetPrivateLocation\n description: |-\n GetPrivateLocation retrieves a single private location by ID, including\n its agent token.\n operationId: PrivateLocationService_GetPrivateLocation.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationResponse'\n post:\n tags:\n - PrivateLocationService\n summary: GetPrivateLocation\n description: |-\n GetPrivateLocation retrieves a single private location by ID, including\n its agent token.\n operationId: PrivateLocationService_GetPrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/ListPrivateLocations:\n get:\n tags:\n - PrivateLocationService\n summary: ListPrivateLocations\n description: |-\n ListPrivateLocations returns a paginated list of private location\n summaries. Agent tokens are not included - use GetPrivateLocation.\n operationId: PrivateLocationService_ListPrivateLocations.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsResponse'\n post:\n tags:\n - PrivateLocationService\n summary: ListPrivateLocations\n description: |-\n ListPrivateLocations returns a paginated list of private location\n summaries. Agent tokens are not included - use GetPrivateLocation.\n operationId: PrivateLocationService_ListPrivateLocations\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/UpdatePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: UpdatePrivateLocation\n description: UpdatePrivateLocation updates a private location.\n operationId: PrivateLocationService_UpdatePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.UpdatePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.UpdatePrivateLocationResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/AddMonitorComponent:\n post:\n tags:\n - StatusPageService\n summary: AddMonitorComponent\n description: AddMonitorComponent adds a monitor-based component to a status page.\n operationId: StatusPageService_AddMonitorComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddMonitorComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddMonitorComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/AddStaticComponent:\n post:\n tags:\n - StatusPageService\n summary: AddStaticComponent\n description: AddStaticComponent adds a static component to a status page.\n operationId: StatusPageService_AddStaticComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddStaticComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddStaticComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreateComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: CreateComponentGroup\n description: CreateComponentGroup creates a new component group.\n operationId: StatusPageService_CreateComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreatePageSubscription:\n post:\n tags:\n - StatusPageService\n summary: 'CreatePageSubscription: operator-added subscriber (email or webhook), no verification.'\n description: Operator-added subscriber (email or webhook) with no verification flow — the partner starts receiving notifications immediately. Supports Slack and Discord webhook URLs in addition to email. A management token is still generated so the subscriber can self-manage (update scope, unsubscribe) without operator involvement. Use this for vendor/partner integrations where consent is established out-of-band; use SubscribeToPage for subscriber-initiated signups that require double opt-in.\n operationId: StatusPageService_CreatePageSubscription\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreatePageSubscriptionRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreatePageSubscriptionResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreateStatusPage:\n post:\n tags:\n - StatusPageService\n summary: CreateStatusPage\n description: CreateStatusPage creates a new status page.\n operationId: StatusPageService_CreateStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/DeleteComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: DeleteComponentGroup\n description: DeleteComponentGroup removes a component group.\n operationId: StatusPageService_DeleteComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/DeleteStatusPage:\n post:\n tags:\n - StatusPageService\n summary: DeleteStatusPage\n description: DeleteStatusPage removes a status page.\n operationId: StatusPageService_DeleteStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetOverallStatus:\n get:\n tags:\n - StatusPageService\n summary: GetOverallStatus\n description: 'Returns the overall status of a status page along with individual component statuses. The overall status is computed from active status reports and maintenances with the following priority: degraded (from active status reports) > maintenance (from active maintenance windows) > operational.'\n operationId: StatusPageService_GetOverallStatus.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusResponse'\n post:\n tags:\n - StatusPageService\n summary: GetOverallStatus\n description: 'Returns the overall status of a status page along with individual component statuses. The overall status is computed from active status reports and maintenances with the following priority: degraded (from active status reports) > maintenance (from active maintenance windows) > operational.'\n operationId: StatusPageService_GetOverallStatus\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetPageComponent:\n get:\n tags:\n - StatusPageService\n summary: GetPageComponent\n description: Returns a single status-page component by its ID, scoped to the authenticated workspace. Use this to resolve a component id to its name (and other fields) instead of fetching the whole page via GetStatusPageContent and filtering .components.\n operationId: StatusPageService_GetPageComponent.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentResponse'\n post:\n tags:\n - StatusPageService\n summary: GetPageComponent\n description: Returns a single status-page component by its ID, scoped to the authenticated workspace. Use this to resolve a component id to its name (and other fields) instead of fetching the whole page via GetStatusPageContent and filtering .components.\n operationId: StatusPageService_GetPageComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetPageComponentDailySummary:\n get:\n tags:\n - StatusPageService\n summary: GetPageComponentDailySummary\n description: 'Returns per-component daily status buckets (ok/degraded/error/count plus a resolved status) merged with the incident, maintenance, and status-report timeline over the last N days (max 45). Suitable as a single source of truth for status-bar and uptime-calendar rendering. Supports two access paths: by id (authenticated, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetPageComponentDailySummary.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryResponse'\n post:\n tags:\n - StatusPageService\n summary: GetPageComponentDailySummary\n description: 'Returns per-component daily status buckets (ok/degraded/error/count plus a resolved status) merged with the incident, maintenance, and status-report timeline over the last N days (max 45). Suitable as a single source of truth for status-bar and uptime-calendar rendering. Supports two access paths: by id (authenticated, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetPageComponentDailySummary\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPage:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPage\n description: GetStatusPage retrieves a specific status page by ID.\n operationId: StatusPageService_GetStatusPage.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPage\n description: GetStatusPage retrieves a specific status page by ID.\n operationId: StatusPageService_GetStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPageContent:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPageContent\n description: 'Returns the full content of a status page including its components, component groups, active status reports, and scheduled maintenances. Supports two access paths: by ID (requires authentication, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetStatusPageContent.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPageContent\n description: 'Returns the full content of a status page including its components, component groups, active status reports, and scheduled maintenances. Supports two access paths: by ID (requires authentication, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetStatusPageContent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPageOverview:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPageOverview\n description: 'Returns everything about a single status page in one authenticated call: the page, its rich rendering configuration, components, component groups, active/recent status reports, maintenances, and the computed overall + per-component statuses. Workspace-scoped by id; there is no public slug access path. Does not include uptime time-series — use GetPageComponentDailySummary for that.'\n operationId: StatusPageService_GetStatusPageOverview.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPageOverview\n description: 'Returns everything about a single status page in one authenticated call: the page, its rich rendering configuration, components, component groups, active/recent status reports, maintenances, and the computed overall + per-component statuses. Workspace-scoped by id; there is no public slug access path. Does not include uptime time-series — use GetPageComponentDailySummary for that.'\n operationId: StatusPageService_GetStatusPageOverview\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/ListStatusPages:\n get:\n tags:\n - StatusPageService\n summary: ListStatusPages\n description: ListStatusPages returns all status pages for the workspace.\n operationId: StatusPageService_ListStatusPages.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesResponse'\n post:\n tags:\n - StatusPageService\n summary: ListStatusPages\n description: ListStatusPages returns all status pages for the workspace.\n operationId: StatusPageService_ListStatusPages\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/ListSubscribers:\n get:\n tags:\n - StatusPageService\n summary: ListSubscribers\n description: ListSubscribers returns all subscribers for a status page.\n operationId: StatusPageService_ListSubscribers.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersResponse'\n post:\n tags:\n - StatusPageService\n summary: ListSubscribers\n description: ListSubscribers returns all subscribers for a status page.\n operationId: StatusPageService_ListSubscribers\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/RemoveComponent:\n post:\n tags:\n - StatusPageService\n summary: RemoveComponent\n description: RemoveComponent removes a component from a status page.\n operationId: StatusPageService_RemoveComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.RemoveComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.RemoveComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/SubscribeToPage:\n post:\n tags:\n - StatusPageService\n summary: 'SubscribeToPage: end-user email self-signup with double opt-in verification.'\n description: End-user email self-signup with double opt-in verification. A verification email is sent and the subscription activates only after the recipient confirms. If the email was previously unsubscribed, the existing row is reactivated instead of a duplicate being created. Use this for subscriber-initiated signups on the public status page; use CreatePageSubscription for operator-initiated (vendor) subscriptions that should skip verification.\n operationId: StatusPageService_SubscribeToPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscribeToPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscribeToPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UnsubscribeFromPage:\n post:\n tags:\n - StatusPageService\n summary: UnsubscribeFromPage\n description: UnsubscribeFromPage removes a subscription from a status page.\n operationId: StatusPageService_UnsubscribeFromPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UnsubscribeFromPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UnsubscribeFromPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateComponent:\n post:\n tags:\n - StatusPageService\n summary: UpdateComponent\n description: UpdateComponent updates an existing component.\n operationId: StatusPageService_UpdateComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: UpdateComponentGroup\n description: UpdateComponentGroup updates an existing component group.\n operationId: StatusPageService_UpdateComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateStatusPage:\n post:\n tags:\n - StatusPageService\n summary: UpdateStatusPage\n description: UpdateStatusPage updates an existing status page.\n operationId: StatusPageService_UpdateStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateStatusPageResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/AddStatusReportUpdate:\n post:\n tags:\n - StatusReportService\n summary: AddStatusReportUpdate\n description: 'Adds a new update entry to an existing status report and transitions the report to the specified status. Status reports follow a lifecycle: investigating -> identified -> monitoring -> resolved. If notify is true, subscribers of the associated page are notified by email about the update.'\n operationId: StatusReportService_AddStatusReportUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.AddStatusReportUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.AddStatusReportUpdateResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/CreateStatusReport:\n post:\n tags:\n - StatusReportService\n summary: CreateStatusReport\n description: Creates a new status report with an initial update entry. The report is associated with a status page and optionally specific page components. An initial StatusReportUpdate is created automatically with the provided status, message, and date. If notify is true, subscribers of the associated page are notified by email.\n operationId: StatusReportService_CreateStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.CreateStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.CreateStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReport:\n post:\n tags:\n - StatusReportService\n summary: DeleteStatusReport\n description: DeleteStatusReport removes a status report and all its updates.\n operationId: StatusReportService_DeleteStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/GetStatusReport:\n get:\n tags:\n - StatusReportService\n summary: GetStatusReport\n description: GetStatusReport retrieves a specific status report by ID (includes full update timeline).\n operationId: StatusReportService_GetStatusReport.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportResponse'\n post:\n tags:\n - StatusReportService\n summary: GetStatusReport\n description: GetStatusReport retrieves a specific status report by ID (includes full update timeline).\n operationId: StatusReportService_GetStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/ListStatusReports:\n get:\n tags:\n - StatusReportService\n summary: ListStatusReports\n description: ListStatusReports returns all status reports for the workspace (metadata only).\n operationId: StatusReportService_ListStatusReports.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsResponse'\n post:\n tags:\n - StatusReportService\n summary: ListStatusReports\n description: ListStatusReports returns all status reports for the workspace (metadata only).\n operationId: StatusReportService_ListStatusReports\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReport:\n post:\n tags:\n - StatusReportService\n summary: UpdateStatusReport\n description: UpdateStatusReport updates the metadata of a status report (title, page components).\n operationId: StatusReportService_UpdateStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportResponse'\n";
+export default "openapi: 3.1.0\ninfo:\n description: OpenStatus is a open-source status page platform with global uptime monitoring. The OpenStatus API allows you to interact with the OpenStatus platform programmatically. To get started you need to create an account on https://www.openstatus.dev/ and create an api token in your settings. Requests are rate limited per API key or token (600 per minute, 100 per 10 seconds); exceeding a limit returns HTTP 429 with a Retry-After header. See https://www.openstatus.dev/docs/reference/api-rate-limits.\n title: OpenStatus API\n version: v2.0.0\n contact:\n email: ping@openstatus.dev\n url: https://www.openstatus.dev\nservers:\n - url: https://api.openstatus.dev\n description: Production\nexternalDocs:\n description: OpenStatus Documentation\n url: https://www.openstatus.dev/docs\ncomponents:\n responses:\n RateLimited:\n description: Rate limit exceeded (Connect code resource_exhausted). Retry after the number of seconds in the Retry-After header. See https://www.openstatus.dev/docs/reference/api-rate-limits.\n headers:\n Retry-After:\n description: Seconds to wait before retrying.\n schema:\n type: integer\n example: 7\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n securitySchemes:\n ApiKeyAuth:\n type: apiKey\n in: header\n name: x-openstatus-key\n schemas:\n connect.error:\n type: object\n properties:\n code:\n type: string\n examples:\n - not_found\n enum:\n - canceled\n - unknown\n - invalid_argument\n - deadline_exceeded\n - not_found\n - already_exists\n - permission_denied\n - resource_exhausted\n - failed_precondition\n - aborted\n - out_of_range\n - unimplemented\n - internal\n - unavailable\n - data_loss\n - unauthenticated\n description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].\n message:\n type: string\n description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.\n details:\n type: array\n items:\n $ref: '#/components/schemas/connect.error_details.Any'\n description: A list of messages that carry the error details. There is no limit on the number of messages.\n title: Connect Error\n additionalProperties: true\n description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation'\n connect.error_details.Any:\n type: object\n properties:\n type:\n type: string\n description: 'A URL that acts as a globally unique identifier for the type of the serialized message. For example: `type.googleapis.com/google.rpc.ErrorInfo`. This is used to determine the schema of the data in the `value` field and is the discriminator for the `debug` field.'\n value:\n type: string\n format: binary\n description: The Protobuf message, serialized as bytes and base64-encoded. The specific message type is identified by the `type` field.\n debug:\n oneOf:\n - type: object\n title: Any\n additionalProperties: true\n description: Detailed error information.\n discriminator:\n propertyName: type\n title: Debug\n description: Deserialized error detail payload. The 'type' field indicates the schema. This field is for easier debugging and should not be relied upon for application logic.\n additionalProperties: true\n description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message, with an additional debug field for ConnectRPC error details.\n openstatus.health.v1.CheckRequest:\n type: object\n properties:\n service:\n type: string\n title: service\n description: Optional service name to check. If empty, checks overall service health.\n title: CheckRequest\n additionalProperties: false\n description: CheckRequest is the request message for health checks.\n openstatus.health.v1.CheckResponse:\n type: object\n properties:\n status:\n title: status\n description: The serving status of the service.\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse.ServingStatus'\n title: CheckResponse\n additionalProperties: false\n description: CheckResponse is the response message for health checks.\n openstatus.health.v1.CheckResponse.ServingStatus:\n type: string\n title: ServingStatus\n enum:\n - SERVING_STATUS_UNSPECIFIED\n - SERVING_STATUS_SERVING\n - SERVING_STATUS_NOT_SERVING\n description: ServingStatus represents the health status of the service.\n openstatus.maintenance.v1.AddMaintenanceUpdateRequest:\n type: object\n properties:\n maintenanceId:\n type: string\n title: maintenance_id\n minLength: 1\n description: ID of the maintenance to update (required).\n message:\n type: string\n title: message\n minLength: 1\n description: Public update message (required).\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Optional date for the update (RFC 3339 format). Defaults to current time.\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this update.\n title: AddMaintenanceUpdateRequest\n additionalProperties: false\n description: AddMaintenanceUpdateRequest is the request to append a maintenance update.\n openstatus.maintenance.v1.AddMaintenanceUpdateResponse:\n type: object\n properties:\n maintenanceUpdate:\n title: maintenance_update\n description: The created update.\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: AddMaintenanceUpdateResponse\n additionalProperties: false\n description: AddMaintenanceUpdateResponse is the response after appending an update.\n openstatus.maintenance.v1.CreateMaintenanceRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - Database Migration\n title: title\n maxLength: 256\n minLength: 1\n description: Title of the maintenance (required, 1-256 characters).\n message:\n type: string\n title: message\n minLength: 1\n description: |-\n Message describing the maintenance (required). Posted as the first\n maintenance update.\n from:\n type: string\n examples:\n - \"2024-03-01T02:00:00Z\"\n title: from\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Start time of the maintenance window (RFC 3339 format, required).\n to:\n type: string\n examples:\n - \"2024-03-01T06:00:00Z\"\n title: to\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: End time of the maintenance window (RFC 3339 format, required).\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: Page ID to associate with this maintenance (required).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: Page component IDs to associate with this maintenance (optional).\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this maintenance (optional, defaults to false).\n title: CreateMaintenanceRequest\n additionalProperties: false\n description: CreateMaintenanceRequest is the request to create a new maintenance window.\n openstatus.maintenance.v1.CreateMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The created maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: CreateMaintenanceResponse\n additionalProperties: false\n description: CreateMaintenanceResponse is the response after creating a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to delete (required).\n title: DeleteMaintenanceRequest\n additionalProperties: false\n description: DeleteMaintenanceRequest is the request to delete a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMaintenanceResponse\n additionalProperties: false\n description: DeleteMaintenanceResponse is the response after deleting a maintenance window.\n openstatus.maintenance.v1.DeleteMaintenanceUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to remove (required).\n title: DeleteMaintenanceUpdateRequest\n additionalProperties: false\n description: DeleteMaintenanceUpdateRequest is the request to remove an update.\n openstatus.maintenance.v1.DeleteMaintenanceUpdateResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMaintenanceUpdateResponse\n additionalProperties: false\n description: DeleteMaintenanceUpdateResponse is the response after removing an update.\n openstatus.maintenance.v1.GetMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to retrieve (required).\n title: GetMaintenanceRequest\n additionalProperties: false\n description: GetMaintenanceRequest is the request to get a maintenance window by ID.\n openstatus.maintenance.v1.GetMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The requested maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: GetMaintenanceResponse\n additionalProperties: false\n description: GetMaintenanceResponse is the response containing the maintenance window.\n openstatus.maintenance.v1.ListMaintenancesRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of maintenances to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of maintenances to skip for pagination (defaults to 0).\n pageId:\n type:\n - string\n - \"null\"\n title: page_id\n description: Filter by page ID (optional).\n title: ListMaintenancesRequest\n additionalProperties: false\n description: ListMaintenancesRequest is the request to list maintenance windows.\n openstatus.maintenance.v1.ListMaintenancesResponse:\n type: object\n properties:\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: List of maintenances.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of maintenances matching the filter.\n title: ListMaintenancesResponse\n additionalProperties: false\n description: ListMaintenancesResponse is the response containing maintenance window summaries.\n openstatus.maintenance.v1.Maintenance:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the maintenance.\n title:\n type: string\n title: title\n description: Title of the maintenance.\n message:\n type: string\n title: message\n description: Message of the newest maintenance update.\n from:\n type: string\n title: from\n description: Start time of the maintenance window (RFC 3339 format).\n to:\n type: string\n title: to\n description: End time of the maintenance window (RFC 3339 format).\n pageId:\n type: string\n title: page_id\n description: ID of the page this maintenance is associated with.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the maintenance was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the maintenance was last updated (RFC 3339 format).\n updates:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: updates\n description: Full maintenance update timeline, newest first.\n title: Maintenance\n additionalProperties: false\n description: Maintenance represents a maintenance window with full details.\n openstatus.maintenance.v1.MaintenanceSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the maintenance.\n title:\n type: string\n title: title\n description: Title of the maintenance.\n message:\n type: string\n title: message\n description: Message of the newest maintenance update.\n from:\n type: string\n title: from\n description: Start time of the maintenance window (RFC 3339 format).\n to:\n type: string\n title: to\n description: End time of the maintenance window (RFC 3339 format).\n pageId:\n type: string\n title: page_id\n description: ID of the page this maintenance is associated with.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the maintenance was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the maintenance was last updated (RFC 3339 format).\n title: MaintenanceSummary\n additionalProperties: false\n description: MaintenanceSummary represents metadata for a maintenance window (used in list responses).\n openstatus.maintenance.v1.MaintenanceUpdate:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the update.\n message:\n type: string\n title: message\n description: Public update message.\n date:\n type: string\n title: date\n description: Date of the update (RFC 3339 format).\n maintenanceId:\n type: string\n title: maintenance_id\n description: ID of the maintenance this update belongs to.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the update was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the update was last updated (RFC 3339 format).\n title: MaintenanceUpdate\n additionalProperties: false\n description: MaintenanceUpdate represents a timeline entry for a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the maintenance to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n maxLength: 256\n minLength: 1\n description: New title for the maintenance (optional).\n message:\n type:\n - string\n - \"null\"\n title: message\n description: Replaces the message of the newest maintenance update (optional).\n from:\n type:\n - string\n - \"null\"\n title: from\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New start time (RFC 3339 format, optional).\n to:\n type:\n - string\n - \"null\"\n title: to\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New end time (RFC 3339 format, optional).\n pageId:\n type:\n - string\n - \"null\"\n title: page_id\n description: 'Deprecated: page_id is now derived from page_component_ids.'\n deprecated: true\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: New list of page component IDs (optional, replaces existing list).\n updatePageComponentIds:\n type:\n - boolean\n - \"null\"\n title: update_page_component_ids\n description: |-\n Set to true to update page component associations.\n When true, page_component_ids replaces the existing list (empty clears all).\n When false or unset, page_component_ids is ignored and existing associations are preserved.\n title: UpdateMaintenanceRequest\n additionalProperties: false\n description: UpdateMaintenanceRequest is the request to update a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceResponse:\n type: object\n properties:\n maintenance:\n title: maintenance\n description: The updated maintenance.\n $ref: '#/components/schemas/openstatus.maintenance.v1.Maintenance'\n title: UpdateMaintenanceResponse\n additionalProperties: false\n description: UpdateMaintenanceResponse is the response after updating a maintenance window.\n openstatus.maintenance.v1.UpdateMaintenanceUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to edit (required).\n message:\n type:\n - string\n - \"null\"\n title: message\n minLength: 1\n description: New public message.\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New update date (RFC 3339 format).\n title: UpdateMaintenanceUpdateRequest\n additionalProperties: false\n description: UpdateMaintenanceUpdateRequest is the request to edit an update.\n openstatus.maintenance.v1.UpdateMaintenanceUpdateResponse:\n type: object\n properties:\n maintenanceUpdate:\n title: maintenance_update\n description: The updated timeline entry.\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceUpdate'\n title: UpdateMaintenanceUpdateResponse\n additionalProperties: false\n description: UpdateMaintenanceUpdateResponse is the response after editing an update.\n openstatus.monitor.v1.BodyAssertion:\n type: object\n properties:\n target:\n type: string\n title: target\n description: Target value to compare against.\n comparator:\n not:\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.StringComparator'\n title: BodyAssertion\n additionalProperties: false\n description: BodyAssertion defines an assertion for response body content.\n openstatus.monitor.v1.CreateDNSMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: CreateDNSMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateDNSMonitorRequest is the request to create a new DNS monitor.\n openstatus.monitor.v1.CreateDNSMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: CreateDNSMonitorResponse\n additionalProperties: false\n description: CreateDNSMonitorResponse is the response after creating a DNS monitor.\n openstatus.monitor.v1.CreateGRPCMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: CreateGRPCMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateGRPCMonitorRequest is the request to create a new gRPC monitor.\n openstatus.monitor.v1.CreateGRPCMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: CreateGRPCMonitorResponse\n additionalProperties: false\n description: CreateGRPCMonitorResponse is the response after creating a gRPC monitor.\n openstatus.monitor.v1.CreateHTTPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: CreateHTTPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateHTTPMonitorRequest is the request to create a new HTTP monitor.\n openstatus.monitor.v1.CreateHTTPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: CreateHTTPMonitorResponse\n additionalProperties: false\n description: CreateHTTPMonitorResponse is the response after creating an HTTP monitor.\n openstatus.monitor.v1.CreateICMPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: CreateICMPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateICMPMonitorRequest is the request to create a new ICMP monitor.\n openstatus.monitor.v1.CreateICMPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: CreateICMPMonitorResponse\n additionalProperties: false\n description: CreateICMPMonitorResponse is the response after creating an ICMP monitor.\n openstatus.monitor.v1.CreateTCPMonitorRequest:\n type: object\n properties:\n monitor:\n title: monitor\n description: Monitor configuration (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: CreateTCPMonitorRequest\n required:\n - monitor\n additionalProperties: false\n description: CreateTCPMonitorRequest is the request to create a new TCP monitor.\n openstatus.monitor.v1.CreateTCPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The created monitor with assigned ID.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: CreateTCPMonitorResponse\n additionalProperties: false\n description: CreateTCPMonitorResponse is the response after creating a TCP monitor.\n openstatus.monitor.v1.DNSMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - DNS Resolution Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - example.com\n title: uri\n maxLength: 2048\n minLength: 1\n description: Domain to resolve (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n recordAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.RecordAssertion'\n title: record_assertions\n maxItems: 10\n description: DNS record assertions for validation.\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: DNSMonitor\n additionalProperties: false\n description: DNSMonitor defines the configuration for a DNS monitor.\n openstatus.monitor.v1.DeleteMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to delete (required).\n title: DeleteMonitorRequest\n additionalProperties: false\n description: DeleteMonitorRequest is the request to delete a monitor.\n openstatus.monitor.v1.DeleteMonitorResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteMonitorResponse\n additionalProperties: false\n description: DeleteMonitorResponse is the response after deleting a monitor.\n openstatus.monitor.v1.GRPCMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Checkout gRPC\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - api.example.com:443\n title: uri\n maxLength: 2048\n minLength: 1\n pattern: ^(\\[[0-9a-fA-F:]+\\]|[^:/\\s]+):[0-9]{1,5}$\n description: Target in \"host:port\" form. IPv6 addresses must be bracketed.\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n service:\n type:\n - string\n - \"null\"\n examples:\n - checkout.v1.CheckoutService\n title: service\n maxLength: 512\n description: Service name passed to Health/Check. Empty means overall server health.\n tlsMode:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.GRPCTlsMode'\n - type: \"null\"\n title: tls_mode\n description: How the connection to the target is secured. Defaults to TLS.\n metadata:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: metadata\n maxItems: 20\n description: Metadata sent with the health check request.\n title: GRPCMonitor\n additionalProperties: false\n description: |-\n GRPCMonitor defines the configuration for a gRPC health check monitor.\n The probe calls grpc.health.v1.Health/Check on the target.\n openstatus.monitor.v1.GRPCTlsMode:\n type: string\n title: GRPCTlsMode\n enum:\n - GRPC_TLS_MODE_UNSPECIFIED\n - GRPC_TLS_MODE_TLS\n - GRPC_TLS_MODE_PLAINTEXT\n - GRPC_TLS_MODE_TLS_INSECURE\n description: GRPCTlsMode selects how the probe secures its connection to the target.\n openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get a response log for (required).\n logId:\n type: string\n title: log_id\n minLength: 1\n description: Response log ID to retrieve (required).\n title: GetMonitorHTTPResponseLogRequest\n additionalProperties: false\n description: GetMonitorHTTPResponseLogRequest is the request to get one response log.\n openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse:\n type: object\n properties:\n log:\n title: log\n description: Response log details.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogDetail'\n title: GetMonitorHTTPResponseLogResponse\n additionalProperties: false\n description: GetMonitorHTTPResponseLogResponse is the response containing one response log.\n openstatus.monitor.v1.GetMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to retrieve (required).\n title: GetMonitorRequest\n additionalProperties: false\n description: GetMonitorRequest is the request to get a single monitor by ID.\n openstatus.monitor.v1.GetMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The monitor configuration (one of HTTP, TCP, DNS, ICMP, or gRPC).\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorConfig'\n title: GetMonitorResponse\n additionalProperties: false\n description: GetMonitorResponse is the response containing the monitor.\n openstatus.monitor.v1.GetMonitorStatusRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get status for (required).\n title: GetMonitorStatusRequest\n additionalProperties: false\n description: GetMonitorStatusRequest is the request to get the status of all regions for a monitor.\n openstatus.monitor.v1.GetMonitorStatusResponse:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Monitor ID.\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.RegionStatus'\n title: regions\n description: Status for each region.\n title: GetMonitorStatusResponse\n additionalProperties: false\n description: GetMonitorStatusResponse is the response containing the status of all regions for a monitor.\n openstatus.monitor.v1.GetMonitorSummaryRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to get summary for (required).\n timeRange:\n title: time_range\n description: Time range for metrics aggregation (defaults to 1 day if unspecified).\n $ref: '#/components/schemas/openstatus.monitor.v1.TimeRange'\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Optional filter by regions. If empty, returns metrics for all regions.\n title: GetMonitorSummaryRequest\n additionalProperties: false\n description: GetMonitorSummaryRequest is the request to get aggregated metrics for a monitor.\n openstatus.monitor.v1.GetMonitorSummaryResponse:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Monitor ID.\n lastPingAt:\n type: string\n title: last_ping_at\n description: Timestamp of the last check in RFC 3339 format.\n totalSuccessful:\n type:\n - integer\n - string\n title: total_successful\n format: int64\n description: Total number of successful requests.\n totalDegraded:\n type:\n - integer\n - string\n title: total_degraded\n format: int64\n description: Total number of degraded requests.\n totalFailed:\n type:\n - integer\n - string\n title: total_failed\n format: int64\n description: Total number of failed requests.\n p50:\n type:\n - integer\n - string\n title: p50\n format: int64\n description: 50th percentile (median) latency in milliseconds.\n p75:\n type:\n - integer\n - string\n title: p75\n format: int64\n description: 75th percentile latency in milliseconds.\n p90:\n type:\n - integer\n - string\n title: p90\n format: int64\n description: 90th percentile latency in milliseconds.\n p95:\n type:\n - integer\n - string\n title: p95\n format: int64\n description: 95th percentile latency in milliseconds.\n p99:\n type:\n - integer\n - string\n title: p99\n format: int64\n description: 99th percentile latency in milliseconds.\n timeRange:\n title: time_range\n description: Time range used for the metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.TimeRange'\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n description: Regions included in the metrics.\n title: GetMonitorSummaryResponse\n additionalProperties: false\n description: GetMonitorSummaryResponse is the response containing aggregated metrics for a monitor.\n openstatus.monitor.v1.HTTPMethod:\n type: string\n title: HTTPMethod\n enum:\n - HTTP_METHOD_UNSPECIFIED\n - HTTP_METHOD_GET\n - HTTP_METHOD_POST\n - HTTP_METHOD_HEAD\n - HTTP_METHOD_PUT\n - HTTP_METHOD_PATCH\n - HTTP_METHOD_DELETE\n - HTTP_METHOD_TRACE\n - HTTP_METHOD_CONNECT\n - HTTP_METHOD_OPTIONS\n description: HTTP methods supported for monitors.\n openstatus.monitor.v1.HTTPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Production API Health Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n url:\n type: string\n examples:\n - https://api.example.com/health\n title: url\n maxLength: 2048\n minLength: 1\n format: uri\n description: URL to monitor (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n method:\n not:\n enum:\n - HTTP_METHOD_UNSPECIFIED\n title: method\n description: HTTP method to use (defaults to GET).\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMethod'\n body:\n type: string\n examples:\n - map[key:value]\n title: body\n description: Request body (optional).\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n followRedirects:\n type:\n - boolean\n - \"null\"\n title: follow_redirects\n description: Whether to follow HTTP redirects (defaults to true when not specified).\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: headers\n maxItems: 20\n description: Custom headers for the request.\n statusCodeAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.StatusCodeAssertion'\n title: status_code_assertions\n maxItems: 10\n description: Status code assertions for the response.\n bodyAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.BodyAssertion'\n title: body_assertions\n maxItems: 10\n description: Body content assertions for the response.\n headerAssertions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HeaderAssertion'\n title: header_assertions\n maxItems: 10\n description: Header assertions for the response.\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: HTTPMonitor\n additionalProperties: false\n description: HTTPMonitor defines the configuration for an HTTP monitor.\n openstatus.monitor.v1.HTTPResponseLogDetail:\n type: object\n properties:\n log:\n title: log\n description: Compact response log fields.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogListItem'\n url:\n type: string\n title: url\n description: Checked URL.\n error:\n type: boolean\n title: error\n description: Whether the check errored.\n message:\n type:\n - string\n - \"null\"\n title: message\n description: Error message, when present.\n headers:\n type: object\n title: headers\n additionalProperties:\n type: string\n title: value\n description: Redacted response headers.\n assertions:\n type:\n - string\n - \"null\"\n title: assertions\n description: Serialized assertions used for the check.\n title: HTTPResponseLogDetail\n additionalProperties: false\n description: HTTPResponseLogDetail contains full response log debugging data.\n openstatus.monitor.v1.HTTPResponseLogDetail.HeadersEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: HeadersEntry\n additionalProperties: false\n openstatus.monitor.v1.HTTPResponseLogListItem:\n type: object\n properties:\n id:\n type:\n - string\n - \"null\"\n title: id\n description: Response log ID.\n latency:\n type: integer\n title: latency\n format: int32\n description: Latency in milliseconds.\n statusCode:\n type:\n - integer\n - \"null\"\n title: status_code\n format: int32\n description: HTTP status code.\n monitorId:\n type: string\n title: monitor_id\n description: Monitor ID.\n requestStatus:\n title: request_status\n description: Request status classification.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogRequestStatus'\n region:\n title: region\n description: Region where the check ran.\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n cronTimestamp:\n type:\n - integer\n - string\n title: cron_timestamp\n format: int64\n description: Cron bucket timestamp in Unix milliseconds.\n trigger:\n title: trigger\n description: Check trigger.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogTrigger'\n timestamp:\n type:\n - integer\n - string\n title: timestamp\n format: int64\n description: Response timestamp in Unix milliseconds.\n timing:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogTiming'\n - type: \"null\"\n title: timing\n description: Timing phases.\n title: HTTPResponseLogListItem\n additionalProperties: false\n description: HTTPResponseLogListItem is a compact response log entry.\n openstatus.monitor.v1.HTTPResponseLogPagination:\n type: object\n properties:\n limit:\n type: integer\n title: limit\n format: int32\n description: Requested page size.\n offset:\n type: integer\n title: offset\n format: int32\n description: Requested offset.\n hasMore:\n type: boolean\n title: has_more\n description: Whether more logs are available.\n nextOffset:\n type:\n - integer\n - \"null\"\n title: next_offset\n format: int32\n description: Next offset if more logs are available.\n title: HTTPResponseLogPagination\n additionalProperties: false\n description: HTTPResponseLogPagination contains offset pagination metadata.\n openstatus.monitor.v1.HTTPResponseLogRequestStatus:\n type: string\n title: HTTPResponseLogRequestStatus\n enum:\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_UNSPECIFIED\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_SUCCESS\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_ERROR\n - HTTP_RESPONSE_LOG_REQUEST_STATUS_DEGRADED\n description: HTTPResponseLogRequestStatus is the result classification for an HTTP response log.\n openstatus.monitor.v1.HTTPResponseLogTiming:\n type: object\n properties:\n dns:\n type: integer\n title: dns\n format: int32\n description: DNS lookup duration.\n connect:\n type: integer\n title: connect\n format: int32\n description: TCP connection duration.\n tls:\n type: integer\n title: tls\n format: int32\n description: TLS handshake duration.\n ttfb:\n type: integer\n title: ttfb\n format: int32\n description: Time to first byte duration.\n transfer:\n type: integer\n title: transfer\n format: int32\n description: Response transfer duration.\n title: HTTPResponseLogTiming\n additionalProperties: false\n description: HTTPResponseLogTiming contains calculated timing phases in milliseconds.\n openstatus.monitor.v1.HTTPResponseLogTrigger:\n type: string\n title: HTTPResponseLogTrigger\n enum:\n - HTTP_RESPONSE_LOG_TRIGGER_UNSPECIFIED\n - HTTP_RESPONSE_LOG_TRIGGER_CRON\n - HTTP_RESPONSE_LOG_TRIGGER_API\n description: HTTPResponseLogTrigger describes what started the monitor check.\n openstatus.monitor.v1.HeaderAssertion:\n type: object\n properties:\n target:\n type: string\n title: target\n description: Target value to compare against.\n comparator:\n not:\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.StringComparator'\n key:\n type: string\n title: key\n minLength: 1\n description: Header key to check (required).\n title: HeaderAssertion\n additionalProperties: false\n description: HeaderAssertion defines an assertion for response headers.\n openstatus.monitor.v1.Headers:\n type: object\n properties:\n key:\n type: string\n examples:\n - Authorization\n title: key\n minLength: 1\n description: Header name.\n value:\n type: string\n examples:\n - Bearer token123\n title: value\n description: Header value.\n title: Headers\n additionalProperties: false\n description: Headers represents a key-value pair for HTTP headers.\n openstatus.monitor.v1.ICMPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Ping Gateway\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - 1.1.1.1\n title: uri\n maxLength: 2048\n minLength: 1\n description: URI to monitor in format \"host or IP\" (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: ICMPMonitor\n additionalProperties: false\n description: ICMPMonitor defines the configuration for a ICMP monitor.\n openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to list response logs for (required).\n fromTimestamp:\n type:\n - integer\n - string\n - \"null\"\n title: from_timestamp\n format: int64\n description: Start of the response log window as Unix milliseconds within the 14-day retention window.\n toTimestamp:\n type:\n - integer\n - string\n - \"null\"\n title: to_timestamp\n format: int64\n description: End of the response log window as Unix milliseconds within the 14-day retention window.\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of logs to return (1-100, defaults to 25).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of logs to skip for pagination (defaults to 0).\n title: ListMonitorHTTPResponseLogsRequest\n additionalProperties: false\n description: ListMonitorHTTPResponseLogsRequest is the request to list response logs within the 14-day HTTP response-log window.\n openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse:\n type: object\n properties:\n logs:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogListItem'\n title: logs\n description: Response logs.\n pagination:\n title: pagination\n description: Pagination metadata.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPResponseLogPagination'\n title: ListMonitorHTTPResponseLogsResponse\n additionalProperties: false\n description: ListMonitorHTTPResponseLogsResponse is the response containing response logs.\n openstatus.monitor.v1.ListMonitorsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of monitors to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of monitors to skip for pagination (defaults to 0).\n title: ListMonitorsRequest\n additionalProperties: false\n description: ListMonitorsRequest is the request to list monitors.\n openstatus.monitor.v1.ListMonitorsResponse:\n type: object\n properties:\n httpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: http_monitors\n description: HTTP monitors in the workspace.\n tcpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: tcp_monitors\n description: TCP monitors in the workspace.\n dnsMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: dns_monitors\n description: DNS monitors in the workspace.\n icmpMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: icmp_monitors\n description: ICMP monitors in the workspace.\n grpcMonitors:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: grpc_monitors\n description: gRPC monitors in the workspace.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of monitors across all types.\n title: ListMonitorsResponse\n additionalProperties: false\n description: ListMonitorsResponse is the response containing a list of monitors.\n openstatus.monitor.v1.MonitorConfig:\n type: object\n oneOf:\n - type: object\n properties:\n dns:\n title: dns\n description: DNS monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: dns\n required:\n - dns\n - type: object\n properties:\n grpc:\n title: grpc\n description: gRPC monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: grpc\n required:\n - grpc\n - type: object\n properties:\n http:\n title: http\n description: HTTP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: http\n required:\n - http\n - type: object\n properties:\n icmp:\n title: icmp\n description: ICMP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: icmp\n required:\n - icmp\n - type: object\n properties:\n tcp:\n title: tcp\n description: TCP monitor configuration.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: tcp\n required:\n - tcp\n title: MonitorConfig\n additionalProperties: false\n description: MonitorConfig represents the type-specific configuration for a monitor.\n openstatus.monitor.v1.MonitorStatus:\n type: string\n title: MonitorStatus\n enum:\n - MONITOR_STATUS_UNSPECIFIED\n - MONITOR_STATUS_ACTIVE\n - MONITOR_STATUS_DEGRADED\n - MONITOR_STATUS_ERROR\n description: MonitorStatus represents the operational status of a monitor.\n openstatus.monitor.v1.NumberComparator:\n type: string\n title: NumberComparator\n enum:\n - NUMBER_COMPARATOR_UNSPECIFIED\n - NUMBER_COMPARATOR_EQUAL\n - NUMBER_COMPARATOR_NOT_EQUAL\n - NUMBER_COMPARATOR_GREATER_THAN\n - NUMBER_COMPARATOR_GREATER_THAN_OR_EQUAL\n - NUMBER_COMPARATOR_LESS_THAN\n - NUMBER_COMPARATOR_LESS_THAN_OR_EQUAL\n description: NumberComparator defines comparison operations for numeric values.\n openstatus.monitor.v1.OpenTelemetryConfig:\n type: object\n properties:\n endpoint:\n type: string\n title: endpoint\n maxLength: 2048\n description: OTEL endpoint URL.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Headers'\n title: headers\n maxItems: 20\n description: Custom headers for OTEL requests.\n title: OpenTelemetryConfig\n additionalProperties: false\n description: OpenTelemetry configuration for exporting metrics.\n openstatus.monitor.v1.Periodicity:\n type: string\n title: Periodicity\n enum:\n - PERIODICITY_UNSPECIFIED\n - PERIODICITY_30S\n - PERIODICITY_1M\n - PERIODICITY_5M\n - PERIODICITY_10M\n - PERIODICITY_30M\n - PERIODICITY_1H\n description: Monitor periodicity options.\n openstatus.monitor.v1.RecordAssertion:\n type: object\n properties:\n record:\n type: string\n title: record\n enum:\n - A\n - AAAA\n - CNAME\n - MX\n - TXT\n description: DNS record type (e.g., \"A\", \"AAAA\", \"CNAME\", \"MX\", \"TXT\").\n comparator:\n not:\n enum:\n - RECORD_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.RecordComparator'\n target:\n type: string\n title: target\n description: Target value to compare against.\n title: RecordAssertion\n additionalProperties: false\n description: RecordAssertion defines an assertion for DNS records.\n openstatus.monitor.v1.RecordComparator:\n type: string\n title: RecordComparator\n enum:\n - RECORD_COMPARATOR_UNSPECIFIED\n - RECORD_COMPARATOR_EQUAL\n - RECORD_COMPARATOR_NOT_EQUAL\n - RECORD_COMPARATOR_CONTAINS\n - RECORD_COMPARATOR_NOT_CONTAINS\n description: RecordComparator defines comparison operations for DNS records.\n openstatus.monitor.v1.Region:\n type: string\n title: Region\n enum:\n - REGION_UNSPECIFIED\n - REGION_FLY_AMS\n - REGION_FLY_ARN\n - REGION_FLY_BOM\n - REGION_FLY_CDG\n - REGION_FLY_DFW\n - REGION_FLY_EWR\n - REGION_FLY_FRA\n - REGION_FLY_GRU\n - REGION_FLY_IAD\n - REGION_FLY_JNB\n - REGION_FLY_LAX\n - REGION_FLY_LHR\n - REGION_FLY_NRT\n - REGION_FLY_ORD\n - REGION_FLY_SJC\n - REGION_FLY_SIN\n - REGION_FLY_SYD\n - REGION_FLY_YYZ\n - REGION_KOYEB_FRA\n - REGION_KOYEB_PAR\n - REGION_KOYEB_SFO\n - REGION_KOYEB_SIN\n - REGION_KOYEB_TYO\n - REGION_KOYEB_WAS\n - REGION_RAILWAY_US_WEST2\n - REGION_RAILWAY_US_EAST4\n - REGION_RAILWAY_EUROPE_WEST4\n - REGION_RAILWAY_ASIA_SOUTHEAST1\n description: |-\n Geographic regions where monitors can run checks from.\n REGION_FLY_BOM is deprecated and rejected on create/update; use REGION_FLY_SIN.\n openstatus.monitor.v1.RegionStatus:\n type: object\n properties:\n region:\n title: region\n description: The region identifier.\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n status:\n title: status\n description: The status of the monitor in this region.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n title: RegionStatus\n additionalProperties: false\n description: RegionStatus represents the status of a monitor in a specific region.\n openstatus.monitor.v1.StatusCodeAssertion:\n type: object\n properties:\n target:\n type:\n - integer\n - string\n title: target\n maximum: 599\n minimum: 100\n format: int64\n description: Target status code to compare against (100-599).\n comparator:\n not:\n enum:\n - NUMBER_COMPARATOR_UNSPECIFIED\n title: comparator\n description: Comparison operation (required, must not be UNSPECIFIED).\n $ref: '#/components/schemas/openstatus.monitor.v1.NumberComparator'\n title: StatusCodeAssertion\n additionalProperties: false\n description: StatusCodeAssertion defines an assertion for HTTP status codes.\n openstatus.monitor.v1.StringComparator:\n type: string\n title: StringComparator\n enum:\n - STRING_COMPARATOR_UNSPECIFIED\n - STRING_COMPARATOR_CONTAINS\n - STRING_COMPARATOR_NOT_CONTAINS\n - STRING_COMPARATOR_EQUAL\n - STRING_COMPARATOR_NOT_EQUAL\n - STRING_COMPARATOR_EMPTY\n - STRING_COMPARATOR_NOT_EMPTY\n - STRING_COMPARATOR_GREATER_THAN\n - STRING_COMPARATOR_GREATER_THAN_OR_EQUAL\n - STRING_COMPARATOR_LESS_THAN\n - STRING_COMPARATOR_LESS_THAN_OR_EQUAL\n description: StringComparator defines comparison operations for string values.\n openstatus.monitor.v1.TCPMonitor:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the monitor (output only for create requests).\n name:\n type: string\n examples:\n - Database Connection Check\n title: name\n maxLength: 256\n minLength: 1\n description: Name of the monitor (required, max 256 characters).\n uri:\n type: string\n examples:\n - tcp://db.example.com:5432\n title: uri\n maxLength: 2048\n minLength: 1\n description: URI to monitor in format \"host:port\" (required, max 2048 characters).\n periodicity:\n not:\n enum:\n - PERIODICITY_UNSPECIFIED\n title: periodicity\n description: Check periodicity (required).\n $ref: '#/components/schemas/openstatus.monitor.v1.Periodicity'\n timeout:\n type:\n - integer\n - string\n title: timeout\n maximum: 120000\n minimum: 0\n format: int64\n description: Timeout in milliseconds (0-120000, defaults to 45000).\n degradedAt:\n type:\n - integer\n - string\n - \"null\"\n title: degraded_at\n maximum: 120000\n minimum: 0\n format: int64\n description: Latency threshold for degraded status in milliseconds (optional, 0-120000).\n retry:\n type:\n - integer\n - string\n title: retry\n maximum: 10\n minimum: 0\n format: int64\n description: Number of retry attempts (0-10, defaults to 3).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the monitor (optional).\n active:\n type:\n - boolean\n - \"null\"\n title: active\n description: Whether the monitor is active (defaults to false).\n public:\n type:\n - boolean\n - \"null\"\n title: public\n description: Whether the monitor is publicly visible (defaults to false).\n regions:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.monitor.v1.Region'\n title: regions\n maxItems: 28\n description: Geographic regions to run checks from.\n openTelemetry:\n title: open_telemetry\n description: OpenTelemetry configuration for exporting metrics.\n $ref: '#/components/schemas/openstatus.monitor.v1.OpenTelemetryConfig'\n status:\n title: status\n description: Current operational status of the monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.MonitorStatus'\n privateLocationIds:\n type: array\n items:\n type: string\n readOnly: true\n title: private_location_ids\n description: IDs of private locations that run this monitor. Read-only.\n readOnly: true\n title: TCPMonitor\n additionalProperties: false\n description: TCPMonitor defines the configuration for a TCP monitor.\n openstatus.monitor.v1.TimeRange:\n type: string\n title: TimeRange\n enum:\n - TIME_RANGE_UNSPECIFIED\n - TIME_RANGE_1D\n - TIME_RANGE_7D\n - TIME_RANGE_14D\n description: TimeRange represents the time period for metrics aggregation.\n openstatus.monitor.v1.TriggerMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to trigger (required).\n title: TriggerMonitorRequest\n additionalProperties: false\n description: TriggerMonitorRequest is the request to trigger a monitor check.\n openstatus.monitor.v1.TriggerMonitorResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the trigger was successful.\n title: TriggerMonitorResponse\n additionalProperties: false\n description: TriggerMonitorResponse is the response after triggering a monitor.\n openstatus.monitor.v1.UpdateDNSMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateDNSMonitorRequest\n additionalProperties: false\n description: UpdateDNSMonitorRequest is the request to update an existing DNS monitor.\n openstatus.monitor.v1.UpdateDNSMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.DNSMonitor'\n title: UpdateDNSMonitorResponse\n additionalProperties: false\n description: UpdateDNSMonitorResponse is the response after updating a DNS monitor.\n openstatus.monitor.v1.UpdateGRPCMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateGRPCMonitorRequest\n additionalProperties: false\n description: UpdateGRPCMonitorRequest is the request to update an existing gRPC monitor.\n openstatus.monitor.v1.UpdateGRPCMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.GRPCMonitor'\n title: UpdateGRPCMonitorResponse\n additionalProperties: false\n description: UpdateGRPCMonitorResponse is the response after updating a gRPC monitor.\n openstatus.monitor.v1.UpdateHTTPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateHTTPMonitorRequest\n additionalProperties: false\n description: UpdateHTTPMonitorRequest is the request to update an existing HTTP monitor.\n openstatus.monitor.v1.UpdateHTTPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.HTTPMonitor'\n title: UpdateHTTPMonitorResponse\n additionalProperties: false\n description: UpdateHTTPMonitorResponse is the response after updating an HTTP monitor.\n openstatus.monitor.v1.UpdateICMPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateICMPMonitorRequest\n additionalProperties: false\n description: UpdateICMPMonitorRequest is the request to update an existing ICMP monitor.\n openstatus.monitor.v1.UpdateICMPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.ICMPMonitor'\n title: UpdateICMPMonitorResponse\n additionalProperties: false\n description: UpdateICMPMonitorResponse is the response after updating an ICMP monitor.\n openstatus.monitor.v1.UpdateTCPMonitorRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Monitor ID to update (required).\n monitor:\n oneOf:\n - $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n - type: \"null\"\n title: monitor\n description: Updated monitor configuration (all fields optional for partial updates).\n title: UpdateTCPMonitorRequest\n additionalProperties: false\n description: UpdateTCPMonitorRequest is the request to update an existing TCP monitor.\n openstatus.monitor.v1.UpdateTCPMonitorResponse:\n type: object\n properties:\n monitor:\n title: monitor\n description: The updated monitor.\n $ref: '#/components/schemas/openstatus.monitor.v1.TCPMonitor'\n title: UpdateTCPMonitorResponse\n additionalProperties: false\n description: UpdateTCPMonitorResponse is the response after updating a TCP monitor.\n openstatus.notification.v1.CheckNotificationLimitRequest:\n type: object\n title: CheckNotificationLimitRequest\n additionalProperties: false\n description: CheckNotificationLimitRequest is the request to check notification limits.\n openstatus.notification.v1.CheckNotificationLimitResponse:\n type: object\n properties:\n limitReached:\n type: boolean\n title: limit_reached\n description: Whether the workspace has reached its notification limit.\n currentCount:\n type: integer\n title: current_count\n format: int32\n description: Current number of notification channels.\n maxCount:\n type: integer\n title: max_count\n format: int32\n description: Maximum allowed notification channels.\n title: CheckNotificationLimitResponse\n additionalProperties: false\n description: CheckNotificationLimitResponse is the response containing limit information.\n openstatus.notification.v1.CreateNotificationRequest:\n type: object\n properties:\n name:\n type: string\n examples:\n - Slack Ops Channel\n title: name\n minLength: 1\n description: Display name for the notification channel.\n provider:\n not:\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors to associate with this notification.\n title: CreateNotificationRequest\n required:\n - data\n additionalProperties: false\n description: CreateNotificationRequest is the request to create a new notification channel.\n openstatus.notification.v1.CreateNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The created notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: CreateNotificationResponse\n additionalProperties: false\n description: CreateNotificationResponse is the response after creating a notification channel.\n openstatus.notification.v1.DeleteNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to delete (required).\n title: DeleteNotificationRequest\n additionalProperties: false\n description: DeleteNotificationRequest is the request to delete a notification channel.\n openstatus.notification.v1.DeleteNotificationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteNotificationResponse\n additionalProperties: false\n description: DeleteNotificationResponse is the response after deleting a notification channel.\n openstatus.notification.v1.DiscordData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://discord.com/api/webhooks/123/abc\n title: webhook_url\n format: uri\n description: Discord webhook URL.\n title: DiscordData\n additionalProperties: false\n description: DiscordData contains configuration for Discord notifications.\n openstatus.notification.v1.EmailData:\n type: object\n properties:\n email:\n type: string\n examples:\n - ops-team@example.com\n title: email\n format: email\n description: Email address to send notifications to.\n title: EmailData\n additionalProperties: false\n description: EmailData contains configuration for email notifications.\n openstatus.notification.v1.GetNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to retrieve (required).\n title: GetNotificationRequest\n additionalProperties: false\n description: GetNotificationRequest is the request to get a notification channel.\n openstatus.notification.v1.GetNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: GetNotificationResponse\n additionalProperties: false\n description: GetNotificationResponse is the response containing the notification channel.\n openstatus.notification.v1.GoogleChatData:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n format: uri\n description: Google Chat webhook URL.\n title: GoogleChatData\n additionalProperties: false\n description: GoogleChatData contains configuration for Google Chat notifications.\n openstatus.notification.v1.GrafanaOncallData:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n format: uri\n description: Grafana OnCall webhook URL.\n title: GrafanaOncallData\n additionalProperties: false\n description: GrafanaOncallData contains configuration for Grafana OnCall notifications.\n openstatus.notification.v1.ListNotificationsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of notifications to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of notifications to skip for pagination (defaults to 0).\n title: ListNotificationsRequest\n additionalProperties: false\n description: ListNotificationsRequest is the request to list notification channels.\n openstatus.notification.v1.ListNotificationsResponse:\n type: object\n properties:\n notifications:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationSummary'\n title: notifications\n description: Notification channel summaries.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of notification channels.\n title: ListNotificationsResponse\n additionalProperties: false\n description: ListNotificationsResponse is the response containing notification channels.\n openstatus.notification.v1.MsTeamsData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://prod-00.westeurope.logic.azure.com:443/workflows/abc/triggers/manual/paths/invoke\n title: webhook_url\n format: uri\n description: Microsoft Teams webhook URL (Power Automate Workflows).\n title: MsTeamsData\n additionalProperties: false\n description: MsTeamsData contains configuration for Microsoft Teams notifications.\n openstatus.notification.v1.Notification:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the notification.\n name:\n type: string\n title: name\n description: Display name for the notification channel.\n provider:\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors associated with this notification.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the notification was created (RFC 3339).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the notification was last updated (RFC 3339).\n title: Notification\n additionalProperties: false\n description: Notification represents a notification channel with full details.\n openstatus.notification.v1.NotificationData:\n type: object\n oneOf:\n - type: object\n properties:\n discord:\n title: discord\n description: Discord configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.DiscordData'\n title: discord\n required:\n - discord\n - type: object\n properties:\n email:\n title: email\n description: Email configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.EmailData'\n title: email\n required:\n - email\n - type: object\n properties:\n googleChat:\n title: google_chat\n description: Google Chat configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.GoogleChatData'\n title: google_chat\n required:\n - googleChat\n - type: object\n properties:\n grafanaOncall:\n title: grafana_oncall\n description: Grafana OnCall configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.GrafanaOncallData'\n title: grafana_oncall\n required:\n - grafanaOncall\n - type: object\n properties:\n msTeams:\n title: ms_teams\n description: Microsoft Teams configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.MsTeamsData'\n title: ms_teams\n required:\n - msTeams\n - type: object\n properties:\n ntfy:\n title: ntfy\n description: Ntfy configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NtfyData'\n title: ntfy\n required:\n - ntfy\n - type: object\n properties:\n opsgenie:\n title: opsgenie\n description: Opsgenie configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.OpsgenieData'\n title: opsgenie\n required:\n - opsgenie\n - type: object\n properties:\n pagerduty:\n title: pagerduty\n description: PagerDuty configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.PagerDutyData'\n title: pagerduty\n required:\n - pagerduty\n - type: object\n properties:\n slack:\n title: slack\n description: Slack configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.SlackData'\n title: slack\n required:\n - slack\n - type: object\n properties:\n sms:\n title: sms\n description: 'Deprecated: SMS is no longer offered; use whatsapp.'\n deprecated: true\n $ref: '#/components/schemas/openstatus.notification.v1.SmsData'\n title: sms\n required:\n - sms\n - type: object\n properties:\n telegram:\n title: telegram\n description: Telegram configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.TelegramData'\n title: telegram\n required:\n - telegram\n - type: object\n properties:\n webhook:\n title: webhook\n description: Webhook configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.WebhookData'\n title: webhook\n required:\n - webhook\n - type: object\n properties:\n whatsapp:\n title: whatsapp\n description: WhatsApp configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.WhatsappData'\n title: whatsapp\n required:\n - whatsapp\n title: NotificationData\n additionalProperties: false\n description: NotificationData is a union of provider-specific configuration.\n openstatus.notification.v1.NotificationProvider:\n type: string\n title: NotificationProvider\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n - NOTIFICATION_PROVIDER_DISCORD\n - NOTIFICATION_PROVIDER_EMAIL\n - NOTIFICATION_PROVIDER_GOOGLE_CHAT\n - NOTIFICATION_PROVIDER_GRAFANA_ONCALL\n - NOTIFICATION_PROVIDER_NTFY\n - NOTIFICATION_PROVIDER_PAGERDUTY\n - NOTIFICATION_PROVIDER_OPSGENIE\n - NOTIFICATION_PROVIDER_SLACK\n - NOTIFICATION_PROVIDER_SMS\n - NOTIFICATION_PROVIDER_TELEGRAM\n - NOTIFICATION_PROVIDER_WEBHOOK\n - NOTIFICATION_PROVIDER_WHATSAPP\n - NOTIFICATION_PROVIDER_MS_TEAMS\n description: NotificationProvider represents the supported notification channel types.\n openstatus.notification.v1.NotificationSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the notification.\n name:\n type: string\n title: name\n description: Display name for the notification channel.\n provider:\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n monitorCount:\n type: integer\n title: monitor_count\n format: int32\n description: Number of monitors associated with this notification.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the notification was created (RFC 3339).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the notification was last updated (RFC 3339).\n title: NotificationSummary\n additionalProperties: false\n description: NotificationSummary represents a notification channel summary for list responses.\n openstatus.notification.v1.NtfyData:\n type: object\n properties:\n topic:\n type: string\n examples:\n - openstatus-alerts\n title: topic\n minLength: 1\n description: Ntfy topic to publish to.\n serverUrl:\n type: string\n title: server_url\n description: Ntfy server URL (defaults to https://ntfy.sh).\n token:\n type:\n - string\n - \"null\"\n title: token\n description: Optional authentication token.\n title: NtfyData\n additionalProperties: false\n description: NtfyData contains configuration for Ntfy notifications.\n openstatus.notification.v1.OpsgenieData:\n type: object\n properties:\n apiKey:\n type: string\n title: api_key\n minLength: 1\n description: Opsgenie API key.\n region:\n title: region\n description: Opsgenie region.\n $ref: '#/components/schemas/openstatus.notification.v1.OpsgenieRegion'\n title: OpsgenieData\n additionalProperties: false\n description: OpsgenieData contains configuration for Opsgenie notifications.\n openstatus.notification.v1.OpsgenieRegion:\n type: string\n title: OpsgenieRegion\n enum:\n - OPSGENIE_REGION_UNSPECIFIED\n - OPSGENIE_REGION_US\n - OPSGENIE_REGION_EU\n description: OpsgenieRegion represents the Opsgenie API region.\n openstatus.notification.v1.PagerDutyData:\n type: object\n properties:\n integrationKey:\n type: string\n examples:\n - a1b2c3d4e5f6g7h8i9j0\n title: integration_key\n minLength: 1\n description: PagerDuty integration key.\n title: PagerDutyData\n additionalProperties: false\n description: PagerDutyData contains configuration for PagerDuty notifications.\n openstatus.notification.v1.SendTestNotificationRequest:\n type: object\n properties:\n provider:\n not:\n enum:\n - NOTIFICATION_PROVIDER_UNSPECIFIED\n title: provider\n description: Provider type.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationProvider'\n data:\n title: data\n description: Provider-specific configuration.\n $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n title: SendTestNotificationRequest\n required:\n - data\n additionalProperties: false\n description: SendTestNotificationRequest is the request to send a test notification.\n openstatus.notification.v1.SendTestNotificationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the test was successful.\n errorMessage:\n type:\n - string\n - \"null\"\n title: error_message\n description: Optional error message if the test failed.\n title: SendTestNotificationResponse\n additionalProperties: false\n description: SendTestNotificationResponse is the response after sending a test notification.\n openstatus.notification.v1.SlackData:\n type: object\n properties:\n webhookUrl:\n type: string\n examples:\n - https://hooks.slack.com/services/T00/B00/xxx\n title: webhook_url\n format: uri\n description: Slack webhook URL.\n title: SlackData\n additionalProperties: false\n description: SlackData contains configuration for Slack notifications.\n openstatus.notification.v1.SmsData:\n type: object\n properties:\n phoneNumber:\n type: string\n examples:\n - \"+14155551234\"\n title: phone_number\n minLength: 1\n description: Phone number to send SMS to.\n title: SmsData\n additionalProperties: false\n description: 'Deprecated: SMS is no longer offered; use WhatsappData. Kept for existing channels.'\n deprecated: true\n openstatus.notification.v1.TelegramData:\n type: object\n properties:\n chatId:\n type: string\n examples:\n - \"-1001234567890\"\n title: chat_id\n minLength: 1\n description: Telegram chat ID.\n title: TelegramData\n additionalProperties: false\n description: TelegramData contains configuration for Telegram notifications.\n openstatus.notification.v1.UpdateNotificationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: Notification ID to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n description: Updated display name.\n data:\n oneOf:\n - $ref: '#/components/schemas/openstatus.notification.v1.NotificationData'\n - type: \"null\"\n title: data\n description: Updated provider-specific configuration.\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: Updated monitor IDs to associate.\n updateMonitorIds:\n type:\n - boolean\n - \"null\"\n title: update_monitor_ids\n description: |-\n Set to true to update monitor associations.\n When true, monitor_ids replaces the existing list (empty clears all).\n When false or unset, monitor_ids is ignored and existing associations are preserved.\n title: UpdateNotificationRequest\n additionalProperties: false\n description: UpdateNotificationRequest is the request to update a notification channel.\n openstatus.notification.v1.UpdateNotificationResponse:\n type: object\n properties:\n notification:\n title: notification\n description: The updated notification channel.\n $ref: '#/components/schemas/openstatus.notification.v1.Notification'\n title: UpdateNotificationResponse\n additionalProperties: false\n description: UpdateNotificationResponse is the response after updating a notification channel.\n openstatus.notification.v1.WebhookData:\n type: object\n properties:\n endpoint:\n type: string\n examples:\n - https://api.example.com/webhooks/openstatus\n title: endpoint\n format: uri\n description: Webhook endpoint URL.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.notification.v1.WebhookHeader'\n title: headers\n description: Optional custom headers.\n title: WebhookData\n additionalProperties: false\n description: WebhookData contains configuration for custom webhook notifications.\n openstatus.notification.v1.WebhookHeader:\n type: object\n properties:\n key:\n type: string\n title: key\n minLength: 1\n description: Header name.\n value:\n type: string\n title: value\n description: Header value.\n title: WebhookHeader\n additionalProperties: false\n description: WebhookHeader represents a custom header for webhook requests.\n openstatus.notification.v1.WhatsappData:\n type: object\n properties:\n phoneNumber:\n type: string\n title: phone_number\n minLength: 1\n description: Phone number to send WhatsApp messages to.\n title: WhatsappData\n additionalProperties: false\n description: WhatsappData contains configuration for WhatsApp notifications.\n openstatus.private_location.v1.CreatePrivateLocationRequest:\n type: object\n properties:\n name:\n type: string\n examples:\n - eu-west-agent\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the private location (required, 1-256 characters).\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors this private location should run (optional).\n metadata:\n type: object\n title: metadata\n maxProperties: 20\n additionalProperties:\n type: string\n title: value\n maxLength: 256\n description: User-defined key/value labels (optional, up to 20 entries).\n title: CreatePrivateLocationRequest\n additionalProperties: false\n description: CreatePrivateLocationRequest is the request to create a new private location.\n openstatus.private_location.v1.CreatePrivateLocationRequest.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.CreatePrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The created private location, including its generated agent token.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: CreatePrivateLocationResponse\n additionalProperties: false\n description: CreatePrivateLocationResponse is the response after creating a private location.\n openstatus.private_location.v1.DeletePrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to delete (required).\n title: DeletePrivateLocationRequest\n additionalProperties: false\n description: DeletePrivateLocationRequest is the request to delete a private location.\n openstatus.private_location.v1.DeletePrivateLocationResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeletePrivateLocationResponse\n additionalProperties: false\n description: DeletePrivateLocationResponse is the response after deleting a private location.\n openstatus.private_location.v1.GetPrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to retrieve (required).\n title: GetPrivateLocationRequest\n additionalProperties: false\n description: GetPrivateLocationRequest is the request to get a private location by ID.\n openstatus.private_location.v1.GetPrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The requested private location.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: GetPrivateLocationResponse\n additionalProperties: false\n description: GetPrivateLocationResponse is the response containing the private location.\n openstatus.private_location.v1.ListPrivateLocationsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of private locations to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of private locations to skip for pagination (defaults to 0).\n title: ListPrivateLocationsRequest\n additionalProperties: false\n description: ListPrivateLocationsRequest is the request to list private locations.\n openstatus.private_location.v1.ListPrivateLocationsResponse:\n type: object\n properties:\n privateLocations:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationSummary'\n title: private_locations\n description: List of private locations.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of private locations in the workspace.\n title: ListPrivateLocationsResponse\n additionalProperties: false\n description: ListPrivateLocationsResponse is the response containing private location summaries.\n openstatus.private_location.v1.PrivateLocation:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the private location.\n name:\n type: string\n title: name\n description: Display name for the private location.\n token:\n type: string\n title: token\n description: |-\n Agent credential. Generated by the server on creation and used by the\n agent to authenticate; treat it as a secret.\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: IDs of monitors this private location runs.\n lastSeenAt:\n type: string\n title: last_seen_at\n description: Last time the agent reported a result (RFC 3339), empty if it never has.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the private location was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the private location was last updated (RFC 3339 format).\n metadata:\n type: object\n title: metadata\n additionalProperties:\n type: string\n title: value\n description: User-defined key/value labels attached to this private location.\n status:\n title: status\n description: Computed health of the agent. Read-only.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationStatus'\n title: PrivateLocation\n additionalProperties: false\n description: PrivateLocation represents a self-hosted checker agent with full details.\n openstatus.private_location.v1.PrivateLocation.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.PrivateLocationStatus:\n type: string\n title: PrivateLocationStatus\n enum:\n - PRIVATE_LOCATION_STATUS_UNSPECIFIED\n - PRIVATE_LOCATION_STATUS_ACTIVE\n - PRIVATE_LOCATION_STATUS_ERROR\n description: |-\n PrivateLocationStatus is the computed health of a private location, derived\n from the agent heartbeat. Read-only — it cannot be set through the API.\n openstatus.private_location.v1.PrivateLocationSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the private location.\n name:\n type: string\n title: name\n description: Display name for the private location.\n monitorCount:\n type: integer\n title: monitor_count\n format: int32\n description: Number of monitors this private location runs.\n lastSeenAt:\n type: string\n title: last_seen_at\n description: Last time the agent reported a result (RFC 3339), empty if it never has.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the private location was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the private location was last updated (RFC 3339 format).\n status:\n title: status\n description: Computed health of the agent. Read-only.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocationStatus'\n metadata:\n type: object\n title: metadata\n additionalProperties:\n type: string\n title: value\n description: User-defined key/value labels attached to this private location.\n title: PrivateLocationSummary\n additionalProperties: false\n description: |-\n PrivateLocationSummary represents metadata for a private location (used in\n list responses). The agent token is intentionally omitted.\n openstatus.private_location.v1.PrivateLocationSummary.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.UpdatePrivateLocationRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the private location to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n minLength: 1\n description: New display name for the private location (optional).\n monitorIds:\n type: array\n items:\n type: string\n title: monitor_ids\n description: New list of monitor IDs. Only applied when update_monitor_ids is true.\n updateMonitorIds:\n type:\n - boolean\n - \"null\"\n title: update_monitor_ids\n description: |-\n When true, monitor_ids replaces the current associations (an empty list\n clears all). When false or unset, monitor_ids is ignored and existing\n associations are preserved.\n metadata:\n type: object\n title: metadata\n maxProperties: 20\n additionalProperties:\n type: string\n title: value\n maxLength: 256\n description: New key/value labels. Only applied when update_metadata is true.\n updateMetadata:\n type:\n - boolean\n - \"null\"\n title: update_metadata\n description: |-\n When true, metadata replaces the current labels (an empty map clears all).\n When false or unset, metadata is ignored and existing labels are preserved.\n title: UpdatePrivateLocationRequest\n additionalProperties: false\n description: UpdatePrivateLocationRequest is the request to update a private location.\n openstatus.private_location.v1.UpdatePrivateLocationRequest.MetadataEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: MetadataEntry\n additionalProperties: false\n openstatus.private_location.v1.UpdatePrivateLocationResponse:\n type: object\n properties:\n privateLocation:\n title: private_location\n description: The updated private location.\n $ref: '#/components/schemas/openstatus.private_location.v1.PrivateLocation'\n title: UpdatePrivateLocationResponse\n additionalProperties: false\n description: UpdatePrivateLocationResponse is the response after updating a private location.\n openstatus.status_page.v1.AddMonitorComponentRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to add the component to (required).\n monitorId:\n type: string\n title: monitor_id\n minLength: 1\n description: ID of the monitor to associate with this component (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n description: Display name for the component (optional, defaults to monitor name).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: Display order of the component (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: ID of the group to add this component to (optional).\n title: AddMonitorComponentRequest\n additionalProperties: false\n description: AddMonitorComponentRequest is the request to add a monitor-based component to a status page.\n openstatus.status_page.v1.AddMonitorComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The created component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: AddMonitorComponentResponse\n additionalProperties: false\n description: AddMonitorComponentResponse is the response after adding a monitor component.\n openstatus.status_page.v1.AddStaticComponentRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to add the component to (required).\n name:\n type: string\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the component (required).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: Display order of the component (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: ID of the group to add this component to (optional).\n title: AddStaticComponentRequest\n additionalProperties: false\n description: AddStaticComponentRequest is the request to add a static component to a status page.\n openstatus.status_page.v1.AddStaticComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The created component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: AddStaticComponentResponse\n additionalProperties: false\n description: AddStaticComponentResponse is the response after adding a static component.\n openstatus.status_page.v1.ComponentDayBucket:\n type: object\n properties:\n day:\n type: string\n title: day\n description: Day in RFC 3339 format (UTC midnight).\n count:\n type:\n - integer\n - string\n title: count\n format: int64\n description: Total checks that day.\n ok:\n type:\n - integer\n - string\n title: ok\n format: int64\n description: Successful checks.\n degraded:\n type:\n - integer\n - string\n title: degraded\n format: int64\n description: Degraded checks.\n error:\n type:\n - integer\n - string\n title: error\n format: int64\n description: Failed checks.\n status:\n title: status\n description: Convenience resolved status for the day.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentDayStatus'\n impact:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n - type: \"null\"\n title: impact\n description: Worst status-report impact overlapping the day (absent when none).\n title: ComponentDayBucket\n additionalProperties: false\n description: ComponentDayBucket is one day of status data for a component.\n openstatus.status_page.v1.ComponentDayStatus:\n type: string\n title: ComponentDayStatus\n enum:\n - COMPONENT_DAY_STATUS_UNSPECIFIED\n - COMPONENT_DAY_STATUS_OPERATIONAL\n - COMPONENT_DAY_STATUS_DEGRADED\n - COMPONENT_DAY_STATUS_DOWN\n - COMPONENT_DAY_STATUS_MAINTENANCE\n - COMPONENT_DAY_STATUS_EMPTY\n description: ComponentDayStatus is the resolved status of a component on a given day.\n openstatus.status_page.v1.ComponentEvent:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Identifier of the underlying event.\n name:\n type: string\n title: name\n description: Human-readable name (incident \"Downtime\", maintenance / report title).\n type:\n title: type\n description: Kind of event.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEventType'\n status:\n title: status\n description: Projected status this event contributes.\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEventStatus'\n from:\n type: string\n title: from\n description: Start time (RFC 3339).\n to:\n type:\n - string\n - \"null\"\n title: to\n description: End time (RFC 3339); absent while the event is ongoing.\n impact:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n - type: \"null\"\n title: impact\n description: Worst impact over the event (reports only; absent otherwise).\n title: ComponentEvent\n additionalProperties: false\n description: ComponentEvent is a single incident / maintenance / report affecting a component.\n openstatus.status_page.v1.ComponentEventStatus:\n type: string\n title: ComponentEventStatus\n enum:\n - COMPONENT_EVENT_STATUS_UNSPECIFIED\n - COMPONENT_EVENT_STATUS_OPERATIONAL\n - COMPONENT_EVENT_STATUS_DEGRADED\n - COMPONENT_EVENT_STATUS_DOWN\n - COMPONENT_EVENT_STATUS_MAINTENANCE\n description: ComponentEventStatus is the projected status an event contributes.\n openstatus.status_page.v1.ComponentEventType:\n type: string\n title: ComponentEventType\n enum:\n - COMPONENT_EVENT_TYPE_UNSPECIFIED\n - COMPONENT_EVENT_TYPE_MAINTENANCE\n - COMPONENT_EVENT_TYPE_INCIDENT\n - COMPONENT_EVENT_TYPE_REPORT\n description: ComponentEventType is the kind of timeline event affecting a component.\n openstatus.status_page.v1.ComponentStatus:\n type: object\n properties:\n componentId:\n type: string\n title: component_id\n description: ID of the component.\n status:\n title: status\n description: Current status of the component.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n title: ComponentStatus\n additionalProperties: false\n description: ComponentStatus represents the status of a single component.\n openstatus.status_page.v1.CreateComponentGroupRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to create the group in (required).\n name:\n type: string\n title: name\n maxLength: 256\n minLength: 1\n description: Display name for the group (required).\n defaultOpen:\n type:\n - boolean\n - \"null\"\n title: default_open\n description: Whether the group should be expanded by default on the status page (optional, defaults to false).\n title: CreateComponentGroupRequest\n additionalProperties: false\n description: CreateComponentGroupRequest is the request to create a new component group.\n openstatus.status_page.v1.CreateComponentGroupResponse:\n type: object\n properties:\n group:\n title: group\n description: The created component group.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: CreateComponentGroupResponse\n additionalProperties: false\n description: CreateComponentGroupResponse is the response after creating a component group.\n openstatus.status_page.v1.CreatePageSubscriptionRequest:\n type: object\n allOf:\n - properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 255\n description: Optional human-readable label.\n componentIds:\n type: array\n items:\n type: string\n title: component_ids\n description: Component scope. Empty = entire page.\n - oneOf:\n - type: object\n properties:\n emailChannel:\n title: email_channel\n $ref: '#/components/schemas/openstatus.status_page.v1.EmailChannel'\n title: email_channel\n required:\n - emailChannel\n - type: object\n properties:\n webhookChannel:\n title: webhook_channel\n $ref: '#/components/schemas/openstatus.status_page.v1.WebhookChannel'\n title: webhook_channel\n required:\n - webhookChannel\n title: CreatePageSubscriptionRequest\n additionalProperties: false\n description: CreatePageSubscriptionRequest is the request to add a vendor-managed subscriber to a status page.\n openstatus.status_page.v1.CreatePageSubscriptionResponse:\n type: object\n properties:\n subscriber:\n title: subscriber\n description: The created subscriber.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: CreatePageSubscriptionResponse\n additionalProperties: false\n description: CreatePageSubscriptionResponse is the response after creating a vendor-managed subscription.\n openstatus.status_page.v1.CreateStatusPageRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - Acme Corp Status\n title: title\n maxLength: 256\n minLength: 1\n description: Title of the status page (required).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: Description of the status page (optional).\n slug:\n type: string\n examples:\n - my-status-page\n title: slug\n maxLength: 256\n minLength: 1\n pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$\n description: URL-friendly slug for the status page (required). Must be lowercase alphanumeric with hyphens.\n homepageUrl:\n type:\n - string\n - \"null\"\n examples:\n - https://www.example.com\n title: homepage_url\n description: URL to the homepage (optional).\n contactUrl:\n type:\n - string\n - \"null\"\n title: contact_url\n description: URL to the contact page (optional).\n defaultLocale:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n - type: \"null\"\n title: default_locale\n description: Default locale for the status page (optional, defaults to EN).\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: Enabled locales for the status page (optional).\n icon:\n type:\n - string\n - \"null\"\n title: icon\n maxLength: 1024\n description: Icon URL for the status page (optional).\n customDomain:\n type:\n - string\n - \"null\"\n title: custom_domain\n maxLength: 256\n description: Custom domain for the status page (optional).\n theme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n - type: \"null\"\n title: theme\n description: Visual theme for the status page (optional, defaults to SYSTEM).\n accessType:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n - type: \"null\"\n title: access_type\n description: Access type for the status page (optional, defaults to PUBLIC).\n password:\n type:\n - string\n - \"null\"\n title: password\n maxLength: 256\n minLength: 1\n description: Password for the status page (required when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: Email domains allowed to access the page (used when access_type is AUTHENTICATED).\n allowIndex:\n type:\n - boolean\n - \"null\"\n title: allow_index\n description: Whether search engines are allowed to index this status page (optional, defaults to true).\n allowedIpRanges:\n type:\n - string\n - \"null\"\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (required when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: |-\n Per-mode CSS variable overrides merged over the theme (optional).\n Only supported variable names are accepted. Requires the custom-theme plan feature.\n title: CreateStatusPageRequest\n additionalProperties: false\n description: CreateStatusPageRequest is the request to create a new status page.\n openstatus.status_page.v1.CreateStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The created status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: CreateStatusPageResponse\n additionalProperties: false\n description: CreateStatusPageResponse is the response after creating a status page.\n openstatus.status_page.v1.CustomTheme:\n type: object\n properties:\n light:\n type: object\n title: light\n additionalProperties:\n type: string\n title: value\n description: 'CSS variable overrides applied in light mode, keyed by variable name (e.g. \"--primary\": \"hsl(24 94% 50%)\").'\n dark:\n type: object\n title: dark\n additionalProperties:\n type: string\n title: value\n description: CSS variable overrides applied in dark mode, keyed by variable name.\n title: CustomTheme\n additionalProperties: false\n description: CustomTheme holds per-mode CSS variable overrides merged over the page theme.\n openstatus.status_page.v1.CustomTheme.DarkEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: DarkEntry\n additionalProperties: false\n openstatus.status_page.v1.CustomTheme.LightEntry:\n type: object\n properties:\n key:\n type: string\n title: key\n value:\n type: string\n title: value\n title: LightEntry\n additionalProperties: false\n openstatus.status_page.v1.DeleteComponentGroupRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component group to delete (required).\n title: DeleteComponentGroupRequest\n additionalProperties: false\n description: DeleteComponentGroupRequest is the request to delete a component group.\n openstatus.status_page.v1.DeleteComponentGroupResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteComponentGroupResponse\n additionalProperties: false\n description: DeleteComponentGroupResponse is the response after deleting a component group.\n openstatus.status_page.v1.DeleteStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to delete (required).\n title: DeleteStatusPageRequest\n additionalProperties: false\n description: DeleteStatusPageRequest is the request to delete a status page.\n openstatus.status_page.v1.DeleteStatusPageResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteStatusPageResponse\n additionalProperties: false\n description: DeleteStatusPageResponse is the response after deleting a status page.\n openstatus.status_page.v1.EmailChannel:\n type: object\n properties:\n email:\n type: string\n title: email\n format: email\n description: Email address of the subscriber (required).\n title: EmailChannel\n additionalProperties: false\n description: EmailChannel carries the email-channel fields for CreatePageSubscription.\n openstatus.status_page.v1.GetOverallStatusRequest:\n type: object\n oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetOverallStatusRequest\n additionalProperties: false\n description: GetOverallStatusRequest is the request to get the overall status of a status page.\n openstatus.status_page.v1.GetOverallStatusResponse:\n type: object\n properties:\n overallStatus:\n title: overall_status\n description: Aggregated status across all components.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n componentStatuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentStatus'\n title: component_statuses\n description: Status of individual components.\n title: GetOverallStatusResponse\n additionalProperties: false\n description: GetOverallStatusResponse is the response containing the overall status and individual component statuses.\n openstatus.status_page.v1.GetPageComponentDailySummaryRequest:\n type: object\n allOf:\n - properties:\n componentIds:\n type: array\n items:\n type: string\n minLength: 1\n title: component_ids\n description: Restrict the result to these component ids (optional, defaults to all components).\n days:\n type:\n - integer\n - \"null\"\n title: days\n maximum: 45\n minimum: 1\n format: int32\n description: Number of days to return (1-45, defaults to 45 if unspecified).\n - oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetPageComponentDailySummaryRequest\n additionalProperties: false\n description: GetPageComponentDailySummaryRequest is the request for per-component daily summaries.\n openstatus.status_page.v1.GetPageComponentDailySummaryResponse:\n type: object\n properties:\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentDailySummary'\n title: components\n description: Per-component daily summaries, in page order.\n title: GetPageComponentDailySummaryResponse\n additionalProperties: false\n description: GetPageComponentDailySummaryResponse is the response containing per-component summaries.\n openstatus.status_page.v1.GetPageComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to retrieve (required).\n title: GetPageComponentRequest\n additionalProperties: false\n description: GetPageComponentRequest is the request to fetch a single component by ID.\n openstatus.status_page.v1.GetPageComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The requested component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: GetPageComponentResponse\n additionalProperties: false\n description: GetPageComponentResponse is the response containing the component.\n openstatus.status_page.v1.GetStatusPageContentRequest:\n type: object\n oneOf:\n - type: object\n properties:\n id:\n type: string\n title: id\n description: ID of the status page.\n title: id\n required:\n - id\n - type: object\n properties:\n slug:\n type: string\n title: slug\n description: Slug of the status page.\n title: slug\n required:\n - slug\n title: GetStatusPageContentRequest\n additionalProperties: false\n description: GetStatusPageContentRequest is the request to get the full content of a status page.\n openstatus.status_page.v1.GetStatusPageContentResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The status page details.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: components\n description: Components on the status page.\n groups:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: groups\n description: Component groups on the status page.\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: status_reports\n description: Active and recent status reports.\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: Scheduled maintenances.\n title: GetStatusPageContentResponse\n additionalProperties: false\n description: GetStatusPageContentResponse is the response containing the full status page content.\n openstatus.status_page.v1.GetStatusPageOverviewRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page (required, workspace-scoped).\n title: GetStatusPageOverviewRequest\n additionalProperties: false\n description: GetStatusPageOverviewRequest requests the full overview of a status page by id.\n openstatus.status_page.v1.GetStatusPageOverviewResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The status page details.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n configuration:\n title: configuration\n description: Rich rendering configuration of the page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageConfiguration'\n components:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: components\n description: Components on the status page.\n groups:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: groups\n description: Component groups on the status page.\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: status_reports\n description: Active and recent status reports.\n maintenances:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.maintenance.v1.MaintenanceSummary'\n title: maintenances\n description: Scheduled maintenances.\n overallStatus:\n title: overall_status\n description: Aggregated status across all components.\n $ref: '#/components/schemas/openstatus.status_page.v1.OverallStatus'\n componentStatuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentStatus'\n title: component_statuses\n description: Status of individual components.\n title: GetStatusPageOverviewResponse\n additionalProperties: false\n description: GetStatusPageOverviewResponse bundles all data for a single status page.\n openstatus.status_page.v1.GetStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to retrieve (required).\n title: GetStatusPageRequest\n additionalProperties: false\n description: GetStatusPageRequest is the request to get a status page by ID.\n openstatus.status_page.v1.GetStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The requested status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: GetStatusPageResponse\n additionalProperties: false\n description: GetStatusPageResponse is the response containing the status page.\n openstatus.status_page.v1.ListStatusPagesRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of pages to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of pages to skip for pagination (defaults to 0).\n title: ListStatusPagesRequest\n additionalProperties: false\n description: ListStatusPagesRequest is the request to list status pages.\n openstatus.status_page.v1.ListStatusPagesResponse:\n type: object\n properties:\n statusPages:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPageSummary'\n title: status_pages\n description: List of status pages (metadata only).\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of status pages.\n title: ListStatusPagesResponse\n additionalProperties: false\n description: ListStatusPagesResponse is the response containing status page summaries.\n openstatus.status_page.v1.ListSubscribersRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to list subscribers for (required).\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of subscribers to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of subscribers to skip for pagination (defaults to 0).\n includeUnsubscribed:\n type:\n - boolean\n - \"null\"\n title: include_unsubscribed\n description: Whether to include unsubscribed users (defaults to false).\n title: ListSubscribersRequest\n additionalProperties: false\n description: ListSubscribersRequest is the request to list subscribers of a status page.\n openstatus.status_page.v1.ListSubscribersResponse:\n type: object\n properties:\n subscribers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: subscribers\n description: List of subscribers.\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of subscribers matching the filter.\n title: ListSubscribersResponse\n additionalProperties: false\n description: ListSubscribersResponse is the response containing status page subscribers.\n openstatus.status_page.v1.Locale:\n type: string\n title: Locale\n enum:\n - LOCALE_UNSPECIFIED\n - LOCALE_EN\n - LOCALE_FR\n - LOCALE_DE\n - LOCALE_TR\n - LOCALE_HI\n - LOCALE_KO\n - LOCALE_JA\n description: Locale defines the supported languages for a status page.\n openstatus.status_page.v1.OverallStatus:\n type: string\n title: OverallStatus\n enum:\n - OVERALL_STATUS_UNSPECIFIED\n - OVERALL_STATUS_OPERATIONAL\n - OVERALL_STATUS_DEGRADED\n - OVERALL_STATUS_PARTIAL_OUTAGE\n - OVERALL_STATUS_MAJOR_OUTAGE\n - OVERALL_STATUS_MAINTENANCE\n - OVERALL_STATUS_UNKNOWN\n description: OverallStatus represents the aggregated status of all components on a page.\n openstatus.status_page.v1.PageAccessType:\n type: string\n title: PageAccessType\n enum:\n - PAGE_ACCESS_TYPE_UNSPECIFIED\n - PAGE_ACCESS_TYPE_PUBLIC\n - PAGE_ACCESS_TYPE_PASSWORD_PROTECTED\n - PAGE_ACCESS_TYPE_AUTHENTICATED\n - PAGE_ACCESS_TYPE_IP_RESTRICTED\n description: PageAccessType defines who can access the status page.\n openstatus.status_page.v1.PageBarType:\n type: string\n title: PageBarType\n enum:\n - PAGE_BAR_TYPE_UNSPECIFIED\n - PAGE_BAR_TYPE_ABSOLUTE\n - PAGE_BAR_TYPE_MANUAL\n description: PageBarType mirrors page.configuration.type (how the status bar is computed).\n openstatus.status_page.v1.PageComponent:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the component.\n pageId:\n type: string\n title: page_id\n description: ID of the status page this component belongs to.\n name:\n type: string\n title: name\n description: Display name of the component.\n description:\n type: string\n title: description\n description: Description of the component (optional).\n type:\n title: type\n description: Type of the component (monitor or static).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentType'\n monitorId:\n type: string\n title: monitor_id\n description: ID of the monitor if type is MONITOR (optional).\n order:\n type: integer\n title: order\n format: int32\n description: Display order of the component.\n groupId:\n type: string\n title: group_id\n description: ID of the group this component belongs to (optional).\n groupOrder:\n type: integer\n title: group_order\n format: int32\n description: Order within the group if grouped.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the component was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the component was last updated (RFC 3339 format).\n title: PageComponent\n additionalProperties: false\n description: PageComponent represents a component displayed on a status page.\n openstatus.status_page.v1.PageComponentDailySummary:\n type: object\n properties:\n componentId:\n type: string\n title: component_id\n description: ID of the component.\n type:\n title: type\n description: Component type (monitor or static).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentType'\n monitorId:\n type:\n - string\n - \"null\"\n title: monitor_id\n description: Monitor id backing the component (absent for static components).\n name:\n type: string\n title: name\n description: Display name of the component.\n buckets:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentDayBucket'\n title: buckets\n description: Per-day buckets, oldest first.\n events:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.ComponentEvent'\n title: events\n description: Events affecting the component within the window.\n title: PageComponentDailySummary\n additionalProperties: false\n description: PageComponentDailySummary is the per-day buckets + event timeline for one component.\n openstatus.status_page.v1.PageComponentGroup:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the group.\n pageId:\n type: string\n title: page_id\n description: ID of the status page this group belongs to.\n name:\n type: string\n title: name\n description: Display name of the group.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the group was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the group was last updated (RFC 3339 format).\n defaultOpen:\n type: boolean\n title: default_open\n description: Whether the group should be expanded by default on the status page.\n title: PageComponentGroup\n additionalProperties: false\n description: PageComponentGroup represents a group of components on a status page.\n openstatus.status_page.v1.PageComponentType:\n type: string\n title: PageComponentType\n enum:\n - PAGE_COMPONENT_TYPE_UNSPECIFIED\n - PAGE_COMPONENT_TYPE_MONITOR\n - PAGE_COMPONENT_TYPE_STATIC\n description: PageComponentType defines the type of a component on a status page.\n openstatus.status_page.v1.PageConfiguration:\n type: object\n properties:\n metricType:\n title: metric_type\n description: Which metric the status bars represent (configuration.value).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageMetricType'\n barType:\n title: bar_type\n description: How the status bar is computed (configuration.type).\n $ref: '#/components/schemas/openstatus.status_page.v1.PageBarType'\n showUptime:\n type: boolean\n title: show_uptime\n description: Whether to show the uptime percentage (configuration.uptime).\n themeKey:\n type: string\n title: theme_key\n description: |-\n Theme key from the theme store (configuration.theme), e.g. \"default\".\n Free-form string rather than an enum because the theme catalog is dynamic.\n days:\n type: integer\n title: days\n format: int32\n description: 'Number of uptime-bar days rendered on the page (configuration.days): 30 or 45.'\n title: PageConfiguration\n additionalProperties: false\n description: PageConfiguration is the rich rendering config stored in page.configuration.\n openstatus.status_page.v1.PageMetricType:\n type: string\n title: PageMetricType\n enum:\n - PAGE_METRIC_TYPE_UNSPECIFIED\n - PAGE_METRIC_TYPE_DURATION\n - PAGE_METRIC_TYPE_REQUESTS\n - PAGE_METRIC_TYPE_MANUAL\n description: PageMetricType mirrors page.configuration.value (which metric the status bars represent).\n openstatus.status_page.v1.PageSubscriber:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the subscriber.\n pageId:\n type: string\n title: page_id\n description: ID of the status page the user is subscribed to.\n email:\n type: string\n title: email\n description: Email address of the subscriber (empty for webhook channels).\n acceptedAt:\n type: string\n title: accepted_at\n description: Timestamp when the subscription was accepted/confirmed (RFC 3339 format, optional).\n unsubscribedAt:\n type: string\n title: unsubscribed_at\n description: Timestamp when the user unsubscribed (RFC 3339 format, optional).\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the subscription was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the subscription was last updated (RFC 3339 format).\n source:\n title: source\n description: How the subscription was created. Vendor-added rows skip verification.\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscriberSource'\n name:\n type:\n - string\n - \"null\"\n title: name\n description: 'Optional human-readable label (e.g. \"Supabase #incidents\").'\n channelType:\n type: string\n title: channel_type\n description: 'Channel type: \"email\" or \"webhook\".'\n webhookUrl:\n type:\n - string\n - \"null\"\n title: webhook_url\n description: Webhook URL (populated only for channel_type = \"webhook\").\n channelConfig:\n type:\n - string\n - \"null\"\n title: channel_config\n description: JSON-encoded channel config (e.g. custom headers). Populated for webhook channels.\n componentIds:\n type: array\n items:\n type: string\n title: component_ids\n description: IDs of components this subscription is scoped to. Empty = entire page.\n title: PageSubscriber\n additionalProperties: false\n description: PageSubscriber represents a subscriber to a status page.\n openstatus.status_page.v1.PageTheme:\n type: string\n title: PageTheme\n enum:\n - PAGE_THEME_UNSPECIFIED\n - PAGE_THEME_SYSTEM\n - PAGE_THEME_LIGHT\n - PAGE_THEME_DARK\n description: PageTheme defines the visual theme of the status page.\n openstatus.status_page.v1.RemoveComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to remove (required).\n title: RemoveComponentRequest\n additionalProperties: false\n description: RemoveComponentRequest is the request to remove a component from a status page.\n openstatus.status_page.v1.RemoveComponentResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the removal was successful.\n title: RemoveComponentResponse\n additionalProperties: false\n description: RemoveComponentResponse is the response after removing a component.\n openstatus.status_page.v1.StatusPage:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status page.\n title:\n type: string\n title: title\n description: Title of the status page.\n description:\n type: string\n title: description\n description: Description of the status page.\n slug:\n type: string\n examples:\n - acme-corp\n title: slug\n description: URL-friendly slug for the status page.\n customDomain:\n type: string\n examples:\n - status.example.com\n title: custom_domain\n description: Custom domain for the status page (optional).\n published:\n type: boolean\n title: published\n description: Whether the status page is published and visible.\n accessType:\n title: access_type\n description: Access type for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n theme:\n title: theme\n description: Visual theme for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n homepageUrl:\n type: string\n title: homepage_url\n description: URL to the homepage (optional).\n contactUrl:\n type: string\n title: contact_url\n description: URL to the contact page (optional).\n icon:\n type: string\n title: icon\n description: Icon URL for the status page (optional).\n createdAt:\n type: string\n examples:\n - \"2024-01-15T09:00:00Z\"\n title: created_at\n description: Timestamp when the page was created (RFC 3339 format).\n updatedAt:\n type: string\n examples:\n - \"2024-06-20T14:30:00Z\"\n title: updated_at\n description: Timestamp when the page was last updated (RFC 3339 format).\n defaultLocale:\n title: default_locale\n description: Default locale for the status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: Enabled locales for the status page.\n password:\n type: string\n title: password\n description: Password for the status page (only set when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: Email domains allowed to access the page (only set when access_type is AUTHENTICATED).\n allowIndex:\n type: boolean\n title: allow_index\n description: Whether search engines are allowed to index this status page.\n allowedIpRanges:\n type: string\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (only set when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: Per-mode CSS variable overrides merged over the theme (only set when configured).\n title: StatusPage\n additionalProperties: false\n description: StatusPage represents a full status page with all details.\n openstatus.status_page.v1.StatusPageSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status page.\n title:\n type: string\n title: title\n description: Title of the status page.\n slug:\n type: string\n title: slug\n description: URL-friendly slug for the status page.\n published:\n type: boolean\n title: published\n description: Whether the status page is published and visible.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the page was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the page was last updated (RFC 3339 format).\n customDomain:\n type: string\n examples:\n - status.example.com\n title: custom_domain\n description: Custom domain for the status page (optional).\n title: StatusPageSummary\n additionalProperties: false\n description: StatusPageSummary represents metadata for a status page (used in list responses).\n openstatus.status_page.v1.SubscribeToPageRequest:\n type: object\n properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to subscribe to (required).\n email:\n type: string\n examples:\n - user@example.com\n title: email\n format: email\n description: Email address to subscribe (required).\n title: SubscribeToPageRequest\n additionalProperties: false\n description: SubscribeToPageRequest is the request to subscribe an email to a status page.\n openstatus.status_page.v1.SubscribeToPageResponse:\n type: object\n properties:\n subscriber:\n title: subscriber\n description: The created subscriber.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageSubscriber'\n title: SubscribeToPageResponse\n additionalProperties: false\n description: SubscribeToPageResponse is the response after subscribing to a status page.\n openstatus.status_page.v1.SubscriberSource:\n type: string\n title: SubscriberSource\n enum:\n - SUBSCRIBER_SOURCE_UNSPECIFIED\n - SUBSCRIBER_SOURCE_SELF_SIGNUP\n - SUBSCRIBER_SOURCE_VENDOR\n - SUBSCRIBER_SOURCE_IMPORT\n description: SubscriberSource indicates how the subscription was created.\n openstatus.status_page.v1.UnsubscribeFromPageRequest:\n type: object\n allOf:\n - properties:\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: ID of the status page to unsubscribe from (required).\n - oneOf:\n - type: object\n properties:\n email:\n type: string\n title: email\n description: Email address to unsubscribe.\n title: email\n required:\n - email\n - type: object\n properties:\n id:\n type: string\n title: id\n description: Subscriber ID.\n title: id\n required:\n - id\n title: UnsubscribeFromPageRequest\n additionalProperties: false\n description: UnsubscribeFromPageRequest is the request to unsubscribe from a status page.\n openstatus.status_page.v1.UnsubscribeFromPageResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the unsubscription was successful.\n title: UnsubscribeFromPageResponse\n additionalProperties: false\n description: UnsubscribeFromPageResponse is the response after unsubscribing from a status page.\n openstatus.status_page.v1.UpdateComponentGroupRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component group to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n minLength: 1\n description: New display name for the group (optional).\n defaultOpen:\n type:\n - boolean\n - \"null\"\n title: default_open\n description: Whether the group should be expanded by default on the status page (optional).\n title: UpdateComponentGroupRequest\n additionalProperties: false\n description: UpdateComponentGroupRequest is the request to update a component group.\n openstatus.status_page.v1.UpdateComponentGroupResponse:\n type: object\n properties:\n group:\n title: group\n description: The updated component group.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponentGroup'\n title: UpdateComponentGroupResponse\n additionalProperties: false\n description: UpdateComponentGroupResponse is the response after updating a component group.\n openstatus.status_page.v1.UpdateComponentRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the component to update (required).\n name:\n type:\n - string\n - \"null\"\n title: name\n maxLength: 256\n description: New display name for the component (optional).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: New description for the component (optional).\n order:\n type:\n - integer\n - \"null\"\n title: order\n format: int32\n description: New display order (optional).\n groupId:\n type:\n - string\n - \"null\"\n title: group_id\n description: New group ID (optional, set to empty string to remove from group).\n groupOrder:\n type:\n - integer\n - \"null\"\n title: group_order\n format: int32\n description: New order within the group (optional).\n title: UpdateComponentRequest\n additionalProperties: false\n description: UpdateComponentRequest is the request to update a component.\n openstatus.status_page.v1.UpdateComponentResponse:\n type: object\n properties:\n component:\n title: component\n description: The updated component.\n $ref: '#/components/schemas/openstatus.status_page.v1.PageComponent'\n title: UpdateComponentResponse\n additionalProperties: false\n description: UpdateComponentResponse is the response after updating a component.\n openstatus.status_page.v1.UpdateStatusPageRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status page to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n maxLength: 256\n minLength: 1\n description: New title for the status page (optional).\n description:\n type:\n - string\n - \"null\"\n title: description\n maxLength: 1024\n description: New description for the status page (optional).\n slug:\n type:\n - string\n - \"null\"\n title: slug\n maxLength: 256\n minLength: 1\n pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$\n description: New slug for the status page (optional).\n homepageUrl:\n type:\n - string\n - \"null\"\n title: homepage_url\n description: New homepage URL (optional).\n contactUrl:\n type:\n - string\n - \"null\"\n title: contact_url\n description: New contact URL (optional).\n defaultLocale:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n - type: \"null\"\n title: default_locale\n description: New default locale for the status page (optional).\n locales:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.Locale'\n title: locales\n description: New enabled locales for the status page (optional).\n icon:\n type:\n - string\n - \"null\"\n title: icon\n maxLength: 1024\n description: New icon URL for the status page (optional).\n customDomain:\n type:\n - string\n - \"null\"\n title: custom_domain\n maxLength: 256\n description: New custom domain (optional).\n theme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageTheme'\n - type: \"null\"\n title: theme\n description: New visual theme (optional).\n accessType:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.PageAccessType'\n - type: \"null\"\n title: access_type\n description: New access type (optional).\n password:\n type:\n - string\n - \"null\"\n title: password\n maxLength: 256\n minLength: 1\n description: New password (optional, required when access_type is PASSWORD_PROTECTED).\n authEmailDomains:\n type: array\n items:\n type: string\n title: auth_email_domains\n description: New email domains (optional, required when access_type is AUTHENTICATED).\n allowIndex:\n type:\n - boolean\n - \"null\"\n title: allow_index\n description: Whether search engines are allowed to index this status page (optional).\n allowedIpRanges:\n type:\n - string\n - \"null\"\n title: allowed_ip_ranges\n description: Comma-separated IPv4 CIDR ranges (required when access_type is IP_RESTRICTED).\n customTheme:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_page.v1.CustomTheme'\n - type: \"null\"\n title: custom_theme\n description: |-\n New per-mode CSS variable overrides (optional). Omit to keep the current\n value; send an empty message to clear. Requires the custom-theme plan feature.\n title: UpdateStatusPageRequest\n additionalProperties: false\n description: UpdateStatusPageRequest is the request to update a status page.\n openstatus.status_page.v1.UpdateStatusPageResponse:\n type: object\n properties:\n statusPage:\n title: status_page\n description: The updated status page.\n $ref: '#/components/schemas/openstatus.status_page.v1.StatusPage'\n title: UpdateStatusPageResponse\n additionalProperties: false\n description: UpdateStatusPageResponse is the response after updating a status page.\n openstatus.status_page.v1.WebhookChannel:\n type: object\n properties:\n webhookUrl:\n type: string\n title: webhook_url\n maxLength: 2048\n minLength: 1\n format: uri\n description: Webhook URL (required). Payload flavor (Slack / Discord / generic) is auto-detected from the URL prefix.\n headers:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_page.v1.WebhookChannelHeader'\n title: headers\n description: Optional custom HTTP headers attached to every dispatch.\n title: WebhookChannel\n additionalProperties: false\n description: WebhookChannel carries the webhook-channel fields for CreatePageSubscription.\n openstatus.status_page.v1.WebhookChannelHeader:\n type: object\n properties:\n key:\n type: string\n title: key\n minLength: 1\n value:\n type: string\n title: value\n title: WebhookChannelHeader\n additionalProperties: false\n description: WebhookChannelHeader is a single custom HTTP header.\n openstatus.status_report.v1.AddStatusReportUpdateRequest:\n type: object\n properties:\n statusReportId:\n type: string\n title: status_report_id\n minLength: 1\n description: ID of the status report to update (required).\n status:\n title: status\n description: New status for the report (required).\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n message:\n type: string\n title: message\n minLength: 1\n description: Message describing what changed (required).\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Optional date for the update (RFC 3339 format). Defaults to current time if not provided.\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this update (optional, defaults to false).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: |-\n Per-component impacts this update sets (optional). Components named here\n are added to the report's affected set; omitted components keep their\n prior impact.\n title: AddStatusReportUpdateRequest\n additionalProperties: false\n description: AddStatusReportUpdateRequest is the request to add a new update to a status report.\n openstatus.status_report.v1.AddStatusReportUpdateResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The updated status report with the new update included.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: AddStatusReportUpdateResponse\n additionalProperties: false\n description: AddStatusReportUpdateResponse is the response after adding an update to a status report.\n openstatus.status_report.v1.ComponentImpact:\n type: object\n properties:\n pageComponentId:\n type: string\n title: page_component_id\n description: ID of the affected page component.\n impact:\n title: impact\n description: Impact set for the component.\n $ref: '#/components/schemas/openstatus.status_report.v1.PageComponentImpact'\n title: ComponentImpact\n additionalProperties: false\n description: ComponentImpact pairs a page component with the impact an update set for it.\n openstatus.status_report.v1.CreateStatusReportRequest:\n type: object\n properties:\n title:\n type: string\n examples:\n - API Degradation Investigation\n title: title\n minLength: 1\n description: Title of the status report (required).\n status:\n title: status\n description: Initial status (required).\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n message:\n type: string\n examples:\n - We are investigating reports of increased API latency.\n title: message\n minLength: 1\n description: Initial message describing the incident (required).\n date:\n type: string\n examples:\n - \"2024-03-15T10:30:00Z\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: Date when the event occurred (RFC 3339 format, required).\n pageId:\n type: string\n title: page_id\n minLength: 1\n description: Page ID to associate with this report (required).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: Page component IDs to associate with this report (optional).\n notify:\n type:\n - boolean\n - \"null\"\n title: notify\n description: Whether to notify subscribers about this status report (optional, defaults to false).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: |-\n Per-component impacts set by the initial update (optional). When provided,\n the named components are added to the report's affected set. Omitting this\n field creates a legacy report without impact tracking.\n title: CreateStatusReportRequest\n additionalProperties: false\n description: CreateStatusReportRequest is the request to create a new status report.\n openstatus.status_report.v1.CreateStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The created status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: CreateStatusReportResponse\n additionalProperties: false\n description: CreateStatusReportResponse is the response after creating a status report.\n openstatus.status_report.v1.DeleteStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to delete (required).\n title: DeleteStatusReportRequest\n additionalProperties: false\n description: DeleteStatusReportRequest is the request to delete a status report.\n openstatus.status_report.v1.DeleteStatusReportResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteStatusReportResponse\n additionalProperties: false\n description: DeleteStatusReportResponse is the response after deleting a status report.\n openstatus.status_report.v1.DeleteStatusReportUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to remove (required).\n title: DeleteStatusReportUpdateRequest\n additionalProperties: false\n description: DeleteStatusReportUpdateRequest is the request to remove a status report update.\n openstatus.status_report.v1.DeleteStatusReportUpdateResponse:\n type: object\n properties:\n success:\n type: boolean\n title: success\n description: Whether the deletion was successful.\n title: DeleteStatusReportUpdateResponse\n additionalProperties: false\n description: DeleteStatusReportUpdateResponse is the response after removing a status report update.\n openstatus.status_report.v1.GetStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to retrieve (required).\n title: GetStatusReportRequest\n additionalProperties: false\n description: GetStatusReportRequest is the request to get a status report by ID.\n openstatus.status_report.v1.GetStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The requested status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: GetStatusReportResponse\n additionalProperties: false\n description: GetStatusReportResponse is the response containing the status report with its full update timeline.\n openstatus.status_report.v1.ListStatusReportsRequest:\n type: object\n properties:\n limit:\n type:\n - integer\n - \"null\"\n title: limit\n maximum: 100\n minimum: 1\n format: int32\n description: Maximum number of reports to return (1-100, defaults to 50).\n offset:\n type:\n - integer\n - \"null\"\n title: offset\n minimum: 0\n format: int32\n description: Number of reports to skip for pagination (defaults to 0).\n statuses:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title: statuses\n description: Filter by status (optional). If empty, returns all statuses.\n title: ListStatusReportsRequest\n additionalProperties: false\n description: ListStatusReportsRequest is the request to list status reports.\n openstatus.status_report.v1.ListStatusReportsResponse:\n type: object\n properties:\n statusReports:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportSummary'\n title: status_reports\n description: List of status reports (metadata only, use GetStatusReport for full details).\n totalSize:\n type: integer\n title: total_size\n format: int32\n description: Total number of reports matching the filter.\n title: ListStatusReportsResponse\n additionalProperties: false\n description: ListStatusReportsResponse is the response containing status report summaries.\n openstatus.status_report.v1.PageComponentImpact:\n type: string\n title: PageComponentImpact\n enum:\n - PAGE_COMPONENT_IMPACT_UNSPECIFIED\n - PAGE_COMPONENT_IMPACT_OPERATIONAL\n - PAGE_COMPONENT_IMPACT_DEGRADED_PERFORMANCE\n - PAGE_COMPONENT_IMPACT_PARTIAL_OUTAGE\n - PAGE_COMPONENT_IMPACT_MAJOR_OUTAGE\n description: |-\n PageComponentImpact is the per-component impact a status report update sets.\n UNSPECIFIED means the caller doesn't speak impact (legacy) — it is NOT operational.\n openstatus.status_report.v1.StatusReport:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status report.\n status:\n title: status\n description: Current status of the report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title:\n type: string\n title: title\n description: Title of the status report.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n updates:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportUpdate'\n title: updates\n description: Timeline of updates for this report (only included in GetStatusReport).\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the report was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the report was last updated (RFC 3339 format).\n title: StatusReport\n additionalProperties: false\n description: StatusReport represents an incident or maintenance report with full details.\n openstatus.status_report.v1.StatusReportStatus:\n type: string\n title: StatusReportStatus\n enum:\n - STATUS_REPORT_STATUS_UNSPECIFIED\n - STATUS_REPORT_STATUS_INVESTIGATING\n - STATUS_REPORT_STATUS_IDENTIFIED\n - STATUS_REPORT_STATUS_MONITORING\n - STATUS_REPORT_STATUS_RESOLVED\n description: StatusReportStatus represents the current state of a status report.\n openstatus.status_report.v1.StatusReportSummary:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the status report.\n status:\n title: status\n description: Current status of the report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n title:\n type: string\n title: title\n description: Title of the status report.\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: IDs of affected page components.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the report was created (RFC 3339 format).\n updatedAt:\n type: string\n title: updated_at\n description: Timestamp when the report was last updated (RFC 3339 format).\n title: StatusReportSummary\n additionalProperties: false\n description: StatusReportSummary represents metadata for a status report (used in list responses).\n openstatus.status_report.v1.StatusReportUpdate:\n type: object\n properties:\n id:\n type: string\n title: id\n description: Unique identifier for the update.\n status:\n title: status\n description: Status at the time of this update.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n date:\n type: string\n title: date\n description: Timestamp when this update occurred (RFC 3339 format).\n message:\n type: string\n title: message\n description: Message describing the update.\n createdAt:\n type: string\n title: created_at\n description: Timestamp when the update was created (RFC 3339 format).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: Per-component impacts this update set (empty for legacy reports).\n title: StatusReportUpdate\n additionalProperties: false\n description: StatusReportUpdate represents a single update entry in a status report timeline.\n openstatus.status_report.v1.UpdateStatusReportRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the status report to update (required).\n title:\n type:\n - string\n - \"null\"\n title: title\n description: New title for the report (optional).\n pageComponentIds:\n type: array\n items:\n type: string\n title: page_component_ids\n description: New list of page component IDs (optional, replaces existing list).\n updatePageComponentIds:\n type:\n - boolean\n - \"null\"\n title: update_page_component_ids\n description: |-\n Set to true to update page component associations.\n When true, page_component_ids replaces the existing list (empty clears all).\n When false or unset, page_component_ids is ignored and existing associations are preserved.\n title: UpdateStatusReportRequest\n additionalProperties: false\n description: UpdateStatusReportRequest is the request to update a status report's metadata.\n openstatus.status_report.v1.UpdateStatusReportResponse:\n type: object\n properties:\n statusReport:\n title: status_report\n description: The updated status report.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReport'\n title: UpdateStatusReportResponse\n additionalProperties: false\n description: UpdateStatusReportResponse is the response after updating a status report.\n openstatus.status_report.v1.UpdateStatusReportUpdateRequest:\n type: object\n properties:\n id:\n type: string\n title: id\n minLength: 1\n description: ID of the update to edit (required).\n status:\n oneOf:\n - $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'\n - type: \"null\"\n title: status\n description: New status for this entry (optional).\n message:\n type:\n - string\n - \"null\"\n title: message\n minLength: 1\n description: New message (optional).\n date:\n type:\n - string\n - \"null\"\n title: date\n pattern: ^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$\n description: New date for this entry (RFC 3339 format, optional).\n componentImpacts:\n type: array\n items:\n $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'\n title: component_impacts\n description: Replacement impact set for this update (optional, see update_component_impacts).\n updateComponentImpacts:\n type:\n - boolean\n - \"null\"\n title: update_component_impacts\n description: |-\n Set to true to replace the update's component impacts with component_impacts\n (empty clears them). When false or unset, component_impacts is ignored.\n title: UpdateStatusReportUpdateRequest\n additionalProperties: false\n description: UpdateStatusReportUpdateRequest is the request to edit a status report update.\n openstatus.status_report.v1.UpdateStatusReportUpdateResponse:\n type: object\n properties:\n statusReportUpdate:\n title: status_report_update\n description: The edited timeline entry.\n $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportUpdate'\n title: UpdateStatusReportUpdateResponse\n additionalProperties: false\n description: UpdateStatusReportUpdateResponse is the response after editing a status report update.\nsecurity:\n - ApiKeyAuth: []\ntags:\n - name: MonitorService\n description: |\n Create, update, delete, and query monitors. Supports HTTP, TCP, and DNS monitor types\n with configurable check intervals, regions, assertions, and alerting thresholds.\n - name: StatusPageService\n description: |\n Manage public status pages with components, component groups, and email subscribers.\n Includes endpoints for retrieving full page content and aggregated status.\n - name: NotificationService\n description: |\n Configure notification channels (Slack, Discord, PagerDuty, email, webhooks, etc.)\n and associate them with monitors. Supports 12 notification providers.\n - name: StatusReportService\n description: |\n Create and manage incident reports with status updates. Reports follow a lifecycle:\n investigating -> identified -> monitoring -> resolved.\n - name: MaintenanceService\n description: |\n Schedule maintenance windows for status page components. Subscribers can be\n notified automatically when maintenance is created.\n - name: HealthService\n description: Health check endpoint for load balancer probes. No authentication required.\n - name: PrivateLocationService\n description: |-\n PrivateLocationService provides CRUD operations for private locations —\n self-hosted checker agents that run monitors from your own network.\npaths:\n /rpc/openstatus.health.v1.HealthService/Check:\n get:\n tags:\n - HealthService\n summary: Check\n description: Check returns the current serving status of the service.\n operationId: HealthService_Check.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse'\n post:\n tags:\n - HealthService\n summary: Check\n description: Check returns the current serving status of the service.\n operationId: HealthService_Check\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.health.v1.CheckResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/AddMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: AddMaintenanceUpdate\n description: AddMaintenanceUpdate appends a public update to a maintenance timeline.\n operationId: MaintenanceService_AddMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.AddMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.AddMaintenanceUpdateResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/CreateMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: CreateMaintenance\n description: CreateMaintenance creates a new maintenance window.\n operationId: MaintenanceService_CreateMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.CreateMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.CreateMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/DeleteMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: DeleteMaintenance\n description: DeleteMaintenance removes a maintenance window.\n operationId: MaintenanceService_DeleteMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/DeleteMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: DeleteMaintenanceUpdate\n description: DeleteMaintenanceUpdate removes an existing maintenance update.\n operationId: MaintenanceService_DeleteMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.DeleteMaintenanceUpdateResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/GetMaintenance:\n get:\n tags:\n - MaintenanceService\n summary: GetMaintenance\n description: GetMaintenance retrieves a specific maintenance window by ID.\n operationId: MaintenanceService_GetMaintenance.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceResponse'\n post:\n tags:\n - MaintenanceService\n summary: GetMaintenance\n description: GetMaintenance retrieves a specific maintenance window by ID.\n operationId: MaintenanceService_GetMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.GetMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/ListMaintenances:\n get:\n tags:\n - MaintenanceService\n summary: ListMaintenances\n description: ListMaintenances returns all maintenance windows for the workspace.\n operationId: MaintenanceService_ListMaintenances.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesResponse'\n post:\n tags:\n - MaintenanceService\n summary: ListMaintenances\n description: ListMaintenances returns all maintenance windows for the workspace.\n operationId: MaintenanceService_ListMaintenances\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.ListMaintenancesResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/UpdateMaintenance:\n post:\n tags:\n - MaintenanceService\n summary: UpdateMaintenance\n description: UpdateMaintenance updates a maintenance window.\n operationId: MaintenanceService_UpdateMaintenance\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceResponse'\n /rpc/openstatus.maintenance.v1.MaintenanceService/UpdateMaintenanceUpdate:\n post:\n tags:\n - MaintenanceService\n summary: UpdateMaintenanceUpdate\n description: UpdateMaintenanceUpdate edits an existing maintenance update.\n operationId: MaintenanceService_UpdateMaintenanceUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.maintenance.v1.UpdateMaintenanceUpdateResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateDNSMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateDNSMonitor\n description: CreateDNSMonitor creates a new DNS monitor.\n operationId: MonitorService_CreateDNSMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateDNSMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateDNSMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateGRPCMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateGRPCMonitor\n description: CreateGRPCMonitor creates a new gRPC health check monitor.\n operationId: MonitorService_CreateGRPCMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateGRPCMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateGRPCMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateHTTPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateHTTPMonitor\n description: Creates a new HTTP monitor in the authenticated workspace. Configure the target URL, HTTP method, request headers and body, response assertions (status code, body content, headers), check periodicity, geographic regions, and optional OpenTelemetry export. The monitor starts checking immediately if set to active.\n operationId: MonitorService_CreateHTTPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateHTTPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateHTTPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateICMPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateICMPMonitor\n description: CreateICMPMonitor creates a new ICMP monitor.\n operationId: MonitorService_CreateICMPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateICMPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateICMPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/CreateTCPMonitor:\n post:\n tags:\n - MonitorService\n summary: CreateTCPMonitor\n description: CreateTCPMonitor creates a new TCP monitor.\n operationId: MonitorService_CreateTCPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateTCPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.CreateTCPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/DeleteMonitor:\n post:\n tags:\n - MonitorService\n summary: DeleteMonitor\n description: DeleteMonitor removes a monitor.\n operationId: MonitorService_DeleteMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.DeleteMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.DeleteMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitor:\n get:\n tags:\n - MonitorService\n summary: GetMonitor\n description: |-\n GetMonitor returns a single monitor by ID within the authenticated workspace.\n Returns the monitor configuration (HTTP, TCP, DNS, ICMP, or gRPC) using the MonitorConfig oneof type.\n operationId: MonitorService_GetMonitor.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitor\n description: |-\n GetMonitor returns a single monitor by ID within the authenticated workspace.\n Returns the monitor configuration (HTTP, TCP, DNS, ICMP, or gRPC) using the MonitorConfig oneof type.\n operationId: MonitorService_GetMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorHTTPResponseLog:\n get:\n tags:\n - MonitorService\n summary: GetMonitorHTTPResponseLog\n description: GetMonitorHTTPResponseLog returns one response log for an HTTP monitor.\n operationId: MonitorService_GetMonitorHTTPResponseLog.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorHTTPResponseLog\n description: GetMonitorHTTPResponseLog returns one response log for an HTTP monitor.\n operationId: MonitorService_GetMonitorHTTPResponseLog\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorHTTPResponseLogResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorStatus:\n get:\n tags:\n - MonitorService\n summary: GetMonitorStatus\n description: GetMonitorStatus returns the current status of all regions for a monitor.\n operationId: MonitorService_GetMonitorStatus.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorStatus\n description: GetMonitorStatus returns the current status of all regions for a monitor.\n operationId: MonitorService_GetMonitorStatus\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorStatusResponse'\n /rpc/openstatus.monitor.v1.MonitorService/GetMonitorSummary:\n get:\n tags:\n - MonitorService\n summary: GetMonitorSummary\n description: Returns aggregated metrics for a monitor including latency percentiles (p50, p75, p90, p95, p99), request counts by status (successful, degraded, failed), and the timestamp of the last check. Metrics can be scoped to a time range (1 day, 7 days, or 14 days) and filtered by specific regions.\n operationId: MonitorService_GetMonitorSummary.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryResponse'\n post:\n tags:\n - MonitorService\n summary: GetMonitorSummary\n description: Returns aggregated metrics for a monitor including latency percentiles (p50, p75, p90, p95, p99), request counts by status (successful, degraded, failed), and the timestamp of the last check. Metrics can be scoped to a time range (1 day, 7 days, or 14 days) and filtered by specific regions.\n operationId: MonitorService_GetMonitorSummary\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.GetMonitorSummaryResponse'\n /rpc/openstatus.monitor.v1.MonitorService/ListMonitorHTTPResponseLogs:\n get:\n tags:\n - MonitorService\n summary: ListMonitorHTTPResponseLogs\n description: ListMonitorHTTPResponseLogs returns paginated response logs for an HTTP monitor from the 14-day HTTP response-log window.\n operationId: MonitorService_ListMonitorHTTPResponseLogs.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse'\n post:\n tags:\n - MonitorService\n summary: ListMonitorHTTPResponseLogs\n description: ListMonitorHTTPResponseLogs returns paginated response logs for an HTTP monitor from the 14-day HTTP response-log window.\n operationId: MonitorService_ListMonitorHTTPResponseLogs\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorHTTPResponseLogsResponse'\n /rpc/openstatus.monitor.v1.MonitorService/ListMonitors:\n get:\n tags:\n - MonitorService\n summary: ListMonitors\n description: ListMonitors returns a paginated list of all monitors in the workspace.\n operationId: MonitorService_ListMonitors.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsResponse'\n post:\n tags:\n - MonitorService\n summary: ListMonitors\n description: ListMonitors returns a paginated list of all monitors in the workspace.\n operationId: MonitorService_ListMonitors\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.ListMonitorsResponse'\n /rpc/openstatus.monitor.v1.MonitorService/TriggerMonitor:\n post:\n tags:\n - MonitorService\n summary: TriggerMonitor\n description: Manually triggers an immediate check for the specified monitor across all configured regions. This operation is rate-limited under the synthetic-checks quota. A monitor run record is created and the check is dispatched to the checker service.\n operationId: MonitorService_TriggerMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.TriggerMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.TriggerMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateDNSMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateDNSMonitor\n description: UpdateDNSMonitor updates an existing DNS monitor.\n operationId: MonitorService_UpdateDNSMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateDNSMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateDNSMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateGRPCMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateGRPCMonitor\n description: UpdateGRPCMonitor updates an existing gRPC monitor.\n operationId: MonitorService_UpdateGRPCMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateGRPCMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateGRPCMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateHTTPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateHTTPMonitor\n description: UpdateHTTPMonitor updates an existing HTTP monitor.\n operationId: MonitorService_UpdateHTTPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateHTTPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateHTTPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateICMPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateICMPMonitor\n description: UpdateICMPMonitor updates an existing ICMP monitor.\n operationId: MonitorService_UpdateICMPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateICMPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateICMPMonitorResponse'\n /rpc/openstatus.monitor.v1.MonitorService/UpdateTCPMonitor:\n post:\n tags:\n - MonitorService\n summary: UpdateTCPMonitor\n description: UpdateTCPMonitor updates an existing TCP monitor.\n operationId: MonitorService_UpdateTCPMonitor\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateTCPMonitorRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.monitor.v1.UpdateTCPMonitorResponse'\n /rpc/openstatus.notification.v1.NotificationService/CheckNotificationLimit:\n get:\n tags:\n - NotificationService\n summary: CheckNotificationLimit\n description: CheckNotificationLimit checks if the workspace has reached its notification limit.\n operationId: NotificationService_CheckNotificationLimit.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitResponse'\n post:\n tags:\n - NotificationService\n summary: CheckNotificationLimit\n description: CheckNotificationLimit checks if the workspace has reached its notification limit.\n operationId: NotificationService_CheckNotificationLimit\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CheckNotificationLimitResponse'\n /rpc/openstatus.notification.v1.NotificationService/CreateNotification:\n post:\n tags:\n - NotificationService\n summary: CreateNotification\n description: CreateNotification creates a new notification channel.\n operationId: NotificationService_CreateNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CreateNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.CreateNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/DeleteNotification:\n post:\n tags:\n - NotificationService\n summary: DeleteNotification\n description: DeleteNotification removes a notification channel.\n operationId: NotificationService_DeleteNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.DeleteNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.DeleteNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/GetNotification:\n get:\n tags:\n - NotificationService\n summary: GetNotification\n description: GetNotification retrieves a notification channel by ID.\n operationId: NotificationService_GetNotification.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationResponse'\n post:\n tags:\n - NotificationService\n summary: GetNotification\n description: GetNotification retrieves a notification channel by ID.\n operationId: NotificationService_GetNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.GetNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/ListNotifications:\n get:\n tags:\n - NotificationService\n summary: ListNotifications\n description: ListNotifications returns a list of notification channels.\n operationId: NotificationService_ListNotifications.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsResponse'\n post:\n tags:\n - NotificationService\n summary: ListNotifications\n description: ListNotifications returns a list of notification channels.\n operationId: NotificationService_ListNotifications\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.ListNotificationsResponse'\n /rpc/openstatus.notification.v1.NotificationService/SendTestNotification:\n post:\n tags:\n - NotificationService\n summary: SendTestNotification\n description: Sends a test notification to the specified provider to verify that the configuration is correct. This does not require an existing notification channel - just provide the provider type and its configuration data. Returns success status and an error message if the test failed.\n operationId: NotificationService_SendTestNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.SendTestNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.SendTestNotificationResponse'\n /rpc/openstatus.notification.v1.NotificationService/UpdateNotification:\n post:\n tags:\n - NotificationService\n summary: UpdateNotification\n description: UpdateNotification updates an existing notification channel.\n operationId: NotificationService_UpdateNotification\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.UpdateNotificationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.notification.v1.UpdateNotificationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/CreatePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: CreatePrivateLocation\n description: Creates a private location. The agent token is generated by the server and returned in the response - it cannot be supplied by the caller. Use the token to configure the agent so it can pull its monitors and report results.\n operationId: PrivateLocationService_CreatePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.CreatePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.CreatePrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/DeletePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: DeletePrivateLocation\n description: DeletePrivateLocation removes a private location.\n operationId: PrivateLocationService_DeletePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.DeletePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.DeletePrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/GetPrivateLocation:\n get:\n tags:\n - PrivateLocationService\n summary: GetPrivateLocation\n description: |-\n GetPrivateLocation retrieves a single private location by ID, including\n its agent token.\n operationId: PrivateLocationService_GetPrivateLocation.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationResponse'\n post:\n tags:\n - PrivateLocationService\n summary: GetPrivateLocation\n description: |-\n GetPrivateLocation retrieves a single private location by ID, including\n its agent token.\n operationId: PrivateLocationService_GetPrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.GetPrivateLocationResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/ListPrivateLocations:\n get:\n tags:\n - PrivateLocationService\n summary: ListPrivateLocations\n description: |-\n ListPrivateLocations returns a paginated list of private location\n summaries. Agent tokens are not included - use GetPrivateLocation.\n operationId: PrivateLocationService_ListPrivateLocations.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsResponse'\n post:\n tags:\n - PrivateLocationService\n summary: ListPrivateLocations\n description: |-\n ListPrivateLocations returns a paginated list of private location\n summaries. Agent tokens are not included - use GetPrivateLocation.\n operationId: PrivateLocationService_ListPrivateLocations\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.ListPrivateLocationsResponse'\n /rpc/openstatus.private_location.v1.PrivateLocationService/UpdatePrivateLocation:\n post:\n tags:\n - PrivateLocationService\n summary: UpdatePrivateLocation\n description: UpdatePrivateLocation updates a private location.\n operationId: PrivateLocationService_UpdatePrivateLocation\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.UpdatePrivateLocationRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.private_location.v1.UpdatePrivateLocationResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/AddMonitorComponent:\n post:\n tags:\n - StatusPageService\n summary: AddMonitorComponent\n description: AddMonitorComponent adds a monitor-based component to a status page.\n operationId: StatusPageService_AddMonitorComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddMonitorComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddMonitorComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/AddStaticComponent:\n post:\n tags:\n - StatusPageService\n summary: AddStaticComponent\n description: AddStaticComponent adds a static component to a status page.\n operationId: StatusPageService_AddStaticComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddStaticComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.AddStaticComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreateComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: CreateComponentGroup\n description: CreateComponentGroup creates a new component group.\n operationId: StatusPageService_CreateComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreatePageSubscription:\n post:\n tags:\n - StatusPageService\n summary: 'CreatePageSubscription: operator-added subscriber (email or webhook), no verification.'\n description: Operator-added subscriber (email or webhook) with no verification flow — the partner starts receiving notifications immediately. Supports Slack and Discord webhook URLs in addition to email. A management token is still generated so the subscriber can self-manage (update scope, unsubscribe) without operator involvement. Use this for vendor/partner integrations where consent is established out-of-band; use SubscribeToPage for subscriber-initiated signups that require double opt-in.\n operationId: StatusPageService_CreatePageSubscription\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreatePageSubscriptionRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreatePageSubscriptionResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/CreateStatusPage:\n post:\n tags:\n - StatusPageService\n summary: CreateStatusPage\n description: CreateStatusPage creates a new status page.\n operationId: StatusPageService_CreateStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.CreateStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/DeleteComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: DeleteComponentGroup\n description: DeleteComponentGroup removes a component group.\n operationId: StatusPageService_DeleteComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/DeleteStatusPage:\n post:\n tags:\n - StatusPageService\n summary: DeleteStatusPage\n description: DeleteStatusPage removes a status page.\n operationId: StatusPageService_DeleteStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.DeleteStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetOverallStatus:\n get:\n tags:\n - StatusPageService\n summary: GetOverallStatus\n description: 'Returns the overall status of a status page along with individual component statuses. The overall status is computed from active status reports and maintenances with the following priority: degraded (from active status reports) > maintenance (from active maintenance windows) > operational.'\n operationId: StatusPageService_GetOverallStatus.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusResponse'\n post:\n tags:\n - StatusPageService\n summary: GetOverallStatus\n description: 'Returns the overall status of a status page along with individual component statuses. The overall status is computed from active status reports and maintenances with the following priority: degraded (from active status reports) > maintenance (from active maintenance windows) > operational.'\n operationId: StatusPageService_GetOverallStatus\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetOverallStatusResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetPageComponent:\n get:\n tags:\n - StatusPageService\n summary: GetPageComponent\n description: Returns a single status-page component by its ID, scoped to the authenticated workspace. Use this to resolve a component id to its name (and other fields) instead of fetching the whole page via GetStatusPageContent and filtering .components.\n operationId: StatusPageService_GetPageComponent.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentResponse'\n post:\n tags:\n - StatusPageService\n summary: GetPageComponent\n description: Returns a single status-page component by its ID, scoped to the authenticated workspace. Use this to resolve a component id to its name (and other fields) instead of fetching the whole page via GetStatusPageContent and filtering .components.\n operationId: StatusPageService_GetPageComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetPageComponentDailySummary:\n get:\n tags:\n - StatusPageService\n summary: GetPageComponentDailySummary\n description: 'Returns per-component daily status buckets (ok/degraded/error/count plus a resolved status) merged with the incident, maintenance, and status-report timeline over the last N days (max 45). Suitable as a single source of truth for status-bar and uptime-calendar rendering. Supports two access paths: by id (authenticated, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetPageComponentDailySummary.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryResponse'\n post:\n tags:\n - StatusPageService\n summary: GetPageComponentDailySummary\n description: 'Returns per-component daily status buckets (ok/degraded/error/count plus a resolved status) merged with the incident, maintenance, and status-report timeline over the last N days (max 45). Suitable as a single source of truth for status-bar and uptime-calendar rendering. Supports two access paths: by id (authenticated, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetPageComponentDailySummary\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetPageComponentDailySummaryResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPage:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPage\n description: GetStatusPage retrieves a specific status page by ID.\n operationId: StatusPageService_GetStatusPage.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPage\n description: GetStatusPage retrieves a specific status page by ID.\n operationId: StatusPageService_GetStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPageContent:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPageContent\n description: 'Returns the full content of a status page including its components, component groups, active status reports, and scheduled maintenances. Supports two access paths: by ID (requires authentication, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetStatusPageContent.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPageContent\n description: 'Returns the full content of a status page including its components, component groups, active status reports, and scheduled maintenances. Supports two access paths: by ID (requires authentication, workspace-scoped) or by slug (public access, requires the page to be published with access_type=PUBLIC).'\n operationId: StatusPageService_GetStatusPageContent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageContentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/GetStatusPageOverview:\n get:\n tags:\n - StatusPageService\n summary: GetStatusPageOverview\n description: 'Returns everything about a single status page in one authenticated call: the page, its rich rendering configuration, components, component groups, active/recent status reports, maintenances, and the computed overall + per-component statuses. Workspace-scoped by id; there is no public slug access path. Does not include uptime time-series — use GetPageComponentDailySummary for that.'\n operationId: StatusPageService_GetStatusPageOverview.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewResponse'\n post:\n tags:\n - StatusPageService\n summary: GetStatusPageOverview\n description: 'Returns everything about a single status page in one authenticated call: the page, its rich rendering configuration, components, component groups, active/recent status reports, maintenances, and the computed overall + per-component statuses. Workspace-scoped by id; there is no public slug access path. Does not include uptime time-series — use GetPageComponentDailySummary for that.'\n operationId: StatusPageService_GetStatusPageOverview\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.GetStatusPageOverviewResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/ListStatusPages:\n get:\n tags:\n - StatusPageService\n summary: ListStatusPages\n description: ListStatusPages returns all status pages for the workspace.\n operationId: StatusPageService_ListStatusPages.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesResponse'\n post:\n tags:\n - StatusPageService\n summary: ListStatusPages\n description: ListStatusPages returns all status pages for the workspace.\n operationId: StatusPageService_ListStatusPages\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListStatusPagesResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/ListSubscribers:\n get:\n tags:\n - StatusPageService\n summary: ListSubscribers\n description: ListSubscribers returns all subscribers for a status page.\n operationId: StatusPageService_ListSubscribers.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersResponse'\n post:\n tags:\n - StatusPageService\n summary: ListSubscribers\n description: ListSubscribers returns all subscribers for a status page.\n operationId: StatusPageService_ListSubscribers\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.ListSubscribersResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/RemoveComponent:\n post:\n tags:\n - StatusPageService\n summary: RemoveComponent\n description: RemoveComponent removes a component from a status page.\n operationId: StatusPageService_RemoveComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.RemoveComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.RemoveComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/SubscribeToPage:\n post:\n tags:\n - StatusPageService\n summary: 'SubscribeToPage: end-user email self-signup with double opt-in verification.'\n description: End-user email self-signup with double opt-in verification. A verification email is sent and the subscription activates only after the recipient confirms. If the email was previously unsubscribed, the existing row is reactivated instead of a duplicate being created. Use this for subscriber-initiated signups on the public status page; use CreatePageSubscription for operator-initiated (vendor) subscriptions that should skip verification.\n operationId: StatusPageService_SubscribeToPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscribeToPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.SubscribeToPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UnsubscribeFromPage:\n post:\n tags:\n - StatusPageService\n summary: UnsubscribeFromPage\n description: UnsubscribeFromPage removes a subscription from a status page.\n operationId: StatusPageService_UnsubscribeFromPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UnsubscribeFromPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UnsubscribeFromPageResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateComponent:\n post:\n tags:\n - StatusPageService\n summary: UpdateComponent\n description: UpdateComponent updates an existing component.\n operationId: StatusPageService_UpdateComponent\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateComponentGroup:\n post:\n tags:\n - StatusPageService\n summary: UpdateComponentGroup\n description: UpdateComponentGroup updates an existing component group.\n operationId: StatusPageService_UpdateComponentGroup\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentGroupRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateComponentGroupResponse'\n /rpc/openstatus.status_page.v1.StatusPageService/UpdateStatusPage:\n post:\n tags:\n - StatusPageService\n summary: UpdateStatusPage\n description: UpdateStatusPage updates an existing status page.\n operationId: StatusPageService_UpdateStatusPage\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateStatusPageRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_page.v1.UpdateStatusPageResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/AddStatusReportUpdate:\n post:\n tags:\n - StatusReportService\n summary: AddStatusReportUpdate\n description: 'Adds a new update entry to an existing status report and transitions the report to the specified status. Status reports follow a lifecycle: investigating -> identified -> monitoring -> resolved. If notify is true, subscribers of the associated page are notified by email about the update.'\n operationId: StatusReportService_AddStatusReportUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.AddStatusReportUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.AddStatusReportUpdateResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/CreateStatusReport:\n post:\n tags:\n - StatusReportService\n summary: CreateStatusReport\n description: Creates a new status report with an initial update entry. The report is associated with a status page and optionally specific page components. An initial StatusReportUpdate is created automatically with the provided status, message, and date. If notify is true, subscribers of the associated page are notified by email.\n operationId: StatusReportService_CreateStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.CreateStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.CreateStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReport:\n post:\n tags:\n - StatusReportService\n summary: DeleteStatusReport\n description: DeleteStatusReport removes a status report and all its updates.\n operationId: StatusReportService_DeleteStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReportUpdate:\n post:\n tags:\n - StatusReportService\n summary: DeleteStatusReportUpdate\n description: 'Removes a status report update. The report''s status is re-derived from the remaining updates. Deleting the last remaining update is rejected with INVALID_ARGUMENT: delete the status report instead.'\n operationId: StatusReportService_DeleteStatusReportUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/GetStatusReport:\n get:\n tags:\n - StatusReportService\n summary: GetStatusReport\n description: GetStatusReport retrieves a specific status report by ID (includes full update timeline).\n operationId: StatusReportService_GetStatusReport.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportResponse'\n post:\n tags:\n - StatusReportService\n summary: GetStatusReport\n description: GetStatusReport retrieves a specific status report by ID (includes full update timeline).\n operationId: StatusReportService_GetStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.GetStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/ListStatusReports:\n get:\n tags:\n - StatusReportService\n summary: ListStatusReports\n description: ListStatusReports returns all status reports for the workspace (metadata only).\n operationId: StatusReportService_ListStatusReports.get\n parameters:\n - name: message\n in: query\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsRequest'\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsResponse'\n post:\n tags:\n - StatusReportService\n summary: ListStatusReports\n description: ListStatusReports returns all status reports for the workspace (metadata only).\n operationId: StatusReportService_ListStatusReports\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.ListStatusReportsResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReport:\n post:\n tags:\n - StatusReportService\n summary: UpdateStatusReport\n description: UpdateStatusReport updates the metadata of a status report (title, page components).\n operationId: StatusReportService_UpdateStatusReport\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportResponse'\n /rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReportUpdate:\n post:\n tags:\n - StatusReportService\n summary: UpdateStatusReportUpdate\n description: Edits an existing status report update in place. Editing the status or date of the latest update re-derives the report's overall status. Subscribers are not notified.\n operationId: StatusReportService_UpdateStatusReportUpdate\n requestBody:\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateRequest'\n required: true\n responses:\n \"429\":\n $ref: '#/components/responses/RateLimited'\n default:\n description: Error\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/connect.error'\n \"200\":\n description: Success\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateResponse'\n";
diff --git a/apps/server/static/openapi.json b/apps/server/static/openapi.json
index af90039af..5447e5fa2 100644
--- a/apps/server/static/openapi.json
+++ b/apps/server/static/openapi.json
@@ -5980,6 +5980,33 @@
"additionalProperties": false,
"description": "DeleteStatusReportResponse is the response after deleting a status report."
},
+ "openstatus.status_report.v1.DeleteStatusReportUpdateRequest": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "id",
+ "minLength": 1,
+ "description": "ID of the update to remove (required)."
+ }
+ },
+ "title": "DeleteStatusReportUpdateRequest",
+ "additionalProperties": false,
+ "description": "DeleteStatusReportUpdateRequest is the request to remove a status report update."
+ },
+ "openstatus.status_report.v1.DeleteStatusReportUpdateResponse": {
+ "type": "object",
+ "properties": {
+ "success": {
+ "type": "boolean",
+ "title": "success",
+ "description": "Whether the deletion was successful."
+ }
+ },
+ "title": "DeleteStatusReportUpdateResponse",
+ "additionalProperties": false,
+ "description": "DeleteStatusReportUpdateResponse is the response after removing a status report update."
+ },
"openstatus.status_report.v1.GetStatusReportRequest": {
"type": "object",
"properties": {
@@ -6259,6 +6286,70 @@
"title": "UpdateStatusReportResponse",
"additionalProperties": false,
"description": "UpdateStatusReportResponse is the response after updating a status report."
+ },
+ "openstatus.status_report.v1.UpdateStatusReportUpdateRequest": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "title": "id",
+ "minLength": 1,
+ "description": "ID of the update to edit (required)."
+ },
+ "status": {
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.StatusReportStatus"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "title": "status",
+ "description": "New status for this entry (optional)."
+ },
+ "message": {
+ "type": ["string", "null"],
+ "title": "message",
+ "minLength": 1,
+ "description": "New message (optional)."
+ },
+ "date": {
+ "type": ["string", "null"],
+ "title": "date",
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$",
+ "description": "New date for this entry (RFC 3339 format, optional)."
+ },
+ "componentImpacts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.ComponentImpact"
+ },
+ "title": "component_impacts",
+ "description": "Replacement impact set for this update (optional, see update_component_impacts)."
+ },
+ "updateComponentImpacts": {
+ "type": ["boolean", "null"],
+ "title": "update_component_impacts",
+ "description": "Set to true to replace the update's component impacts with component_impacts\n (empty clears them). When false or unset, component_impacts is ignored."
+ }
+ },
+ "title": "UpdateStatusReportUpdateRequest",
+ "additionalProperties": false,
+ "description": "UpdateStatusReportUpdateRequest is the request to edit a status report update."
+ },
+ "openstatus.status_report.v1.UpdateStatusReportUpdateResponse": {
+ "type": "object",
+ "properties": {
+ "statusReportUpdate": {
+ "title": "status_report_update",
+ "description": "The edited timeline entry.",
+ "$ref": "#/components/schemas/openstatus.status_report.v1.StatusReportUpdate"
+ }
+ },
+ "title": "UpdateStatusReportUpdateResponse",
+ "additionalProperties": false,
+ "description": "UpdateStatusReportUpdateResponse is the response after editing a status report update."
}
}
},
@@ -9975,6 +10066,49 @@
}
}
},
+ "/rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReportUpdate": {
+ "post": {
+ "tags": ["StatusReportService"],
+ "summary": "DeleteStatusReportUpdate",
+ "description": "Removes a status report update. The report's status is re-derived from the remaining updates. Deleting the last remaining update is rejected with INVALID_ARGUMENT: delete the status report instead.",
+ "operationId": "StatusReportService_DeleteStatusReportUpdate",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateResponse"
+ }
+ }
+ }
+ },
+ "429": {
+ "$ref": "#/components/responses/RateLimited"
+ },
+ "default": {
+ "description": "Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/connect.error"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/rpc/openstatus.status_report.v1.StatusReportService/GetStatusReport": {
"get": {
"tags": ["StatusReportService"],
@@ -10191,6 +10325,49 @@
}
}
}
+ },
+ "/rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReportUpdate": {
+ "post": {
+ "tags": ["StatusReportService"],
+ "summary": "UpdateStatusReportUpdate",
+ "description": "Edits an existing status report update in place. Editing the status or date of the latest update re-derives the report's overall status. Subscribers are not notified.",
+ "operationId": "StatusReportService_UpdateStatusReportUpdate",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateResponse"
+ }
+ }
+ }
+ },
+ "429": {
+ "$ref": "#/components/responses/RateLimited"
+ },
+ "default": {
+ "description": "Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/connect.error"
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
diff --git a/apps/server/static/openapi.yaml b/apps/server/static/openapi.yaml
index 047485093..2c040ceba 100644
--- a/apps/server/static/openapi.yaml
+++ b/apps/server/static/openapi.yaml
@@ -5019,6 +5019,27 @@ components:
title: DeleteStatusReportResponse
additionalProperties: false
description: DeleteStatusReportResponse is the response after deleting a status report.
+ openstatus.status_report.v1.DeleteStatusReportUpdateRequest:
+ type: object
+ properties:
+ id:
+ type: string
+ title: id
+ minLength: 1
+ description: ID of the update to remove (required).
+ title: DeleteStatusReportUpdateRequest
+ additionalProperties: false
+ description: DeleteStatusReportUpdateRequest is the request to remove a status report update.
+ openstatus.status_report.v1.DeleteStatusReportUpdateResponse:
+ type: object
+ properties:
+ success:
+ type: boolean
+ title: success
+ description: Whether the deletion was successful.
+ title: DeleteStatusReportUpdateResponse
+ additionalProperties: false
+ description: DeleteStatusReportUpdateResponse is the response after removing a status report update.
openstatus.status_report.v1.GetStatusReportRequest:
type: object
properties:
@@ -5252,6 +5273,61 @@ components:
title: UpdateStatusReportResponse
additionalProperties: false
description: UpdateStatusReportResponse is the response after updating a status report.
+ openstatus.status_report.v1.UpdateStatusReportUpdateRequest:
+ type: object
+ properties:
+ id:
+ type: string
+ title: id
+ minLength: 1
+ description: ID of the update to edit (required).
+ status:
+ oneOf:
+ - $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'
+ - type: "null"
+ title: status
+ description: New status for this entry (optional).
+ message:
+ type:
+ - string
+ - "null"
+ title: message
+ minLength: 1
+ description: New message (optional).
+ date:
+ type:
+ - string
+ - "null"
+ title: date
+ pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$
+ description: New date for this entry (RFC 3339 format, optional).
+ componentImpacts:
+ type: array
+ items:
+ $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'
+ title: component_impacts
+ description: Replacement impact set for this update (optional, see update_component_impacts).
+ updateComponentImpacts:
+ type:
+ - boolean
+ - "null"
+ title: update_component_impacts
+ description: |-
+ Set to true to replace the update's component impacts with component_impacts
+ (empty clears them). When false or unset, component_impacts is ignored.
+ title: UpdateStatusReportUpdateRequest
+ additionalProperties: false
+ description: UpdateStatusReportUpdateRequest is the request to edit a status report update.
+ openstatus.status_report.v1.UpdateStatusReportUpdateResponse:
+ type: object
+ properties:
+ statusReportUpdate:
+ title: status_report_update
+ description: The edited timeline entry.
+ $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportUpdate'
+ title: UpdateStatusReportUpdateResponse
+ additionalProperties: false
+ description: UpdateStatusReportUpdateResponse is the response after editing a status report update.
security:
- ApiKeyAuth: []
tags:
@@ -7674,6 +7750,34 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportResponse'
+ /rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReportUpdate:
+ post:
+ tags:
+ - StatusReportService
+ summary: DeleteStatusReportUpdate
+ description: 'Removes a status report update. The report''s status is re-derived from the remaining updates. Deleting the last remaining update is rejected with INVALID_ARGUMENT: delete the status report instead.'
+ operationId: StatusReportService_DeleteStatusReportUpdate
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateRequest'
+ required: true
+ responses:
+ "429":
+ $ref: '#/components/responses/RateLimited'
+ default:
+ description: Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/connect.error'
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateResponse'
/rpc/openstatus.status_report.v1.StatusReportService/GetStatusReport:
get:
tags:
@@ -7814,3 +7918,31 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportResponse'
+ /rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReportUpdate:
+ post:
+ tags:
+ - StatusReportService
+ summary: UpdateStatusReportUpdate
+ description: Edits an existing status report update in place. Editing the status or date of the latest update re-derives the report's overall status. Subscribers are not notified.
+ operationId: StatusReportService_UpdateStatusReportUpdate
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateRequest'
+ required: true
+ responses:
+ "429":
+ $ref: '#/components/responses/RateLimited'
+ default:
+ description: Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/connect.error'
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateResponse'
diff --git a/apps/status-page/next-env.d.ts b/apps/status-page/next-env.d.ts
index 9edff1c7c..a419cbe4e 100644
--- a/apps/status-page/next-env.d.ts
+++ b/apps/status-page/next-env.d.ts
@@ -1,6 +1,7 @@
///
///
-import "./.next/types/routes.d.ts";
+import "./.next/dev/types/routes.d.ts";
+import "./.next/dev/types/root-params.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/apps/web/src/content/pages/docs/reference/maintenance.mdx b/apps/web/src/content/pages/docs/reference/maintenance.mdx
index 6b6ce53bd..5afe21156 100644
--- a/apps/web/src/content/pages/docs/reference/maintenance.mdx
+++ b/apps/web/src/content/pages/docs/reference/maintenance.mdx
@@ -85,7 +85,7 @@ A maintenance is a timeline of dated notes. The first one is the announcement wr
- **Date** — Datetime (optional). When the note applies. Defaults to the time it is posted.
- **Notify** — Boolean (optional, write-only). Sends the note to status page subscribers.
-A maintenance always keeps at least one update: deleting the last one is rejected, delete the maintenance instead. Reads return them newest-first under `updates` (RPC, agent tools) or `maintenanceUpdates` (status page JSON). The public status page, feeds and Markdown render the updates in order, oldest first on the page.
+A maintenance always keeps at least one update: deleting the last one is rejected; delete the maintenance instead. Reads return them newest-first under `updates` (RPC, agent tools) or `maintenanceUpdates` (status page JSON). The public status page, feeds and Markdown render the updates in order, oldest first on the page.
## Relationships
diff --git a/apps/web/src/content/pages/docs/reference/mcp-server.mdx b/apps/web/src/content/pages/docs/reference/mcp-server.mdx
index 6152d8e08..d9ffa5a85 100644
--- a/apps/web/src/content/pages/docs/reference/mcp-server.mdx
+++ b/apps/web/src/content/pages/docs/reference/mcp-server.mdx
@@ -62,7 +62,7 @@ For AI agents that should only observe state — health summaries, paging on-cal
## Tools
-The server exposes 26 tools (24 on plans without the `audit-log` feature), grouped by resource: 22 scoped to the workspace tied to your credential, plus 4 public content tools that read openstatus.dev pages on any credential and any scope (see [Content](#content)). Workspaces with incident management enabled get 10 more (see [Incidents](#incidents)). Mutations write to the audit log with `actor_type = "mcp"` (see [Audit log](#audit-log)).
+The server exposes 29 tools (27 on plans without the `audit-log` feature), grouped by resource: 25 scoped to the workspace tied to your credential, plus 4 public content tools that read openstatus.dev pages on any credential and any scope (see [Content](#content)). Workspaces with incident management enabled get 10 more (see [Incidents](#incidents)). Mutations write to the audit log with `actor_type = "mcp"` (see [Audit log](#audit-log)).
### Pages
@@ -75,11 +75,14 @@ The server exposes 26 tools (24 on plans without the `audit-log` feature), group
| Tool | Type | Purpose |
|----------------------------|----------|---------|
-| `list_status_reports` | read | List status reports newest-first. `filter: "active" \| "all"` (defaults to active = excludes resolved). Paginated via `page` (1-indexed) and `perPage`; response carries a `pagination` object with `page`, `perPage`, `totalSize`, and `totalPages`. |
+| `list_status_reports` | read | List status reports newest-first, each with its `updates` timeline (newest first, with ids, capped at the 10 most recent) and `latestUpdate`. `filter: "active" \| "all"` (defaults to active = excludes resolved). Paginated via `page` (1-indexed) and `perPage`; response carries a `pagination` object with `page`, `perPage`, `totalSize`, and `totalPages`. |
+| `get_status_report` | read | Get one status report with its full `updates` timeline (newest first, with ids, uncapped) and `pageComponentIds`. Use it to reach entries older than the 10 that `list_status_reports` returns. |
| `create_status_report` | mutation | Create a new status report on a status page with an initial public update. |
| `add_status_report_update` | mutation | Append a public update to an existing status report and bump its status. |
| `update_status_report` | mutation | Edit a report's title, status, or affected components without posting a public update. |
| `resolve_status_report` | mutation | Mark a report resolved and post a final public update with the supplied message. |
+| `update_status_report_update` | mutation | Edit the status, message, date or component impacts of an existing update. |
+| `delete_status_report_update` | mutation | Remove an update. A report keeps at least one; the report's status is re-derived. |
### Maintenance
@@ -97,7 +100,7 @@ Registered only when incident management is enabled for the workspace — otherw
| Tool | Type | Purpose |
|-----------------------|----------|---------|
-| `list_incidents` | read | List declared incidents, open ones first. Optional `status` filter; `limit` ≤ 100 and `offset`. |
+| `list_incidents` | read | List declared incidents, newest declared first. Optional `status` filter; `limit` ≤ 100 and `offset`. |
| `get_incident` | read | One incident with its timeline (newest first, up to 50 events) and linked status report. |
| `declare_incident` | mutation | Declare an incident with a `title` and `severity` (`critical` / `major` / `minor`), optionally a summary, commander, start time and status report to link. |
| `update_incident` | mutation | Change the title, severity, summary, commander or start time. |
@@ -188,6 +191,7 @@ The mutation and the notify dispatch are sequential, not transactional. The muta
| `create_maintenance` | Maintenance scheduled notification |
| `add_maintenance_update` | Notification for the new note |
| `update_status_report` | n/a — metadata-only edit, never has a notify path |
+| `update_status_report_update` / `delete_status_report_update` | n/a — edits to existing entries never notify |
The required `notify` field, combined with the mandatory draft-and-confirm workflow in each tool's description, encodes the contract that LLMs must:
diff --git a/apps/web/src/content/pages/docs/reference/status-report.mdx b/apps/web/src/content/pages/docs/reference/status-report.mdx
index 789792a59..d7e6642d6 100644
--- a/apps/web/src/content/pages/docs/reference/status-report.mdx
+++ b/apps/web/src/content/pages/docs/reference/status-report.mdx
@@ -70,6 +70,20 @@ A status report can be attached to one or more [page components](/docs/reference
All attached components must belong to the same status page. Adding a component impact in a later update (see below) automatically adds that component to the report's affected set.
+## Updates
+
+A status report is a timeline of dated entries. The first one is written at creation; later ones track progress until the resolution. Each update has:
+
+- **Status** — the [status](#status) the report moves to with this entry.
+- **Message** — String (required). The public note.
+- **Date** — Datetime (optional). When the entry applies. Defaults to the time it is posted.
+- **Component impacts** — per-component impact declared by this entry (see [below](#component-impacts)).
+- **Notify** — Boolean (write-only). Sends the entry to status page subscribers. Optional over RPC and from the dashboard; the MCP tools require it so the agent states the choice explicitly. Only new entries notify; editing one never does.
+
+The report's status is derived from its latest update by date, so editing or removing an update can change it. A report always keeps at least one update: deleting the last one is rejected; delete the report instead. Reads return the entries newest-first under `updates` (RPC), and the public status page renders them in order.
+
+Entries are edited and removed from the dashboard timeline, through the `UpdateStatusReportUpdate` and `DeleteStatusReportUpdate` RPC methods, and through the `update_status_report_update` and `delete_status_report_update` [MCP tools](/docs/reference/mcp-server). All three accept `resolved`: setting the latest entry to `resolved` resolves the report without notifying subscribers, whereas `resolve_status_report` appends a new resolution update and notifies.
+
## Component impacts
Beyond marking a component as affected, each update of a status report can declare **how badly** each component is affected. This per-component impact drives the component's live status, the report's overall indicator, and the uptime percentage. Reports only uses these impacts as its uptime source, while Monitor checks with **Time per status** also includes report intervals alongside monitor downtime.
diff --git a/apps/web/src/content/pages/docs/sdk/nodejs/maintenance-service.mdx b/apps/web/src/content/pages/docs/sdk/nodejs/maintenance-service.mdx
index 84038b6cf..dbaddb45b 100644
--- a/apps/web/src/content/pages/docs/sdk/nodejs/maintenance-service.mdx
+++ b/apps/web/src/content/pages/docs/sdk/nodejs/maintenance-service.mdx
@@ -4,7 +4,7 @@ title: Maintenance Service
description: "Manage scheduled maintenance windows with the openstatus Node.js SDK"
---
-Manage scheduled maintenance windows. The Maintenance Service provides 5 RPC methods.
+Manage scheduled maintenance windows. The Maintenance Service provides 8 RPC methods.
## Create Maintenance Window
@@ -15,8 +15,8 @@ const { maintenance } = await client.maintenance.v1.MaintenanceService
message: "We will be upgrading our database infrastructure.",
from: "2024-01-20T02:00:00Z",
to: "2024-01-20T04:00:00Z",
- pageId: "page_123",
- pageComponentIds: ["comp_456"],
+ pageId: "1",
+ pageComponentIds: ["12"],
notify: true,
});
@@ -34,7 +34,7 @@ const { maintenances, totalSize } = await client.maintenance.v1
.MaintenanceService.listMaintenances({
limit: 10,
offset: 0,
- pageId: "page_123",
+ pageId: "1",
});
console.log(`Found ${totalSize} maintenance windows`);
@@ -46,7 +46,7 @@ console.log(`Found ${totalSize} maintenance windows`);
```typescript
const { maintenance } = await client.maintenance.v1.MaintenanceService
- .getMaintenance({ id: "maint_123" });
+ .getMaintenance({ id: "123" });
console.log(`Title: ${maintenance?.title}`);
console.log(`From: ${maintenance?.from}`);
@@ -58,7 +58,7 @@ console.log(`To: ${maintenance?.to}`);
```typescript
const { maintenance } = await client.maintenance.v1.MaintenanceService
.updateMaintenance({
- id: "maint_123",
+ id: "123",
title: "Extended Database Upgrade",
to: "2024-01-20T06:00:00Z",
});
@@ -68,5 +68,37 @@ const { maintenance } = await client.maintenance.v1.MaintenanceService
```typescript
const { success } = await client.maintenance.v1.MaintenanceService
- .deleteMaintenance({ id: "maint_123" });
+ .deleteMaintenance({ id: "123" });
+```
+
+## Maintenance Updates
+
+A maintenance is a timeline of dated notes; the first one is written at creation. A maintenance always keeps at least one update: deleting the last one fails with `invalid_argument`; delete the maintenance instead.
+
+### Add Maintenance Update
+
+```typescript
+const { maintenanceUpdate } = await client.maintenance.v1.MaintenanceService
+ .addMaintenanceUpdate({
+ maintenanceId: "123",
+ message: "Work has started.",
+ notify: true,
+ });
+```
+
+### Update Maintenance Update
+
+```typescript
+const { maintenanceUpdate } = await client.maintenance.v1.MaintenanceService
+ .updateMaintenanceUpdate({
+ id: "456",
+ message: "Work has started, running 30 minutes behind.",
+ });
+```
+
+### Delete Maintenance Update
+
+```typescript
+const { success } = await client.maintenance.v1.MaintenanceService
+ .deleteMaintenanceUpdate({ id: "456" });
```
diff --git a/apps/web/src/content/pages/docs/sdk/nodejs/status-report-service.mdx b/apps/web/src/content/pages/docs/sdk/nodejs/status-report-service.mdx
index 16d4fa2c6..d812e35e6 100644
--- a/apps/web/src/content/pages/docs/sdk/nodejs/status-report-service.mdx
+++ b/apps/web/src/content/pages/docs/sdk/nodejs/status-report-service.mdx
@@ -4,7 +4,7 @@ title: Status Report Service
description: "Manage incident reports and status updates with the openstatus Node.js SDK"
---
-Manage incident reports with update timelines. The Status Report Service provides 6 RPC methods.
+Manage incident reports with update timelines. The Status Report Service provides 8 RPC methods.
## Create Status Report
@@ -24,8 +24,8 @@ const { statusReport } = await client.statusReport.v1.StatusReportService
status: StatusReportStatus.INVESTIGATING,
message: "We are investigating reports of increased latency.",
date: "2024-01-15T10:30:00Z",
- pageId: "page_123",
- pageComponentIds: ["comp_456"],
+ pageId: "1",
+ pageComponentIds: ["12"],
notify: true,
});
@@ -41,7 +41,7 @@ import { StatusReportStatus } from "@openstatus/sdk-node";
const { statusReport } = await client.statusReport.v1.StatusReportService
.addStatusReportUpdate({
- statusReportId: "sr_123",
+ statusReportId: "123",
status: StatusReportStatus.IDENTIFIED,
message: "The issue has been identified as a database connection problem.",
date: "2024-01-15T11:00:00Z",
@@ -49,6 +49,34 @@ const { statusReport } = await client.statusReport.v1.StatusReportService
});
```
+## Edit / Delete Status Report Updates
+
+Entries in the timeline can be corrected or removed. Editing never notifies subscribers; editing the latest entry's status re-derives the report's status.
+
+### Update Status Report Update
+
+```typescript
+import { StatusReportStatus } from "@openstatus/sdk-node";
+
+const { statusReportUpdate } = await client.statusReport.v1.StatusReportService
+ .updateStatusReportUpdate({
+ id: "456",
+ status: StatusReportStatus.MONITORING,
+ message: "A fix has been deployed and we are monitoring.",
+ });
+```
+
+To replace the entry's component impacts, pass `componentImpacts` together with `updateComponentImpacts: true` (an empty list clears them). Without the flag the impacts stay untouched.
+
+### Delete Status Report Update
+
+A report always keeps at least one update. Deleting the last one fails with `invalid_argument`; delete the report instead.
+
+```typescript
+const { success } = await client.statusReport.v1.StatusReportService
+ .deleteStatusReportUpdate({ id: "456" });
+```
+
## List Status Reports
List status reports with optional status filtering and pagination.
@@ -76,7 +104,7 @@ Returns the full report including the updates timeline.
import { StatusReportStatus } from "@openstatus/sdk-node";
const { statusReport } = await client.statusReport.v1.StatusReportService
- .getStatusReport({ id: "sr_123" });
+ .getStatusReport({ id: "123" });
console.log(`Title: ${statusReport?.title}`);
console.log(`Status: ${StatusReportStatus[statusReport?.status ?? 0]}`);
@@ -91,9 +119,9 @@ for (const update of statusReport?.updates ?? []) {
```typescript
const { statusReport } = await client.statusReport.v1.StatusReportService
.updateStatusReport({
- id: "sr_123",
+ id: "123",
title: "Updated Title",
- pageComponentIds: ["comp_456", "comp_789"],
+ pageComponentIds: ["12", "13"],
});
```
@@ -101,5 +129,5 @@ const { statusReport } = await client.statusReport.v1.StatusReportService
```typescript
const { success } = await client.statusReport.v1.StatusReportService
- .deleteStatusReport({ id: "sr_123" });
+ .deleteStatusReport({ id: "123" });
```
diff --git a/packages/icons/src/lucide/index.ts b/packages/icons/src/lucide/index.ts
index d2a0008c3..11202d790 100644
--- a/packages/icons/src/lucide/index.ts
+++ b/packages/icons/src/lucide/index.ts
@@ -81,6 +81,7 @@ export {
Network,
ArrowRight as Next,
Bell as Notification,
+ BellOff as NotificationOff,
LayoutGrid as Overview,
CircleDashed as Pending,
Play,
diff --git a/packages/icons/src/nucleo/index.ts b/packages/icons/src/nucleo/index.ts
index 6e8dd660a..dd2081716 100644
--- a/packages/icons/src/nucleo/index.ts
+++ b/packages/icons/src/nucleo/index.ts
@@ -80,6 +80,7 @@ export { More } from "./more";
export { Network } from "./network";
export { Next } from "./next";
export { Notification } from "./notification";
+export { NotificationOff } from "./notification-off";
export { Overview } from "./overview";
export { Pending } from "./pending";
export { Play } from "./play";
diff --git a/packages/icons/src/nucleo/notification-off.tsx b/packages/icons/src/nucleo/notification-off.tsx
new file mode 100644
index 000000000..c1346cf98
--- /dev/null
+++ b/packages/icons/src/nucleo/notification-off.tsx
@@ -0,0 +1,54 @@
+import { forwardRef } from "react";
+
+import type { IconProps } from "../types";
+
+// from nucleo-ui-outline-18 (BellSlash); 18px grid, so the 1.5 stroke renders as 2px at size 24
+export const NotificationOff = forwardRef(
+ ({ size = 24, strokeWidth = 1.5, ...props }, ref) => (
+
+
+
+
+
+
+ ),
+);
+NotificationOff.displayName = "NotificationOff";
diff --git a/packages/proto/api/openstatus/status_report/v1/service.proto b/packages/proto/api/openstatus/status_report/v1/service.proto
index de6a1c8ec..95d16fced 100644
--- a/packages/proto/api/openstatus/status_report/v1/service.proto
+++ b/packages/proto/api/openstatus/status_report/v1/service.proto
@@ -39,6 +39,20 @@ service StatusReportService {
description: "Adds a new update entry to an existing status report and transitions the report to the specified status. Status reports follow a lifecycle: investigating -> identified -> monitoring -> resolved. If notify is true, subscribers of the associated page are notified by email about the update."
};
}
+
+ // UpdateStatusReportUpdate edits an existing timeline entry (status, message, date, component impacts).
+ rpc UpdateStatusReportUpdate(UpdateStatusReportUpdateRequest) returns (UpdateStatusReportUpdateResponse) {
+ option (gnostic.openapi.v3.operation) = {
+ description: "Edits an existing status report update in place. Editing the status or date of the latest update re-derives the report's overall status. Subscribers are not notified."
+ };
+ }
+
+ // DeleteStatusReportUpdate removes a timeline entry. A report always keeps at least one update.
+ rpc DeleteStatusReportUpdate(DeleteStatusReportUpdateRequest) returns (DeleteStatusReportUpdateResponse) {
+ option (gnostic.openapi.v3.operation) = {
+ description: "Removes a status report update. The report's status is re-derived from the remaining updates. Deleting the last remaining update is rejected with INVALID_ARGUMENT: delete the status report instead."
+ };
+ }
}
// CreateStatusReportRequest is the request to create a new status report.
@@ -184,3 +198,43 @@ message AddStatusReportUpdateResponse {
// The updated status report with the new update included.
StatusReport status_report = 1;
}
+
+// UpdateStatusReportUpdateRequest is the request to edit a status report update.
+message UpdateStatusReportUpdateRequest {
+ // ID of the update to edit (required).
+ string id = 1 [(buf.validate.field).string.min_len = 1];
+
+ // New status for this entry (optional).
+ optional StatusReportStatus status = 2 [(buf.validate.field).enum.defined_only = true];
+
+ // New message (optional).
+ optional string message = 3 [(buf.validate.field).string.min_len = 1];
+
+ // New date for this entry (RFC 3339 format, optional).
+ optional string date = 4 [(buf.validate.field).string.pattern = "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$"];
+
+ // Replacement impact set for this update (optional, see update_component_impacts).
+ repeated ComponentImpact component_impacts = 5;
+
+ // Set to true to replace the update's component impacts with component_impacts
+ // (empty clears them). When false or unset, component_impacts is ignored.
+ optional bool update_component_impacts = 6;
+}
+
+// UpdateStatusReportUpdateResponse is the response after editing a status report update.
+message UpdateStatusReportUpdateResponse {
+ // The edited timeline entry.
+ StatusReportUpdate status_report_update = 1;
+}
+
+// DeleteStatusReportUpdateRequest is the request to remove a status report update.
+message DeleteStatusReportUpdateRequest {
+ // ID of the update to remove (required).
+ string id = 1 [(buf.validate.field).string.min_len = 1];
+}
+
+// DeleteStatusReportUpdateResponse is the response after removing a status report update.
+message DeleteStatusReportUpdateResponse {
+ // Whether the deletion was successful.
+ bool success = 1;
+}
diff --git a/packages/proto/gen/openapi.yaml b/packages/proto/gen/openapi.yaml
index 047485093..2c040ceba 100644
--- a/packages/proto/gen/openapi.yaml
+++ b/packages/proto/gen/openapi.yaml
@@ -5019,6 +5019,27 @@ components:
title: DeleteStatusReportResponse
additionalProperties: false
description: DeleteStatusReportResponse is the response after deleting a status report.
+ openstatus.status_report.v1.DeleteStatusReportUpdateRequest:
+ type: object
+ properties:
+ id:
+ type: string
+ title: id
+ minLength: 1
+ description: ID of the update to remove (required).
+ title: DeleteStatusReportUpdateRequest
+ additionalProperties: false
+ description: DeleteStatusReportUpdateRequest is the request to remove a status report update.
+ openstatus.status_report.v1.DeleteStatusReportUpdateResponse:
+ type: object
+ properties:
+ success:
+ type: boolean
+ title: success
+ description: Whether the deletion was successful.
+ title: DeleteStatusReportUpdateResponse
+ additionalProperties: false
+ description: DeleteStatusReportUpdateResponse is the response after removing a status report update.
openstatus.status_report.v1.GetStatusReportRequest:
type: object
properties:
@@ -5252,6 +5273,61 @@ components:
title: UpdateStatusReportResponse
additionalProperties: false
description: UpdateStatusReportResponse is the response after updating a status report.
+ openstatus.status_report.v1.UpdateStatusReportUpdateRequest:
+ type: object
+ properties:
+ id:
+ type: string
+ title: id
+ minLength: 1
+ description: ID of the update to edit (required).
+ status:
+ oneOf:
+ - $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportStatus'
+ - type: "null"
+ title: status
+ description: New status for this entry (optional).
+ message:
+ type:
+ - string
+ - "null"
+ title: message
+ minLength: 1
+ description: New message (optional).
+ date:
+ type:
+ - string
+ - "null"
+ title: date
+ pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})$
+ description: New date for this entry (RFC 3339 format, optional).
+ componentImpacts:
+ type: array
+ items:
+ $ref: '#/components/schemas/openstatus.status_report.v1.ComponentImpact'
+ title: component_impacts
+ description: Replacement impact set for this update (optional, see update_component_impacts).
+ updateComponentImpacts:
+ type:
+ - boolean
+ - "null"
+ title: update_component_impacts
+ description: |-
+ Set to true to replace the update's component impacts with component_impacts
+ (empty clears them). When false or unset, component_impacts is ignored.
+ title: UpdateStatusReportUpdateRequest
+ additionalProperties: false
+ description: UpdateStatusReportUpdateRequest is the request to edit a status report update.
+ openstatus.status_report.v1.UpdateStatusReportUpdateResponse:
+ type: object
+ properties:
+ statusReportUpdate:
+ title: status_report_update
+ description: The edited timeline entry.
+ $ref: '#/components/schemas/openstatus.status_report.v1.StatusReportUpdate'
+ title: UpdateStatusReportUpdateResponse
+ additionalProperties: false
+ description: UpdateStatusReportUpdateResponse is the response after editing a status report update.
security:
- ApiKeyAuth: []
tags:
@@ -7674,6 +7750,34 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportResponse'
+ /rpc/openstatus.status_report.v1.StatusReportService/DeleteStatusReportUpdate:
+ post:
+ tags:
+ - StatusReportService
+ summary: DeleteStatusReportUpdate
+ description: 'Removes a status report update. The report''s status is re-derived from the remaining updates. Deleting the last remaining update is rejected with INVALID_ARGUMENT: delete the status report instead.'
+ operationId: StatusReportService_DeleteStatusReportUpdate
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateRequest'
+ required: true
+ responses:
+ "429":
+ $ref: '#/components/responses/RateLimited'
+ default:
+ description: Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/connect.error'
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.DeleteStatusReportUpdateResponse'
/rpc/openstatus.status_report.v1.StatusReportService/GetStatusReport:
get:
tags:
@@ -7814,3 +7918,31 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportResponse'
+ /rpc/openstatus.status_report.v1.StatusReportService/UpdateStatusReportUpdate:
+ post:
+ tags:
+ - StatusReportService
+ summary: UpdateStatusReportUpdate
+ description: Edits an existing status report update in place. Editing the status or date of the latest update re-derives the report's overall status. Subscribers are not notified.
+ operationId: StatusReportService_UpdateStatusReportUpdate
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateRequest'
+ required: true
+ responses:
+ "429":
+ $ref: '#/components/responses/RateLimited'
+ default:
+ description: Error
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/connect.error'
+ "200":
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/openstatus.status_report.v1.UpdateStatusReportUpdateResponse'
diff --git a/packages/proto/gen/ts/openstatus/status_report/v1/service_pb.ts b/packages/proto/gen/ts/openstatus/status_report/v1/service_pb.ts
index b8f76554c..c6e3a2fb7 100644
--- a/packages/proto/gen/ts/openstatus/status_report/v1/service_pb.ts
+++ b/packages/proto/gen/ts/openstatus/status_report/v1/service_pb.ts
@@ -6,7 +6,7 @@ import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegen
import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2";
import { file_buf_validate_validate } from "../../../buf/validate/validate_pb.ts";
import { file_gnostic_openapi_v3_annotations } from "../../../gnostic/openapi/v3/annotations_pb.ts";
-import type { ComponentImpact, StatusReport, StatusReportStatus, StatusReportSummary } from "./status_report_pb.ts";
+import type { ComponentImpact, StatusReport, StatusReportStatus, StatusReportSummary, StatusReportUpdate } from "./status_report_pb.ts";
import { file_openstatus_status_report_v1_status_report } from "./status_report_pb.ts";
import type { Message } from "@bufbuild/protobuf";
@@ -14,7 +14,7 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file openstatus/status_report/v1/service.proto.
*/
export const file_openstatus_status_report_v1_service: GenFile = /*@__PURE__*/
- fileDesc("CilvcGVuc3RhdHVzL3N0YXR1c19yZXBvcnQvdjEvc2VydmljZS5wcm90bxIbb3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxIpAEChlDcmVhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0EjoKBXRpdGxlGAEgASgJQiu6RyE6HxIdQVBJIERlZ3JhZGF0aW9uIEludmVzdGlnYXRpb266SARyAhABEkkKBnN0YXR1cxgCIAEoDjIvLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnRTdGF0dXNCCLpIBYIBAhABElUKB21lc3NhZ2UYAyABKAlCRLpHOjo4EjZXZSBhcmUgaW52ZXN0aWdhdGluZyByZXBvcnRzIG9mIGluY3JlYXNlZCBBUEkgbGF0ZW5jeS66SARyAhABEnYKBGRhdGUYBCABKAlCaLpHGjoYEhYiMjAyNC0wMy0xNVQxMDozMDowMFoiukhIckYyRF5cZHs0fS1cZHsyfS1cZHsyfVRcZHsyfTpcZHsyfTpcZHsyfShcLlxkezEsOX0pPyhafFsrLV1cZHsyfTpcZHsyfSkkEhgKB3BhZ2VfaWQYBSABKAlCB7pIBHICEAESGgoScGFnZV9jb21wb25lbnRfaWRzGAYgAygJEhMKBm5vdGlmeRgHIAEoCEgAiAEBEkcKEWNvbXBvbmVudF9pbXBhY3RzGAggAygLMiwub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkNvbXBvbmVudEltcGFjdEIJCgdfbm90aWZ5Il4KGkNyZWF0ZVN0YXR1c1JlcG9ydFJlc3BvbnNlEkAKDXN0YXR1c19yZXBvcnQYASABKAsyKS5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0Ii0KFkdldFN0YXR1c1JlcG9ydFJlcXVlc3QSEwoCaWQYASABKAlCB7pIBHICEAEiWwoXR2V0U3RhdHVzUmVwb3J0UmVzcG9uc2USQAoNc3RhdHVzX3JlcG9ydBgBIAEoCzIpLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnQirwEKGExpc3RTdGF0dXNSZXBvcnRzUmVxdWVzdBIdCgVsaW1pdBgBIAEoBUIJukgGGgQYZCgBSACIAQESHAoGb2Zmc2V0GAIgASgFQge6SAQaAigASAGIAQESQQoIc3RhdHVzZXMYAyADKA4yLy5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0U3RhdHVzQggKBl9saW1pdEIJCgdfb2Zmc2V0InkKGUxpc3RTdGF0dXNSZXBvcnRzUmVzcG9uc2USSAoOc3RhdHVzX3JlcG9ydHMYASADKAsyMC5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0U3VtbWFyeRISCgp0b3RhbF9zaXplGAIgASgFIrABChlVcGRhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0EhMKAmlkGAEgASgJQge6SARyAhABEhIKBXRpdGxlGAIgASgJSACIAQESGgoScGFnZV9jb21wb25lbnRfaWRzGAMgAygJEiYKGXVwZGF0ZV9wYWdlX2NvbXBvbmVudF9pZHMYBCABKAhIAYgBAUIICgZfdGl0bGVCHAoaX3VwZGF0ZV9wYWdlX2NvbXBvbmVudF9pZHMiXgoaVXBkYXRlU3RhdHVzUmVwb3J0UmVzcG9uc2USQAoNc3RhdHVzX3JlcG9ydBgBIAEoCzIpLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnQiMAoZRGVsZXRlU3RhdHVzUmVwb3J0UmVxdWVzdBITCgJpZBgBIAEoCUIHukgEcgIQASItChpEZWxldGVTdGF0dXNSZXBvcnRSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIIvgCChxBZGRTdGF0dXNSZXBvcnRVcGRhdGVSZXF1ZXN0EiEKEHN0YXR1c19yZXBvcnRfaWQYASABKAlCB7pIBHICEAESSQoGc3RhdHVzGAIgASgOMi8ub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlN0YXR1c1JlcG9ydFN0YXR1c0IIukgFggECEAESGAoHbWVzc2FnZRgDIAEoCUIHukgEcgIQARJeCgRkYXRlGAQgASgJQku6SEhyRjJEXlxkezR9LVxkezJ9LVxkezJ9VFxkezJ9OlxkezJ9OlxkezJ9KFwuXGR7MSw5fSk/KFp8WystXVxkezJ9OlxkezJ9KSRIAIgBARITCgZub3RpZnkYBSABKAhIAYgBARJHChFjb21wb25lbnRfaW1wYWN0cxgGIAMoCzIsLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5Db21wb25lbnRJbXBhY3RCBwoFX2RhdGVCCQoHX25vdGlmeSJhCh1BZGRTdGF0dXNSZXBvcnRVcGRhdGVSZXNwb25zZRJACg1zdGF0dXNfcmVwb3J0GAEgASgLMikub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlN0YXR1c1JlcG9ydDK/CwoTU3RhdHVzUmVwb3J0U2VydmljZRLOAwoSQ3JlYXRlU3RhdHVzUmVwb3J0EjYub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkNyZWF0ZVN0YXR1c1JlcG9ydFJlcXVlc3QaNy5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuQ3JlYXRlU3RhdHVzUmVwb3J0UmVzcG9uc2UixgK6R8ICGr8CQ3JlYXRlcyBhIG5ldyBzdGF0dXMgcmVwb3J0IHdpdGggYW4gaW5pdGlhbCB1cGRhdGUgZW50cnkuIFRoZSByZXBvcnQgaXMgYXNzb2NpYXRlZCB3aXRoIGEgc3RhdHVzIHBhZ2UgYW5kIG9wdGlvbmFsbHkgc3BlY2lmaWMgcGFnZSBjb21wb25lbnRzLiBBbiBpbml0aWFsIFN0YXR1c1JlcG9ydFVwZGF0ZSBpcyBjcmVhdGVkIGF1dG9tYXRpY2FsbHkgd2l0aCB0aGUgcHJvdmlkZWQgc3RhdHVzLCBtZXNzYWdlLCBhbmQgZGF0ZS4gSWYgbm90aWZ5IGlzIHRydWUsIHN1YnNjcmliZXJzIG9mIHRoZSBhc3NvY2lhdGVkIHBhZ2UgYXJlIG5vdGlmaWVkIGJ5IGVtYWlsLhKBAQoPR2V0U3RhdHVzUmVwb3J0EjMub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkdldFN0YXR1c1JlcG9ydFJlcXVlc3QaNC5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuR2V0U3RhdHVzUmVwb3J0UmVzcG9uc2UiA5ACARKHAQoRTGlzdFN0YXR1c1JlcG9ydHMSNS5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuTGlzdFN0YXR1c1JlcG9ydHNSZXF1ZXN0GjYub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkxpc3RTdGF0dXNSZXBvcnRzUmVzcG9uc2UiA5ACARKFAQoSVXBkYXRlU3RhdHVzUmVwb3J0EjYub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlVwZGF0ZVN0YXR1c1JlcG9ydFJlcXVlc3QaNy5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuVXBkYXRlU3RhdHVzUmVwb3J0UmVzcG9uc2UShQEKEkRlbGV0ZVN0YXR1c1JlcG9ydBI2Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5EZWxldGVTdGF0dXNSZXBvcnRSZXF1ZXN0Gjcub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkRlbGV0ZVN0YXR1c1JlcG9ydFJlc3BvbnNlErgDChVBZGRTdGF0dXNSZXBvcnRVcGRhdGUSOS5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuQWRkU3RhdHVzUmVwb3J0VXBkYXRlUmVxdWVzdBo6Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5BZGRTdGF0dXNSZXBvcnRVcGRhdGVSZXNwb25zZSKnArpHowIaoAJBZGRzIGEgbmV3IHVwZGF0ZSBlbnRyeSB0byBhbiBleGlzdGluZyBzdGF0dXMgcmVwb3J0IGFuZCB0cmFuc2l0aW9ucyB0aGUgcmVwb3J0IHRvIHRoZSBzcGVjaWZpZWQgc3RhdHVzLiBTdGF0dXMgcmVwb3J0cyBmb2xsb3cgYSBsaWZlY3ljbGU6IGludmVzdGlnYXRpbmcgLT4gaWRlbnRpZmllZCAtPiBtb25pdG9yaW5nIC0+IHJlc29sdmVkLiBJZiBub3RpZnkgaXMgdHJ1ZSwgc3Vic2NyaWJlcnMgb2YgdGhlIGFzc29jaWF0ZWQgcGFnZSBhcmUgbm90aWZpZWQgYnkgZW1haWwgYWJvdXQgdGhlIHVwZGF0ZS5CXlpcZ2l0aHViLmNvbS9vcGVuc3RhdHVzaHEvb3BlbnN0YXR1cy9wYWNrYWdlcy9wcm90by9vcGVuc3RhdHVzL3N0YXR1c19yZXBvcnQvdjE7c3RhdHVzcmVwb3J0djFiBnByb3RvMw", [file_buf_validate_validate, file_gnostic_openapi_v3_annotations, file_openstatus_status_report_v1_status_report]);
+ fileDesc("CilvcGVuc3RhdHVzL3N0YXR1c19yZXBvcnQvdjEvc2VydmljZS5wcm90bxIbb3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxIpAEChlDcmVhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0EjoKBXRpdGxlGAEgASgJQiu6RyE6HxIdQVBJIERlZ3JhZGF0aW9uIEludmVzdGlnYXRpb266SARyAhABEkkKBnN0YXR1cxgCIAEoDjIvLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnRTdGF0dXNCCLpIBYIBAhABElUKB21lc3NhZ2UYAyABKAlCRLpHOjo4EjZXZSBhcmUgaW52ZXN0aWdhdGluZyByZXBvcnRzIG9mIGluY3JlYXNlZCBBUEkgbGF0ZW5jeS66SARyAhABEnYKBGRhdGUYBCABKAlCaLpHGjoYEhYiMjAyNC0wMy0xNVQxMDozMDowMFoiukhIckYyRF5cZHs0fS1cZHsyfS1cZHsyfVRcZHsyfTpcZHsyfTpcZHsyfShcLlxkezEsOX0pPyhafFsrLV1cZHsyfTpcZHsyfSkkEhgKB3BhZ2VfaWQYBSABKAlCB7pIBHICEAESGgoScGFnZV9jb21wb25lbnRfaWRzGAYgAygJEhMKBm5vdGlmeRgHIAEoCEgAiAEBEkcKEWNvbXBvbmVudF9pbXBhY3RzGAggAygLMiwub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkNvbXBvbmVudEltcGFjdEIJCgdfbm90aWZ5Il4KGkNyZWF0ZVN0YXR1c1JlcG9ydFJlc3BvbnNlEkAKDXN0YXR1c19yZXBvcnQYASABKAsyKS5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0Ii0KFkdldFN0YXR1c1JlcG9ydFJlcXVlc3QSEwoCaWQYASABKAlCB7pIBHICEAEiWwoXR2V0U3RhdHVzUmVwb3J0UmVzcG9uc2USQAoNc3RhdHVzX3JlcG9ydBgBIAEoCzIpLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnQirwEKGExpc3RTdGF0dXNSZXBvcnRzUmVxdWVzdBIdCgVsaW1pdBgBIAEoBUIJukgGGgQYZCgBSACIAQESHAoGb2Zmc2V0GAIgASgFQge6SAQaAigASAGIAQESQQoIc3RhdHVzZXMYAyADKA4yLy5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0U3RhdHVzQggKBl9saW1pdEIJCgdfb2Zmc2V0InkKGUxpc3RTdGF0dXNSZXBvcnRzUmVzcG9uc2USSAoOc3RhdHVzX3JlcG9ydHMYASADKAsyMC5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0U3VtbWFyeRISCgp0b3RhbF9zaXplGAIgASgFIrABChlVcGRhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0EhMKAmlkGAEgASgJQge6SARyAhABEhIKBXRpdGxlGAIgASgJSACIAQESGgoScGFnZV9jb21wb25lbnRfaWRzGAMgAygJEiYKGXVwZGF0ZV9wYWdlX2NvbXBvbmVudF9pZHMYBCABKAhIAYgBAUIICgZfdGl0bGVCHAoaX3VwZGF0ZV9wYWdlX2NvbXBvbmVudF9pZHMiXgoaVXBkYXRlU3RhdHVzUmVwb3J0UmVzcG9uc2USQAoNc3RhdHVzX3JlcG9ydBgBIAEoCzIpLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5TdGF0dXNSZXBvcnQiMAoZRGVsZXRlU3RhdHVzUmVwb3J0UmVxdWVzdBITCgJpZBgBIAEoCUIHukgEcgIQASItChpEZWxldGVTdGF0dXNSZXBvcnRSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIIvgCChxBZGRTdGF0dXNSZXBvcnRVcGRhdGVSZXF1ZXN0EiEKEHN0YXR1c19yZXBvcnRfaWQYASABKAlCB7pIBHICEAESSQoGc3RhdHVzGAIgASgOMi8ub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlN0YXR1c1JlcG9ydFN0YXR1c0IIukgFggECEAESGAoHbWVzc2FnZRgDIAEoCUIHukgEcgIQARJeCgRkYXRlGAQgASgJQku6SEhyRjJEXlxkezR9LVxkezJ9LVxkezJ9VFxkezJ9OlxkezJ9OlxkezJ9KFwuXGR7MSw5fSk/KFp8WystXVxkezJ9OlxkezJ9KSRIAIgBARITCgZub3RpZnkYBSABKAhIAYgBARJHChFjb21wb25lbnRfaW1wYWN0cxgGIAMoCzIsLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5Db21wb25lbnRJbXBhY3RCBwoFX2RhdGVCCQoHX25vdGlmeSJhCh1BZGRTdGF0dXNSZXBvcnRVcGRhdGVSZXNwb25zZRJACg1zdGF0dXNfcmVwb3J0GAEgASgLMikub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlN0YXR1c1JlcG9ydCKyAwofVXBkYXRlU3RhdHVzUmVwb3J0VXBkYXRlUmVxdWVzdBITCgJpZBgBIAEoCUIHukgEcgIQARJOCgZzdGF0dXMYAiABKA4yLy5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuU3RhdHVzUmVwb3J0U3RhdHVzQgi6SAWCAQIQAUgAiAEBEh0KB21lc3NhZ2UYAyABKAlCB7pIBHICEAFIAYgBARJeCgRkYXRlGAQgASgJQku6SEhyRjJEXlxkezR9LVxkezJ9LVxkezJ9VFxkezJ9OlxkezJ9OlxkezJ9KFwuXGR7MSw5fSk/KFp8WystXVxkezJ9OlxkezJ9KSRIAogBARJHChFjb21wb25lbnRfaW1wYWN0cxgFIAMoCzIsLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5Db21wb25lbnRJbXBhY3QSJQoYdXBkYXRlX2NvbXBvbmVudF9pbXBhY3RzGAYgASgISAOIAQFCCQoHX3N0YXR1c0IKCghfbWVzc2FnZUIHCgVfZGF0ZUIbChlfdXBkYXRlX2NvbXBvbmVudF9pbXBhY3RzInEKIFVwZGF0ZVN0YXR1c1JlcG9ydFVwZGF0ZVJlc3BvbnNlEk0KFHN0YXR1c19yZXBvcnRfdXBkYXRlGAEgASgLMi8ub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlN0YXR1c1JlcG9ydFVwZGF0ZSI2Ch9EZWxldGVTdGF0dXNSZXBvcnRVcGRhdGVSZXF1ZXN0EhMKAmlkGAEgASgJQge6SARyAhABIjMKIERlbGV0ZVN0YXR1c1JlcG9ydFVwZGF0ZVJlc3BvbnNlEg8KB3N1Y2Nlc3MYASABKAgy8hAKE1N0YXR1c1JlcG9ydFNlcnZpY2USzgMKEkNyZWF0ZVN0YXR1c1JlcG9ydBI2Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5DcmVhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0Gjcub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkNyZWF0ZVN0YXR1c1JlcG9ydFJlc3BvbnNlIsYCukfCAhq/AkNyZWF0ZXMgYSBuZXcgc3RhdHVzIHJlcG9ydCB3aXRoIGFuIGluaXRpYWwgdXBkYXRlIGVudHJ5LiBUaGUgcmVwb3J0IGlzIGFzc29jaWF0ZWQgd2l0aCBhIHN0YXR1cyBwYWdlIGFuZCBvcHRpb25hbGx5IHNwZWNpZmljIHBhZ2UgY29tcG9uZW50cy4gQW4gaW5pdGlhbCBTdGF0dXNSZXBvcnRVcGRhdGUgaXMgY3JlYXRlZCBhdXRvbWF0aWNhbGx5IHdpdGggdGhlIHByb3ZpZGVkIHN0YXR1cywgbWVzc2FnZSwgYW5kIGRhdGUuIElmIG5vdGlmeSBpcyB0cnVlLCBzdWJzY3JpYmVycyBvZiB0aGUgYXNzb2NpYXRlZCBwYWdlIGFyZSBub3RpZmllZCBieSBlbWFpbC4SgQEKD0dldFN0YXR1c1JlcG9ydBIzLm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5HZXRTdGF0dXNSZXBvcnRSZXF1ZXN0GjQub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkdldFN0YXR1c1JlcG9ydFJlc3BvbnNlIgOQAgEShwEKEUxpc3RTdGF0dXNSZXBvcnRzEjUub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkxpc3RTdGF0dXNSZXBvcnRzUmVxdWVzdBo2Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5MaXN0U3RhdHVzUmVwb3J0c1Jlc3BvbnNlIgOQAgEShQEKElVwZGF0ZVN0YXR1c1JlcG9ydBI2Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5VcGRhdGVTdGF0dXNSZXBvcnRSZXF1ZXN0Gjcub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLlVwZGF0ZVN0YXR1c1JlcG9ydFJlc3BvbnNlEoUBChJEZWxldGVTdGF0dXNSZXBvcnQSNi5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuRGVsZXRlU3RhdHVzUmVwb3J0UmVxdWVzdBo3Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5EZWxldGVTdGF0dXNSZXBvcnRSZXNwb25zZRK4AwoVQWRkU3RhdHVzUmVwb3J0VXBkYXRlEjkub3BlbnN0YXR1cy5zdGF0dXNfcmVwb3J0LnYxLkFkZFN0YXR1c1JlcG9ydFVwZGF0ZVJlcXVlc3QaOi5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuQWRkU3RhdHVzUmVwb3J0VXBkYXRlUmVzcG9uc2UipwK6R6MCGqACQWRkcyBhIG5ldyB1cGRhdGUgZW50cnkgdG8gYW4gZXhpc3Rpbmcgc3RhdHVzIHJlcG9ydCBhbmQgdHJhbnNpdGlvbnMgdGhlIHJlcG9ydCB0byB0aGUgc3BlY2lmaWVkIHN0YXR1cy4gU3RhdHVzIHJlcG9ydHMgZm9sbG93IGEgbGlmZWN5Y2xlOiBpbnZlc3RpZ2F0aW5nIC0+IGlkZW50aWZpZWQgLT4gbW9uaXRvcmluZyAtPiByZXNvbHZlZC4gSWYgbm90aWZ5IGlzIHRydWUsIHN1YnNjcmliZXJzIG9mIHRoZSBhc3NvY2lhdGVkIHBhZ2UgYXJlIG5vdGlmaWVkIGJ5IGVtYWlsIGFib3V0IHRoZSB1cGRhdGUuEscCChhVcGRhdGVTdGF0dXNSZXBvcnRVcGRhdGUSPC5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuVXBkYXRlU3RhdHVzUmVwb3J0VXBkYXRlUmVxdWVzdBo9Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5VcGRhdGVTdGF0dXNSZXBvcnRVcGRhdGVSZXNwb25zZSKtAbpHqQEapgFFZGl0cyBhbiBleGlzdGluZyBzdGF0dXMgcmVwb3J0IHVwZGF0ZSBpbiBwbGFjZS4gRWRpdGluZyB0aGUgc3RhdHVzIG9yIGRhdGUgb2YgdGhlIGxhdGVzdCB1cGRhdGUgcmUtZGVyaXZlcyB0aGUgcmVwb3J0J3Mgb3ZlcmFsbCBzdGF0dXMuIFN1YnNjcmliZXJzIGFyZSBub3Qgbm90aWZpZWQuEuYCChhEZWxldGVTdGF0dXNSZXBvcnRVcGRhdGUSPC5vcGVuc3RhdHVzLnN0YXR1c19yZXBvcnQudjEuRGVsZXRlU3RhdHVzUmVwb3J0VXBkYXRlUmVxdWVzdBo9Lm9wZW5zdGF0dXMuc3RhdHVzX3JlcG9ydC52MS5EZWxldGVTdGF0dXNSZXBvcnRVcGRhdGVSZXNwb25zZSLMAbpHyAEaxQFSZW1vdmVzIGEgc3RhdHVzIHJlcG9ydCB1cGRhdGUuIFRoZSByZXBvcnQncyBzdGF0dXMgaXMgcmUtZGVyaXZlZCBmcm9tIHRoZSByZW1haW5pbmcgdXBkYXRlcy4gRGVsZXRpbmcgdGhlIGxhc3QgcmVtYWluaW5nIHVwZGF0ZSBpcyByZWplY3RlZCB3aXRoIElOVkFMSURfQVJHVU1FTlQ6IGRlbGV0ZSB0aGUgc3RhdHVzIHJlcG9ydCBpbnN0ZWFkLkJeWlxnaXRodWIuY29tL29wZW5zdGF0dXNocS9vcGVuc3RhdHVzL3BhY2thZ2VzL3Byb3RvL29wZW5zdGF0dXMvc3RhdHVzX3JlcG9ydC92MTtzdGF0dXNyZXBvcnR2MWIGcHJvdG8z", [file_buf_validate_validate, file_gnostic_openapi_v3_annotations, file_openstatus_status_report_v1_status_report]);
/**
* CreateStatusReportRequest is the request to create a new status report.
@@ -400,6 +400,126 @@ export type AddStatusReportUpdateResponse = Message<"openstatus.status_report.v1
export const AddStatusReportUpdateResponseSchema: GenMessage = /*@__PURE__*/
messageDesc(file_openstatus_status_report_v1_service, 11);
+/**
+ * UpdateStatusReportUpdateRequest is the request to edit a status report update.
+ *
+ * @generated from message openstatus.status_report.v1.UpdateStatusReportUpdateRequest
+ */
+export type UpdateStatusReportUpdateRequest = Message<"openstatus.status_report.v1.UpdateStatusReportUpdateRequest"> & {
+ /**
+ * ID of the update to edit (required).
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+
+ /**
+ * New status for this entry (optional).
+ *
+ * @generated from field: optional openstatus.status_report.v1.StatusReportStatus status = 2;
+ */
+ status?: StatusReportStatus | undefined;
+
+ /**
+ * New message (optional).
+ *
+ * @generated from field: optional string message = 3;
+ */
+ message?: string | undefined;
+
+ /**
+ * New date for this entry (RFC 3339 format, optional).
+ *
+ * @generated from field: optional string date = 4;
+ */
+ date?: string | undefined;
+
+ /**
+ * Replacement impact set for this update (optional, see update_component_impacts).
+ *
+ * @generated from field: repeated openstatus.status_report.v1.ComponentImpact component_impacts = 5;
+ */
+ componentImpacts: ComponentImpact[];
+
+ /**
+ * Set to true to replace the update's component impacts with component_impacts
+ * (empty clears them). When false or unset, component_impacts is ignored.
+ *
+ * @generated from field: optional bool update_component_impacts = 6;
+ */
+ updateComponentImpacts?: boolean | undefined;
+};
+
+/**
+ * Describes the message openstatus.status_report.v1.UpdateStatusReportUpdateRequest.
+ * Use `create(UpdateStatusReportUpdateRequestSchema)` to create a new message.
+ */
+export const UpdateStatusReportUpdateRequestSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_status_report_v1_service, 12);
+
+/**
+ * UpdateStatusReportUpdateResponse is the response after editing a status report update.
+ *
+ * @generated from message openstatus.status_report.v1.UpdateStatusReportUpdateResponse
+ */
+export type UpdateStatusReportUpdateResponse = Message<"openstatus.status_report.v1.UpdateStatusReportUpdateResponse"> & {
+ /**
+ * The edited timeline entry.
+ *
+ * @generated from field: openstatus.status_report.v1.StatusReportUpdate status_report_update = 1;
+ */
+ statusReportUpdate?: StatusReportUpdate | undefined;
+};
+
+/**
+ * Describes the message openstatus.status_report.v1.UpdateStatusReportUpdateResponse.
+ * Use `create(UpdateStatusReportUpdateResponseSchema)` to create a new message.
+ */
+export const UpdateStatusReportUpdateResponseSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_status_report_v1_service, 13);
+
+/**
+ * DeleteStatusReportUpdateRequest is the request to remove a status report update.
+ *
+ * @generated from message openstatus.status_report.v1.DeleteStatusReportUpdateRequest
+ */
+export type DeleteStatusReportUpdateRequest = Message<"openstatus.status_report.v1.DeleteStatusReportUpdateRequest"> & {
+ /**
+ * ID of the update to remove (required).
+ *
+ * @generated from field: string id = 1;
+ */
+ id: string;
+};
+
+/**
+ * Describes the message openstatus.status_report.v1.DeleteStatusReportUpdateRequest.
+ * Use `create(DeleteStatusReportUpdateRequestSchema)` to create a new message.
+ */
+export const DeleteStatusReportUpdateRequestSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_status_report_v1_service, 14);
+
+/**
+ * DeleteStatusReportUpdateResponse is the response after removing a status report update.
+ *
+ * @generated from message openstatus.status_report.v1.DeleteStatusReportUpdateResponse
+ */
+export type DeleteStatusReportUpdateResponse = Message<"openstatus.status_report.v1.DeleteStatusReportUpdateResponse"> & {
+ /**
+ * Whether the deletion was successful.
+ *
+ * @generated from field: bool success = 1;
+ */
+ success: boolean;
+};
+
+/**
+ * Describes the message openstatus.status_report.v1.DeleteStatusReportUpdateResponse.
+ * Use `create(DeleteStatusReportUpdateResponseSchema)` to create a new message.
+ */
+export const DeleteStatusReportUpdateResponseSchema: GenMessage = /*@__PURE__*/
+ messageDesc(file_openstatus_status_report_v1_service, 15);
+
/**
* StatusReportService provides CRUD operations for status reports.
*
@@ -466,6 +586,26 @@ export const StatusReportService: GenService<{
input: typeof AddStatusReportUpdateRequestSchema;
output: typeof AddStatusReportUpdateResponseSchema;
},
+ /**
+ * UpdateStatusReportUpdate edits an existing timeline entry (status, message, date, component impacts).
+ *
+ * @generated from rpc openstatus.status_report.v1.StatusReportService.UpdateStatusReportUpdate
+ */
+ updateStatusReportUpdate: {
+ methodKind: "unary";
+ input: typeof UpdateStatusReportUpdateRequestSchema;
+ output: typeof UpdateStatusReportUpdateResponseSchema;
+ },
+ /**
+ * DeleteStatusReportUpdate removes a timeline entry. A report always keeps at least one update.
+ *
+ * @generated from rpc openstatus.status_report.v1.StatusReportService.DeleteStatusReportUpdate
+ */
+ deleteStatusReportUpdate: {
+ methodKind: "unary";
+ input: typeof DeleteStatusReportUpdateRequestSchema;
+ output: typeof DeleteStatusReportUpdateResponseSchema;
+ },
}> = /*@__PURE__*/
serviceDesc(file_openstatus_status_report_v1_service, 0);
diff --git a/packages/services/src/agent-tools/incident.ts b/packages/services/src/agent-tools/incident.ts
index 1f7c144b6..47ad2738e 100644
--- a/packages/services/src/agent-tools/incident.ts
+++ b/packages/services/src/agent-tools/incident.ts
@@ -54,7 +54,7 @@ export const listIncidentsTool: AgentTool<
> = {
name: "list_incidents",
description:
- "List managed incidents in this workspace (declared by the team, not monitor downtime), open ones first.",
+ "List managed incidents in this workspace (declared by the team, not monitor downtime), newest declared first. Filter by `status` to see only open ones.",
scope: "read",
destructive: false,
inputSchema: ListIncidentsInput,
diff --git a/packages/services/src/agent-tools/index.ts b/packages/services/src/agent-tools/index.ts
index 23ad177b6..90516666c 100644
--- a/packages/services/src/agent-tools/index.ts
+++ b/packages/services/src/agent-tools/index.ts
@@ -39,9 +39,12 @@ import { listPrivateLocationsTool } from "./private-location";
import {
addStatusReportUpdateTool,
createStatusReportTool,
+ deleteStatusReportUpdateTool,
+ getStatusReportTool,
listStatusReportsTool,
resolveStatusReportTool,
updateStatusReportTool,
+ updateStatusReportUpdateTool,
} from "./status-report";
import type { AnyAgentTool } from "./types";
@@ -82,9 +85,12 @@ export { listPrivateLocationsTool } from "./private-location";
export {
addStatusReportUpdateTool,
createStatusReportTool,
+ deleteStatusReportUpdateTool,
+ getStatusReportTool,
listStatusReportsTool,
resolveStatusReportTool,
updateStatusReportTool,
+ updateStatusReportUpdateTool,
} from "./status-report";
export type {
AgentTool,
@@ -116,10 +122,13 @@ export const agentTools = {
list_status_pages: listStatusPagesTool,
list_page_components: listPageComponentsTool,
list_status_reports: listStatusReportsTool,
+ get_status_report: getStatusReportTool,
create_status_report: createStatusReportTool,
add_status_report_update: addStatusReportUpdateTool,
update_status_report: updateStatusReportTool,
resolve_status_report: resolveStatusReportTool,
+ update_status_report_update: updateStatusReportUpdateTool,
+ delete_status_report_update: deleteStatusReportUpdateTool,
list_incidents: listIncidentsTool,
get_incident: getIncidentTool,
declare_incident: declareIncidentTool,
diff --git a/packages/services/src/agent-tools/prompt.ts b/packages/services/src/agent-tools/prompt.ts
index d321d594f..573c47025 100644
--- a/packages/services/src/agent-tools/prompt.ts
+++ b/packages/services/src/agent-tools/prompt.ts
@@ -32,7 +32,7 @@ export function buildAgentSystemPrompt(opts: AgentSystemPromptOptions): string {
? `\n\nAfter a tool returns, the dashboard already renders a structured view of the result:
- Write tools (create_*, update_*, resolve_*, add_*) render a diff card with every input/output field (id, status, message, dates, notify outcome).
- List tools (list_status_pages, list_page_components, list_status_reports, list_maintenances, list_monitors, list_notifications, list_response_logs, list_audit_logs, search_docs, search_content) render a table with one row per result.
-- Detail tools (get_monitor, get_monitor_status, get_monitor_summary, get_response_log, get_audit_log) render a structured detail card.
+- Detail tools (get_status_report, get_monitor, get_monitor_status, get_monitor_summary, get_response_log, get_audit_log) render a structured detail card.
DO NOT restate that data in your reply — no markdown tables, no bullet recaps of the rows, no field-by-field summaries. A one-line acknowledgement ("You have 4 status reports — 3 active." / "Monitor 12 is healthy in 5/7 regions; failing in gru, fra." / "Incident resolved.") plus an optional next step is enough.
Exception: after get_doc_page or get_content_page, DO synthesize an answer from the page content — the answer is the point; just don't paste the whole page.`
: "";
@@ -68,7 +68,7 @@ You help teams manage status pages, status reports, and maintenance windows, ans
Anti-guess rules — these are absolute:
- You have NO knowledge of this workspace's data. NEVER invent or guess IDs (page id, status report id, maintenance id, page component id, monitor id, notification id, response log id).
- Before referencing a status page: call list_status_pages.
-- Before referencing a status report: call list_status_reports.
+- Before referencing a status report: call list_status_reports. Its updates stop at the 10 most recent entries; call get_status_report for the full timeline before editing or deleting an older entry.
- Before referencing a maintenance window: call list_maintenances.
- Before referencing a page component (including by name like "the laser pointer"): call list_page_components({ pageId }).
- Before referencing a monitor (including by name like "the API monitor"): call list_monitors.
diff --git a/packages/services/src/agent-tools/status-report.ts b/packages/services/src/agent-tools/status-report.ts
index 59e396616..fd0c6d649 100644
--- a/packages/services/src/agent-tools/status-report.ts
+++ b/packages/services/src/agent-tools/status-report.ts
@@ -8,11 +8,13 @@ import { attributedUserSchema, toAgentUser } from "../attribution";
import type { ServiceContext } from "../context";
import {
addStatusReportUpdate,
+ deleteStatusReportUpdate,
getStatusReport,
listStatusReports,
notifyStatusReport,
resolveStatusReport,
updateStatusReport,
+ updateStatusReportUpdate,
} from "../status-report";
import { createStatusReport } from "../status-report/create";
import {
@@ -75,6 +77,9 @@ const ACTIVE_STATUSES = statusReportStatusSchema.options.filter(
(s) => s !== "resolved",
);
+// keeps list output bounded for long-running incidents
+const LIST_UPDATES_LIMIT = 10;
+
const ListStatusReportsInputShape = z.object({
filter: z
.enum(["active", "all"])
@@ -117,12 +122,21 @@ const ListStatusReportsOutput = z.object({
updatedBy: attributedUserSchema.nullable(),
latestUpdate: z
.object({
+ id: z.number().int(),
message: z.string(),
status: statusReportStatusSchema,
date: z.string().nullable(),
createdBy: attributedUserSchema.nullable(),
})
.nullable(),
+ updates: z.array(
+ z.object({
+ id: z.number().int(),
+ status: statusReportStatusSchema,
+ message: z.string(),
+ date: z.string().nullable(),
+ }),
+ ),
}),
),
pagination: z.object({
@@ -139,7 +153,7 @@ export const listStatusReportsTool: AgentTool<
> = {
name: "list_status_reports",
description:
- "List status reports in this workspace, newest first. Filter by status (e.g. exclude 'resolved' to see active incidents). Returns the most recent update per report so the current public message is visible without a follow-up call. Paginated via `page` (1-indexed) and `perPage`.",
+ "List status reports in this workspace, newest first. Filter by status (e.g. exclude 'resolved' to see active incidents). Returns each report's timeline newest-first under `updates`, capped at the 10 most recent entries (ids feed update_status_report_update / delete_status_report_update; call get_status_report for the full timeline), plus `latestUpdate` with its author. Paginated via `page` (1-indexed) and `perPage`.",
scope: "read",
destructive: false,
inputSchema: ListStatusReportsInputShape,
@@ -170,12 +184,19 @@ export const listStatusReportsTool: AgentTool<
updatedBy: toAgentUser(r.updatedByUser),
latestUpdate: latestUpdate
? {
+ id: latestUpdate.id,
message: latestUpdate.message,
status: latestUpdate.status,
date: latestUpdate.date?.toISOString() ?? null,
createdBy: toAgentUser(latestUpdate.createdByUser),
}
: null,
+ updates: r.updates.slice(0, LIST_UPDATES_LIMIT).map((u) => ({
+ id: u.id,
+ status: u.status,
+ message: u.message,
+ date: u.date?.toISOString() ?? null,
+ })),
};
}),
pagination: {
@@ -188,6 +209,70 @@ export const listStatusReportsTool: AgentTool<
},
};
+const GetStatusReportInput = z.object({
+ id: z
+ .number()
+ .int()
+ .describe("Status report id from list_status_reports — never guess."),
+});
+
+const GetStatusReportOutput = z.object({
+ id: z.number().int(),
+ title: z.string(),
+ status: statusReportStatusSchema,
+ pageId: z.number().int().nullable(),
+ pageComponentIds: z.array(z.number().int()),
+ createdAt: z.string().nullable(),
+ updatedAt: z.string().nullable(),
+ createdBy: attributedUserSchema.nullable(),
+ updatedBy: attributedUserSchema.nullable(),
+ updates: z.array(
+ z.object({
+ id: z.number().int(),
+ status: statusReportStatusSchema,
+ message: z.string(),
+ date: z.string().nullable(),
+ createdBy: attributedUserSchema.nullable(),
+ componentImpacts: componentImpactsSchema,
+ }),
+ ),
+});
+
+export const getStatusReportTool: AgentTool<
+ z.infer,
+ z.infer
+> = {
+ name: "get_status_report",
+ description:
+ "Get one status report with its FULL timeline newest-first under `updates` (no cap — list_status_reports stops at the 10 most recent). Use it to find the id of an older entry for update_status_report_update / delete_status_report_update.",
+ scope: "read",
+ destructive: false,
+ inputSchema: GetStatusReportInput,
+ outputSchema: GetStatusReportOutput,
+ async run({ ctx, input }) {
+ const r = await getStatusReport({ ctx, input: { id: input.id } });
+ return {
+ id: r.id,
+ title: r.title,
+ status: r.status,
+ pageId: r.pageId,
+ pageComponentIds: r.pageComponentIds,
+ createdAt: r.createdAt?.toISOString() ?? null,
+ updatedAt: r.updatedAt?.toISOString() ?? null,
+ createdBy: toAgentUser(r.createdByUser),
+ updatedBy: toAgentUser(r.updatedByUser),
+ updates: r.updates.map((u) => ({
+ id: u.id,
+ status: u.status,
+ message: u.message,
+ date: u.date?.toISOString() ?? null,
+ createdBy: toAgentUser(u.createdByUser),
+ componentImpacts: u.componentImpacts,
+ })),
+ };
+ },
+};
+
const CreateStatusReportInputShape = z.object({
title: z.string().min(1).max(256).describe("Short, public-facing title."),
status: statusReportStatusSchema.describe("Initial status for the report."),
@@ -643,3 +728,127 @@ export const resolveStatusReportTool: AgentTool<
};
},
};
+
+const UpdateStatusReportUpdateInputShape = z.object({
+ id: z
+ .number()
+ .int()
+ .describe(
+ "Status report update id from list_status_reports (`updates[].id`; `latestUpdate.id` is the newest) or a prior create/add result — never guess.",
+ ),
+ status: statusReportStatusSchema
+ .optional()
+ .describe(
+ "New status for this entry. 'resolved' is allowed: on the latest entry it resolves the report without notifying subscribers (use resolve_status_report to publish a new resolution update).",
+ ),
+ message: z.string().min(1).optional().describe("New public message."),
+ date: z.iso.datetime().optional().describe("New date for this entry."),
+ componentImpacts: componentImpactsSchema
+ .optional()
+ .describe(
+ "Replace this entry's full impact set (empty array clears it). Omit to leave impacts untouched. Component ids MUST come from list_page_components.",
+ ),
+});
+
+const UpdateStatusReportUpdateOutput = z.object({
+ id: z.number().int(),
+ statusReportId: z.number().int(),
+ status: statusReportStatusSchema,
+ message: z.string(),
+ date: z.string(),
+});
+
+export const updateStatusReportUpdateTool: AgentTool<
+ z.infer,
+ z.infer
+> = {
+ name: "update_status_report_update",
+ description:
+ "Edit an existing status report timeline entry (message, date, status, component impacts). PUBLIC and AUDIT-LOGGED. Does not notify subscribers. Editing the latest entry's status re-derives the report's status, including to 'resolved'. The update id MUST come from list_status_reports (`updates[].id`; `latestUpdate.id` is the newest) or a prior create/add result.",
+ scope: "write",
+ destructive: true,
+ inputSchema: UpdateStatusReportUpdateInputShape,
+ outputSchema: UpdateStatusReportUpdateOutput,
+ approval: {
+ summarize: (input) => ({
+ title: `Edit Status Report Update #${input.id}`,
+ lines: [
+ ...(input.status ? [{ label: "Status", value: input.status }] : []),
+ ...(input.date ? [{ label: "Date", value: input.date }] : []),
+ ...(input.componentImpacts
+ ? [
+ {
+ label: "Impacts",
+ value: input.componentImpacts.length
+ ? formatComponentImpacts(input.componentImpacts).join(", ")
+ : "cleared",
+ ref: {
+ kind: "componentImpacts" as const,
+ impacts: input.componentImpacts,
+ },
+ },
+ ]
+ : []),
+ ...(input.message ? [{ label: "Message", value: input.message }] : []),
+ ],
+ }),
+ verb: "updated",
+ },
+ async run({ ctx, input }) {
+ const update = await updateStatusReportUpdate({
+ ctx,
+ input: {
+ id: input.id,
+ status: input.status,
+ message: input.message,
+ date: input.date ? new Date(input.date) : undefined,
+ componentImpacts: input.componentImpacts,
+ },
+ });
+ return {
+ id: update.id,
+ statusReportId: update.statusReportId,
+ status: update.status,
+ message: update.message,
+ date: update.date.toISOString(),
+ };
+ },
+};
+
+const DeleteStatusReportUpdateInputShape = z.object({
+ id: z
+ .number()
+ .int()
+ .describe(
+ "Status report update id from list_status_reports (`updates[].id`; `latestUpdate.id` is the newest) or a prior create/add result — never guess.",
+ ),
+});
+
+const DeleteStatusReportUpdateOutput = z.object({
+ id: z.number().int(),
+ success: z.boolean(),
+});
+
+export const deleteStatusReportUpdateTool: AgentTool<
+ z.infer,
+ z.infer
+> = {
+ name: "delete_status_report_update",
+ description:
+ "Delete a status report timeline entry. PUBLIC, AUDIT-LOGGED, AND IRREVERSIBLE. The report's status is re-derived from the remaining entries. A report must retain at least one update — to remove the only entry, delete the report from the dashboard instead. The update id MUST come from list_status_reports (`updates[].id`; `latestUpdate.id` is the newest) or a prior create/add result.",
+ scope: "write",
+ destructive: true,
+ inputSchema: DeleteStatusReportUpdateInputShape,
+ outputSchema: DeleteStatusReportUpdateOutput,
+ approval: {
+ summarize: (input) => ({
+ title: `Delete Status Report Update #${input.id}`,
+ lines: [{ label: "Update ID", value: String(input.id) }],
+ }),
+ verb: "deleted",
+ },
+ async run({ ctx, input }) {
+ await deleteStatusReportUpdate({ ctx, input });
+ return { id: input.id, success: true };
+ },
+};
diff --git a/packages/services/src/incident/__tests__/incident.test.ts b/packages/services/src/incident/__tests__/incident.test.ts
index 6b2384d7f..5c12bf797 100644
--- a/packages/services/src/incident/__tests__/incident.test.ts
+++ b/packages/services/src/incident/__tests__/incident.test.ts
@@ -739,21 +739,23 @@ describe("deleteIncident", () => {
});
describe("reads", () => {
- test("list puts open incidents first and filters by status", async () => {
+ test("list orders newest declared first and filters by status", async () => {
await withTestTransaction(async (tx) => {
- const resolved = await createIncident(
+ const older = await createIncident(
workspace.id,
- { status: "resolved", declaredAt: new Date() },
+ { status: "open", declaredAt: new Date(Date.now() - 86_400_000) },
tx,
);
- const open = await createIncident(
+ const newer = await createIncident(
workspace.id,
- { status: "open", declaredAt: new Date(Date.now() - 86_400_000) },
+ { status: "resolved", declaredAt: new Date() },
tx,
);
const ctx = as(memberId, tx);
const ids = (await listIncidents({ ctx })).map((i) => i.id);
- expect(ids.indexOf(open.id)).toBeLessThan(ids.indexOf(resolved.id));
+ expect(ids).toContain(newer.id);
+ expect(ids).toContain(older.id);
+ expect(ids.indexOf(newer.id)).toBeLessThan(ids.indexOf(older.id));
const onlyResolved = await listIncidents({
ctx,
input: { status: ["resolved"] },
diff --git a/packages/services/src/incident/list.ts b/packages/services/src/incident/list.ts
index b24542c0b..2730f93f4 100644
--- a/packages/services/src/incident/list.ts
+++ b/packages/services/src/incident/list.ts
@@ -1,4 +1,4 @@
-import { and, desc, eq, inArray, isNotNull, sql } from "@openstatus/db";
+import { and, desc, eq, inArray, isNotNull } from "@openstatus/db";
import { incident } from "@openstatus/db/src/schema";
import { type ServiceContext, getReadDb } from "../context";
@@ -14,9 +14,7 @@ const userColumns = {
deletedAt: true,
} as const;
-const statusOrder = sql`case ${incident.status} when 'open' then 0 when 'mitigated' then 1 when 'resolved' then 2 else 3 end`;
-
-/** Open incidents first, then newest declared. */
+/** Newest declared first. */
export async function listIncidents(args: {
ctx: ServiceContext;
input?: ListIncidentsInput;
@@ -30,7 +28,7 @@ export async function listIncidents(args: {
);
return getReadDb(ctx).query.incident.findMany({
where,
- orderBy: [statusOrder, desc(incident.declaredAt), desc(incident.id)],
+ orderBy: [desc(incident.declaredAt), desc(incident.id)],
limit: input.limit,
offset: input.offset,
with: {
diff --git a/packages/services/src/status-report/__tests__/status-report.test.ts b/packages/services/src/status-report/__tests__/status-report.test.ts
index 2708634e2..7d0179e68 100644
--- a/packages/services/src/status-report/__tests__/status-report.test.ts
+++ b/packages/services/src/status-report/__tests__/status-report.test.ts
@@ -484,6 +484,35 @@ describe("deleteStatusReportUpdate", () => {
expect(remaining).toHaveLength(0);
});
});
+
+ test("the last update cannot be removed", async () => {
+ await withTestTransaction(async (tx) => {
+ const ctx = { ...teamCtx, db: tx };
+ const { statusReport: report, initialUpdate: first } =
+ await createStatusReport({
+ ctx,
+ input: {
+ title: `${TEST_PREFIX}-delete-last-update`,
+ status: "investigating",
+ message: "only one",
+ date: new Date(),
+ pageId: testPageId,
+ pageComponentIds: [],
+ },
+ });
+
+ await expect(
+ deleteStatusReportUpdate({ ctx, input: { id: first.id } }),
+ ).rejects.toBeInstanceOf(ConflictError);
+
+ const remaining = await tx
+ .select()
+ .from(statusReportUpdate)
+ .where(eq(statusReportUpdate.statusReportId, report.id))
+ .all();
+ expect(remaining).toHaveLength(1);
+ });
+ });
});
describe("updateStatusReportUpdate", () => {
diff --git a/packages/services/src/status-report/delete.ts b/packages/services/src/status-report/delete.ts
index ed0bc2be9..f2c91e59a 100644
--- a/packages/services/src/status-report/delete.ts
+++ b/packages/services/src/status-report/delete.ts
@@ -1,4 +1,4 @@
-import { eq } from "@openstatus/db";
+import { eq, sql } from "@openstatus/db";
import { statusReport, statusReportUpdate } from "@openstatus/db/src/schema";
import { emitAudit } from "../audit";
@@ -8,6 +8,7 @@ import {
tryGetActorUserId,
withTransaction,
} from "../context";
+import { ConflictError } from "../errors";
import { unlinkIncidentFromStatusReport } from "../incident/link-status-report";
import { recomputeReportStatus } from "./derive-status";
import { getReportInWorkspace, getReportUpdateInWorkspace } from "./internal";
@@ -67,6 +68,18 @@ export async function deleteStatusReportUpdate(args: {
workspaceId: ctx.workspace.id,
});
+ // the report's status and message are derived from its updates
+ const remaining = await tx
+ .select({ count: sql`count(*)` })
+ .from(statusReportUpdate)
+ .where(eq(statusReportUpdate.statusReportId, existing.statusReportId))
+ .get();
+ if ((remaining?.count ?? 0) <= 1) {
+ throw new ConflictError(
+ "A status report needs at least one update. Delete the report instead.",
+ );
+ }
+
await tx
.delete(statusReportUpdate)
.where(eq(statusReportUpdate.id, existing.id));
diff --git a/packages/ui/src/components/ui/toggle.tsx b/packages/ui/src/components/ui/toggle.tsx
new file mode 100644
index 000000000..6c7d26d25
--- /dev/null
+++ b/packages/ui/src/components/ui/toggle.tsx
@@ -0,0 +1,48 @@
+"use client";
+
+import { cn } from "@openstatus/ui/lib/utils";
+import * as TogglePrimitive from "@radix-ui/react-toggle";
+import { type VariantProps, cva } from "class-variance-authority";
+import type * as React from "react";
+
+const toggleVariants = cva(
+ "hover:bg-muted hover:text-muted-foreground aria-pressed:bg-accent aria-pressed:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ {
+ variants: {
+ variant: {
+ default: "bg-transparent",
+ outline:
+ "border-input hover:bg-accent hover:text-accent-foreground border bg-transparent shadow-xs",
+ },
+ size: {
+ default: "h-9 min-w-9 px-2",
+ sm: "h-8 min-w-8 px-1.5",
+ lg: "h-10 min-w-10 px-2.5",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ },
+);
+
+// Styled via aria-pressed rather than data-state: a Tooltip/Popover trigger
+// with asChild overwrites data-state with its own open/closed value.
+function Toggle({
+ className,
+ variant,
+ size,
+ ...props
+}: React.ComponentProps &
+ VariantProps) {
+ return (
+
+ );
+}
+
+export { Toggle, toggleVariants };
--
2.51.2