diff --git a/.gitignore b/.gitignore index 8a4ff3b..194ee84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /dist/ /bin/ +.worktrees/ *.out .DS_Store diff --git a/applications.go b/applications.go index 365bd6f..bf1ca8d 100644 --- a/applications.go +++ b/applications.go @@ -49,6 +49,20 @@ func (s *ApplicationsService) ReadList(ctx context.Context, req *RUMApplicationL return out, resp, nil } +// Test application webhook. +// +// Send a sample RUM alert event to verify an application's webhook URL. +// +// API: POST /rum/application/webhook/test (rum-application-webhook-test). +func (s *ApplicationsService) WebhookTest(ctx context.Context, req *RUMWebhookTestRequest) (*RUMWebhookTestResponse, *Response, error) { + out := new(RUMWebhookTestResponse) + resp, err := s.client.do(ctx, "/rum/application/webhook/test", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + // Create application. // // Create a new RUM application. Returns the generated `application_id` and `client_token`. diff --git a/incidents.go b/incidents.go index 5b03b73..0e62390 100644 --- a/incidents.go +++ b/incidents.go @@ -360,3 +360,104 @@ func (s *IncidentsService) WarRoomList(ctx context.Context, req *ListWarRoomsReq } return out, resp, nil } + +// List post-mortem templates. +// +// Return built-in and custom post-mortem templates for the account. +// +// API: POST /incident/post-mortem/template/list (postmortem-read-list-templates). +func (s *IncidentsService) PostmortemReadListTemplates(ctx context.Context, req *ListPostMortemTemplatesRequest) (*ListPostMortemTemplatesResponse, *Response, error) { + out := new(ListPostMortemTemplatesResponse) + resp, err := s.client.do(ctx, "/incident/post-mortem/template/list", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + +// Get post-mortem template detail. +// +// Return one post-mortem template by ID. +// +// API: GET /incident/post-mortem/template/info (postmortem-read-template-info). +func (s *IncidentsService) PostmortemReadTemplateInfo(ctx context.Context, req *IncidentsPostmortemReadTemplateInfoRequest) (*PostMortemTemplate, *Response, error) { + out := new(PostMortemTemplate) + resp, err := s.client.doGet(ctx, "/incident/post-mortem/template/info", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + +// Delete post-mortem template. +// +// Delete a custom post-mortem template. +// +// API: POST /incident/post-mortem/template/delete (postmortem-write-delete-template). +func (s *IncidentsService) PostmortemWriteDeleteTemplate(ctx context.Context, req *DeletePostMortemTemplateRequest) (*Response, error) { + return s.client.do(ctx, "/incident/post-mortem/template/delete", req, nil) +} + +// Initialize post-mortem. +// +// Create a post-mortem draft from one or more incidents and a template. +// +// API: POST /incident/post-mortem/init (postmortem-write-init). +func (s *IncidentsService) PostmortemWriteInit(ctx context.Context, req *InitPostMortemRequest) (*PostMortemItem, *Response, error) { + out := new(PostMortemItem) + resp, err := s.client.do(ctx, "/incident/post-mortem/init", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + +// Update post-mortem basics. +// +// Replace the incident facts stored in a post-mortem report. +// +// API: POST /incident/post-mortem/basics/reset (postmortem-write-reset-basics). +func (s *IncidentsService) PostmortemWriteResetBasics(ctx context.Context, req *ResetPostMortemBasicsRequest) (*Response, error) { + return s.client.do(ctx, "/incident/post-mortem/basics/reset", req, nil) +} + +// Update post-mortem follow-ups. +// +// Replace the follow-up action items on a post-mortem report. +// +// API: POST /incident/post-mortem/follow-ups/reset (postmortem-write-reset-follow-ups). +func (s *IncidentsService) PostmortemWriteResetFollowUps(ctx context.Context, req *ResetPostMortemFollowUpsRequest) (*Response, error) { + return s.client.do(ctx, "/incident/post-mortem/follow-ups/reset", req, nil) +} + +// Update post-mortem status. +// +// Set a post-mortem report to drafting or published. +// +// API: POST /incident/post-mortem/status/reset (postmortem-write-reset-status). +func (s *IncidentsService) PostmortemWriteResetStatus(ctx context.Context, req *ResetPostMortemStatusRequest) (*Response, error) { + return s.client.do(ctx, "/incident/post-mortem/status/reset", req, nil) +} + +// Update post-mortem title. +// +// Replace the title of a post-mortem report. +// +// API: POST /incident/post-mortem/title/reset (postmortem-write-reset-title). +func (s *IncidentsService) PostmortemWriteResetTitle(ctx context.Context, req *ResetPostMortemTitleRequest) (*Response, error) { + return s.client.do(ctx, "/incident/post-mortem/title/reset", req, nil) +} + +// Create or update post-mortem template. +// +// Create a custom post-mortem template or update an existing one. +// +// API: POST /incident/post-mortem/template/upsert (postmortem-write-upsert-template). +func (s *IncidentsService) PostmortemWriteUpsertTemplate(ctx context.Context, req *UpsertPostMortemTemplateRequest) (*PostMortemTemplate, *Response, error) { + out := new(PostMortemTemplate) + resp, err := s.client.do(ctx, "/incident/post-mortem/template/upsert", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} diff --git a/integrations.go b/integrations.go index 4025adb..c719853 100644 --- a/integrations.go +++ b/integrations.go @@ -7,6 +7,20 @@ import "context" // IntegrationsService handles the "On-call/Integrations" API resource. type IntegrationsService service +// Attempt IM person linking. +// +// Try to automatically link unbound members to their IM accounts for one integration. +// +// API: POST /datasource/im/person/try-link (datasourceImPersonTryLink). +func (s *IntegrationsService) DatasourceImPersonTryLink(ctx context.Context, req *TryLinkPersonRequest) (*TryLinkPersonResponse, *Response, error) { + out := new(TryLinkPersonResponse) + resp, err := s.client.do(ctx, "/datasource/im/person/try-link", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + // Get webhook delivery detail. // // Retrieve the detailed payload and response for a specific webhook delivery attempt. diff --git a/internal/cmd/gen/main.go b/internal/cmd/gen/main.go index 5abd873..4f77526 100644 --- a/internal/cmd/gen/main.go +++ b/internal/cmd/gen/main.go @@ -190,7 +190,7 @@ func (g *Gen) collectServices(paths map[string]any) []service { for _, e := range entries { opIDs = append(opIDs, str(e.op, "operationId")) } - names := methodNames(opIDs) + names := methodNames(tag, opIDs) svc := service{Name: serviceName(tag), Tag: tag} for _, e := range entries { diff --git a/internal/cmd/gen/naming.go b/internal/cmd/gen/naming.go index 0235bfe..532da3a 100644 --- a/internal/cmd/gen/naming.go +++ b/internal/cmd/gen/naming.go @@ -120,9 +120,14 @@ func commonPrefixLen(opTokens [][]string) int { } } +var methodPrefixByTag = map[string][]string{ + "On-call/Incidents": {"incident"}, + "On-call/Integrations": {"webhook", "history"}, +} + // methodNames computes a unique Go method name for each operationId within a -// service by stripping the shared leading resource tokens, then deduping. -func methodNames(opIDs []string) map[string]string { +// service by stripping stable service-specific leading tokens, then deduping. +func methodNames(tag string, opIDs []string) map[string]string { opTokens := make([][]string, len(opIDs)) for i, id := range opIDs { opTokens[i] = tokens(id) @@ -133,6 +138,9 @@ func methodNames(opIDs []string) map[string]string { used := make(map[string]int) for i, id := range opIDs { toks := opTokens[i][n:] + if prefix, ok := methodPrefixByTag[tag]; ok && hasTokenPrefix(opTokens[i], prefix) { + toks = opTokens[i][len(prefix):] + } if len(toks) == 0 { toks = opTokens[i] } @@ -155,6 +163,18 @@ func methodNames(opIDs []string) map[string]string { return result } +func hasTokenPrefix(toks, prefix []string) bool { + if len(toks) <= len(prefix) { + return false + } + for i, p := range prefix { + if strings.ToLower(toks[i]) != p { + return false + } + } + return true +} + func itoa(n int) string { if n == 0 { return "0" diff --git a/models_gen.go b/models_gen.go index 85ba36e..3bc2ff8 100644 --- a/models_gen.go +++ b/models_gen.go @@ -1916,6 +1916,12 @@ type DeletePostMortemRequest struct { PostMortemID string `json:"post_mortem_id,omitempty" toon:"post_mortem_id,omitempty"` } +// DeletePostMortemTemplateRequest is generated from the Flashduty OpenAPI schema. +type DeletePostMortemTemplateRequest struct { + // Template ID. + TemplateID string `json:"template_id,omitempty" toon:"template_id,omitempty"` +} + // DeleteStatusPageChangeRequest is generated from the Flashduty OpenAPI schema. type DeleteStatusPageChangeRequest struct { // Target event ID. @@ -1934,6 +1940,32 @@ type DeleteStatusPageChangeTimelineRequest struct { UpdateID string `json:"update_id,omitempty" toon:"update_id,omitempty"` } +// DeleteStatusPageComponentRequest is generated from the Flashduty OpenAPI schema. +type DeleteStatusPageComponentRequest struct { + // IDs of components to delete. + ComponentIDs []string `json:"component_ids,omitempty" toon:"component_ids,omitempty"` + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` +} + +// DeleteStatusPageSectionRequest is generated from the Flashduty OpenAPI schema. +type DeleteStatusPageSectionRequest struct { + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` + // IDs of sections to delete. + SectionIDs []string `json:"section_ids,omitempty" toon:"section_ids,omitempty"` +} + +// DeleteStatusPageTemplateRequest is generated from the Flashduty OpenAPI schema. +type DeleteStatusPageTemplateRequest struct { + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` + // Template ID to delete. + TemplateID string `json:"template_id,omitempty" toon:"template_id,omitempty"` + // Template category. + Type string `json:"type,omitempty" toon:"type,omitempty"` +} + // DeleteWarRoomRequest is generated from the Flashduty OpenAPI schema. type DeleteWarRoomRequest struct { // Incident ID (MongoDB ObjectID). @@ -2951,6 +2983,14 @@ type InhibitRuleItem struct { UpdatedBy int64 `json:"updated_by" toon:"updated_by"` } +// InitPostMortemRequest is generated from the Flashduty OpenAPI schema. +type InitPostMortemRequest struct { + // Incident IDs to link to the report. 1-10 incidents. + IncidentIDs []string `json:"incident_ids,omitempty" toon:"incident_ids,omitempty"` + // Template ID used to initialize the report. + TemplateID string `json:"template_id,omitempty" toon:"template_id,omitempty"` +} + // InsightAlertByLabelItem is generated from the Flashduty OpenAPI schema. type InsightAlertByLabelItem struct { // Hour bucket when `split_hours` is enabled. @@ -3376,6 +3416,27 @@ type ListPastIncidentsResponse struct { Items []PastIncidentItem `json:"items" toon:"items"` } +// ListPostMortemTemplatesRequest is generated from the Flashduty OpenAPI schema. +type ListPostMortemTemplatesRequest struct { + ListOptions + // Ascending order when true. + Asc bool `json:"asc,omitempty" toon:"asc,omitempty"` + // Field used to order results. + OrderBy string `json:"order_by,omitempty" toon:"order_by,omitempty"` +} + +// ListPostMortemTemplatesResponse is generated from the Flashduty OpenAPI schema. +type ListPostMortemTemplatesResponse struct { + // True when another page is available. + HasNextPage bool `json:"has_next_page" toon:"has_next_page"` + // Templates in the current page. + Items []PostMortemTemplate `json:"items" toon:"items"` + // Cursor for forward pagination. + SearchAfterCtx string `json:"search_after_ctx" toon:"search_after_ctx"` + // Total matching templates. + Total int64 `json:"total" toon:"total"` +} + // ListPostMortemsRequest is generated from the Flashduty OpenAPI schema. type ListPostMortemsRequest struct { ListOptions @@ -4442,6 +4503,45 @@ type PostMortemMeta struct { UpdatedAtSeconds Timestamp `json:"updated_at_seconds" toon:"updated_at_seconds"` } +// PostMortemTemplate is generated from the Flashduty OpenAPI schema. +type PostMortemTemplate struct { + // Account ID that owns the template. 0 for built-in templates. + AccountID int64 `json:"account_id" toon:"account_id"` + // BlockNote JSON content used to initialize the report body. + Content string `json:"content" toon:"content"` + // Markdown version of the template content, used by AI generation. + ContentMarkdown string `json:"content_markdown" toon:"content_markdown"` + // Unix timestamp in seconds when the template was created. + CreatedAtSeconds Timestamp `json:"created_at_seconds" toon:"created_at_seconds"` + // Template description. + Description string `json:"description" toon:"description"` + // Template name shown in the console. + Name string `json:"name" toon:"name"` + // Managing team ID. Built-in templates use 0. + TeamID int64 `json:"team_id" toon:"team_id"` + // Template ID. Built-in templates use a stable `post_mortem_default_tmpl_*` ID. + TemplateID string `json:"template_id" toon:"template_id"` + // Unix timestamp in seconds when the template was last updated. + UpdatedAtSeconds Timestamp `json:"updated_at_seconds" toon:"updated_at_seconds"` +} + +// PreviewSyncRequest is generated from the Flashduty OpenAPI schema. +type PreviewSyncRequest struct { + // Additional type-specific query arguments. + Args map[string]string `json:"args,omitempty" toon:"args,omitempty"` + // Shift the query window backward by this many seconds to compensate for data ingestion latency. + DelaySeconds int64 `json:"delay_seconds,omitempty" toon:"delay_seconds,omitempty"` + // Datasource display name as configured in the account. + DsName string `json:"ds_name,omitempty" toon:"ds_name,omitempty"` + // Datasource type, e.g. `prometheus`, `loki`, `elasticsearch`. + DsType string `json:"ds_type,omitempty" toon:"ds_type,omitempty"` + // Query expression. Format depends on `ds_type` (PromQL for Prometheus, LogQL for Loki, etc.). + Expr string `json:"expr,omitempty" toon:"expr,omitempty"` +} + +// PreviewSyncResponse is generated from the Flashduty OpenAPI schema. +type PreviewSyncResponse struct{} + // PreviewTemplateRequest is generated from the Flashduty OpenAPI schema. type PreviewTemplateRequest struct { // Template content to render. @@ -4510,6 +4610,46 @@ type ResetIncidentFieldRequest struct { IncidentID string `json:"incident_id,omitempty" toon:"incident_id,omitempty"` } +// ResetPostMortemBasicsRequest is generated from the Flashduty OpenAPI schema. +type ResetPostMortemBasicsRequest struct { + // Unix timestamp in seconds for the earliest linked incident start time. + IncidentsEarliestStartSeconds int64 `json:"incidents_earliest_start_seconds,omitempty" toon:"incidents_earliest_start_seconds,omitempty"` + // Highest severity among linked incidents. + IncidentsHighestSeverity string `json:"incidents_highest_severity,omitempty" toon:"incidents_highest_severity,omitempty"` + // Unix timestamp in seconds for the latest linked incident close time. 0 when still open. + IncidentsLatestCloseSeconds int64 `json:"incidents_latest_close_seconds,omitempty" toon:"incidents_latest_close_seconds,omitempty"` + // Total incident duration in seconds. + IncidentsTotalDurationSeconds int64 `json:"incidents_total_duration_seconds,omitempty" toon:"incidents_total_duration_seconds,omitempty"` + // Post-mortem ID. + PostMortemID string `json:"post_mortem_id,omitempty" toon:"post_mortem_id,omitempty"` + // Responder member IDs to store on the report. + ResponderIDs []int64 `json:"responder_ids,omitempty" toon:"responder_ids,omitempty"` +} + +// ResetPostMortemFollowUpsRequest is generated from the Flashduty OpenAPI schema. +type ResetPostMortemFollowUpsRequest struct { + // Follow-up action items as free text. + FollowUps string `json:"follow_ups,omitempty" toon:"follow_ups,omitempty"` + // Post-mortem ID. + PostMortemID string `json:"post_mortem_id,omitempty" toon:"post_mortem_id,omitempty"` +} + +// ResetPostMortemStatusRequest is generated from the Flashduty OpenAPI schema. +type ResetPostMortemStatusRequest struct { + // Post-mortem ID. + PostMortemID string `json:"post_mortem_id,omitempty" toon:"post_mortem_id,omitempty"` + // Target report status. + Status string `json:"status,omitempty" toon:"status,omitempty"` +} + +// ResetPostMortemTitleRequest is generated from the Flashduty OpenAPI schema. +type ResetPostMortemTitleRequest struct { + // Post-mortem ID. + PostMortemID string `json:"post_mortem_id,omitempty" toon:"post_mortem_id,omitempty"` + // New report title. + Title string `json:"title,omitempty" toon:"title,omitempty"` +} + // ResolveIncidentRequest is generated from the Flashduty OpenAPI schema. type ResolveIncidentRequest struct { // Incident IDs to resolve. At most 100 per call. @@ -5031,6 +5171,24 @@ type RUMIssueUpdateRequest struct { SuspectedCause string `json:"suspected_cause,omitempty" toon:"suspected_cause,omitempty"` } +// RUMWebhookTestRequest is generated from the Flashduty OpenAPI schema. +type RUMWebhookTestRequest struct { + // RUM application ID. + ApplicationID string `json:"application_id,omitempty" toon:"application_id,omitempty"` + // Webhook URL to receive the sample alert event. + WebhookURL string `json:"webhook_url,omitempty" toon:"webhook_url,omitempty"` +} + +// RUMWebhookTestResponse is generated from the Flashduty OpenAPI schema. +type RUMWebhookTestResponse struct { + // `ok` on success, otherwise the delivery error message. + Message string `json:"message" toon:"message"` + // Whether the webhook endpoint accepted the sample event. + OK bool `json:"ok" toon:"ok"` + // HTTP status code returned by the webhook endpoint. 0 when the request did not receive a response. + StatusCode int64 `json:"status_code" toon:"status_code"` +} + // SLSLogstoresRequest is generated from the Flashduty OpenAPI schema. type SLSLogstoresRequest struct { // SLS datasource ID. @@ -6355,6 +6513,18 @@ type ToolInvokeResponse struct { Target ToolInvokeResponseTarget `json:"target" toon:"target"` } +// TryLinkPersonRequest is generated from the Flashduty OpenAPI schema. +type TryLinkPersonRequest struct { + // IM integration ID. + IntegrationID int64 `json:"integration_id,omitempty" toon:"integration_id,omitempty"` +} + +// TryLinkPersonResponse is generated from the Flashduty OpenAPI schema. +type TryLinkPersonResponse struct { + // Person IDs newly linked during this call. + NewLinkedPersonIDs []int64 `json:"new_linked_person_ids" toon:"new_linked_person_ids"` +} + // UnackIncidentRequest is generated from the Flashduty OpenAPI schema. type UnackIncidentRequest struct { // Incident IDs to unacknowledge. At most 100 per call. @@ -6551,6 +6721,22 @@ type UpdateStatusPageChangeTimelineRequest struct { UpdateID string `json:"update_id,omitempty" toon:"update_id,omitempty"` } +// UpsertPostMortemTemplateRequest is generated from the Flashduty OpenAPI schema. +type UpsertPostMortemTemplateRequest struct { + // BlockNote JSON template content. + Content string `json:"content,omitempty" toon:"content,omitempty"` + // Markdown version of the template content. + ContentMarkdown string `json:"content_markdown,omitempty" toon:"content_markdown,omitempty"` + // Template description. + Description string `json:"description,omitempty" toon:"description,omitempty"` + // Template name. + Name string `json:"name,omitempty" toon:"name,omitempty"` + // Managing team ID. Required when creating a custom template. + TeamID int64 `json:"team_id,omitempty" toon:"team_id,omitempty"` + // Template ID. Omit to create a new template; provide it to update an existing template. + TemplateID string `json:"template_id,omitempty" toon:"template_id,omitempty"` +} + // UpsertRouteRequest is generated from the Flashduty OpenAPI schema. type UpsertRouteRequest struct { // Ordered list of case branches. Cases are evaluated top to bottom. @@ -6564,6 +6750,50 @@ type UpsertRouteRequest struct { Version int64 `json:"version,omitempty" toon:"version,omitempty"` } +// UpsertStatusPageComponentRequest is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageComponentRequest struct { + // Components to create or update. + Components []UpsertStatusPageComponentRequestComponentsItem `json:"components,omitempty" toon:"components,omitempty"` + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` +} + +// UpsertStatusPageComponentResponse is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageComponentResponse struct { + // IDs of the created or updated components, in the same order as the request. + ComponentIDs []string `json:"component_ids" toon:"component_ids"` +} + +// UpsertStatusPageSectionRequest is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageSectionRequest struct { + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` + // Sections to create or update. + Sections []UpsertStatusPageSectionRequestSectionsItem `json:"sections,omitempty" toon:"sections,omitempty"` +} + +// UpsertStatusPageSectionResponse is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageSectionResponse struct { + // IDs of the created or updated sections, in the same order as the request. + SectionIDs []string `json:"section_ids" toon:"section_ids"` +} + +// UpsertStatusPageTemplateRequest is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageTemplateRequest struct { + // Status page ID. + PageID int64 `json:"page_id,omitempty" toon:"page_id,omitempty"` + // Template content. + Template UpsertStatusPageTemplateRequestTemplate `json:"template,omitempty" toon:"template,omitempty"` + // Template category. `pre_defined` for predefined event templates; `message` for notification message templates. + Type string `json:"type,omitempty" toon:"type,omitempty"` +} + +// UpsertStatusPageTemplateResponse is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageTemplateResponse struct { + // ID of the created or updated template. + TemplateID string `json:"template_id" toon:"template_id"` +} + // WakeIncidentRequest is generated from the Flashduty OpenAPI schema. type WakeIncidentRequest struct { // Incident IDs to wake. At most 100 per call. @@ -7283,6 +7513,54 @@ type ToolInvokeResponseTarget struct { Locator string `json:"locator" toon:"locator"` } +// UpsertStatusPageComponentRequestComponentsItem is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageComponentRequestComponentsItem struct { + // Component ID. Omit to create a new component; supply to update an existing one. + ComponentID string `json:"component_id,omitempty" toon:"component_id,omitempty"` + // Component description. + Description string `json:"description,omitempty" toon:"description,omitempty"` + // When true, the component is hidden entirely from summary endpoints. + HideAll bool `json:"hide_all,omitempty" toon:"hide_all,omitempty"` + // When true, uptime data is hidden from summary responses. + HideUptime bool `json:"hide_uptime,omitempty" toon:"hide_uptime,omitempty"` + // Component display name. + Name string `json:"name,omitempty" toon:"name,omitempty"` + // Display order within its section. + OrderID int64 `json:"order_id,omitempty" toon:"order_id,omitempty"` + // Parent section ID. Omit to place the component at the top level. + SectionID string `json:"section_id,omitempty" toon:"section_id,omitempty"` +} + +// UpsertStatusPageSectionRequestSectionsItem is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageSectionRequestSectionsItem struct { + // Section description. + Description string `json:"description,omitempty" toon:"description,omitempty"` + // When true, the entire section is hidden from summary endpoints. + HideAll bool `json:"hide_all,omitempty" toon:"hide_all,omitempty"` + // When true, uptime data for all components in this section is hidden. + HideUptime bool `json:"hide_uptime,omitempty" toon:"hide_uptime,omitempty"` + // Section display name. + Name string `json:"name,omitempty" toon:"name,omitempty"` + // Display order. + OrderID int64 `json:"order_id,omitempty" toon:"order_id,omitempty"` + // Section ID. Omit to create a new section; supply to update an existing one. + SectionID string `json:"section_id,omitempty" toon:"section_id,omitempty"` +} + +// UpsertStatusPageTemplateRequestTemplate is generated from the Flashduty OpenAPI schema. +type UpsertStatusPageTemplateRequestTemplate struct { + // Template body text (Markdown). + Description string `json:"description,omitempty" toon:"description,omitempty"` + // Event type this template applies to. + EventType string `json:"event_type,omitempty" toon:"event_type,omitempty"` + // Event status this template represents. + Status string `json:"status,omitempty" toon:"status,omitempty"` + // Template ID. Omit to create; supply to update. + TemplateID string `json:"template_id,omitempty" toon:"template_id,omitempty"` + // Template title. + Title string `json:"title,omitempty" toon:"title,omitempty"` +} + // ChannelsChannelEscalateWebhookRobotListResponseListItemReferencedByItem is generated from the Flashduty OpenAPI schema. type ChannelsChannelEscalateWebhookRobotListResponseListItemReferencedByItem struct { // Channel ID. @@ -7425,6 +7703,12 @@ type IncidentsPostMortemInfoRequest struct { PostMortemID string `url:"post_mortem_id"` } +// IncidentsPostmortemReadTemplateInfoRequest holds the query parameters for Get post-mortem template detail. +type IncidentsPostmortemReadTemplateInfoRequest struct { + // Template ID. + TemplateID string `url:"template_id"` +} + // StatusPagesChangeActiveListRequest holds the query parameters for List active status page events. type StatusPagesChangeActiveListRequest struct { // Status page ID. @@ -7455,6 +7739,12 @@ type StatusPagesChangeListRequest struct { Status string `url:"status"` } +// StatusPagesInfoRequest holds the query parameters for Get status page detail. +type StatusPagesInfoRequest struct { + // Status page ID + PageID string `url:"page_id"` +} + // StatusPagesMigrationStatusRequest holds the query parameters for Get migration status. type StatusPagesMigrationStatusRequest struct { // Migration job ID returned by `migrate-structure` or `migrate-email-subscribers`. @@ -7472,3 +7762,11 @@ type StatusPagesSubscriberListRequest struct { // Page size (1-100). Limit int64 `url:"limit,omitempty"` } + +// StatusPagesTemplateListRequest holds the query parameters for List status page templates. +type StatusPagesTemplateListRequest struct { + // Status page ID. + PageID int64 `url:"page_id"` + // Template category. `pre_defined` returns predefined event templates; `message` returns message notification templates. + Type string `url:"type"` +} diff --git a/monitor_utilities.go b/monitor_utilities.go new file mode 100644 index 0000000..457d61c --- /dev/null +++ b/monitor_utilities.go @@ -0,0 +1,17 @@ +// Code generated by internal/cmd/gen; DO NOT EDIT. + +package flashduty + +import "context" + +// MonitorUtilitiesService handles the "Monitors/Monitor utilities" API resource. +type MonitorUtilitiesService service + +// Preview datasource query. +// +// Execute a synchronous datasource query and return the raw result. Used to preview alert rule expressions before saving. +// +// API: POST /monit/preview/sync (monit-preview-sync). +func (s *MonitorUtilitiesService) Sync(ctx context.Context, req *PreviewSyncRequest) (*Response, error) { + return s.client.do(ctx, "/monit/preview/sync", req, nil) +} diff --git a/openapi/openapi.en.json b/openapi/openapi.en.json index 084e110..1cea8fd 100644 --- a/openapi/openapi.en.json +++ b/openapi/openapi.en.json @@ -128,6 +128,10 @@ { "name": "AI SRE/Sessions", "description": "AI SRE agent session history — list, inspect, and export transcripts." + }, + { + "name": "Monitors/Monitor utilities", + "description": "Monitors service activation and data preview utilities." } ], "paths": { @@ -22665,272 +22669,2105 @@ } } } - } - }, - "components": { - "securitySchemes": { - "AppKeyAuth": { - "type": "apiKey", - "in": "query", - "name": "app_key", - "description": "App key issued from the Flashduty console under Account → APP Keys. Required on every public API call. Keep it secret — it grants the same access as the owning account." - } }, - "responses": { - "BadRequest": { - "description": "Invalid request — usually a missing or malformed parameter.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "missingParameter": { - "summary": "Missing required parameter", - "value": { + "/datasource/im/person/try-link": { + "post": { + "operationId": "datasourceImPersonTryLink", + "summary": "Attempt IM person linking", + "description": "Try to automatically link unbound members to their IM accounts for one integration.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- The server uses member email and phone values to find matching users in DingTalk, Feishu, or WeCom.\n- If no member can be linked, the response contains an empty `new_linked_person_ids` array.", + "href": "/en/api-reference/on-call/integrations/datasource-im-person-try-link", + "metadata": { + "sidebarTitle": "Attempt IM person linking" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/TryLinkPersonResponse" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "InvalidParameter", - "message": "The specified parameter skill_id is not valid." + "data": { + "new_linked_person_ids": [ + 5348648172131 + ] } } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "Unauthorized": { - "description": "Missing or invalid app_key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "missingAppKey": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "Unauthorized", - "message": "You are unauthorized." - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TryLinkPersonRequest" + }, + "example": { + "integration_id": 6113996590131 } } } } - }, - "Forbidden": { - "description": "The app_key is valid but lacks permission for this operation.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "accessDenied": { - "value": { + } + }, + "/incident/post-mortem/init": { + "post": { + "operationId": "postmortem-write-init", + "summary": "Initialize post-mortem", + "description": "Create a post-mortem draft from one or more incidents and a template.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Links at most 10 incidents to one post-mortem report.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-init", + "metadata": { + "sidebarTitle": "Initialize post-mortem" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemItem" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "AccessDenied", - "message": "Access Denied." + "data": { + "meta": { + "account_id": 2451002751131, + "title": "Postmortem1", + "status": "published", + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "template_id": "post_mortem_default_tmpl_en-us", + "incident_ids": [ + "69bb9233331067560c718ecd" + ], + "media_count": 0, + "author_ids": [ + 2477273692131 + ], + "team_id": 2477033058131, + "channel_id": 3047621227131, + "is_private": false, + "channel_name": "Ops Channel", + "created_at_seconds": 1773900354, + "updated_at_seconds": 1773909012 + }, + "basics": { + "incidents_highest_severity": "Warning", + "incidents_earliest_start_seconds": 1761133512, + "incidents_latest_close_seconds": 1761133632, + "incidents_total_duration_seconds": 120, + "responders": [ + { + "person_id": 3790925372131, + "assigned_at": 1761133515, + "acknowledged_at": 0 + } + ] + }, + "content": { + "content": "{\"type\":\"doc\",\"content\":[]}" + }, + "follow_ups": "" } } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "NotFound": { - "description": "The referenced resource does not exist or has been deleted. Note: Flashduty historically returns HTTP 400 with code `ResourceNotFound` for missing domain entities; a true 404 is reserved for unknown routes.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "resourceMissing": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "ResourceNotFound", - "message": "The resource you request is not found" - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitPostMortemRequest" + }, + "example": { + "incident_ids": [ + "69bb9233331067560c718ecd" + ], + "template_id": "post_mortem_default_tmpl_en-us" } } } } - }, - "TooManyRequests": { - "description": "Rate limit hit. Either the global API limit or a per-account limit.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "rateLimited": { - "value": { + } + }, + "/incident/post-mortem/basics/reset": { + "post": { + "operationId": "postmortem-write-reset-basics", + "summary": "Update post-mortem basics", + "description": "Replace the incident facts stored in a post-mortem report.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-reset-basics", + "metadata": { + "sidebarTitle": "Update post-mortem basics" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "RequestTooFrequently", - "message": "Request too frequently." - } + "data": {} } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "ServerError": { - "description": "Unexpected server-side error. Include the request_id when reporting.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "internal": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "InternalError", - "message": "We encountered an internal error, and it has been reported. Please try again later." - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemBasicsRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "incidents_highest_severity": "Warning", + "incidents_earliest_start_seconds": 1761133512, + "incidents_latest_close_seconds": 1761133632, + "incidents_total_duration_seconds": 120, + "responder_ids": [ + 3790925372131 + ] } } } } } }, - "schemas": { - "ErrorCode": { - "type": "string", - "description": "Flashduty error code enum. Every failed API response sets `error.code` to one of these values. The value is a stable wire string — not a localized message and not a numeric status. HTTP status is informational.", - "enum": [ - "OK", - "InvalidParameter", - "BadRequest", - "InvalidContentType", - "ResourceNotFound", - "NoLicense", - "ReferenceExist", - "Unauthorized", - "BalanceNotEnough", - "AccessDenied", - "RouteNotFound", - "MethodNotAllowed", - "UndonedOrderExist", - "RequestLocked", - "EntityTooLarge", - "RequestTooFrequently", - "RequestVerifyRequired", - "DangerousOperation", - "InternalError", - "ServiceUnavailable" - ] - }, - "DutyError": { - "type": "object", - "description": "Error payload inside the response envelope. Present only on non-2xx responses.", - "properties": { - "code": { - "$ref": "#/components/schemas/ErrorCode" - }, - "message": { - "type": "string", - "description": "Human-readable error message, localized by the caller's Accept-Language. May contain field names, IDs, or other context from the failing request." + "/incident/post-mortem/status/reset": { + "post": { + "operationId": "postmortem-write-reset-status", + "summary": "Update post-mortem status", + "description": "Set a post-mortem report to drafting or published.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-reset-status", + "metadata": { + "sidebarTitle": "Update post-mortem status" } }, - "required": [ - "code", - "message" - ] - }, - "SuccessEnvelope": { - "type": "object", - "description": "Success response envelope. On every 2xx response, `request_id` identifies the call (also mirrored in the `Flashcat-Request-Id` header) and `data` holds the endpoint-specific payload. Failure responses use a different shape — see `ErrorResponse`.", - "properties": { - "request_id": { - "type": "string", - "description": "Unique ID for this request. Mirrored in the Flashcat-Request-Id response header. Include it when reporting issues.", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } }, - "data": { - "description": "Endpoint-specific payload. See each operation's 200 response schema." - } - }, - "required": [ - "request_id", - "data" - ] - }, - "ErrorResponse": { - "type": "object", - "description": "Response envelope for errors. `error` is required; `data` is absent.", - "properties": { - "request_id": { - "type": "string", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "error": { - "$ref": "#/components/schemas/DutyError" + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } }, - "required": [ - "request_id", - "error" - ] - }, - "EmptyObject": { - "type": "object", - "description": "An empty object. Returned as the `data` payload by operations whose success signal is simply the absence of an error.", - "additionalProperties": false - }, - "EmptyResponse": { - "type": "object", - "description": "Empty response body. The server returns `data: null` on success.", - "properties": {} - }, - "EmptyRequest": { - "type": "object", - "description": "No parameters required.", - "additionalProperties": false - }, - "CreateIncidentRequest": { - "type": "object", - "description": "Parameters for manually creating an incident.", - "required": [ - "incident_severity" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemStatusRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "status": "published" + } + } + } + } + } + }, + "/incident/post-mortem/title/reset": { + "post": { + "operationId": "postmortem-write-reset-title", + "summary": "Update post-mortem title", + "description": "Replace the title of a post-mortem report.", + "tags": [ + "On-call/Incidents" ], - "properties": { - "incident_severity": { - "type": "string", - "enum": [ - "Info", - "Warning", - "Critical" - ], - "description": "Incident severity." + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-reset-title", + "metadata": { + "sidebarTitle": "Update post-mortem title" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } }, - "title": { - "type": "string", - "maxLength": 512, - "description": "Incident title, up to 512 characters." + "400": { + "$ref": "#/components/responses/BadRequest" }, - "description": { - "type": "string", - "maxLength": 1024, - "description": "Incident description, up to 1024 characters." + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "channel_id": { - "type": "integer", - "format": "int64", - "description": "Channel to file the incident into. Optional; leave unset for a standalone incident." + "429": { + "$ref": "#/components/responses/TooManyRequests" }, - "assigned_to": { + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemTitleRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "title": "Production API latency incident" + } + } + } + } + } + }, + "/incident/post-mortem/follow-ups/reset": { + "post": { + "operationId": "postmortem-write-reset-follow-ups", + "summary": "Update post-mortem follow-ups", + "description": "Replace the follow-up action items on a post-mortem report.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-reset-follow-ups", + "metadata": { + "sidebarTitle": "Update post-mortem follow-ups" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemFollowUpsRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "follow_ups": "- Add database saturation alert\n- Review cache TTL rollout" + } + } + } + } + } + }, + "/incident/post-mortem/template/upsert": { + "post": { + "operationId": "postmortem-write-upsert-template", + "summary": "Create or update post-mortem template", + "description": "Create a custom post-mortem template or update an existing one.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-upsert-template", + "metadata": { + "sidebarTitle": "Create or update post-mortem template" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemTemplate" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertPostMortemTemplateRequest" + }, + "example": { + "team_id": 2477033058131, + "name": "Production incident template", + "description": "Template for production incident reviews.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened." + } + } + } + } + } + }, + "/incident/post-mortem/template/delete": { + "post": { + "operationId": "postmortem-write-delete-template", + "summary": "Delete post-mortem template", + "description": "Delete a custom post-mortem template.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Manage** (`on-call`) |\n\n## Usage\n\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/incidents/postmortem-write-delete-template", + "metadata": { + "sidebarTitle": "Delete post-mortem template" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeletePostMortemTemplateRequest" + }, + "example": { + "template_id": "post_mortem_custom_tmpl_01" + } + } + } + } + } + }, + "/incident/post-mortem/template/list": { + "post": { + "operationId": "postmortem-read-list-templates", + "summary": "List post-mortem templates", + "description": "Return built-in and custom post-mortem templates for the account.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Read** (`on-call`) |", + "href": "/en/api-reference/on-call/incidents/postmortem-read-list-templates", + "metadata": { + "sidebarTitle": "List post-mortem templates" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListPostMortemTemplatesResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "total": 2, + "has_next_page": false, + "items": [ + { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListPostMortemTemplatesRequest" + }, + "example": { + "p": 1, + "limit": 20, + "order_by": "created_at_seconds", + "asc": false + } + } + } + } + } + }, + "/incident/post-mortem/template/info": { + "get": { + "operationId": "postmortem-read-template-info", + "summary": "Get post-mortem template detail", + "description": "Return one post-mortem template by ID.", + "tags": [ + "On-call/Incidents" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Incidents Read** (`on-call`) |", + "href": "/en/api-reference/on-call/incidents/postmortem-read-template-info", + "metadata": { + "sidebarTitle": "Get post-mortem template detail" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemTemplate" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "template_id", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "Template ID." + } + ] + } + }, + "/monit/preview/sync": { + "post": { + "operationId": "monit-preview-sync", + "summary": "Preview datasource query", + "description": "Execute a synchronous datasource query and return the raw result. Used to preview alert rule expressions before saving.", + "tags": [ + "Monitors/Monitor utilities" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **60 requests/minute**; **10 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- `ds_type` must match the datasource type (e.g. `prometheus`, `loki`).\n- `ds_name` is the display name of the datasource as configured in the account.\n- `delay_seconds` shifts the query window backward by the specified number of seconds, useful for accommodating data ingestion latency.\n- The response body is the raw JSON returned by the datasource — its schema varies by datasource type.", + "href": "/en/api-reference/monitors/monitor-utilities/monit-preview-sync", + "metadata": { + "sidebarTitle": "Preview datasource query" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PreviewSyncResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "status": "success", + "data": { + "resultType": "vector", + "result": [] + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreviewSyncRequest" + }, + "example": { + "ds_type": "prometheus", + "ds_name": "Prometheus Prod", + "expr": "rate(http_requests_total[5m])", + "delay_seconds": 0 + } + } + } + } + } + }, + "/rum/application/webhook/test": { + "post": { + "operationId": "rum-application-webhook-test", + "summary": "Test application webhook", + "description": "Send a sample RUM alert event to verify an application's webhook URL.", + "tags": [ + "RUM/Applications" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Applications Manage** (`rum`) |\n\n## Usage\n\n- The endpoint validates the URL before sending the sample event.\n- A failed delivery still returns HTTP 200 with `ok=false` and the delivery error in `message`.", + "href": "/en/api-reference/rum/applications/rum-application-webhook-test", + "metadata": { + "sidebarTitle": "Test application webhook" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RumWebhookTestResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "ok": true, + "status_code": 200, + "message": "ok" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RumWebhookTestRequest" + }, + "example": { + "application_id": "rum-app-prod", + "webhook_url": "https://hooks.example.com/rum-alerts" + } + } + } + } + } + }, + "/status-page/info": { + "get": { + "operationId": "statusPageInfo", + "summary": "Get status page detail", + "description": "Retrieve detailed configuration for a specific status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |", + "href": "/en/api-reference/on-call/status-pages/status-page-info", + "metadata": { + "sidebarTitle": "Get status page detail" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "page_id": 5750613685214, + "name": "Flashduty Status Page", + "url_name": "flashduty-statuspage", + "type": "public", + "custom_domain": "status.example.com", + "logo": "https://cdn.example.com/logo.png", + "favicon": "https://cdn.example.com/favicon.png", + "page_header": "Welcome to our status page", + "page_footer": "2025 Example Corp", + "date_view": "list", + "display_uptime_mode": "chart_and_percentage", + "custom_links": [ + { + "key": "Documentation", + "value": "https://docs.example.com" + } + ], + "contact_info": "mailto:support@example.com", + "components": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "name": "Web Console", + "available_since_seconds": 1765349358, + "order_id": 1 + } + ], + "sections": [ + { + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "name": "Core Services", + "description": "Our core services", + "order_id": 1, + "hide_uptime": false, + "hide_all": false + } + ], + "subscription": { + "email": true, + "im": false + }, + "template_preference": "message" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "page_id", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "Status page ID" + } + ] + } + }, + "/status-page/create": { + "post": { + "operationId": "statusPageCreate", + "summary": "Create status page", + "description": "Create a new status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-create", + "metadata": { + "sidebarTitle": "Create status page" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "page_id": 6294565612043, + "page_name": "My Status Page", + "page_url_name": "my-status-page" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "name": "My Status Page", + "url_name": "my-status-page", + "type": "public", + "page_header": "Welcome to our status page", + "contact_info": "mailto:support@example.com" + } + } + } + } + } + }, + "/status-page/update": { + "post": { + "operationId": "statusPageUpdate", + "summary": "Update status page", + "description": "Update an existing status page configuration.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-update", + "metadata": { + "sidebarTitle": "Update status page" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "page_id": 5750613685214, + "name": "Flashduty Status Page (Updated)", + "page_header": "Updated status page header", + "contact_info": "mailto:support@example.com" + } + } + } + } + } + }, + "/status-page/delete": { + "post": { + "operationId": "statusPageDelete", + "summary": "Delete status page", + "description": "Delete a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-delete", + "metadata": { + "sidebarTitle": "Delete status page" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "page_id": 5750613685214 + } + } + } + } + } + }, + "/status-page/component/upsert": { + "post": { + "operationId": "statusPageComponentUpsert", + "summary": "Upsert status page component", + "description": "Create or update a service component on a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-component-upsert", + "metadata": { + "sidebarTitle": "Upsert status page component" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageComponentResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageComponentRequest" + }, + "example": { + "page_id": 5750613685214, + "components": [ + { + "name": "Web Console", + "description": "Main web interface", + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "order_id": 1 + } + ] + } + } + } + } + } + }, + "/status-page/component/delete": { + "post": { + "operationId": "statusPageComponentDelete", + "summary": "Delete status page component", + "description": "Delete a service component from a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-component-delete", + "metadata": { + "sidebarTitle": "Delete status page component" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageComponentRequest" + }, + "example": { + "page_id": 5750613685214, + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" + ] + } + } + } + } + } + }, + "/status-page/section/upsert": { + "post": { + "operationId": "statusPageSectionUpsert", + "summary": "Upsert status page section", + "description": "Create or update a section on a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-section-upsert", + "metadata": { + "sidebarTitle": "Upsert status page section" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageSectionResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageSectionRequest" + }, + "example": { + "page_id": 5750613685214, + "sections": [ + { + "name": "Core Services", + "description": "Our core services", + "order_id": 1 + } + ] + } + } + } + } + } + }, + "/status-page/section/delete": { + "post": { + "operationId": "statusPageSectionDelete", + "summary": "Delete status page section", + "description": "Delete a section from a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-section-delete", + "metadata": { + "sidebarTitle": "Delete status page section" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageSectionRequest" + }, + "example": { + "page_id": 5750613685214, + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] + } + } + } + } + } + }, + "/status-page/template/upsert": { + "post": { + "operationId": "statusPageTemplateUpsert", + "summary": "Upsert status page template", + "description": "Create or update an event template for a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-template-upsert", + "metadata": { + "sidebarTitle": "Upsert status page template" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageTemplateResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "template_id": "01KP0339G5XDEPM4R86T2B23EP" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageTemplateRequest" + }, + "example": { + "page_id": 5720156736380, + "type": "pre_defined", + "template": { + "title": "Service Disruption", + "event_type": "incident", + "status": "investigating", + "description": "We are investigating a service disruption affecting some users." + } + } + } + } + } + } + }, + "/status-page/template/delete": { + "post": { + "operationId": "statusPageTemplateDelete", + "summary": "Delete status page template", + "description": "Delete an event template from a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-template-delete", + "metadata": { + "sidebarTitle": "Delete status page template" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageTemplateRequest" + }, + "example": { + "page_id": 5720156736380, + "type": "pre_defined", + "template_id": "01KP0339G5XDEPM4R86T2B23EP" + } + } + } + } + } + }, + "/status-page/template/list": { + "get": { + "operationId": "statusPageTemplateList", + "summary": "List status page templates", + "description": "List all event templates for a status page.", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |", + "href": "/en/api-reference/on-call/status-pages/status-page-template-list", + "metadata": { + "sidebarTitle": "List status page templates" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "template_id": "01KC8KP6PHVPSCAB0BTKZBN2HR", + "title": "Service Disruption", + "type": "incident", + "status": "identified", + "description": "We have identified the root cause." + } + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "page_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + }, + "description": "Status page ID." + }, + { + "name": "type", + "in": "query", + "required": true, + "schema": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ] + }, + "description": "Template category. `pre_defined` returns predefined event templates; `message` returns message notification templates." + } + ] + } + } + }, + "components": { + "securitySchemes": { + "AppKeyAuth": { + "type": "apiKey", + "in": "query", + "name": "app_key", + "description": "App key issued from the Flashduty console under Account → APP Keys. Required on every public API call. Keep it secret — it grants the same access as the owning account." + } + }, + "responses": { + "BadRequest": { + "description": "Invalid request — usually a missing or malformed parameter.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "missingParameter": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "InvalidParameter", + "message": "The specified parameter is not valid." + } + } + } + } + } + } + }, + "Unauthorized": { + "description": "Missing or invalid app_key.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "missingAppKey": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "Unauthorized", + "message": "You are unauthorized." + } + } + } + } + } + } + }, + "Forbidden": { + "description": "The app_key is valid but lacks permission for this operation.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "noEditPermission": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "AccessDenied", + "message": "Access Denied." + } + } + } + } + } + } + }, + "NotFound": { + "description": "The referenced resource does not exist or has been deleted. Note: Flashduty historically returns HTTP 400 with code `ResourceNotFound` for missing domain entities; a true 404 is reserved for unknown routes.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "resourceMissing": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "ResourceNotFound", + "message": "The resource you request is not found" + } + } + } + } + } + } + }, + "TooManyRequests": { + "description": "Rate limit hit. Either the global API limit, a per-account limit, or a per-integration limit.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "rateLimited": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "RequestTooFrequently", + "message": "Request too frequently." + } + } + } + } + } + } + }, + "ServerError": { + "description": "Unexpected server-side error. Include the request_id when reporting.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "internal": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "InternalError", + "message": "We encountered an internal error, and it has been reported. Please try again later." + } + } + } + } + } + } + } + }, + "schemas": { + "ErrorCode": { + "type": "string", + "description": "Flashduty error code enum. Every failed API response sets `error.code` to one of these values. The value is a stable wire string — not a localized message and not a numeric status. HTTP status is informational.", + "enum": [ + "OK", + "InvalidParameter", + "BadRequest", + "InvalidContentType", + "ResourceNotFound", + "NoLicense", + "ReferenceExist", + "Unauthorized", + "BalanceNotEnough", + "AccessDenied", + "RouteNotFound", + "MethodNotAllowed", + "UndonedOrderExist", + "RequestLocked", + "EntityTooLarge", + "RequestTooFrequently", + "RequestVerifyRequired", + "DangerousOperation", + "InternalError", + "ServiceUnavailable" + ] + }, + "DutyError": { + "type": "object", + "description": "Error payload inside the response envelope. Present only on non-2xx responses.", + "properties": { + "code": { + "$ref": "#/components/schemas/ErrorCode" + }, + "message": { + "type": "string", + "description": "Human-readable error message, localized by the caller's Accept-Language. May contain field names, IDs, or other context from the failing request." + } + }, + "required": [ + "code", + "message" + ] + }, + "SuccessEnvelope": { + "type": "object", + "description": "Success response envelope. On every 2xx response, `request_id` identifies the call (also mirrored in the `Flashcat-Request-Id` header) and `data` holds the endpoint-specific payload. Failure responses use a different shape — see `ErrorResponse`.", + "properties": { + "request_id": { + "type": "string", + "description": "Unique ID for this request. Mirrored in the Flashcat-Request-Id response header. Include it when reporting issues.", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "data": { + "description": "Endpoint-specific payload. See each operation's 200 response schema." + } + }, + "required": [ + "request_id", + "data" + ] + }, + "ErrorResponse": { + "type": "object", + "description": "Response envelope for errors. `error` is required; `data` is absent.", + "properties": { + "request_id": { + "type": "string", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "error": { + "$ref": "#/components/schemas/DutyError" + } + }, + "required": [ + "request_id", + "error" + ] + }, + "EmptyObject": { + "type": "object", + "description": "An empty object. Returned as the `data` payload by operations whose success signal is simply the absence of an error.", + "additionalProperties": false + }, + "EmptyResponse": { + "type": "object", + "description": "Empty response body. The server returns `data: null` on success.", + "properties": {} + }, + "EmptyRequest": { + "type": "object", + "description": "No parameters required.", + "additionalProperties": false + }, + "CreateIncidentRequest": { + "type": "object", + "description": "Parameters for manually creating an incident.", + "required": [ + "incident_severity" + ], + "properties": { + "incident_severity": { + "type": "string", + "enum": [ + "Info", + "Warning", + "Critical" + ], + "description": "Incident severity." + }, + "title": { + "type": "string", + "maxLength": 512, + "description": "Incident title, up to 512 characters." + }, + "description": { + "type": "string", + "maxLength": 1024, + "description": "Incident description, up to 1024 characters." + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "Channel to file the incident into. Optional; leave unset for a standalone incident." + }, + "assigned_to": { "type": "object", "description": "Incident assignment target. Either `person_ids` or `escalate_rule_id` must be provided.", "properties": { @@ -41224,295 +43061,995 @@ "team_id": { "type": "integer", "format": "int64", - "description": "Owning team id; 0 means no team is bound. Immutable after create." + "description": "Owning team id; 0 means no team is bound. Immutable after create." + }, + "team_name": { + "type": "string", + "description": "Resolved team name; empty for unbound rows or deleted teams." + }, + "is_mine": { + "type": "boolean", + "description": "True when the caller created this session." + }, + "can_manage": { + "type": "boolean", + "description": "True when the caller may rename/archive/delete the session." + }, + "status": { + "type": "string", + "description": "Lifecycle status.", + "enum": [ + "enabled", + "deleted" + ] + }, + "incognito": { + "type": "boolean", + "description": "True for incognito (non-persisted-memory) sessions." + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds when the session was created." + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds of the last session update." + }, + "template_staging_round_id": { + "type": "string", + "description": "Current save→validate round id (template-assistant only); empty otherwise." + }, + "state": { + "type": "object", + "additionalProperties": true, + "description": "Raw session-state bag (session-scoped keys). Omitted when empty." + }, + "bound_environment": { + "$ref": "#/components/schemas/EnvironmentBinding" + }, + "context_resolved": { + "$ref": "#/components/schemas/ContextResolvedItem" + }, + "token_usage": { + "$ref": "#/components/schemas/SessionTokenUsage" + }, + "current_context_tokens": { + "type": "integer", + "format": "int64", + "description": "Size in tokens of the LLM context window as of the most recent turn. 0 means no turn has completed." + }, + "context_window": { + "type": "integer", + "format": "int64", + "description": "The bound model's max context size in tokens. 0 means unknown." + }, + "archived_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds when archived; 0 means not archived." + }, + "pinned_at": { + "type": "integer", + "format": "int64", + "description": "Caller's per-user pin timestamp in milliseconds; 0 means not pinned." + }, + "last_event_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds of the most recent assistant-side event." + }, + "is_running": { + "type": "boolean", + "description": "True when an agent turn is currently in flight for this session." + }, + "has_unread": { + "type": "boolean", + "description": "True when there is assistant output the caller has not yet viewed." + } + } + }, + "SessionListResponse": { + "type": "object", + "description": "A page of agent sessions.", + "properties": { + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of sessions matching the filter (ignoring pagination)." + }, + "sessions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SessionItem" + }, + "description": "The page of sessions." + } + } + }, + "SessionGetRequest": { + "type": "object", + "description": "Fetch one session plus a backward-paged window of its most recent events.", + "properties": { + "session_id": { + "type": "string", + "description": "Target session ID.", + "minLength": 1 + }, + "num_recent_events": { + "type": "integer", + "description": "Legacy page size: number of most-recent events to return. Superseded by `limit` when both are set; 0 uses the server default (100).", + "minimum": 0, + "maximum": 1000 + }, + "limit": { + "type": "integer", + "description": "Page size for events; takes precedence over `num_recent_events`. 0 uses the server default (100).", + "minimum": 0, + "maximum": 1000 + }, + "search_after_ctx": { + "type": "string", + "description": "Opaque keyset cursor from a previous response; pass it back to fetch the next older page.", + "maxLength": 4096 + } + }, + "required": [ + "session_id" + ] + }, + "EventItem": { + "type": "object", + "description": "One persisted session event. content/actions/usage_metadata carry the raw ADK envelope; treat them as opaque structured payloads.", + "properties": { + "event_id": { + "type": "string", + "description": "Event identifier." + }, + "session_id": { + "type": "string", + "description": "Owning session id." + }, + "invocation_id": { + "type": "string", + "description": "ADK invocation id grouping a turn." + }, + "author": { + "type": "string", + "description": "Event author (e.g. user, the agent name)." + }, + "branch": { + "type": "string", + "description": "ADK branch path for nested agents." + }, + "content": { + "type": "object", + "additionalProperties": true, + "description": "ADK content envelope {role, parts:[...]}." + }, + "actions": { + "type": "object", + "additionalProperties": true, + "description": "ADK actions envelope (state deltas, transfers, escalation)." + }, + "usage_metadata": { + "type": "object", + "additionalProperties": true, + "description": "Per-turn token usage metadata." + }, + "partial": { + "type": "boolean", + "description": "True for a streaming partial chunk." + }, + "turn_complete": { + "type": "boolean", + "description": "True on the terminal event of a turn." + }, + "error_code": { + "type": "string", + "description": "Error code when the event represents a failure." + }, + "error_message": { + "type": "string", + "description": "Human-readable error message, when present." + }, + "status": { + "type": "string", + "description": "Event status.", + "enum": [ + "normal", + "compressed" + ] + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in milliseconds when the event was written." + } + } + }, + "SessionGetResponse": { + "type": "object", + "description": "A session plus a backward-paged window of its events.", + "properties": { + "session": { + "$ref": "#/components/schemas/SessionItem" + }, + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventItem" + }, + "description": "Recent events, ascending by (created_at, event_id)." + }, + "has_more_older": { + "type": "boolean", + "description": "True when older events remain beyond this page." + }, + "search_after_ctx": { + "type": "string", + "description": "Opaque keyset cursor; pass back as search_after_ctx to fetch the next older page. Omitted when has_more_older is false." + } + } + }, + "SessionExportRequest": { + "type": "object", + "description": "Export the full event transcript of one session as a streaming NDJSON body.", + "properties": { + "session_id": { + "type": "string", + "description": "Target session ID." + }, + "include_subagents": { + "type": "boolean", + "description": "When true, each subagent_dispatch line is followed by the child session's full event stream, bracketed by its own session_meta. Defaults to false." + } + }, + "required": [ + "session_id" + ] + }, + "SkillUploadRequest": { + "type": "object", + "description": "Multipart form for uploading a skill archive.", + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "Skill archive (.skill / .zip / .tar.gz / .tgz). Max 100MB." + }, + "team_id": { + "type": "integer", + "description": "Team scope for the new skill: 0 = account-wide.", + "format": "int64" + }, + "replace": { + "type": "boolean", + "description": "When true, overwrite an existing same-name skill." + }, + "skill_id": { + "type": "string", + "description": "When replacing a specific skill, its skill ID." + } + }, + "required": [ + "file" + ] + }, + "SessionDeleteRequest": { + "type": "object", + "description": "Session deletion by ID.", + "properties": { + "session_id": { + "type": "string", + "description": "Target session ID.", + "minLength": 1 + } + }, + "required": [ + "session_id" + ] + }, + "DeletePostMortemTemplateRequest": { + "type": "object", + "description": "Parameters for deleting a post-mortem template.", + "required": [ + "template_id" + ], + "properties": { + "template_id": { + "type": "string", + "description": "Template ID." + } + } + }, + "InitPostMortemRequest": { + "type": "object", + "description": "Parameters for initializing a post-mortem report from incidents.", + "required": [ + "incident_ids", + "template_id" + ], + "properties": { + "incident_ids": { + "type": "array", + "minItems": 1, + "maxItems": 10, + "items": { + "type": "string" + }, + "description": "Incident IDs to link to the report. 1-10 incidents." + }, + "template_id": { + "type": "string", + "description": "Template ID used to initialize the report." + } + } + }, + "ListPostMortemTemplatesRequest": { + "type": "object", + "description": "Pagination and ordering options for post-mortem templates.", + "properties": { + "order_by": { + "type": "string", + "enum": [ + "created_at_seconds" + ], + "description": "Field used to order results." + }, + "asc": { + "type": "boolean", + "description": "Ascending order when true." + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Page number starting at 1." + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "Page size, at most 100." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor from a previous response for forward pagination." + } + } + }, + "ListPostMortemTemplatesResponse": { + "type": "object", + "description": "Paginated list of post-mortem templates.", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostMortemTemplate" + }, + "description": "Templates in the current page." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total matching templates." + }, + "has_next_page": { + "type": "boolean", + "description": "True when another page is available." + }, + "search_after_ctx": { + "type": "string", + "description": "Cursor for forward pagination." + } + } + }, + "PostMortemTemplate": { + "type": "object", + "description": "Post-mortem report template.", + "required": [ + "account_id", + "template_id", + "name", + "description", + "content", + "content_markdown", + "team_id", + "created_at_seconds", + "updated_at_seconds" + ], + "properties": { + "account_id": { + "type": "integer", + "format": "int64", + "description": "Account ID that owns the template. 0 for built-in templates." }, - "team_name": { + "template_id": { "type": "string", - "description": "Resolved team name; empty for unbound rows or deleted teams." + "description": "Template ID. Built-in templates use a stable `post_mortem_default_tmpl_*` ID." }, - "is_mine": { - "type": "boolean", - "description": "True when the caller created this session." + "name": { + "type": "string", + "description": "Template name shown in the console." }, - "can_manage": { - "type": "boolean", - "description": "True when the caller may rename/archive/delete the session." + "description": { + "type": "string", + "description": "Template description." }, - "status": { + "content": { "type": "string", - "description": "Lifecycle status.", - "enum": [ - "enabled", - "deleted" - ] + "description": "BlockNote JSON content used to initialize the report body." }, - "incognito": { - "type": "boolean", - "description": "True for incognito (non-persisted-memory) sessions." + "content_markdown": { + "type": "string", + "description": "Markdown version of the template content, used by AI generation." }, - "created_at": { + "team_id": { "type": "integer", "format": "int64", - "description": "Unix timestamp in milliseconds when the session was created." + "description": "Managing team ID. Built-in templates use 0." }, - "updated_at": { + "created_at_seconds": { "type": "integer", "format": "int64", - "description": "Unix timestamp in milliseconds of the last session update." + "description": "Unix timestamp in seconds when the template was created." }, - "template_staging_round_id": { + "updated_at_seconds": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the template was last updated." + } + } + }, + "PreviewSyncRequest": { + "type": "object", + "required": [ + "ds_type", + "ds_name", + "expr" + ], + "description": "Parameters for a synchronous datasource query preview.", + "properties": { + "ds_type": { "type": "string", - "description": "Current save→validate round id (template-assistant only); empty otherwise." + "description": "Datasource type, e.g. `prometheus`, `loki`, `elasticsearch`." }, - "state": { - "type": "object", - "additionalProperties": true, - "description": "Raw session-state bag (session-scoped keys). Omitted when empty." + "ds_name": { + "type": "string", + "description": "Datasource display name as configured in the account." }, - "bound_environment": { - "$ref": "#/components/schemas/EnvironmentBinding" + "expr": { + "type": "string", + "description": "Query expression. Format depends on `ds_type` (PromQL for Prometheus, LogQL for Loki, etc.)." }, - "context_resolved": { - "$ref": "#/components/schemas/ContextResolvedItem" + "delay_seconds": { + "type": "integer", + "description": "Shift the query window backward by this many seconds to compensate for data ingestion latency." }, - "token_usage": { - "$ref": "#/components/schemas/SessionTokenUsage" + "args": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Additional type-specific query arguments." + } + } + }, + "PreviewSyncResponse": { + "type": "object", + "description": "Raw JSON response from the datasource. Schema varies by datasource type." + }, + "ResetPostMortemBasicsRequest": { + "type": "object", + "description": "Basic incident facts to write back to a post-mortem report.", + "required": [ + "post_mortem_id", + "incidents_highest_severity", + "incidents_earliest_start_seconds" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID." }, - "current_context_tokens": { - "type": "integer", - "format": "int64", - "description": "Size in tokens of the LLM context window as of the most recent turn. 0 means no turn has completed." + "incidents_highest_severity": { + "type": "string", + "description": "Highest severity among linked incidents." }, - "context_window": { + "incidents_earliest_start_seconds": { "type": "integer", "format": "int64", - "description": "The bound model's max context size in tokens. 0 means unknown." + "minimum": 1, + "description": "Unix timestamp in seconds for the earliest linked incident start time." }, - "archived_at": { + "incidents_latest_close_seconds": { "type": "integer", "format": "int64", - "description": "Unix timestamp in milliseconds when archived; 0 means not archived." + "minimum": 0, + "description": "Unix timestamp in seconds for the latest linked incident close time. 0 when still open." }, - "pinned_at": { + "incidents_total_duration_seconds": { "type": "integer", "format": "int64", - "description": "Caller's per-user pin timestamp in milliseconds; 0 means not pinned." + "minimum": 0, + "description": "Total incident duration in seconds." }, - "last_event_at": { - "type": "integer", - "format": "int64", - "description": "Unix timestamp in milliseconds of the most recent assistant-side event." + "responder_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Responder member IDs to store on the report." + } + } + }, + "ResetPostMortemFollowUpsRequest": { + "type": "object", + "description": "Parameters for replacing post-mortem follow-up action items.", + "required": [ + "post_mortem_id" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID." }, - "is_running": { - "type": "boolean", - "description": "True when an agent turn is currently in flight for this session." + "follow_ups": { + "type": "string", + "description": "Follow-up action items as free text." + } + } + }, + "ResetPostMortemStatusRequest": { + "type": "object", + "description": "Parameters for changing a post-mortem report status.", + "required": [ + "post_mortem_id", + "status" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID." }, - "has_unread": { - "type": "boolean", - "description": "True when there is assistant output the caller has not yet viewed." + "status": { + "type": "string", + "enum": [ + "drafting", + "published" + ], + "description": "Target report status." } } }, - "SessionListResponse": { + "ResetPostMortemTitleRequest": { "type": "object", - "description": "A page of agent sessions.", + "description": "Parameters for changing a post-mortem report title.", + "required": [ + "post_mortem_id", + "title" + ], "properties": { - "total": { - "type": "integer", - "format": "int64", - "description": "Total number of sessions matching the filter (ignoring pagination)." + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID." }, - "sessions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SessionItem" - }, - "description": "The page of sessions." + "title": { + "type": "string", + "description": "New report title." } } }, - "SessionGetRequest": { + "RumWebhookTestRequest": { "type": "object", - "description": "Fetch one session plus a backward-paged window of its most recent events.", + "description": "Parameters for sending a sample RUM alert webhook.", + "required": [ + "application_id", + "webhook_url" + ], "properties": { - "session_id": { + "application_id": { "type": "string", - "description": "Target session ID.", - "minLength": 1 + "description": "RUM application ID." }, - "num_recent_events": { - "type": "integer", - "description": "Legacy page size: number of most-recent events to return. Superseded by `limit` when both are set; 0 uses the server default (100).", - "minimum": 0, - "maximum": 1000 + "webhook_url": { + "type": "string", + "format": "uri", + "description": "Webhook URL to receive the sample alert event." + } + } + }, + "RumWebhookTestResponse": { + "type": "object", + "description": "Result of the webhook test delivery.", + "required": [ + "ok", + "status_code", + "message" + ], + "properties": { + "ok": { + "type": "boolean", + "description": "Whether the webhook endpoint accepted the sample event." }, - "limit": { + "status_code": { "type": "integer", - "description": "Page size for events; takes precedence over `num_recent_events`. 0 uses the server default (100).", - "minimum": 0, - "maximum": 1000 + "description": "HTTP status code returned by the webhook endpoint. 0 when the request did not receive a response." }, - "search_after_ctx": { + "message": { "type": "string", - "description": "Opaque keyset cursor from a previous response; pass it back to fetch the next older page.", - "maxLength": 4096 + "description": "`ok` on success, otherwise the delivery error message." } - }, + } + }, + "TryLinkPersonRequest": { + "type": "object", + "description": "Parameters for attempting automatic IM account linking.", "required": [ - "session_id" - ] + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "IM integration ID." + } + } }, - "EventItem": { + "TryLinkPersonResponse": { "type": "object", - "description": "One persisted session event. content/actions/usage_metadata carry the raw ADK envelope; treat them as opaque structured payloads.", + "description": "People linked by this attempt.", + "required": [ + "new_linked_person_ids" + ], "properties": { - "event_id": { - "type": "string", - "description": "Event identifier." - }, - "session_id": { + "new_linked_person_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Person IDs newly linked during this call." + } + } + }, + "UpsertPostMortemTemplateRequest": { + "type": "object", + "description": "Parameters for creating or updating a post-mortem template.", + "required": [ + "name", + "content" + ], + "properties": { + "template_id": { "type": "string", - "description": "Owning session id." + "description": "Template ID. Omit to create a new template; provide it to update an existing template." }, - "invocation_id": { - "type": "string", - "description": "ADK invocation id grouping a turn." + "team_id": { + "type": "integer", + "format": "int64", + "description": "Managing team ID. Required when creating a custom template." }, - "author": { + "name": { "type": "string", - "description": "Event author (e.g. user, the agent name)." + "description": "Template name." }, - "branch": { + "description": { "type": "string", - "description": "ADK branch path for nested agents." + "description": "Template description." }, "content": { - "type": "object", - "additionalProperties": true, - "description": "ADK content envelope {role, parts:[...]}." - }, - "actions": { - "type": "object", - "additionalProperties": true, - "description": "ADK actions envelope (state deltas, transfers, escalation)." - }, - "usage_metadata": { - "type": "object", - "additionalProperties": true, - "description": "Per-turn token usage metadata." - }, - "partial": { - "type": "boolean", - "description": "True for a streaming partial chunk." - }, - "turn_complete": { - "type": "boolean", - "description": "True on the terminal event of a turn." - }, - "error_code": { "type": "string", - "description": "Error code when the event represents a failure." - }, - "error_message": { - "type": "string", - "description": "Human-readable error message, when present." + "description": "BlockNote JSON template content." }, - "status": { + "content_markdown": { "type": "string", - "description": "Event status.", - "enum": [ - "normal", - "compressed" - ] - }, - "created_at": { + "description": "Markdown version of the template content." + } + } + }, + "DeleteStatusPageComponentRequest": { + "type": "object", + "description": "Parameters for deleting one or more service components from a status page.", + "required": [ + "page_id", + "component_ids" + ], + "properties": { + "page_id": { "type": "integer", "format": "int64", - "description": "Unix timestamp in milliseconds when the event was written." + "description": "Status page ID." + }, + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "IDs of components to delete." } } }, - "SessionGetResponse": { + "DeleteStatusPageSectionRequest": { "type": "object", - "description": "A session plus a backward-paged window of its events.", + "description": "Parameters for deleting one or more sections from a status page.", + "required": [ + "page_id", + "section_ids" + ], "properties": { - "session": { - "$ref": "#/components/schemas/SessionItem" + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID." }, - "events": { + "section_ids": { "type": "array", "items": { - "$ref": "#/components/schemas/EventItem" + "type": "string" }, - "description": "Recent events, ascending by (created_at, event_id)." + "description": "IDs of sections to delete." + } + } + }, + "DeleteStatusPageTemplateRequest": { + "type": "object", + "description": "Parameters for deleting a status page template.", + "required": [ + "page_id", + "type", + "template_id" + ], + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID." }, - "has_more_older": { - "type": "boolean", - "description": "True when older events remain beyond this page." + "type": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ], + "description": "Template category." }, - "search_after_ctx": { + "template_id": { "type": "string", - "description": "Opaque keyset cursor; pass back as search_after_ctx to fetch the next older page. Omitted when has_more_older is false." + "description": "Template ID to delete." } } }, - "SessionExportRequest": { + "UpsertStatusPageComponentRequest": { "type": "object", - "description": "Export the full event transcript of one session as a streaming NDJSON body.", + "description": "Parameters for creating or updating one or more service components on a status page.", + "required": [ + "page_id", + "components" + ], "properties": { - "session_id": { - "type": "string", - "description": "Target session ID." + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID." }, - "include_subagents": { - "type": "boolean", - "description": "When true, each subagent_dispatch line is followed by the child session's full event stream, bracketed by its own session_meta. Defaults to false." + "components": { + "type": "array", + "description": "Components to create or update.", + "items": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "component_id": { + "type": "string", + "description": "Component ID. Omit to create a new component; supply to update an existing one." + }, + "section_id": { + "type": "string", + "description": "Parent section ID. Omit to place the component at the top level." + }, + "name": { + "type": "string", + "description": "Component display name." + }, + "description": { + "type": "string", + "description": "Component description." + }, + "order_id": { + "type": "integer", + "format": "int64", + "description": "Display order within its section." + }, + "hide_uptime": { + "type": "boolean", + "description": "When true, uptime data is hidden from summary responses." + }, + "hide_all": { + "type": "boolean", + "description": "When true, the component is hidden entirely from summary endpoints." + } + } + } } - }, + } + }, + "UpsertStatusPageComponentResponse": { + "type": "object", + "description": "Result of upserting status page components.", "required": [ - "session_id" - ] + "component_ids" + ], + "properties": { + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "IDs of the created or updated components, in the same order as the request." + } + } }, - "SkillUploadRequest": { + "UpsertStatusPageSectionRequest": { "type": "object", - "description": "Multipart form for uploading a skill archive.", + "description": "Parameters for creating or updating one or more sections on a status page.", + "required": [ + "page_id", + "sections" + ], "properties": { - "file": { - "type": "string", - "format": "binary", - "description": "Skill archive (.skill / .zip / .tar.gz / .tgz). Max 100MB." - }, - "team_id": { + "page_id": { "type": "integer", - "description": "Team scope for the new skill: 0 = account-wide.", - "format": "int64" - }, - "replace": { - "type": "boolean", - "description": "When true, overwrite an existing same-name skill." + "format": "int64", + "description": "Status page ID." }, - "skill_id": { - "type": "string", - "description": "When replacing a specific skill, its skill ID." + "sections": { + "type": "array", + "description": "Sections to create or update.", + "items": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "section_id": { + "type": "string", + "description": "Section ID. Omit to create a new section; supply to update an existing one." + }, + "name": { + "type": "string", + "description": "Section display name." + }, + "description": { + "type": "string", + "description": "Section description." + }, + "order_id": { + "type": "integer", + "format": "int64", + "description": "Display order." + }, + "hide_uptime": { + "type": "boolean", + "description": "When true, uptime data for all components in this section is hidden." + }, + "hide_all": { + "type": "boolean", + "description": "When true, the entire section is hidden from summary endpoints." + } + } + } } - }, + } + }, + "UpsertStatusPageSectionResponse": { + "type": "object", + "description": "Result of upserting status page sections.", "required": [ - "file" - ] + "section_ids" + ], + "properties": { + "section_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "IDs of the created or updated sections, in the same order as the request." + } + } }, - "SessionDeleteRequest": { + "UpsertStatusPageTemplateRequest": { "type": "object", - "description": "Session deletion by ID.", + "description": "Parameters for creating or updating a status page template.", + "required": [ + "page_id", + "type", + "template" + ], "properties": { - "session_id": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID." + }, + "type": { "type": "string", - "description": "Target session ID.", - "minLength": 1 + "enum": [ + "pre_defined", + "message" + ], + "description": "Template category. `pre_defined` for predefined event templates; `message` for notification message templates." + }, + "template": { + "type": "object", + "description": "Template content.", + "required": [ + "title", + "event_type", + "status" + ], + "properties": { + "template_id": { + "type": "string", + "description": "Template ID. Omit to create; supply to update." + }, + "title": { + "type": "string", + "description": "Template title." + }, + "event_type": { + "type": "string", + "enum": [ + "incident", + "maintenance" + ], + "description": "Event type this template applies to." + }, + "status": { + "type": "string", + "enum": [ + "investigating", + "identified", + "monitoring", + "resolved", + "scheduled", + "ongoing", + "completed" + ], + "description": "Event status this template represents." + }, + "description": { + "type": "string", + "description": "Template body text (Markdown)." + } + } } - }, + } + }, + "UpsertStatusPageTemplateResponse": { + "type": "object", + "description": "Result of upserting a status page template.", "required": [ - "session_id" - ] + "template_id" + ], + "properties": { + "template_id": { + "type": "string", + "description": "ID of the created or updated template." + } + } } } } diff --git a/openapi/openapi.zh.json b/openapi/openapi.zh.json index 078a2e1..54a0aff 100644 --- a/openapi/openapi.zh.json +++ b/openapi/openapi.zh.json @@ -128,6 +128,10 @@ { "name": "AI SRE/会话", "description": "AI SRE 智能体会话历史 —— 查询、查看与导出会话记录。" + }, + { + "name": "Monitors/通用工具", + "description": "监控服务开通及数据预览工具。" } ], "paths": { @@ -22657,276 +22661,2109 @@ } } } - } - }, - "components": { - "securitySchemes": { - "AppKeyAuth": { - "type": "apiKey", - "in": "query", - "name": "app_key", - "description": "在 Flashduty 控制台 账户 → APP Key 中签发的 app_key。调用任何公开 API 时都必须携带。它等同于所属账户的身份凭证,请妥善保管。" - } }, - "responses": { - "BadRequest": { - "description": "Invalid request — usually a missing or malformed parameter.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "missingParameter": { - "summary": "Missing required parameter", - "value": { + "/datasource/im/person/try-link": { + "post": { + "operationId": "datasourceImPersonTryLink", + "summary": "尝试关联 IM 人员", + "description": "为指定集成尝试将未绑定成员自动关联到对应的 IM 账号。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 服务端使用成员邮箱和手机号在钉钉、飞书或企业微信中查找匹配用户。\n- 如果没有成员可关联,响应中的 `new_linked_person_ids` 为空数组。", + "href": "/zh/api-reference/on-call/integrations/datasource-im-person-try-link", + "metadata": { + "sidebarTitle": "尝试关联 IM 人员" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/TryLinkPersonResponse" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "InvalidParameter", - "message": "The specified parameter skill_id is not valid." + "data": { + "new_linked_person_ids": [ + 5348648172131 + ] } } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "Unauthorized": { - "description": "Missing or invalid app_key.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "missingAppKey": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "Unauthorized", - "message": "You are unauthorized." - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TryLinkPersonRequest" + }, + "example": { + "integration_id": 6113996590131 } } } } - }, - "Forbidden": { - "description": "The app_key is valid but lacks permission for this operation.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "accessDenied": { - "value": { + } + }, + "/incident/post-mortem/init": { + "post": { + "operationId": "postmortem-write-init", + "summary": "初始化故障复盘", + "description": "根据一个或多个故障和模板创建复盘草稿。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 最多可将 10 个故障关联到同一份复盘报告。\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-init", + "metadata": { + "sidebarTitle": "初始化故障复盘" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemItem" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "AccessDenied", - "message": "Access Denied." + "data": { + "meta": { + "account_id": 2451002751131, + "title": "Postmortem1", + "status": "published", + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "template_id": "post_mortem_default_tmpl_en-us", + "incident_ids": [ + "69bb9233331067560c718ecd" + ], + "media_count": 0, + "author_ids": [ + 2477273692131 + ], + "team_id": 2477033058131, + "channel_id": 3047621227131, + "is_private": false, + "channel_name": "Ops Channel", + "created_at_seconds": 1773900354, + "updated_at_seconds": 1773909012 + }, + "basics": { + "incidents_highest_severity": "Warning", + "incidents_earliest_start_seconds": 1761133512, + "incidents_latest_close_seconds": 1761133632, + "incidents_total_duration_seconds": 120, + "responders": [ + { + "person_id": 3790925372131, + "assigned_at": 1761133515, + "acknowledged_at": 0 + } + ] + }, + "content": { + "content": "{\"type\":\"doc\",\"content\":[]}" + }, + "follow_ups": "" } } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "NotFound": { - "description": "目标资源不存在或已被删除。注意:Flashduty 对业务实体的缺失通常返回 HTTP 400 + code=`ResourceNotFound`,真正的 404 只用于未知路由。", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "resourceMissing": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "ResourceNotFound", - "message": "The resource you request is not found" - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitPostMortemRequest" + }, + "example": { + "incident_ids": [ + "69bb9233331067560c718ecd" + ], + "template_id": "post_mortem_default_tmpl_en-us" } } } } - }, - "TooManyRequests": { - "description": "Rate limit hit. Either the global API limit or a per-account limit.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "rateLimited": { - "value": { + } + }, + "/incident/post-mortem/basics/reset": { + "post": { + "operationId": "postmortem-write-reset-basics", + "summary": "更新故障复盘基础信息", + "description": "替换复盘报告中记录的故障基础信息。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-reset-basics", + "metadata": { + "sidebarTitle": "更新故障复盘基础信息" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "RequestTooFrequently", - "message": "Request too frequently." - } + "data": {} } } } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } - } - }, - "ServerError": { - "description": "Unexpected server-side error. Include the request_id when reporting.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - }, - "examples": { - "internal": { - "value": { - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "error": { - "code": "InternalError", - "message": "We encountered an internal error, and it has been reported. Please try again later." - } - } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemBasicsRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "incidents_highest_severity": "Warning", + "incidents_earliest_start_seconds": 1761133512, + "incidents_latest_close_seconds": 1761133632, + "incidents_total_duration_seconds": 120, + "responder_ids": [ + 3790925372131 + ] } } } } } }, - "schemas": { - "ErrorCode": { - "type": "string", - "description": "Flashduty error code enum. Every failed API response sets `error.code` to one of these values. The value is a stable wire string — not a localized message and not a numeric status. HTTP status is informational.", - "enum": [ - "OK", - "InvalidParameter", - "BadRequest", - "InvalidContentType", - "ResourceNotFound", - "NoLicense", - "ReferenceExist", - "Unauthorized", - "BalanceNotEnough", - "AccessDenied", - "RouteNotFound", - "MethodNotAllowed", - "UndonedOrderExist", - "RequestLocked", - "EntityTooLarge", - "RequestTooFrequently", - "RequestVerifyRequired", - "DangerousOperation", - "InternalError", - "ServiceUnavailable" - ] - }, - "DutyError": { - "type": "object", - "description": "Error payload inside the response envelope. Present only on non-2xx responses.", - "properties": { - "code": { - "$ref": "#/components/schemas/ErrorCode" - }, - "message": { - "type": "string", - "description": "Human-readable error message, localized by the caller's Accept-Language. May contain field names, IDs, or other context from the failing request." + "/incident/post-mortem/status/reset": { + "post": { + "operationId": "postmortem-write-reset-status", + "summary": "更新故障复盘状态", + "description": "将复盘报告设置为草稿或已发布。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-reset-status", + "metadata": { + "sidebarTitle": "更新故障复盘状态" } }, - "required": [ - "code", - "message" - ] - }, - "SuccessEnvelope": { - "type": "object", - "description": "成功响应结构。2xx 响应中 `request_id` 标识本次调用(同时出现在 `Flashcat-Request-Id` 响应头中),`data` 为接口业务 payload。失败响应使用不同结构,参见 `ErrorResponse`。", - "properties": { - "request_id": { - "type": "string", - "description": "本次请求的唯一 ID,也会在 Flashcat-Request-Id 响应头中返回。反馈问题时请一并附上。", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } }, - "data": { - "description": "每个接口自己的业务 payload,详见各接口的 200 响应 schema。" - } - }, - "required": [ - "request_id", - "data" - ] - }, - "ErrorResponse": { - "type": "object", - "description": "Response envelope for errors. `error` is required; `data` is absent.", - "properties": { - "request_id": { - "type": "string", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "error": { - "$ref": "#/components/schemas/DutyError" + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } }, - "required": [ - "request_id", - "error" - ] - }, - "EmptyObject": { - "type": "object", - "description": "空对象。当操作的成功信号就是不报错时,作为 `data` 返回。", - "additionalProperties": false - }, - "EmptyResponse": { - "type": "object", - "description": "空响应体。成功时服务端返回 `data: null`。", - "properties": {} - }, - "EmptyRequest": { - "type": "object", - "description": "无参数。", - "additionalProperties": false - }, - "CreateIncidentRequest": { - "type": "object", - "description": "手动创建故障所需的参数。", - "required": [ - "incident_severity" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemStatusRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "status": "published" + } + } + } + } + } + }, + "/incident/post-mortem/title/reset": { + "post": { + "operationId": "postmortem-write-reset-title", + "summary": "更新故障复盘标题", + "description": "替换复盘报告标题。", + "tags": [ + "On-call/故障管理" ], - "properties": { - "incident_severity": { - "type": "string", - "enum": [ - "Info", - "Warning", - "Critical" - ], - "description": "故障严重程度。" + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-reset-title", + "metadata": { + "sidebarTitle": "更新故障复盘标题" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } }, - "title": { - "type": "string", - "maxLength": 512, - "description": "故障标题,最多 512 个字符。" + "400": { + "$ref": "#/components/responses/BadRequest" }, - "description": { - "type": "string", - "maxLength": 1024, - "description": "故障描述,最多 1024 个字符。" + "401": { + "$ref": "#/components/responses/Unauthorized" }, - "channel_id": { - "type": "integer", - "format": "int64", - "description": "归属的协作空间 ID,留空表示独立故障。" + "429": { + "$ref": "#/components/responses/TooManyRequests" }, - "assigned_to": { - "type": "object", - "description": "故障处理人员指派目标。`person_ids` 与 `escalate_rule_id` 至少设置一项。", - "properties": { - "person_ids": { + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemTitleRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "title": "Production API latency incident" + } + } + } + } + } + }, + "/incident/post-mortem/follow-ups/reset": { + "post": { + "operationId": "postmortem-write-reset-follow-ups", + "summary": "更新故障复盘后续行动", + "description": "替换复盘报告中的后续行动项。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-reset-follow-ups", + "metadata": { + "sidebarTitle": "更新故障复盘后续行动" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResetPostMortemFollowUpsRequest" + }, + "example": { + "post_mortem_id": "8104935102bf89dc01ac638a5261fe7e", + "follow_ups": "- Add database saturation alert\n- Review cache TTL rollout" + } + } + } + } + } + }, + "/incident/post-mortem/template/upsert": { + "post": { + "operationId": "postmortem-write-upsert-template", + "summary": "创建或更新故障复盘模板", + "description": "创建自定义复盘模板,或更新已有模板。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-upsert-template", + "metadata": { + "sidebarTitle": "创建或更新故障复盘模板" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemTemplate" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertPostMortemTemplateRequest" + }, + "example": { + "team_id": 2477033058131, + "name": "Production incident template", + "description": "Template for production incident reviews.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened." + } + } + } + } + } + }, + "/incident/post-mortem/template/delete": { + "post": { + "operationId": "postmortem-write-delete-template", + "summary": "删除故障复盘模板", + "description": "删除自定义复盘模板。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障管理**(`on-call`) |\n\n## 使用说明\n\n- 每次调用都会记录到账户审计日志,请不要把敏感信息放在请求字段中。", + "href": "/zh/api-reference/on-call/incidents/postmortem-write-delete-template", + "metadata": { + "sidebarTitle": "删除故障复盘模板" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeletePostMortemTemplateRequest" + }, + "example": { + "template_id": "post_mortem_custom_tmpl_01" + } + } + } + } + } + }, + "/incident/post-mortem/template/list": { + "post": { + "operationId": "postmortem-read-list-templates", + "summary": "查询故障复盘模板列表", + "description": "返回账号下的内置和自定义故障复盘模板。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障查看**(`on-call`) |", + "href": "/zh/api-reference/on-call/incidents/postmortem-read-list-templates", + "metadata": { + "sidebarTitle": "查询故障复盘模板列表" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListPostMortemTemplatesResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "total": 2, + "has_next_page": false, + "items": [ + { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListPostMortemTemplatesRequest" + }, + "example": { + "p": 1, + "limit": 20, + "order_by": "created_at_seconds", + "asc": false + } + } + } + } + } + }, + "/incident/post-mortem/template/info": { + "get": { + "operationId": "postmortem-read-template-info", + "summary": "查看故障复盘模板详情", + "description": "按 ID 返回单个故障复盘模板。", + "tags": [ + "On-call/故障管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **故障查看**(`on-call`) |", + "href": "/zh/api-reference/on-call/incidents/postmortem-read-template-info", + "metadata": { + "sidebarTitle": "查看故障复盘模板详情" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PostMortemTemplate" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "account_id": 2451002751131, + "template_id": "post_mortem_default_tmpl_en-us", + "name": "Default post-mortem report", + "description": "Default sections for post-mortem reports.", + "content": "[{\"type\":\"heading\",\"content\":\"Summary\"}]", + "content_markdown": "## Summary\nDescribe what happened.", + "team_id": 2477033058131, + "created_at_seconds": 1773900000, + "updated_at_seconds": 1773903600 + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "template_id", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "Template ID." + } + ] + } + }, + "/monit/preview/sync": { + "post": { + "operationId": "monit-preview-sync", + "summary": "同步预览数据源查询", + "description": "同步执行数据源查询并返回原始结果,用于在保存前预览告警规则表达式的效果。", + "tags": [ + "Monitors/通用工具" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **60 次/分钟**;**10 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |\n\n## 使用说明\n\n- `ds_type` 须与数据源类型匹配,如 `prometheus`、`loki`。\n- `ds_name` 为账户中配置的数据源显示名称。\n- `delay_seconds` 将查询窗口向前偏移指定秒数,用于补偿数据摄入延迟。\n- 响应体为数据源返回的原始 JSON,其结构随数据源类型而异。", + "href": "/zh/api-reference/monitors/monitor-utilities/monit-preview-sync", + "metadata": { + "sidebarTitle": "同步预览数据源查询" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PreviewSyncResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "status": "success", + "data": { + "resultType": "vector", + "result": [] + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreviewSyncRequest" + }, + "example": { + "ds_type": "prometheus", + "ds_name": "生产 Prometheus", + "expr": "rate(http_requests_total[5m])", + "delay_seconds": 0 + } + } + } + } + } + }, + "/rum/application/webhook/test": { + "post": { + "operationId": "rum-application-webhook-test", + "summary": "测试应用 Webhook", + "description": "发送一条 RUM 告警样例事件,用于验证应用的 Webhook URL。", + "tags": [ + "RUM/应用管理" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **应用管理**(`rum`) |\n\n## 使用说明\n\n- 接口会先校验 URL,再发送样例事件。\n- 投递失败时仍返回 HTTP 200,但 `ok=false`,错误原因在 `message` 中。", + "href": "/zh/api-reference/rum/applications/rum-application-webhook-test", + "metadata": { + "sidebarTitle": "测试应用 Webhook" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RumWebhookTestResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "ok": true, + "status_code": 200, + "message": "ok" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RumWebhookTestRequest" + }, + "example": { + "application_id": "rum-app-prod", + "webhook_url": "https://hooks.example.com/rum-alerts" + } + } + } + } + } + }, + "/status-page/info": { + "get": { + "operationId": "statusPageInfo", + "summary": "获取状态页详情", + "description": "获取指定状态页的详细配置信息。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |", + "href": "/zh/api-reference/on-call/status-pages/status-page-info", + "metadata": { + "sidebarTitle": "获取状态页详情" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "page_id": 5750613685214, + "name": "Flashduty Status Page", + "url_name": "flashduty-statuspage", + "type": "public", + "custom_domain": "status.example.com", + "logo": "https://cdn.example.com/logo.png", + "favicon": "https://cdn.example.com/favicon.png", + "page_header": "Welcome to our status page", + "page_footer": "2025 Example Corp", + "date_view": "list", + "display_uptime_mode": "chart_and_percentage", + "custom_links": [ + { + "key": "Documentation", + "value": "https://docs.example.com" + } + ], + "contact_info": "mailto:support@example.com", + "components": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "name": "Web Console", + "available_since_seconds": 1765349358, + "order_id": 1 + } + ], + "sections": [ + { + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "name": "Core Services", + "description": "Our core services", + "order_id": 1, + "hide_uptime": false, + "hide_all": false + } + ], + "subscription": { + "email": true, + "im": false + }, + "template_preference": "message" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "page_id", + "in": "query", + "required": true, + "schema": { + "type": "string" + }, + "description": "Status page ID" + } + ] + } + }, + "/status-page/create": { + "post": { + "operationId": "statusPageCreate", + "summary": "创建状态页", + "description": "创建一个新的状态页。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-create", + "metadata": { + "sidebarTitle": "创建状态页" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "page_id": 6294565612043, + "page_name": "My Status Page", + "page_url_name": "my-status-page" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "name": "My Status Page", + "url_name": "my-status-page", + "type": "public", + "page_header": "Welcome to our status page", + "contact_info": "mailto:support@example.com" + } + } + } + } + } + }, + "/status-page/update": { + "post": { + "operationId": "statusPageUpdate", + "summary": "更新状态页", + "description": "更新已有状态页的配置。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-update", + "metadata": { + "sidebarTitle": "更新状态页" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "page_id": 5750613685214, + "name": "Flashduty Status Page (Updated)", + "page_header": "Updated status page header", + "contact_info": "mailto:support@example.com" + } + } + } + } + } + }, + "/status-page/delete": { + "post": { + "operationId": "statusPageDelete", + "summary": "删除状态页", + "description": "删除指定的状态页。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-delete", + "metadata": { + "sidebarTitle": "删除状态页" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmptyRequest" + }, + "example": { + "page_id": 5750613685214 + } + } + } + } + } + }, + "/status-page/component/upsert": { + "post": { + "operationId": "statusPageComponentUpsert", + "summary": "创建或更新状态页组件", + "description": "在状态页上创建或更新服务组件。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-component-upsert", + "metadata": { + "sidebarTitle": "创建或更新状态页组件" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageComponentResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageComponentRequest" + }, + "example": { + "page_id": 5750613685214, + "components": [ + { + "name": "Web Console", + "description": "Main web interface", + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "order_id": 1 + } + ] + } + } + } + } + } + }, + "/status-page/component/delete": { + "post": { + "operationId": "statusPageComponentDelete", + "summary": "删除状态页组件", + "description": "从状态页删除服务组件。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-component-delete", + "metadata": { + "sidebarTitle": "删除状态页组件" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageComponentRequest" + }, + "example": { + "page_id": 5750613685214, + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" + ] + } + } + } + } + } + }, + "/status-page/section/upsert": { + "post": { + "operationId": "statusPageSectionUpsert", + "summary": "创建或更新状态页区域", + "description": "在状态页上创建或更新区域。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-section-upsert", + "metadata": { + "sidebarTitle": "创建或更新状态页区域" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageSectionResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageSectionRequest" + }, + "example": { + "page_id": 5750613685214, + "sections": [ + { + "name": "Core Services", + "description": "Our core services", + "order_id": 1 + } + ] + } + } + } + } + } + }, + "/status-page/section/delete": { + "post": { + "operationId": "statusPageSectionDelete", + "summary": "删除状态页区域", + "description": "从状态页删除区域。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-section-delete", + "metadata": { + "sidebarTitle": "删除状态页区域" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageSectionRequest" + }, + "example": { + "page_id": 5750613685214, + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] + } + } + } + } + } + }, + "/status-page/template/upsert": { + "post": { + "operationId": "statusPageTemplateUpsert", + "summary": "创建或更新状态页模板", + "description": "创建或更新状态页的事件模板。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-template-upsert", + "metadata": { + "sidebarTitle": "创建或更新状态页模板" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UpsertStatusPageTemplateResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "template_id": "01KP0339G5XDEPM4R86T2B23EP" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageTemplateRequest" + }, + "example": { + "page_id": 5720156736380, + "type": "pre_defined", + "template": { + "title": "Service Disruption", + "event_type": "incident", + "status": "investigating", + "description": "We are investigating a service disruption affecting some users." + } + } + } + } + } + } + }, + "/status-page/template/delete": { + "post": { + "operationId": "statusPageTemplateDelete", + "summary": "删除状态页模板", + "description": "删除状态页的事件模板。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **状态页面管理**(`on-call`) |", + "href": "/zh/api-reference/on-call/status-pages/status-page-template-delete", + "metadata": { + "sidebarTitle": "删除状态页模板" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": {} + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteStatusPageTemplateRequest" + }, + "example": { + "page_id": 5720156736380, + "type": "pre_defined", + "template_id": "01KP0339G5XDEPM4R86T2B23EP" + } + } + } + } + } + }, + "/status-page/template/list": { + "get": { + "operationId": "statusPageTemplateList", + "summary": "查询状态页模板列表", + "description": "查询状态页的所有事件模板。", + "tags": [ + "On-call/状态页" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | 无 —— 持有有效的 `app_key` 即可调用 |", + "href": "/zh/api-reference/on-call/status-pages/status-page-template-list", + "metadata": { + "sidebarTitle": "查询状态页模板列表" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "items": [ + { + "template_id": "01KC8KP6PHVPSCAB0BTKZBN2HR", + "title": "Service Disruption", + "type": "incident", + "status": "identified", + "description": "We have identified the root cause." + } + ] + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "parameters": [ + { + "name": "page_id", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + }, + "description": "Status page ID." + }, + { + "name": "type", + "in": "query", + "required": true, + "schema": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ] + }, + "description": "Template category. `pre_defined` returns predefined event templates; `message` returns message notification templates." + } + ] + } + } + }, + "components": { + "securitySchemes": { + "AppKeyAuth": { + "type": "apiKey", + "in": "query", + "name": "app_key", + "description": "在 Flashduty 控制台 账户 → APP Key 中签发的 app_key。调用任何公开 API 时都必须携带。它等同于所属账户的身份凭证,请妥善保管。" + } + }, + "responses": { + "BadRequest": { + "description": "请求非法 — 通常是参数缺失或格式不正确。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "missingParameter": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "InvalidParameter", + "message": "The specified parameter is not valid." + } + } + } + } + } + } + }, + "Unauthorized": { + "description": "app_key 缺失或无效。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "missingAppKey": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "Unauthorized", + "message": "You are unauthorized." + } + } + } + } + } + } + }, + "Forbidden": { + "description": "app_key 有效但没有执行该操作的权限。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "noEditPermission": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "AccessDenied", + "message": "Access Denied." + } + } + } + } + } + } + }, + "NotFound": { + "description": "目标资源不存在或已被删除。注意:Flashduty 对业务实体的缺失通常返回 HTTP 400 + code=`ResourceNotFound`,真正的 404 只用于未知路由。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "resourceMissing": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "ResourceNotFound", + "message": "The resource you request is not found" + } + } + } + } + } + } + }, + "TooManyRequests": { + "description": "命中限流。可能是全局 API 限流、账户级限流或集成级限流。限流按账户聚合。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "rateLimited": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "RequestTooFrequently", + "message": "Request too frequently." + } + } + } + } + } + } + }, + "ServerError": { + "description": "服务端未预期错误。反馈问题时请携带 request_id。", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "examples": { + "internal": { + "value": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "error": { + "code": "InternalError", + "message": "We encountered an internal error, and it has been reported. Please try again later." + } + } + } + } + } + } + } + }, + "schemas": { + "ErrorCode": { + "type": "string", + "description": "Flashduty error code enum. Every failed API response sets `error.code` to one of these values. The value is a stable wire string — not a localized message and not a numeric status. HTTP status is informational.", + "enum": [ + "OK", + "InvalidParameter", + "BadRequest", + "InvalidContentType", + "ResourceNotFound", + "NoLicense", + "ReferenceExist", + "Unauthorized", + "BalanceNotEnough", + "AccessDenied", + "RouteNotFound", + "MethodNotAllowed", + "UndonedOrderExist", + "RequestLocked", + "EntityTooLarge", + "RequestTooFrequently", + "RequestVerifyRequired", + "DangerousOperation", + "InternalError", + "ServiceUnavailable" + ] + }, + "DutyError": { + "type": "object", + "description": "Error payload inside the response envelope. Present only on non-2xx responses.", + "properties": { + "code": { + "$ref": "#/components/schemas/ErrorCode" + }, + "message": { + "type": "string", + "description": "Human-readable error message, localized by the caller's Accept-Language. May contain field names, IDs, or other context from the failing request." + } + }, + "required": [ + "code", + "message" + ] + }, + "SuccessEnvelope": { + "type": "object", + "description": "成功响应结构。2xx 响应中 `request_id` 标识本次调用(同时出现在 `Flashcat-Request-Id` 响应头中),`data` 为接口业务 payload。失败响应使用不同结构,参见 `ErrorResponse`。", + "properties": { + "request_id": { + "type": "string", + "description": "本次请求的唯一 ID,也会在 Flashcat-Request-Id 响应头中返回。反馈问题时请一并附上。", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "data": { + "description": "每个接口自己的业务 payload,详见各接口的 200 响应 schema。" + } + }, + "required": [ + "request_id", + "data" + ] + }, + "ErrorResponse": { + "type": "object", + "description": "Response envelope for errors. `error` is required; `data` is absent.", + "properties": { + "request_id": { + "type": "string", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "error": { + "$ref": "#/components/schemas/DutyError" + } + }, + "required": [ + "request_id", + "error" + ] + }, + "EmptyObject": { + "type": "object", + "description": "空对象。当操作的成功信号就是不报错时,作为 `data` 返回。", + "additionalProperties": false + }, + "EmptyResponse": { + "type": "object", + "description": "空响应体。成功时服务端返回 `data: null`。", + "properties": {} + }, + "EmptyRequest": { + "type": "object", + "description": "无参数。", + "additionalProperties": false + }, + "CreateIncidentRequest": { + "type": "object", + "description": "手动创建故障所需的参数。", + "required": [ + "incident_severity" + ], + "properties": { + "incident_severity": { + "type": "string", + "enum": [ + "Info", + "Warning", + "Critical" + ], + "description": "故障严重程度。" + }, + "title": { + "type": "string", + "maxLength": 512, + "description": "故障标题,最多 512 个字符。" + }, + "description": { + "type": "string", + "maxLength": 1024, + "description": "故障描述,最多 1024 个字符。" + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "归属的协作空间 ID,留空表示独立故障。" + }, + "assigned_to": { + "type": "object", + "description": "故障处理人员指派目标。`person_ids` 与 `escalate_rule_id` 至少设置一项。", + "properties": { + "person_ids": { "type": "array", "items": { "type": "integer", @@ -41215,295 +43052,995 @@ "team_id": { "type": "integer", "format": "int64", - "description": "所属团队 ID;0 表示未绑定团队。创建后不可变更。" + "description": "所属团队 ID;0 表示未绑定团队。创建后不可变更。" + }, + "team_name": { + "type": "string", + "description": "解析出的团队名称;未绑定或团队已删除时为空。" + }, + "is_mine": { + "type": "boolean", + "description": "当该会话由调用者创建时为 true。" + }, + "can_manage": { + "type": "boolean", + "description": "当调用者可重命名/归档/删除该会话时为 true。" + }, + "status": { + "type": "string", + "description": "生命周期状态。", + "enum": [ + "enabled", + "deleted" + ] + }, + "incognito": { + "type": "boolean", + "description": "无痕(不持久化记忆)会话时为 true。" + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "会话创建时间,Unix 毫秒时间戳。" + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "会话最近更新时间,Unix 毫秒时间戳。" + }, + "template_staging_round_id": { + "type": "string", + "description": "当前 save→validate 轮次 ID(仅 template-assistant);否则为空。" + }, + "state": { + "type": "object", + "additionalProperties": true, + "description": "原始会话状态包(会话级键)。为空时省略。" + }, + "bound_environment": { + "$ref": "#/components/schemas/EnvironmentBinding" + }, + "context_resolved": { + "$ref": "#/components/schemas/ContextResolvedItem" + }, + "token_usage": { + "$ref": "#/components/schemas/SessionTokenUsage" + }, + "current_context_tokens": { + "type": "integer", + "format": "int64", + "description": "截至最近一轮的 LLM 上下文窗口的 token 数。0 表示尚无已完成的轮次。" + }, + "context_window": { + "type": "integer", + "format": "int64", + "description": "所绑定模型的最大上下文 token 数。0 表示未知。" + }, + "archived_at": { + "type": "integer", + "format": "int64", + "description": "归档时间,Unix 毫秒时间戳;0 表示未归档。" + }, + "pinned_at": { + "type": "integer", + "format": "int64", + "description": "调用者的个人置顶时间,Unix 毫秒时间戳;0 表示未置顶。" + }, + "last_event_at": { + "type": "integer", + "format": "int64", + "description": "最近一条助手侧事件的时间,Unix 毫秒时间戳。" + }, + "is_running": { + "type": "boolean", + "description": "当该会话当前有正在进行的智能体轮次时为 true。" + }, + "has_unread": { + "type": "boolean", + "description": "当存在调用者尚未查看的助手输出时为 true。" + } + } + }, + "SessionListResponse": { + "type": "object", + "description": "一页智能体会话。", + "properties": { + "total": { + "type": "integer", + "format": "int64", + "description": "匹配过滤条件的会话总数(忽略分页)。" + }, + "sessions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SessionItem" + }, + "description": "当前页的会话。" + } + } + }, + "SessionGetRequest": { + "type": "object", + "description": "查询单个会话,并返回其最近事件的一页(向更早方向分页)。", + "properties": { + "session_id": { + "type": "string", + "description": "目标会话 ID。", + "minLength": 1 + }, + "num_recent_events": { + "type": "integer", + "description": "旧版每页数量:返回的最近事件数。与 `limit` 同时设置时以 `limit` 为准;0 使用服务端默认值(100)。", + "minimum": 0, + "maximum": 1000 + }, + "limit": { + "type": "integer", + "description": "事件每页数量;优先于 `num_recent_events`。0 使用服务端默认值(100)。", + "minimum": 0, + "maximum": 1000 + }, + "search_after_ctx": { + "type": "string", + "description": "上一次响应返回的不透明游标;回传以获取更早的一页。", + "maxLength": 4096 + } + }, + "required": [ + "session_id" + ] + }, + "EventItem": { + "type": "object", + "description": "单条已持久化的会话事件。content/actions/usage_metadata 携带原始 ADK 信封,请将其视为不透明的结构化负载。", + "properties": { + "event_id": { + "type": "string", + "description": "事件标识。" + }, + "session_id": { + "type": "string", + "description": "所属会话 ID。" + }, + "invocation_id": { + "type": "string", + "description": "标识一轮的 ADK 调用 ID。" + }, + "author": { + "type": "string", + "description": "事件作者(如 user 或智能体名称)。" + }, + "branch": { + "type": "string", + "description": "嵌套智能体的 ADK 分支路径。" + }, + "content": { + "type": "object", + "additionalProperties": true, + "description": "ADK content 信封 {role, parts:[...]}。" + }, + "actions": { + "type": "object", + "additionalProperties": true, + "description": "ADK actions 信封(状态增量、转移、升级)。" + }, + "usage_metadata": { + "type": "object", + "additionalProperties": true, + "description": "单轮 token 用量元数据。" + }, + "partial": { + "type": "boolean", + "description": "流式部分分片时为 true。" + }, + "turn_complete": { + "type": "boolean", + "description": "一轮的终止事件上为 true。" + }, + "error_code": { + "type": "string", + "description": "当该事件表示失败时的错误码。" + }, + "error_message": { + "type": "string", + "description": "可读的错误信息(如有)。" + }, + "status": { + "type": "string", + "description": "事件状态。", + "enum": [ + "normal", + "compressed" + ] + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "事件写入时间,Unix 毫秒时间戳。" + } + } + }, + "SessionGetResponse": { + "type": "object", + "description": "一个会话及其事件的一页(向更早方向分页)。", + "properties": { + "session": { + "$ref": "#/components/schemas/SessionItem" + }, + "events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EventItem" + }, + "description": "最近事件,按 (created_at, event_id) 升序排列。" + }, + "has_more_older": { + "type": "boolean", + "description": "当本页之外仍有更早的事件时为 true。" + }, + "search_after_ctx": { + "type": "string", + "description": "不透明游标;作为 search_after_ctx 回传以获取更早的一页。has_more_older 为 false 时省略。" + } + } + }, + "SessionExportRequest": { + "type": "object", + "description": "以流式 NDJSON 导出单个会话的完整事件记录。", + "properties": { + "session_id": { + "type": "string", + "description": "目标会话 ID。" + }, + "include_subagents": { + "type": "boolean", + "description": "为 true 时,每条 subagent_dispatch 行后会跟随子会话的完整事件流,并以其自身的 session_meta 包裹。默认 false。" + } + }, + "required": [ + "session_id" + ] + }, + "SkillUploadRequest": { + "type": "object", + "description": "上传技能压缩包的 multipart 表单。", + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "技能压缩包(.skill / .zip / .tar.gz / .tgz),最大 100MB。" + }, + "team_id": { + "type": "integer", + "description": "新技能的团队范围:0 表示账户级。", + "format": "int64" + }, + "replace": { + "type": "boolean", + "description": "为 true 时覆盖同名技能。" + }, + "skill_id": { + "type": "string", + "description": "替换指定技能时的技能 ID。" + } + }, + "required": [ + "file" + ] + }, + "SessionDeleteRequest": { + "type": "object", + "description": "按 ID 删除会话。", + "properties": { + "session_id": { + "type": "string", + "description": "目标会话 ID。", + "minLength": 1 + } + }, + "required": [ + "session_id" + ] + }, + "DeletePostMortemTemplateRequest": { + "type": "object", + "description": "删除故障复盘模板的参数。", + "required": [ + "template_id" + ], + "properties": { + "template_id": { + "type": "string", + "description": "模板 ID。" + } + } + }, + "InitPostMortemRequest": { + "type": "object", + "description": "从故障初始化复盘报告的参数。", + "required": [ + "incident_ids", + "template_id" + ], + "properties": { + "incident_ids": { + "type": "array", + "minItems": 1, + "maxItems": 10, + "items": { + "type": "string" + }, + "description": "要关联到复盘报告的故障 ID,1-10 个。" + }, + "template_id": { + "type": "string", + "description": "用于初始化报告的模板 ID。" + } + } + }, + "ListPostMortemTemplatesRequest": { + "type": "object", + "description": "故障复盘模板的分页与排序参数。", + "properties": { + "order_by": { + "type": "string", + "enum": [ + "created_at_seconds" + ], + "description": "排序字段。" + }, + "asc": { + "type": "boolean", + "description": "为 true 时按升序排序。" + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "页码,从 1 开始。" + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "每页数量,最多 100。" + }, + "search_after_ctx": { + "type": "string", + "description": "上一页响应返回的向后分页游标。" + } + } + }, + "ListPostMortemTemplatesResponse": { + "type": "object", + "description": "分页后的故障复盘模板列表。", + "required": [ + "items", + "total", + "has_next_page" + ], + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PostMortemTemplate" + }, + "description": "当前页的模板。" + }, + "total": { + "type": "integer", + "format": "int64", + "description": "匹配的模板总数。" + }, + "has_next_page": { + "type": "boolean", + "description": "为 true 表示还有下一页。" + }, + "search_after_ctx": { + "type": "string", + "description": "向后分页游标。" + } + } + }, + "PostMortemTemplate": { + "type": "object", + "description": "故障复盘报告模板。", + "required": [ + "account_id", + "template_id", + "name", + "description", + "content", + "content_markdown", + "team_id", + "created_at_seconds", + "updated_at_seconds" + ], + "properties": { + "account_id": { + "type": "integer", + "format": "int64", + "description": "模板所属账号 ID。内置模板为 0。" }, - "team_name": { + "template_id": { "type": "string", - "description": "解析出的团队名称;未绑定或团队已删除时为空。" + "description": "模板 ID。内置模板使用稳定的 `post_mortem_default_tmpl_*` ID。" }, - "is_mine": { - "type": "boolean", - "description": "当该会话由调用者创建时为 true。" + "name": { + "type": "string", + "description": "控制台展示的模板名称。" }, - "can_manage": { - "type": "boolean", - "description": "当调用者可重命名/归档/删除该会话时为 true。" + "description": { + "type": "string", + "description": "模板描述。" }, - "status": { + "content": { "type": "string", - "description": "生命周期状态。", - "enum": [ - "enabled", - "deleted" - ] + "description": "用于初始化复盘正文的 BlockNote JSON 内容。" }, - "incognito": { - "type": "boolean", - "description": "无痕(不持久化记忆)会话时为 true。" + "content_markdown": { + "type": "string", + "description": "模板内容的 Markdown 版本,供 AI 生成使用。" }, - "created_at": { + "team_id": { "type": "integer", "format": "int64", - "description": "会话创建时间,Unix 毫秒时间戳。" + "description": "管理团队 ID。内置模板为 0。" }, - "updated_at": { + "created_at_seconds": { "type": "integer", "format": "int64", - "description": "会话最近更新时间,Unix 毫秒时间戳。" + "description": "模板创建时间的 Unix 秒级时间戳。" }, - "template_staging_round_id": { + "updated_at_seconds": { + "type": "integer", + "format": "int64", + "description": "模板最近更新时间的 Unix 秒级时间戳。" + } + } + }, + "PreviewSyncRequest": { + "type": "object", + "required": [ + "ds_type", + "ds_name", + "expr" + ], + "description": "同步数据源查询预览的参数。", + "properties": { + "ds_type": { "type": "string", - "description": "当前 save→validate 轮次 ID(仅 template-assistant);否则为空。" + "description": "数据源类型,如 `prometheus`、`loki`、`elasticsearch`。" }, - "state": { - "type": "object", - "additionalProperties": true, - "description": "原始会话状态包(会话级键)。为空时省略。" + "ds_name": { + "type": "string", + "description": "账户中配置的数据源显示名称。" }, - "bound_environment": { - "$ref": "#/components/schemas/EnvironmentBinding" + "expr": { + "type": "string", + "description": "查询表达式,格式因 `ds_type` 而异(Prometheus 为 PromQL,Loki 为 LogQL 等)。" }, - "context_resolved": { - "$ref": "#/components/schemas/ContextResolvedItem" + "delay_seconds": { + "type": "integer", + "description": "将查询窗口向前偏移的秒数,用于补偿数据摄入延迟。" }, - "token_usage": { - "$ref": "#/components/schemas/SessionTokenUsage" + "args": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "特定类型的额外查询参数。" + } + } + }, + "PreviewSyncResponse": { + "type": "object", + "description": "数据源返回的原始 JSON,结构随数据源类型而异。" + }, + "ResetPostMortemBasicsRequest": { + "type": "object", + "description": "写回复盘报告的故障基础信息。", + "required": [ + "post_mortem_id", + "incidents_highest_severity", + "incidents_earliest_start_seconds" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID。" }, - "current_context_tokens": { - "type": "integer", - "format": "int64", - "description": "截至最近一轮的 LLM 上下文窗口的 token 数。0 表示尚无已完成的轮次。" + "incidents_highest_severity": { + "type": "string", + "description": "关联故障中的最高严重级别。" }, - "context_window": { + "incidents_earliest_start_seconds": { "type": "integer", "format": "int64", - "description": "所绑定模型的最大上下文 token 数。0 表示未知。" + "minimum": 1, + "description": "最早关联故障开始时间的 Unix 秒级时间戳。" }, - "archived_at": { + "incidents_latest_close_seconds": { "type": "integer", "format": "int64", - "description": "归档时间,Unix 毫秒时间戳;0 表示未归档。" + "minimum": 0, + "description": "最晚关联故障关闭时间的 Unix 秒级时间戳;仍未关闭时为 0。" }, - "pinned_at": { + "incidents_total_duration_seconds": { "type": "integer", "format": "int64", - "description": "调用者的个人置顶时间,Unix 毫秒时间戳;0 表示未置顶。" + "minimum": 0, + "description": "故障总持续时间,单位秒。" }, - "last_event_at": { - "type": "integer", - "format": "int64", - "description": "最近一条助手侧事件的时间,Unix 毫秒时间戳。" + "responder_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "写入报告的响应人成员 ID。" + } + } + }, + "ResetPostMortemFollowUpsRequest": { + "type": "object", + "description": "替换复盘后续行动项的参数。", + "required": [ + "post_mortem_id" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID。" }, - "is_running": { - "type": "boolean", - "description": "当该会话当前有正在进行的智能体轮次时为 true。" + "follow_ups": { + "type": "string", + "description": "自由文本格式的后续行动项。" + } + } + }, + "ResetPostMortemStatusRequest": { + "type": "object", + "description": "更新复盘报告状态的参数。", + "required": [ + "post_mortem_id", + "status" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID。" }, - "has_unread": { - "type": "boolean", - "description": "当存在调用者尚未查看的助手输出时为 true。" + "status": { + "type": "string", + "enum": [ + "drafting", + "published" + ], + "description": "目标报告状态。" } } }, - "SessionListResponse": { + "ResetPostMortemTitleRequest": { "type": "object", - "description": "一页智能体会话。", + "description": "更新复盘报告标题的参数。", + "required": [ + "post_mortem_id", + "title" + ], "properties": { - "total": { - "type": "integer", - "format": "int64", - "description": "匹配过滤条件的会话总数(忽略分页)。" + "post_mortem_id": { + "type": "string", + "description": "复盘 ID。" }, - "sessions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SessionItem" - }, - "description": "当前页的会话。" + "title": { + "type": "string", + "description": "新的报告标题。" } } }, - "SessionGetRequest": { + "RumWebhookTestRequest": { "type": "object", - "description": "查询单个会话,并返回其最近事件的一页(向更早方向分页)。", + "description": "发送 RUM 告警测试 Webhook 的参数。", + "required": [ + "application_id", + "webhook_url" + ], "properties": { - "session_id": { + "application_id": { "type": "string", - "description": "目标会话 ID。", - "minLength": 1 + "description": "RUM 应用 ID。" }, - "num_recent_events": { - "type": "integer", - "description": "旧版每页数量:返回的最近事件数。与 `limit` 同时设置时以 `limit` 为准;0 使用服务端默认值(100)。", - "minimum": 0, - "maximum": 1000 + "webhook_url": { + "type": "string", + "format": "uri", + "description": "接收测试告警事件的 Webhook URL。" + } + } + }, + "RumWebhookTestResponse": { + "type": "object", + "description": "Webhook 测试投递结果。", + "required": [ + "ok", + "status_code", + "message" + ], + "properties": { + "ok": { + "type": "boolean", + "description": "Webhook 端点是否接受了测试事件。" }, - "limit": { + "status_code": { "type": "integer", - "description": "事件每页数量;优先于 `num_recent_events`。0 使用服务端默认值(100)。", - "minimum": 0, - "maximum": 1000 + "description": "Webhook 端点返回的 HTTP 状态码;未收到响应时为 0。" }, - "search_after_ctx": { + "message": { "type": "string", - "description": "上一次响应返回的不透明游标;回传以获取更早的一页。", - "maxLength": 4096 + "description": "成功时为 `ok`,失败时为投递错误信息。" } - }, + } + }, + "TryLinkPersonRequest": { + "type": "object", + "description": "尝试自动关联 IM 账号的参数。", "required": [ - "session_id" - ] + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "IM 集成 ID。" + } + } }, - "EventItem": { + "TryLinkPersonResponse": { "type": "object", - "description": "单条已持久化的会话事件。content/actions/usage_metadata 携带原始 ADK 信封,请将其视为不透明的结构化负载。", + "description": "本次尝试关联成功的人员。", + "required": [ + "new_linked_person_ids" + ], "properties": { - "event_id": { - "type": "string", - "description": "事件标识。" - }, - "session_id": { + "new_linked_person_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "本次调用中新关联成功的人员 ID。" + } + } + }, + "UpsertPostMortemTemplateRequest": { + "type": "object", + "description": "创建或更新故障复盘模板的参数。", + "required": [ + "name", + "content" + ], + "properties": { + "template_id": { "type": "string", - "description": "所属会话 ID。" + "description": "模板 ID。创建新模板时省略;更新已有模板时传入。" }, - "invocation_id": { - "type": "string", - "description": "标识一轮的 ADK 调用 ID。" + "team_id": { + "type": "integer", + "format": "int64", + "description": "管理团队 ID。创建自定义模板时必填。" }, - "author": { + "name": { "type": "string", - "description": "事件作者(如 user 或智能体名称)。" + "description": "模板名称。" }, - "branch": { + "description": { "type": "string", - "description": "嵌套智能体的 ADK 分支路径。" + "description": "模板描述。" }, "content": { - "type": "object", - "additionalProperties": true, - "description": "ADK content 信封 {role, parts:[...]}。" - }, - "actions": { - "type": "object", - "additionalProperties": true, - "description": "ADK actions 信封(状态增量、转移、升级)。" - }, - "usage_metadata": { - "type": "object", - "additionalProperties": true, - "description": "单轮 token 用量元数据。" - }, - "partial": { - "type": "boolean", - "description": "流式部分分片时为 true。" - }, - "turn_complete": { - "type": "boolean", - "description": "一轮的终止事件上为 true。" - }, - "error_code": { "type": "string", - "description": "当该事件表示失败时的错误码。" - }, - "error_message": { - "type": "string", - "description": "可读的错误信息(如有)。" + "description": "BlockNote JSON 模板内容。" }, - "status": { + "content_markdown": { "type": "string", - "description": "事件状态。", - "enum": [ - "normal", - "compressed" - ] - }, - "created_at": { + "description": "模板内容的 Markdown 版本。" + } + } + }, + "DeleteStatusPageComponentRequest": { + "type": "object", + "description": "删除状态页服务组件的请求参数。", + "required": [ + "page_id", + "component_ids" + ], + "properties": { + "page_id": { "type": "integer", "format": "int64", - "description": "事件写入时间,Unix 毫秒时间戳。" + "description": "状态页 ID。" + }, + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "要删除的组件 ID 列表。" } } }, - "SessionGetResponse": { + "DeleteStatusPageSectionRequest": { "type": "object", - "description": "一个会话及其事件的一页(向更早方向分页)。", + "description": "删除状态页区域的请求参数。", + "required": [ + "page_id", + "section_ids" + ], "properties": { - "session": { - "$ref": "#/components/schemas/SessionItem" + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID。" }, - "events": { + "section_ids": { "type": "array", "items": { - "$ref": "#/components/schemas/EventItem" + "type": "string" }, - "description": "最近事件,按 (created_at, event_id) 升序排列。" + "description": "要删除的区域 ID 列表。" + } + } + }, + "DeleteStatusPageTemplateRequest": { + "type": "object", + "description": "删除状态页模板的请求参数。", + "required": [ + "page_id", + "type", + "template_id" + ], + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID。" }, - "has_more_older": { - "type": "boolean", - "description": "当本页之外仍有更早的事件时为 true。" + "type": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ], + "description": "模板分类。" }, - "search_after_ctx": { + "template_id": { "type": "string", - "description": "不透明游标;作为 search_after_ctx 回传以获取更早的一页。has_more_older 为 false 时省略。" + "description": "要删除的模板 ID。" } } }, - "SessionExportRequest": { + "UpsertStatusPageComponentRequest": { "type": "object", - "description": "以流式 NDJSON 导出单个会话的完整事件记录。", + "description": "创建或更新状态页服务组件的请求参数。", + "required": [ + "page_id", + "components" + ], "properties": { - "session_id": { - "type": "string", - "description": "目标会话 ID。" + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID。" }, - "include_subagents": { - "type": "boolean", - "description": "为 true 时,每条 subagent_dispatch 行后会跟随子会话的完整事件流,并以其自身的 session_meta 包裹。默认 false。" + "components": { + "type": "array", + "description": "要创建或更新的组件列表。", + "items": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "component_id": { + "type": "string", + "description": "组件 ID。省略则创建新组件;提供则更新已有组件。" + }, + "section_id": { + "type": "string", + "description": "所属区域 ID。省略则将组件置于顶层。" + }, + "name": { + "type": "string", + "description": "组件显示名称。" + }, + "description": { + "type": "string", + "description": "组件描述。" + }, + "order_id": { + "type": "integer", + "format": "int64", + "description": "在所属区域中的显示顺序。" + }, + "hide_uptime": { + "type": "boolean", + "description": "为 true 时,在汇总接口中隐藏该组件的可用率数据。" + }, + "hide_all": { + "type": "boolean", + "description": "为 true 时,在汇总接口中完全隐藏该组件。" + } + } + } } - }, + } + }, + "UpsertStatusPageComponentResponse": { + "type": "object", + "description": "创建或更新状态页组件的结果。", "required": [ - "session_id" - ] + "component_ids" + ], + "properties": { + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "创建或更新的组件 ID 列表,顺序与请求一致。" + } + } }, - "SkillUploadRequest": { + "UpsertStatusPageSectionRequest": { "type": "object", - "description": "上传技能压缩包的 multipart 表单。", + "description": "创建或更新状态页区域的请求参数。", + "required": [ + "page_id", + "sections" + ], "properties": { - "file": { - "type": "string", - "format": "binary", - "description": "技能压缩包(.skill / .zip / .tar.gz / .tgz),最大 100MB。" - }, - "team_id": { + "page_id": { "type": "integer", - "description": "新技能的团队范围:0 表示账户级。", - "format": "int64" - }, - "replace": { - "type": "boolean", - "description": "为 true 时覆盖同名技能。" + "format": "int64", + "description": "状态页 ID。" }, - "skill_id": { - "type": "string", - "description": "替换指定技能时的技能 ID。" + "sections": { + "type": "array", + "description": "要创建或更新的区域列表。", + "items": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "section_id": { + "type": "string", + "description": "区域 ID。省略则创建新区域;提供则更新已有区域。" + }, + "name": { + "type": "string", + "description": "区域显示名称。" + }, + "description": { + "type": "string", + "description": "区域描述。" + }, + "order_id": { + "type": "integer", + "format": "int64", + "description": "显示顺序。" + }, + "hide_uptime": { + "type": "boolean", + "description": "为 true 时,隐藏该区域下所有组件的可用率数据。" + }, + "hide_all": { + "type": "boolean", + "description": "为 true 时,在汇总接口中完全隐藏该区域。" + } + } + } } - }, + } + }, + "UpsertStatusPageSectionResponse": { + "type": "object", + "description": "创建或更新状态页区域的结果。", "required": [ - "file" - ] + "section_ids" + ], + "properties": { + "section_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "创建或更新的区域 ID 列表,顺序与请求一致。" + } + } }, - "SessionDeleteRequest": { + "UpsertStatusPageTemplateRequest": { "type": "object", - "description": "按 ID 删除会话。", + "description": "创建或更新状态页模板的请求参数。", + "required": [ + "page_id", + "type", + "template" + ], "properties": { - "session_id": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID。" + }, + "type": { "type": "string", - "description": "目标会话 ID。", - "minLength": 1 + "enum": [ + "pre_defined", + "message" + ], + "description": "模板分类。`pre_defined` 为预定义事件模板;`message` 为通知消息模板。" + }, + "template": { + "type": "object", + "description": "模板内容。", + "required": [ + "title", + "event_type", + "status" + ], + "properties": { + "template_id": { + "type": "string", + "description": "模板 ID。省略则创建;提供则更新。" + }, + "title": { + "type": "string", + "description": "模板标题。" + }, + "event_type": { + "type": "string", + "enum": [ + "incident", + "maintenance" + ], + "description": "本模板适用的事件类型。" + }, + "status": { + "type": "string", + "enum": [ + "investigating", + "identified", + "monitoring", + "resolved", + "scheduled", + "ongoing", + "completed" + ], + "description": "本模板对应的事件状态。" + }, + "description": { + "type": "string", + "description": "模板正文(Markdown)。" + } + } } - }, + } + }, + "UpsertStatusPageTemplateResponse": { + "type": "object", + "description": "创建或更新状态页模板的结果。", "required": [ - "session_id" - ] + "template_id" + ], + "properties": { + "template_id": { + "type": "string", + "description": "创建或更新的模板 ID。" + } + } } } } diff --git a/roundtrip_gen_test.go b/roundtrip_gen_test.go index 0310226..781eae4 100644 --- a/roundtrip_gen_test.go +++ b/roundtrip_gen_test.go @@ -8,170 +8,179 @@ import "encoding/json" // endpoint's response data payload into its generated Go type. It drives the // spec-example round-trip test (roundtrip_test.go). var exampleDataDecoders = map[string]func(json.RawMessage) error{ - "GET /incident/post-mortem/info": func(d json.RawMessage) error { var v PostMortemItem; return json.Unmarshal(d, &v) }, - "GET /status-page/change/active/list": func(d json.RawMessage) error { var v StatusPageChangeListResponse; return json.Unmarshal(d, &v) }, - "GET /status-page/change/info": func(d json.RawMessage) error { var v StatusPageChangeItem; return json.Unmarshal(d, &v) }, - "GET /status-page/change/list": func(d json.RawMessage) error { var v StatusPageChangeListResponse; return json.Unmarshal(d, &v) }, - "GET /status-page/list": func(d json.RawMessage) error { var v ListStatusPageResponse; return json.Unmarshal(d, &v) }, - "GET /status-page/migration/status": func(d json.RawMessage) error { var v StatusPageMigrationJob; return json.Unmarshal(d, &v) }, - "GET /status-page/subscriber/list": func(d json.RawMessage) error { var v StatusPageSubscriberListResponse; return json.Unmarshal(d, &v) }, - "POST /account/info": func(d json.RawMessage) error { var v AccountInfo; return json.Unmarshal(d, &v) }, - "POST /alert-event/list": func(d json.RawMessage) error { var v AlertEventGlobalListResponse; return json.Unmarshal(d, &v) }, - "POST /alert/event/list": func(d json.RawMessage) error { var v AlertEventListResponse; return json.Unmarshal(d, &v) }, - "POST /alert/feed": func(d json.RawMessage) error { var v AlertFeedResponse; return json.Unmarshal(d, &v) }, - "POST /alert/info": func(d json.RawMessage) error { var v AlertItem; return json.Unmarshal(d, &v) }, - "POST /alert/list": func(d json.RawMessage) error { var v AlertListResponse; return json.Unmarshal(d, &v) }, - "POST /alert/list-by-ids": func(d json.RawMessage) error { var v AlertListResponse; return json.Unmarshal(d, &v) }, - "POST /alert/pipeline/info": func(d json.RawMessage) error { var v AlertPipelineItem; return json.Unmarshal(d, &v) }, - "POST /alert/pipeline/list": func(d json.RawMessage) error { var v AlertPipelineListResponse; return json.Unmarshal(d, &v) }, - "POST /audit/operation/list": func(d json.RawMessage) error { var v AuditOperationListResponse; return json.Unmarshal(d, &v) }, - "POST /audit/search": func(d json.RawMessage) error { var v AuditSearchResponse; return json.Unmarshal(d, &v) }, - "POST /calendar/create": func(d json.RawMessage) error { var v CalendarCreateResponse; return json.Unmarshal(d, &v) }, - "POST /calendar/event/list": func(d json.RawMessage) error { var v CalEventListResponse; return json.Unmarshal(d, &v) }, - "POST /calendar/event/upsert": func(d json.RawMessage) error { var v CalEventUpsertResponse; return json.Unmarshal(d, &v) }, - "POST /calendar/info": func(d json.RawMessage) error { var v CalendarItem; return json.Unmarshal(d, &v) }, - "POST /calendar/list": func(d json.RawMessage) error { var v CalendarListResponse; return json.Unmarshal(d, &v) }, - "POST /change/list": func(d json.RawMessage) error { var v ListChangeResponse; return json.Unmarshal(d, &v) }, - "POST /channel/create": func(d json.RawMessage) error { var v ChannelCreateResponse; return json.Unmarshal(d, &v) }, - "POST /channel/escalate/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, - "POST /channel/escalate/rule/info": func(d json.RawMessage) error { var v EscalateRuleItem; return json.Unmarshal(d, &v) }, - "POST /channel/escalate/rule/list": func(d json.RawMessage) error { var v ListEscalationRulesResponse; return json.Unmarshal(d, &v) }, + "GET /incident/post-mortem/info": func(d json.RawMessage) error { var v PostMortemItem; return json.Unmarshal(d, &v) }, + "GET /incident/post-mortem/template/info": func(d json.RawMessage) error { var v PostMortemTemplate; return json.Unmarshal(d, &v) }, + "GET /status-page/change/active/list": func(d json.RawMessage) error { var v StatusPageChangeListResponse; return json.Unmarshal(d, &v) }, + "GET /status-page/change/info": func(d json.RawMessage) error { var v StatusPageChangeItem; return json.Unmarshal(d, &v) }, + "GET /status-page/change/list": func(d json.RawMessage) error { var v StatusPageChangeListResponse; return json.Unmarshal(d, &v) }, + "GET /status-page/list": func(d json.RawMessage) error { var v ListStatusPageResponse; return json.Unmarshal(d, &v) }, + "GET /status-page/migration/status": func(d json.RawMessage) error { var v StatusPageMigrationJob; return json.Unmarshal(d, &v) }, + "GET /status-page/subscriber/list": func(d json.RawMessage) error { var v StatusPageSubscriberListResponse; return json.Unmarshal(d, &v) }, + "POST /account/info": func(d json.RawMessage) error { var v AccountInfo; return json.Unmarshal(d, &v) }, + "POST /alert-event/list": func(d json.RawMessage) error { var v AlertEventGlobalListResponse; return json.Unmarshal(d, &v) }, + "POST /alert/event/list": func(d json.RawMessage) error { var v AlertEventListResponse; return json.Unmarshal(d, &v) }, + "POST /alert/feed": func(d json.RawMessage) error { var v AlertFeedResponse; return json.Unmarshal(d, &v) }, + "POST /alert/info": func(d json.RawMessage) error { var v AlertItem; return json.Unmarshal(d, &v) }, + "POST /alert/list": func(d json.RawMessage) error { var v AlertListResponse; return json.Unmarshal(d, &v) }, + "POST /alert/list-by-ids": func(d json.RawMessage) error { var v AlertListResponse; return json.Unmarshal(d, &v) }, + "POST /alert/pipeline/info": func(d json.RawMessage) error { var v AlertPipelineItem; return json.Unmarshal(d, &v) }, + "POST /alert/pipeline/list": func(d json.RawMessage) error { var v AlertPipelineListResponse; return json.Unmarshal(d, &v) }, + "POST /audit/operation/list": func(d json.RawMessage) error { var v AuditOperationListResponse; return json.Unmarshal(d, &v) }, + "POST /audit/search": func(d json.RawMessage) error { var v AuditSearchResponse; return json.Unmarshal(d, &v) }, + "POST /calendar/create": func(d json.RawMessage) error { var v CalendarCreateResponse; return json.Unmarshal(d, &v) }, + "POST /calendar/event/list": func(d json.RawMessage) error { var v CalEventListResponse; return json.Unmarshal(d, &v) }, + "POST /calendar/event/upsert": func(d json.RawMessage) error { var v CalEventUpsertResponse; return json.Unmarshal(d, &v) }, + "POST /calendar/info": func(d json.RawMessage) error { var v CalendarItem; return json.Unmarshal(d, &v) }, + "POST /calendar/list": func(d json.RawMessage) error { var v CalendarListResponse; return json.Unmarshal(d, &v) }, + "POST /change/list": func(d json.RawMessage) error { var v ListChangeResponse; return json.Unmarshal(d, &v) }, + "POST /channel/create": func(d json.RawMessage) error { var v ChannelCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/escalate/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/escalate/rule/info": func(d json.RawMessage) error { var v EscalateRuleItem; return json.Unmarshal(d, &v) }, + "POST /channel/escalate/rule/list": func(d json.RawMessage) error { var v ListEscalationRulesResponse; return json.Unmarshal(d, &v) }, "POST /channel/escalate/webhook/robot/list": func(d json.RawMessage) error { var v ChannelsChannelEscalateWebhookRobotListResponse return json.Unmarshal(d, &v) }, - "POST /channel/info": func(d json.RawMessage) error { var v ChannelItem; return json.Unmarshal(d, &v) }, - "POST /channel/infos": func(d json.RawMessage) error { var v ChannelInfosResponse; return json.Unmarshal(d, &v) }, - "POST /channel/inhibit/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, - "POST /channel/inhibit/rule/list": func(d json.RawMessage) error { var v ListInhibitRulesResponse; return json.Unmarshal(d, &v) }, - "POST /channel/list": func(d json.RawMessage) error { var v ListChannelsResponse; return json.Unmarshal(d, &v) }, - "POST /channel/silence/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, - "POST /channel/silence/rule/list": func(d json.RawMessage) error { var v ListSilenceRulesResponse; return json.Unmarshal(d, &v) }, - "POST /channel/unsubscribe/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, - "POST /channel/unsubscribe/rule/list": func(d json.RawMessage) error { var v ListDropRulesResponse; return json.Unmarshal(d, &v) }, - "POST /channel/update": func(d json.RawMessage) error { var v UpdateChannelResponse; return json.Unmarshal(d, &v) }, - "POST /datasource/im/war-room-enabled/list": func(d json.RawMessage) error { var v ListWarRoomEnabledResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/info": func(d json.RawMessage) error { var v EnrichmentItem; return json.Unmarshal(d, &v) }, - "POST /enrichment/list": func(d json.RawMessage) error { var v EnrichmentListResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/api/create": func(d json.RawMessage) error { var v MappingAPICreateResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/api/info": func(d json.RawMessage) error { var v MappingAPIItem; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/api/list": func(d json.RawMessage) error { var v MappingAPIListResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/data/download": func(d json.RawMessage) error { var v CSVFileResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/data/list": func(d json.RawMessage) error { var v MappingDataListResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/data/upsert": func(d json.RawMessage) error { var v MappingDataUpsertResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/schema/create": func(d json.RawMessage) error { var v MappingSchemaCreateResponse; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/schema/info": func(d json.RawMessage) error { var v MappingSchemaItem; return json.Unmarshal(d, &v) }, - "POST /enrichment/mapping/schema/list": func(d json.RawMessage) error { var v MappingSchemaListResponse; return json.Unmarshal(d, &v) }, - "POST /field/create": func(d json.RawMessage) error { var v CreateFieldResponse; return json.Unmarshal(d, &v) }, - "POST /field/info": func(d json.RawMessage) error { var v FieldItem; return json.Unmarshal(d, &v) }, - "POST /field/list": func(d json.RawMessage) error { var v FieldListResponse; return json.Unmarshal(d, &v) }, - "POST /incident/alert/list": func(d json.RawMessage) error { var v ListIncidentAlertsResponse; return json.Unmarshal(d, &v) }, - "POST /incident/create": func(d json.RawMessage) error { var v CreateIncidentResponse; return json.Unmarshal(d, &v) }, - "POST /incident/custom-action/do": func(d json.RawMessage) error { var v DoIncidentCustomActionResponse; return json.Unmarshal(d, &v) }, - "POST /incident/feed": func(d json.RawMessage) error { var v ListIncidentFeedResponse; return json.Unmarshal(d, &v) }, - "POST /incident/info": func(d json.RawMessage) error { var v IncidentInfo; return json.Unmarshal(d, &v) }, - "POST /incident/list": func(d json.RawMessage) error { var v IncidentListResponse; return json.Unmarshal(d, &v) }, - "POST /incident/list-by-ids": func(d json.RawMessage) error { var v IncidentListResponse; return json.Unmarshal(d, &v) }, - "POST /incident/past/list": func(d json.RawMessage) error { var v ListPastIncidentsResponse; return json.Unmarshal(d, &v) }, - "POST /incident/post-mortem/list": func(d json.RawMessage) error { var v ListPostMortemsResponse; return json.Unmarshal(d, &v) }, - "POST /incident/war-room/add-member": func(d json.RawMessage) error { var v string; return json.Unmarshal(d, &v) }, - "POST /incident/war-room/create": func(d json.RawMessage) error { var v WarRoom; return json.Unmarshal(d, &v) }, - "POST /incident/war-room/default-observers": func(d json.RawMessage) error { var v GetWarRoomDefaultObserversResponse; return json.Unmarshal(d, &v) }, - "POST /incident/war-room/detail": func(d json.RawMessage) error { var v WarRoom; return json.Unmarshal(d, &v) }, - "POST /incident/war-room/list": func(d json.RawMessage) error { var v ListWarRoomsResponse; return json.Unmarshal(d, &v) }, - "POST /insight/account": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, - "POST /insight/alert/topk-by-label": func(d json.RawMessage) error { var v InsightAlertByLabelResponse; return json.Unmarshal(d, &v) }, - "POST /insight/channel": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, - "POST /insight/incident/list": func(d json.RawMessage) error { var v InsightIncidentListResponse; return json.Unmarshal(d, &v) }, - "POST /insight/responder": func(d json.RawMessage) error { var v ResponderInsightResponse; return json.Unmarshal(d, &v) }, - "POST /insight/team": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, - "POST /member/info": func(d json.RawMessage) error { var v MemberInfoResponse; return json.Unmarshal(d, &v) }, - "POST /member/invite": func(d json.RawMessage) error { var v MemberInviteResponse; return json.Unmarshal(d, &v) }, - "POST /member/list": func(d json.RawMessage) error { var v MemberListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/create": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/info": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/list": func(d json.RawMessage) error { var v DataSourceListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/sls/logstores": func(d json.RawMessage) error { var v SLSLogstoresResponse; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/sls/projects": func(d json.RawMessage) error { var v SLSProjectsResponse; return json.Unmarshal(d, &v) }, - "POST /monit/datasource/update": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, - "POST /monit/query/diagnose": func(d json.RawMessage) error { var v DiagnoseResponse; return json.Unmarshal(d, &v) }, - "POST /monit/query/rows": func(d json.RawMessage) error { var v QueryRowsResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/audit/detail": func(d json.RawMessage) error { var v AlertRuleAudit; return json.Unmarshal(d, &v) }, - "POST /monit/rule/audits": func(d json.RawMessage) error { var v RuleAuditListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/counter/channel": func(d json.RawMessage) error { var v RuleCounterChannelResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/counter/node": func(d json.RawMessage) error { var v RuleCounterNodeResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/counter/status": func(d json.RawMessage) error { var v RuleStatusResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/counter/total": func(d json.RawMessage) error { var v RuleCounterTotalResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/create": func(d json.RawMessage) error { var v AlertRule; return json.Unmarshal(d, &v) }, - "POST /monit/rule/dstypes": func(d json.RawMessage) error { var v RuleDsTypesResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/export": func(d json.RawMessage) error { var v AlertRuleExportListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/import": func(d json.RawMessage) error { var v RuleImportResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/info": func(d json.RawMessage) error { var v AlertRuleInfoResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/list/basic": func(d json.RawMessage) error { var v RuleBasicListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/move": func(d json.RawMessage) error { var v RuleNameMessageListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/status": func(d json.RawMessage) error { var v RuleStatusResponse; return json.Unmarshal(d, &v) }, - "POST /monit/rule/update": func(d json.RawMessage) error { var v AlertRule; return json.Unmarshal(d, &v) }, - "POST /monit/rule/update/fields": func(d json.RawMessage) error { var v RuleNameMessageListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/store/ruleset/create": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, - "POST /monit/store/ruleset/info": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, - "POST /monit/store/ruleset/list": func(d json.RawMessage) error { var v StoreRulesetListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/store/ruleset/update": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, - "POST /monit/targets": func(d json.RawMessage) error { var v TargetsListResponse; return json.Unmarshal(d, &v) }, - "POST /monit/tools/catalog": func(d json.RawMessage) error { var v ToolCatalogResponse; return json.Unmarshal(d, &v) }, - "POST /monit/tools/invoke": func(d json.RawMessage) error { var v ToolInvokeResponse; return json.Unmarshal(d, &v) }, - "POST /person/infos": func(d json.RawMessage) error { var v PersonInfosResponse; return json.Unmarshal(d, &v) }, - "POST /role/info": func(d json.RawMessage) error { var v RoleItem; return json.Unmarshal(d, &v) }, - "POST /role/list": func(d json.RawMessage) error { var v RoleListResponse; return json.Unmarshal(d, &v) }, - "POST /role/permission/factor/list": func(d json.RawMessage) error { var v PermissionFactorListResponse; return json.Unmarshal(d, &v) }, - "POST /role/permission/list": func(d json.RawMessage) error { var v RolePermissionListResponse; return json.Unmarshal(d, &v) }, - "POST /role/upsert": func(d json.RawMessage) error { var v RoleUpsertResponse; return json.Unmarshal(d, &v) }, - "POST /route/info": func(d json.RawMessage) error { var v RouteItem; return json.Unmarshal(d, &v) }, - "POST /route/list": func(d json.RawMessage) error { var v ListRoutesResponse; return json.Unmarshal(d, &v) }, - "POST /rum/application/create": func(d json.RawMessage) error { var v RUMApplicationCreateResponse; return json.Unmarshal(d, &v) }, - "POST /rum/application/info": func(d json.RawMessage) error { var v RUMApplicationItem; return json.Unmarshal(d, &v) }, - "POST /rum/application/infos": func(d json.RawMessage) error { var v RUMApplicationInfosResponse; return json.Unmarshal(d, &v) }, - "POST /rum/application/list": func(d json.RawMessage) error { var v RUMApplicationListResponse; return json.Unmarshal(d, &v) }, - "POST /rum/issue/info": func(d json.RawMessage) error { var v RUMIssueItem; return json.Unmarshal(d, &v) }, - "POST /rum/issue/list": func(d json.RawMessage) error { var v RUMIssueListResponse; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/create": func(d json.RawMessage) error { var v A2aAgentCreateResponse; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/get": func(d json.RawMessage) error { var v A2aAgentItem; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/list": func(d json.RawMessage) error { var v A2aAgentListResponse; return json.Unmarshal(d, &v) }, - "POST /safari/a2a-agent/update": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/create": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/get": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/list": func(d json.RawMessage) error { var v McpServerListResponse; return json.Unmarshal(d, &v) }, - "POST /safari/mcp/server/update": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, - "POST /safari/session/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/session/get": func(d json.RawMessage) error { var v SessionGetResponse; return json.Unmarshal(d, &v) }, - "POST /safari/session/list": func(d json.RawMessage) error { var v SessionListResponse; return json.Unmarshal(d, &v) }, - "POST /safari/skill/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/skill/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/skill/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, - "POST /safari/skill/get": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, - "POST /safari/skill/list": func(d json.RawMessage) error { var v SkillListResponse; return json.Unmarshal(d, &v) }, - "POST /safari/skill/update": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, - "POST /safari/skill/upload": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, - "POST /schedule/create": func(d json.RawMessage) error { var v ScheduleIDResponse; return json.Unmarshal(d, &v) }, - "POST /schedule/info": func(d json.RawMessage) error { var v ScheduleItem; return json.Unmarshal(d, &v) }, - "POST /schedule/infos": func(d json.RawMessage) error { var v ScheduleSelfResponse; return json.Unmarshal(d, &v) }, - "POST /schedule/list": func(d json.RawMessage) error { var v ScheduleListResponse; return json.Unmarshal(d, &v) }, - "POST /schedule/preview": func(d json.RawMessage) error { var v ScheduleItem; return json.Unmarshal(d, &v) }, - "POST /schedule/self": func(d json.RawMessage) error { var v ScheduleSelfResponse; return json.Unmarshal(d, &v) }, - "POST /sourcemap/list": func(d json.RawMessage) error { var v SourcemapListResponse; return json.Unmarshal(d, &v) }, - "POST /status-page/change/create": func(d json.RawMessage) error { var v StatusPageChangeCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/info": func(d json.RawMessage) error { var v ChannelItem; return json.Unmarshal(d, &v) }, + "POST /channel/infos": func(d json.RawMessage) error { var v ChannelInfosResponse; return json.Unmarshal(d, &v) }, + "POST /channel/inhibit/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/inhibit/rule/list": func(d json.RawMessage) error { var v ListInhibitRulesResponse; return json.Unmarshal(d, &v) }, + "POST /channel/list": func(d json.RawMessage) error { var v ListChannelsResponse; return json.Unmarshal(d, &v) }, + "POST /channel/silence/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/silence/rule/list": func(d json.RawMessage) error { var v ListSilenceRulesResponse; return json.Unmarshal(d, &v) }, + "POST /channel/unsubscribe/rule/create": func(d json.RawMessage) error { var v RuleCreateResponse; return json.Unmarshal(d, &v) }, + "POST /channel/unsubscribe/rule/list": func(d json.RawMessage) error { var v ListDropRulesResponse; return json.Unmarshal(d, &v) }, + "POST /channel/update": func(d json.RawMessage) error { var v UpdateChannelResponse; return json.Unmarshal(d, &v) }, + "POST /datasource/im/person/try-link": func(d json.RawMessage) error { var v TryLinkPersonResponse; return json.Unmarshal(d, &v) }, + "POST /datasource/im/war-room-enabled/list": func(d json.RawMessage) error { var v ListWarRoomEnabledResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/info": func(d json.RawMessage) error { var v EnrichmentItem; return json.Unmarshal(d, &v) }, + "POST /enrichment/list": func(d json.RawMessage) error { var v EnrichmentListResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/api/create": func(d json.RawMessage) error { var v MappingAPICreateResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/api/info": func(d json.RawMessage) error { var v MappingAPIItem; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/api/list": func(d json.RawMessage) error { var v MappingAPIListResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/data/download": func(d json.RawMessage) error { var v CSVFileResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/data/list": func(d json.RawMessage) error { var v MappingDataListResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/data/upsert": func(d json.RawMessage) error { var v MappingDataUpsertResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/schema/create": func(d json.RawMessage) error { var v MappingSchemaCreateResponse; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/schema/info": func(d json.RawMessage) error { var v MappingSchemaItem; return json.Unmarshal(d, &v) }, + "POST /enrichment/mapping/schema/list": func(d json.RawMessage) error { var v MappingSchemaListResponse; return json.Unmarshal(d, &v) }, + "POST /field/create": func(d json.RawMessage) error { var v CreateFieldResponse; return json.Unmarshal(d, &v) }, + "POST /field/info": func(d json.RawMessage) error { var v FieldItem; return json.Unmarshal(d, &v) }, + "POST /field/list": func(d json.RawMessage) error { var v FieldListResponse; return json.Unmarshal(d, &v) }, + "POST /incident/alert/list": func(d json.RawMessage) error { var v ListIncidentAlertsResponse; return json.Unmarshal(d, &v) }, + "POST /incident/create": func(d json.RawMessage) error { var v CreateIncidentResponse; return json.Unmarshal(d, &v) }, + "POST /incident/custom-action/do": func(d json.RawMessage) error { var v DoIncidentCustomActionResponse; return json.Unmarshal(d, &v) }, + "POST /incident/feed": func(d json.RawMessage) error { var v ListIncidentFeedResponse; return json.Unmarshal(d, &v) }, + "POST /incident/info": func(d json.RawMessage) error { var v IncidentInfo; return json.Unmarshal(d, &v) }, + "POST /incident/list": func(d json.RawMessage) error { var v IncidentListResponse; return json.Unmarshal(d, &v) }, + "POST /incident/list-by-ids": func(d json.RawMessage) error { var v IncidentListResponse; return json.Unmarshal(d, &v) }, + "POST /incident/past/list": func(d json.RawMessage) error { var v ListPastIncidentsResponse; return json.Unmarshal(d, &v) }, + "POST /incident/post-mortem/init": func(d json.RawMessage) error { var v PostMortemItem; return json.Unmarshal(d, &v) }, + "POST /incident/post-mortem/list": func(d json.RawMessage) error { var v ListPostMortemsResponse; return json.Unmarshal(d, &v) }, + "POST /incident/post-mortem/template/list": func(d json.RawMessage) error { var v ListPostMortemTemplatesResponse; return json.Unmarshal(d, &v) }, + "POST /incident/post-mortem/template/upsert": func(d json.RawMessage) error { var v PostMortemTemplate; return json.Unmarshal(d, &v) }, + "POST /incident/war-room/add-member": func(d json.RawMessage) error { var v string; return json.Unmarshal(d, &v) }, + "POST /incident/war-room/create": func(d json.RawMessage) error { var v WarRoom; return json.Unmarshal(d, &v) }, + "POST /incident/war-room/default-observers": func(d json.RawMessage) error { var v GetWarRoomDefaultObserversResponse; return json.Unmarshal(d, &v) }, + "POST /incident/war-room/detail": func(d json.RawMessage) error { var v WarRoom; return json.Unmarshal(d, &v) }, + "POST /incident/war-room/list": func(d json.RawMessage) error { var v ListWarRoomsResponse; return json.Unmarshal(d, &v) }, + "POST /insight/account": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, + "POST /insight/alert/topk-by-label": func(d json.RawMessage) error { var v InsightAlertByLabelResponse; return json.Unmarshal(d, &v) }, + "POST /insight/channel": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, + "POST /insight/incident/list": func(d json.RawMessage) error { var v InsightIncidentListResponse; return json.Unmarshal(d, &v) }, + "POST /insight/responder": func(d json.RawMessage) error { var v ResponderInsightResponse; return json.Unmarshal(d, &v) }, + "POST /insight/team": func(d json.RawMessage) error { var v DimensionInsightResponse; return json.Unmarshal(d, &v) }, + "POST /member/info": func(d json.RawMessage) error { var v MemberInfoResponse; return json.Unmarshal(d, &v) }, + "POST /member/invite": func(d json.RawMessage) error { var v MemberInviteResponse; return json.Unmarshal(d, &v) }, + "POST /member/list": func(d json.RawMessage) error { var v MemberListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/create": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/info": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/list": func(d json.RawMessage) error { var v DataSourceListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/sls/logstores": func(d json.RawMessage) error { var v SLSLogstoresResponse; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/sls/projects": func(d json.RawMessage) error { var v SLSProjectsResponse; return json.Unmarshal(d, &v) }, + "POST /monit/datasource/update": func(d json.RawMessage) error { var v DataSourceItem; return json.Unmarshal(d, &v) }, + "POST /monit/query/diagnose": func(d json.RawMessage) error { var v DiagnoseResponse; return json.Unmarshal(d, &v) }, + "POST /monit/query/rows": func(d json.RawMessage) error { var v QueryRowsResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/audit/detail": func(d json.RawMessage) error { var v AlertRuleAudit; return json.Unmarshal(d, &v) }, + "POST /monit/rule/audits": func(d json.RawMessage) error { var v RuleAuditListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/counter/channel": func(d json.RawMessage) error { var v RuleCounterChannelResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/counter/node": func(d json.RawMessage) error { var v RuleCounterNodeResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/counter/status": func(d json.RawMessage) error { var v RuleStatusResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/counter/total": func(d json.RawMessage) error { var v RuleCounterTotalResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/create": func(d json.RawMessage) error { var v AlertRule; return json.Unmarshal(d, &v) }, + "POST /monit/rule/dstypes": func(d json.RawMessage) error { var v RuleDsTypesResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/export": func(d json.RawMessage) error { var v AlertRuleExportListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/import": func(d json.RawMessage) error { var v RuleImportResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/info": func(d json.RawMessage) error { var v AlertRuleInfoResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/list/basic": func(d json.RawMessage) error { var v RuleBasicListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/move": func(d json.RawMessage) error { var v RuleNameMessageListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/status": func(d json.RawMessage) error { var v RuleStatusResponse; return json.Unmarshal(d, &v) }, + "POST /monit/rule/update": func(d json.RawMessage) error { var v AlertRule; return json.Unmarshal(d, &v) }, + "POST /monit/rule/update/fields": func(d json.RawMessage) error { var v RuleNameMessageListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/store/ruleset/create": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, + "POST /monit/store/ruleset/info": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, + "POST /monit/store/ruleset/list": func(d json.RawMessage) error { var v StoreRulesetListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/store/ruleset/update": func(d json.RawMessage) error { var v StoreRulesetItem; return json.Unmarshal(d, &v) }, + "POST /monit/targets": func(d json.RawMessage) error { var v TargetsListResponse; return json.Unmarshal(d, &v) }, + "POST /monit/tools/catalog": func(d json.RawMessage) error { var v ToolCatalogResponse; return json.Unmarshal(d, &v) }, + "POST /monit/tools/invoke": func(d json.RawMessage) error { var v ToolInvokeResponse; return json.Unmarshal(d, &v) }, + "POST /person/infos": func(d json.RawMessage) error { var v PersonInfosResponse; return json.Unmarshal(d, &v) }, + "POST /role/info": func(d json.RawMessage) error { var v RoleItem; return json.Unmarshal(d, &v) }, + "POST /role/list": func(d json.RawMessage) error { var v RoleListResponse; return json.Unmarshal(d, &v) }, + "POST /role/permission/factor/list": func(d json.RawMessage) error { var v PermissionFactorListResponse; return json.Unmarshal(d, &v) }, + "POST /role/permission/list": func(d json.RawMessage) error { var v RolePermissionListResponse; return json.Unmarshal(d, &v) }, + "POST /role/upsert": func(d json.RawMessage) error { var v RoleUpsertResponse; return json.Unmarshal(d, &v) }, + "POST /route/info": func(d json.RawMessage) error { var v RouteItem; return json.Unmarshal(d, &v) }, + "POST /route/list": func(d json.RawMessage) error { var v ListRoutesResponse; return json.Unmarshal(d, &v) }, + "POST /rum/application/create": func(d json.RawMessage) error { var v RUMApplicationCreateResponse; return json.Unmarshal(d, &v) }, + "POST /rum/application/info": func(d json.RawMessage) error { var v RUMApplicationItem; return json.Unmarshal(d, &v) }, + "POST /rum/application/infos": func(d json.RawMessage) error { var v RUMApplicationInfosResponse; return json.Unmarshal(d, &v) }, + "POST /rum/application/list": func(d json.RawMessage) error { var v RUMApplicationListResponse; return json.Unmarshal(d, &v) }, + "POST /rum/application/webhook/test": func(d json.RawMessage) error { var v RUMWebhookTestResponse; return json.Unmarshal(d, &v) }, + "POST /rum/issue/info": func(d json.RawMessage) error { var v RUMIssueItem; return json.Unmarshal(d, &v) }, + "POST /rum/issue/list": func(d json.RawMessage) error { var v RUMIssueListResponse; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/create": func(d json.RawMessage) error { var v A2aAgentCreateResponse; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/get": func(d json.RawMessage) error { var v A2aAgentItem; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/list": func(d json.RawMessage) error { var v A2aAgentListResponse; return json.Unmarshal(d, &v) }, + "POST /safari/a2a-agent/update": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/create": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/get": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/list": func(d json.RawMessage) error { var v McpServerListResponse; return json.Unmarshal(d, &v) }, + "POST /safari/mcp/server/update": func(d json.RawMessage) error { var v McpServerItem; return json.Unmarshal(d, &v) }, + "POST /safari/session/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/session/get": func(d json.RawMessage) error { var v SessionGetResponse; return json.Unmarshal(d, &v) }, + "POST /safari/session/list": func(d json.RawMessage) error { var v SessionListResponse; return json.Unmarshal(d, &v) }, + "POST /safari/skill/delete": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/skill/disable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/skill/enable": func(d json.RawMessage) error { var v any; return json.Unmarshal(d, &v) }, + "POST /safari/skill/get": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, + "POST /safari/skill/list": func(d json.RawMessage) error { var v SkillListResponse; return json.Unmarshal(d, &v) }, + "POST /safari/skill/update": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, + "POST /safari/skill/upload": func(d json.RawMessage) error { var v SkillItem; return json.Unmarshal(d, &v) }, + "POST /schedule/create": func(d json.RawMessage) error { var v ScheduleIDResponse; return json.Unmarshal(d, &v) }, + "POST /schedule/info": func(d json.RawMessage) error { var v ScheduleItem; return json.Unmarshal(d, &v) }, + "POST /schedule/infos": func(d json.RawMessage) error { var v ScheduleSelfResponse; return json.Unmarshal(d, &v) }, + "POST /schedule/list": func(d json.RawMessage) error { var v ScheduleListResponse; return json.Unmarshal(d, &v) }, + "POST /schedule/preview": func(d json.RawMessage) error { var v ScheduleItem; return json.Unmarshal(d, &v) }, + "POST /schedule/self": func(d json.RawMessage) error { var v ScheduleSelfResponse; return json.Unmarshal(d, &v) }, + "POST /sourcemap/list": func(d json.RawMessage) error { var v SourcemapListResponse; return json.Unmarshal(d, &v) }, + "POST /status-page/change/create": func(d json.RawMessage) error { var v StatusPageChangeCreateResponse; return json.Unmarshal(d, &v) }, "POST /status-page/change/timeline/create": func(d json.RawMessage) error { var v StatusPageChangeTimelineCreateResponse return json.Unmarshal(d, &v) }, + "POST /status-page/component/upsert": func(d json.RawMessage) error { var v UpsertStatusPageComponentResponse; return json.Unmarshal(d, &v) }, "POST /status-page/migrate-email-subscribers": func(d json.RawMessage) error { var v StatusPageMigrationStartResponse; return json.Unmarshal(d, &v) }, "POST /status-page/migrate-structure": func(d json.RawMessage) error { var v StatusPageMigrationStartResponse; return json.Unmarshal(d, &v) }, + "POST /status-page/section/upsert": func(d json.RawMessage) error { var v UpsertStatusPageSectionResponse; return json.Unmarshal(d, &v) }, "POST /status-page/subscriber/export": func(d json.RawMessage) error { var v StatusPageSubscriberExportResponse; return json.Unmarshal(d, &v) }, + "POST /status-page/template/upsert": func(d json.RawMessage) error { var v UpsertStatusPageTemplateResponse; return json.Unmarshal(d, &v) }, "POST /team/info": func(d json.RawMessage) error { var v TeamItem; return json.Unmarshal(d, &v) }, "POST /team/infos": func(d json.RawMessage) error { var v TeamInfosResponse; return json.Unmarshal(d, &v) }, "POST /team/list": func(d json.RawMessage) error { var v TeamListResponse; return json.Unmarshal(d, &v) }, diff --git a/services_gen.go b/services_gen.go index c5fbf39..6cd83ee 100644 --- a/services_gen.go +++ b/services_gen.go @@ -15,6 +15,7 @@ type genServices struct { AlertRules *AlertRulesService DataSources *DataSourcesService Diagnostics *DiagnosticsService + MonitorUtilities *MonitorUtilitiesService RuleSets *RuleSetsService AlertEnrichment *AlertEnrichmentService Alerts *AlertsService @@ -48,6 +49,7 @@ func (c *Client) initServices() { c.AlertRules = (*AlertRulesService)(&c.common) c.DataSources = (*DataSourcesService)(&c.common) c.Diagnostics = (*DiagnosticsService)(&c.common) + c.MonitorUtilities = (*MonitorUtilitiesService)(&c.common) c.RuleSets = (*RuleSetsService)(&c.common) c.AlertEnrichment = (*AlertEnrichmentService)(&c.common) c.Alerts = (*AlertsService)(&c.common) diff --git a/status_pages.go b/status_pages.go index 0333303..0058ae7 100644 --- a/status_pages.go +++ b/status_pages.go @@ -127,6 +127,56 @@ func (s *StatusPagesService) ChangeUpdate(ctx context.Context, req *UpdateStatus return s.client.do(ctx, "/status-page/change/update", req, nil) } +// Delete status page component. +// +// Delete a service component from a status page. +// +// API: POST /status-page/component/delete (statusPageComponentDelete). +func (s *StatusPagesService) ComponentDelete(ctx context.Context, req *DeleteStatusPageComponentRequest) (*Response, error) { + return s.client.do(ctx, "/status-page/component/delete", req, nil) +} + +// Upsert status page component. +// +// Create or update a service component on a status page. +// +// API: POST /status-page/component/upsert (statusPageComponentUpsert). +func (s *StatusPagesService) ComponentUpsert(ctx context.Context, req *UpsertStatusPageComponentRequest) (*UpsertStatusPageComponentResponse, *Response, error) { + out := new(UpsertStatusPageComponentResponse) + resp, err := s.client.do(ctx, "/status-page/component/upsert", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + +// Create status page. +// +// Create a new status page. +// +// API: POST /status-page/create (statusPageCreate). +func (s *StatusPagesService) Create(ctx context.Context) (*Response, error) { + return s.client.do(ctx, "/status-page/create", nil, nil) +} + +// Delete status page. +// +// Delete a status page. +// +// API: POST /status-page/delete (statusPageDelete). +func (s *StatusPagesService) Delete(ctx context.Context) (*Response, error) { + return s.client.do(ctx, "/status-page/delete", nil, nil) +} + +// Get status page detail. +// +// Retrieve detailed configuration for a specific status page. +// +// API: GET /status-page/info (statusPageInfo). +func (s *StatusPagesService) Info(ctx context.Context, req *StatusPagesInfoRequest) (*Response, error) { + return s.client.doGet(ctx, "/status-page/info", req, nil) +} + // Migrate email subscribers. // // Start a migration job that imports email subscribers from an Atlassian Statuspage into an existing Flashduty status page. @@ -178,6 +228,29 @@ func (s *StatusPagesService) MigrationStatus(ctx context.Context, req *StatusPag return out, resp, nil } +// Delete status page section. +// +// Delete a section from a status page. +// +// API: POST /status-page/section/delete (statusPageSectionDelete). +func (s *StatusPagesService) SectionDelete(ctx context.Context, req *DeleteStatusPageSectionRequest) (*Response, error) { + return s.client.do(ctx, "/status-page/section/delete", req, nil) +} + +// Upsert status page section. +// +// Create or update a section on a status page. +// +// API: POST /status-page/section/upsert (statusPageSectionUpsert). +func (s *StatusPagesService) SectionUpsert(ctx context.Context, req *UpsertStatusPageSectionRequest) (*UpsertStatusPageSectionResponse, *Response, error) { + out := new(UpsertStatusPageSectionResponse) + resp, err := s.client.do(ctx, "/status-page/section/upsert", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + // Export subscribers. // // Export subscribers list for a status page as a CSV attachment. The response is a `text/csv` file with columns: Method, Recipient, Components, Subscribe All, Locale. @@ -214,3 +287,44 @@ func (s *StatusPagesService) SubscriberList(ctx context.Context, req *StatusPage } return out, resp, nil } + +// Delete status page template. +// +// Delete an event template from a status page. +// +// API: POST /status-page/template/delete (statusPageTemplateDelete). +func (s *StatusPagesService) TemplateDelete(ctx context.Context, req *DeleteStatusPageTemplateRequest) (*Response, error) { + return s.client.do(ctx, "/status-page/template/delete", req, nil) +} + +// List status page templates. +// +// List all event templates for a status page. +// +// API: GET /status-page/template/list (statusPageTemplateList). +func (s *StatusPagesService) TemplateList(ctx context.Context, req *StatusPagesTemplateListRequest) (*Response, error) { + return s.client.doGet(ctx, "/status-page/template/list", req, nil) +} + +// Upsert status page template. +// +// Create or update an event template for a status page. +// +// API: POST /status-page/template/upsert (statusPageTemplateUpsert). +func (s *StatusPagesService) TemplateUpsert(ctx context.Context, req *UpsertStatusPageTemplateRequest) (*UpsertStatusPageTemplateResponse, *Response, error) { + out := new(UpsertStatusPageTemplateResponse) + resp, err := s.client.do(ctx, "/status-page/template/upsert", req, out) + if err != nil { + return nil, resp, err + } + return out, resp, nil +} + +// Update status page. +// +// Update an existing status page configuration. +// +// API: POST /status-page/update (statusPageUpdate). +func (s *StatusPagesService) Update(ctx context.Context) (*Response, error) { + return s.client.do(ctx, "/status-page/update", nil, nil) +}