From ab49720e47e49f8ed6b2b7739d0ea9050b933e3c Mon Sep 17 00:00:00 2001 From: alick-liming Date: Sat, 10 Oct 2026 13:28:37 +0800 Subject: [PATCH] docs(api): sync public integration contract to test --- api-reference/on-call.openapi.en.json | 4708 +++++++++++------ api-reference/on-call.openapi.zh.json | 4708 +++++++++++------ api-reference/openapi.en.json | 7004 +++++++++++++++---------- api-reference/openapi.zh.json | 7004 +++++++++++++++---------- docs.json | 58 +- en/openapi/api-catalog.mdx | 15 +- zh/openapi/api-catalog.mdx | 15 +- 7 files changed, 14702 insertions(+), 8810 deletions(-) diff --git a/api-reference/on-call.openapi.en.json b/api-reference/on-call.openapi.en.json index d24f293f..c6fdcc70 100644 --- a/api-reference/on-call.openapi.en.json +++ b/api-reference/on-call.openapi.en.json @@ -17411,6 +17411,769 @@ } } } + }, + "/integration/type/list": { + "post": { + "operationId": "integration-api-read-type-list", + "summary": "List integration types", + "description": "List the integration types the account can configure.", + "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 Read** (`on-call`) |\n\n## Usage\n\n- When `orderby` is omitted, types come back in console ranking order and `p`/`limit` still apply.\n- `supports_api_create` tells you which types `POST /integration/create` accepts.", + "href": "/en/api-reference/on-call/integrations/integration-api-read-type-list", + "metadata": { + "sidebarTitle": "List integration types" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListIntegrationTypesResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "p": 1, + "limit": 20, + "total": 2, + "items": [ + { + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "plugin_type_logo_url": "https://cdn.flashcat.cloud/plugin/standard-alert.svg", + "category": "event.alert", + "status": "enabled", + "supports_api_create": true + }, + { + "plugin_type": "jira.change", + "plugin_type_name": "Jira", + "plugin_type_logo_url": "https://cdn.flashcat.cloud/plugin/jira.svg", + "category": "event.change", + "status": "enabled", + "supports_api_create": true + } + ] + } + } + } + } + }, + "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/IntegrationTypeListRequest" + }, + "example": { + "p": 1, + "limit": 20, + "category": "event.alert" + } + } + } + } + } + }, + "/integration/list": { + "post": { + "operationId": "integration-api-read-list", + "summary": "List integrations", + "description": "List public integrations with their stored settings, decrypted keys, and edit permissions.", + "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 Read** (`on-call`) |\n\n## Usage\n\n- `orderby` defaults to `created_at`; `plugin_type` is sorted by the underlying plugin.\n- `plugin_type`, `status` and `category` accept comma-separated values; `ref_ids` values must start with `c_`, `a_` or `w_`; a `c_` filter is syntactically accepted but does not return channel-owned integrations.\n- With `is_my_team` set, results are limited to your teams and `team_ids` narrows that set further.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Items include `settings`, `integration_key`, `plugin_id`, `account_id`, and the legacy `data_source_id` alias; credential values are not masked.", + "href": "/en/api-reference/on-call/integrations/integration-api-read-list", + "metadata": { + "sidebarTitle": "List integrations" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListIntegrationsResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "p": 1, + "limit": 20, + "total": 1, + "items": [ + { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775203200, + "last_time": 1775298600, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100", + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "data_source_id": 6113996590131, + "account_id": 100, + "exclusive_data_source_id": 0 + } + ] + } + } + } + } + }, + "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/ListIntegrationsRequest" + }, + "example": { + "p": 1, + "limit": 20, + "status": "enabled" + } + } + } + } + } + }, + "/integration/info": { + "post": { + "operationId": "integration-api-read-info", + "summary": "Get integration detail", + "description": "Get a public integration with its stored settings and decrypted integration key.", + "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 Read** (`on-call`) |\n\n## Usage\n\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Settings and the integration key are returned without masking, matching the legacy datasource detail response.", + "href": "/en/api-reference/on-call/integrations/integration-api-read-info", + "metadata": { + "sidebarTitle": "Get integration detail" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/IntegrationDetail" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775203200, + "last_time": 1775298600, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100" + } + } + } + } + }, + "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/GetIntegrationRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/create": { + "post": { + "operationId": "integration-api-write-create", + "summary": "Create integration", + "description": "Create a public integration for a supported alert, change, IM, or webhook type.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- `plugin_type` must be one of the types listed by `POST /integration/type/list` with `supports_api_create: true`; anything else returns `InvalidParameter`.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- An omitted `integration_key` is generated automatically; a supplied key must satisfy the length, account suffix, and uniqueness checks.\n- With `is_test: true`, inspect `test.success`; an HTTP 200 response alone does not establish that the plugin test succeeded.\n- Every call is recorded in the account audit log.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-create", + "metadata": { + "sidebarTitle": "Create integration" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/CreateIntegrationResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "integration_key": "0123456789abcdef0123456789abcdef100", + "test": { + "success": true, + "message": "" + } + } + } + } + } + }, + "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/CreateIntegrationRequest" + }, + "example": { + "plugin_type": "standard.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "team_id": 1467226103121, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "is_test": true + } + } + } + } + } + }, + "/integration/update": { + "post": { + "operationId": "integration-api-write-update", + "summary": "Update integration", + "description": "Update an integration's name, description, team, or settings.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- Only the fields you send are changed; omitted fields keep their current value.\n- Submitting `settings` replaces the configuration; known sensitive fields omitted or sent as `******` retain their value. Send `headers: {}` to clear headers; use the integration type’s explicit empty value to clear a body.\n- Submit `settings` together with `is_test: true` to receive a plugin test result; settings in the response are not masked.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Write access also requires object permission: the account owner, an administrator, the creator, or a member of the assigned team; with no team, members with Integrations Manage may operate. Read-only integrations cannot be changed.\n- Every call is recorded in the account audit log.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-update", + "metadata": { + "sidebarTitle": "Update integration" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/IntegrationDetail" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts (primary)", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775298600, + "last_time": 1775298600, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100", + "test": { + "success": true, + "message": "" + } + } + } + } + } + }, + "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/UpdateIntegrationRequest" + }, + "example": { + "integration_id": 6113996590131, + "name": "Prod metrics alerts (primary)", + "team_id": 1467226103121, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "is_test": true + } + } + } + } + } + }, + "/integration/delete": { + "post": { + "operationId": "integration-api-write-delete", + "summary": "Delete integration", + "description": "Delete an integration that nothing else references.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- Deleting an integration that other objects still reference returns HTTP 400 with `error.code` = `ReferenceExist` and `data.refs` listing them.\n- Every call is recorded in the account audit log.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Write access also requires object permission: the account owner, an administrator, the creator, or a member of the assigned team; with no team, members with Integrations Manage may operate. Read-only integrations cannot be changed.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-delete", + "metadata": { + "sidebarTitle": "Delete integration" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/enable": { + "post": { + "operationId": "integration-api-write-enable", + "summary": "Enable integration", + "description": "Re-enable a disabled integration so it accepts events again.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- Enabling an integration resumes its scheduled pull task and heartbeat, and requires the integration type to be available on the current plan.\n- Every call is recorded in the account audit log.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Write access also requires object permission: the account owner, an administrator, the creator, or a member of the assigned team; with no team, members with Integrations Manage may operate. Read-only integrations cannot be changed.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-enable", + "metadata": { + "sidebarTitle": "Enable integration" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/disable": { + "post": { + "operationId": "integration-api-write-disable", + "summary": "Disable integration", + "description": "Disable an integration without deleting its configuration.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- Disabling stops event ingestion and pauses the scheduled pull task; settings are kept so the integration can be enabled again.\n- Every call is recorded in the account audit log.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Write access also requires object permission: the account owner, an administrator, the creator, or a member of the assigned team; with no team, members with Integrations Manage may operate. Read-only integrations cannot be changed.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-disable", + "metadata": { + "sidebarTitle": "Disable integration" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/key/rotate": { + "post": { + "operationId": "integration-api-write-rotate-key", + "summary": "Rotate integration key", + "description": "Issue a new integration key and invalidate the previous one.", + "tags": [ + "On-call/Integrations" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Integrations Manage** (`on-call`) |\n\n## Usage\n\n- The previous key stops working immediately; after rotation, update the pushing side with the new key.\n- The new key can also be read from `/integration/list` and `/integration/info`.\n- These APIs manage public (account-level) integrations only, not channel-owned dedicated integrations.\n- Write access also requires object permission: the account owner, an administrator, the creator, or a member of the assigned team; with no team, members with Integrations Manage may operate. Read-only integrations cannot be changed.\n- Every call is recorded in the account audit log.", + "href": "/en/api-reference/on-call/integrations/integration-api-write-rotate-key", + "metadata": { + "sidebarTitle": "Rotate integration key" + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RotateIntegrationKeyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_key": "0123456789abcdef0123456789abcdef100" + } + } + } + } + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } } }, "components": { @@ -31329,183 +32092,556 @@ "incidents_total_duration_seconds": { "type": "integer", "format": "int64", - "minimum": 0, - "description": "Total incident duration in seconds." + "minimum": 0, + "description": "Total incident duration in seconds." + }, + "responder_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Responder member IDs to store on the report." + } + } + }, + "ResetPostMortemContentRequest": { + "type": "object", + "description": "Parameters for fully replacing a drafting post-mortem report body.", + "required": [ + "post_mortem_id", + "markdown", + "expected_revision", + "idempotency_key" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "ID of the post-mortem to reset; obtain it from `POST /incident/post-mortem/list`." + }, + "markdown": { + "type": "string", + "description": "Replacement Markdown content. Limited to 4 MiB." + }, + "expected_revision": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0, + "description": "Current content revision expected by the caller. Pass 0 for the first write to a document that has never been saved." + }, + "idempotency_key": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "Non-blank key for safely retrying this exact reset request." + } + } + }, + "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; obtain it from `POST /incident/post-mortem/list`." + }, + "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; obtain it from `POST /incident/post-mortem/list`." + }, + "status": { + "type": "string", + "enum": [ + "drafting", + "published" + ], + "description": "Target report status: `drafting` draft, `published` published." + } + } + }, + "ResetPostMortemTitleRequest": { + "type": "object", + "description": "Parameters for changing a post-mortem report title.", + "required": [ + "post_mortem_id", + "title" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID; obtain it from `POST /incident/post-mortem/list`." + }, + "title": { + "type": "string", + "description": "New report title." + } + } + }, + "TryLinkPersonRequest": { + "type": "object", + "description": "Parameters for attempting automatic IM account linking.", + "required": [ + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "IM integration ID; obtain it from `POST /datasource/im/war-room-enabled/list`." + } + } + }, + "TryLinkPersonResponse": { + "type": "object", + "description": "People linked by this attempt. When nobody could be newly linked, the response either carries an empty `new_linked_person_ids` array or omits the `data` field entirely.", + "required": [ + "new_linked_person_ids" + ], + "properties": { + "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": "Template ID. Omit to create a new template; provide it to update an existing template." + }, + "team_id": { + "type": "integer", + "format": "int64", + "description": "Managing team ID. Required when creating a custom template." + }, + "name": { + "type": "string", + "description": "Template name." + }, + "description": { + "type": "string", + "description": "Template description." + }, + "content": { + "type": "string", + "description": "BlockNote JSON template content." + }, + "content_markdown": { + "type": "string", + "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": "Status page ID; obtain it from `GET /status-page/list`." + }, + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Component IDs to delete; obtain them from `GET /status-page/info`.", + "minItems": 1 + } + } + }, + "DeleteStatusPageSectionRequest": { + "type": "object", + "description": "Parameters for deleting one or more sections from a status page.", + "required": [ + "page_id", + "section_ids" + ], + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID; obtain it from `GET /status-page/list`." }, - "responder_ids": { + "section_ids": { "type": "array", "items": { - "type": "integer", - "format": "int64" + "type": "string" }, - "description": "Responder member IDs to store on the report." + "description": "Section IDs to delete; obtain them from `GET /status-page/info`.", + "minItems": 1 } } }, - "ResetPostMortemContentRequest": { + "DeleteStatusPageTemplateRequest": { "type": "object", - "description": "Parameters for fully replacing a drafting post-mortem report body.", + "description": "Parameters for deleting a status page template.", "required": [ - "post_mortem_id", - "markdown", - "expected_revision", - "idempotency_key" + "page_id", + "type", + "template_id" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "ID of the post-mortem to reset; obtain it from `POST /incident/post-mortem/list`." + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID; obtain it from `GET /status-page/list`." }, - "markdown": { + "type": { "type": "string", - "description": "Replacement Markdown content. Limited to 4 MiB." - }, - "expected_revision": { - "type": [ - "integer", - "null" + "enum": [ + "pre_defined", + "message" ], - "format": "int64", - "minimum": 0, - "description": "Current content revision expected by the caller. Pass 0 for the first write to a document that has never been saved." + "description": "Template kind: `pre_defined` predefined template, `message` message template." }, - "idempotency_key": { + "template_id": { "type": "string", - "minLength": 1, - "maxLength": 128, - "description": "Non-blank key for safely retrying this exact reset request." + "description": "ID of the template to delete; obtain it from `GET /status-page/template/list`." } } }, - "ResetPostMortemFollowUpsRequest": { + "UpsertStatusPageComponentRequest": { "type": "object", - "description": "Parameters for replacing post-mortem follow-up action items.", + "description": "Parameters for creating or updating one or more service components on a status page.", "required": [ - "post_mortem_id" + "page_id", + "components" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "Post-mortem ID; obtain it from `POST /incident/post-mortem/list`." + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID; obtain it from `GET /status-page/list`." }, - "follow_ups": { - "type": "string", - "description": "Follow-up action items as free text." + "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." + }, + "available_since_seconds": { + "type": "integer", + "format": "int64", + "description": "Time the component became (or becomes) available, in Unix seconds. On create, defaults to the current time; on update, replaces the stored value." + } + } + }, + "minItems": 1 } } }, - "ResetPostMortemStatusRequest": { + "UpsertStatusPageComponentResponse": { "type": "object", - "description": "Parameters for changing a post-mortem report status.", + "description": "Result of upserting status page components.", "required": [ - "post_mortem_id", - "status" + "component_ids" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "Post-mortem ID; obtain it from `POST /incident/post-mortem/list`." - }, - "status": { - "type": "string", - "enum": [ - "drafting", - "published" - ], - "description": "Target report status: `drafting` draft, `published` published." + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "IDs of the created or updated components, in the same order as the request." } } }, - "ResetPostMortemTitleRequest": { + "UpsertStatusPageSectionRequest": { "type": "object", - "description": "Parameters for changing a post-mortem report title.", + "description": "Parameters for creating or updating one or more sections on a status page.", "required": [ - "post_mortem_id", - "title" + "page_id", + "sections" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "Post-mortem ID; obtain it from `POST /incident/post-mortem/list`." + "page_id": { + "type": "integer", + "format": "int64", + "description": "Status page ID; obtain it from `GET /status-page/list`." }, - "title": { - "type": "string", - "description": "New report title." + "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." + } + } + }, + "minItems": 1 } } }, - "TryLinkPersonRequest": { + "UpsertStatusPageSectionResponse": { "type": "object", - "description": "Parameters for attempting automatic IM account linking.", + "description": "Result of upserting status page sections.", "required": [ - "integration_id" + "section_ids" ], "properties": { - "integration_id": { + "section_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "IDs of the created or updated sections, in the same order as the request." + } + } + }, + "UpsertStatusPageTemplateRequest": { + "type": "object", + "description": "Parameters for creating or updating a status page template.", + "required": [ + "page_id", + "type", + "template" + ], + "properties": { + "page_id": { "type": "integer", "format": "int64", - "description": "IM integration ID; obtain it from `POST /datasource/im/war-room-enabled/list`." + "description": "Status page ID; obtain it from `GET /status-page/list`." + }, + "type": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ], + "description": "Template category. `pre_defined` for predefined event templates; `message` for notification message templates." + }, + "template": { + "oneOf": [ + { + "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" + }, + { + "$ref": "#/components/schemas/StatusPageMessageTemplate" + } + ], + "description": "Template content. Shape depends on `type`: a predefined event template for `pre_defined`, a message template for `message`." } } }, - "TryLinkPersonResponse": { + "UpsertStatusPageTemplateResponse": { "type": "object", - "description": "People linked by this attempt. When nobody could be newly linked, the response either carries an empty `new_linked_person_ids` array or omits the `data` field entirely.", + "description": "Result of upserting a status page template.", "required": [ - "new_linked_person_ids" + "template_id" ], "properties": { - "new_linked_person_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Person IDs newly linked during this call." + "template_id": { + "type": "string", + "description": "ID of the created or updated template." } } }, - "UpsertPostMortemTemplateRequest": { + "CreateStatusPageRequest": { "type": "object", - "description": "Parameters for creating or updating a post-mortem template.", - "required": [ - "name", - "content" - ], "properties": { - "template_id": { + "name": { "type": "string", - "description": "Template ID. Omit to create a new template; provide it to update an existing template." + "description": "Display name of the status page.", + "maxLength": 255 }, - "team_id": { - "type": "integer", - "format": "int64", - "description": "Managing team ID. Required when creating a custom template." + "url_name": { + "type": "string", + "description": "URL-safe slug, unique per account and page type.", + "maxLength": 255 }, - "name": { + "type": { "type": "string", - "description": "Template name." + "description": "Visibility type: `public` accessible to anyone, `internal` restricted to logged-in members of this account.", + "enum": [ + "public", + "internal" + ] }, - "description": { + "custom_domain": { "type": "string", - "description": "Template description." + "description": "Custom domain for a public status page.", + "maxLength": 255 }, - "content": { + "page_title": { "type": "string", - "description": "BlockNote JSON template content." + "description": "Browser title shown for the status page." }, - "content_markdown": { + "page_header": { "type": "string", - "description": "Markdown version of the template content." + "description": "Header content shown on the status page." + }, + "page_footer": { + "type": "string", + "description": "Footer content shown on the status page." + }, + "date_view": { + "type": "string", + "description": "How change dates are displayed: `calendar` calendar view, `list` list view.", + "enum": [ + "calendar", + "list" + ] + }, + "display_uptime_mode": { + "type": "string", + "description": "Uptime display mode: `chart_and_percentage` chart plus percentage, `chart` chart only, `none` hidden.", + "enum": [ + "chart_and_percentage", + "chart", + "none" + ] + }, + "custom_links": { + "type": "array", + "description": "Custom navigation links shown on the status page.", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "contact_info": { + "type": "string", + "description": "Get-in-touch contact, such as a mailto or website URL." + }, + "subscription": { + "$ref": "#/components/schemas/StatusPageSubscriptionItem", + "description": "Subscription channel toggles." } - } + }, + "required": [ + "name", + "url_name", + "type", + "date_view", + "display_uptime_mode" + ] }, - "DeleteStatusPageComponentRequest": { + "CreateStatusPageResponse": { "type": "object", - "description": "Parameters for deleting one or more service components from a status page.", + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "Created status page ID." + }, + "page_name": { + "type": "string", + "description": "Created status page name." + }, + "page_url_name": { + "type": "string", + "description": "Final URL-safe slug assigned to the status page." + } + }, "required": [ "page_id", - "component_ids" + "page_name", + "page_url_name" + ] + }, + "UpdateStatusPageRequest": { + "type": "object", + "description": "Parameters for updating an existing status page. All fields except `page_id` are optional; omit a field or pass null to keep its existing value.", + "required": [ + "page_id" ], "properties": { "page_id": { @@ -31513,1023 +32649,1294 @@ "format": "int64", "description": "Status page ID; obtain it from `GET /status-page/list`." }, - "component_ids": { + "name": { + "type": [ + "string", + "null" + ], + "description": "Display name of the status page. Omit or pass null to keep the existing value.", + "maxLength": 255 + }, + "url_name": { + "type": [ + "string", + "null" + ], + "description": "URL-safe slug, unique per account and page type. Omit or pass null to keep the existing value.", + "maxLength": 255 + }, + "custom_domain": { + "type": [ + "string", + "null" + ], + "description": "Custom domain for a public status page. Omit or pass null to keep the existing value.", + "maxLength": 255 + }, + "page_title": { + "type": [ + "string", + "null" + ], + "description": "Browser title shown for the status page. Omit or pass null to keep the existing value." + }, + "logo": { + "type": [ + "string", + "null" + ], + "description": "Logo image of the status page. Omit or pass null to keep the existing value." + }, + "dark_logo": { + "type": [ + "string", + "null" + ], + "description": "Dark-mode logo image of the status page. Omit or pass null to keep the existing value." + }, + "logo_url": { + "type": [ + "string", + "null" + ], + "description": "URL opened when the logo is clicked. Omit or pass null to keep the existing value.", + "maxLength": 255 + }, + "favicon": { + "type": [ + "string", + "null" + ], + "description": "Favicon of the status page. Omit or pass null to keep the existing value." + }, + "page_header": { + "type": [ + "string", + "null" + ], + "description": "Header content shown on the status page. Omit or pass null to keep the existing value." + }, + "page_footer": { + "type": [ + "string", + "null" + ], + "description": "Footer content shown on the status page. Omit or pass null to keep the existing value." + }, + "date_view": { + "type": [ + "string", + "null" + ], + "description": "How change dates are displayed. Leave empty to keep the current value. `calendar` uses a calendar view; `list` uses a list view.", + "enum": [ + "calendar", + "list" + ] + }, + "display_uptime_mode": { + "type": [ + "string", + "null" + ], + "description": "How uptime is displayed. Leave empty to keep the current value. `chart_and_percentage` shows both chart and percentage; `chart` shows only the chart; `none` hides uptime.", + "enum": [ + "chart_and_percentage", + "chart", + "none" + ] + }, + "custom_links": { "type": "array", + "description": "Custom navigation links shown on the status page. Omit or pass an empty array to keep the current links.", "items": { - "type": "string" - }, - "description": "Component IDs to delete; obtain them from `GET /status-page/info`.", - "minItems": 1 + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "contact_info": { + "type": [ + "string", + "null" + ], + "description": "Get-in-touch contact, such as a mailto or website URL. Omit or pass null to keep the existing value." + }, + "subscription": { + "$ref": "#/components/schemas/StatusPageSubscriptionItem", + "description": "Subscription channel toggles. Omit or pass null to keep the existing value." + }, + "template_preference": { + "type": [ + "string", + "null" + ], + "description": "Preferred event template type: `pre_defined` or `message`. Omit or pass null to keep the existing value." } } }, - "DeleteStatusPageSectionRequest": { + "DeleteStatusPageRequest": { "type": "object", - "description": "Parameters for deleting one or more sections from a status page.", + "description": "Parameters for deleting a status page.", "required": [ - "page_id", - "section_ids" + "page_id" ], "properties": { "page_id": { "type": "integer", "format": "int64", "description": "Status page ID; obtain it from `GET /status-page/list`." - }, - "section_ids": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Section IDs to delete; obtain them from `GET /status-page/info`.", - "minItems": 1 } } }, - "DeleteStatusPageTemplateRequest": { + "CustomFieldValues": { "type": "object", - "description": "Parameters for deleting a status page template.", + "description": "Values keyed by account custom field name. The active form determines the allowed keys, types, and required fields.", + "additionalProperties": true + }, + "IncidentActionImage": { + "type": "object", + "description": "Image attached to an acknowledgement or resolution timeline entry.", "required": [ - "page_id", - "type", - "template_id" + "src" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." + "src": { + "type": "string", + "description": "Image source. Accepts an `img_` upload token, an `http(s)` URL, or an object-storage key beginning with `/`." }, - "type": { + "href": { "type": "string", - "enum": [ - "pre_defined", - "message" - ], - "description": "Template kind: `pre_defined` predefined template, `message` message template." + "description": "Optional link that the image points to." }, - "template_id": { + "alt": { "type": "string", - "description": "ID of the template to delete; obtain it from `GET /status-page/template/list`." + "description": "Alternative text for the image." } } }, - "UpsertStatusPageComponentRequest": { + "IncidentCardHiddenFields": { "type": "object", - "description": "Parameters for creating or updating one or more service components on a status page.", + "description": "Incident-card fields to hide, keyed by IM app type. Only supported IM app types and field names are accepted.", + "propertyNames": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "slack_app", + "teams_app", + "wecom_app" + ] + }, + "additionalProperties": { + "type": "array", + "description": "Incident-card field names to hide for this IM app.", + "items": { + "type": "string", + "enum": [ + "channel", + "snoozed_before", + "severity", + "responders", + "aggregate_alert_count", + "detail", + "ai_analysis" + ] + } + } + }, + "PreviewIncidentCardFixedField": { + "type": "object", + "description": "Fixed incident-card fields returned for supported IM previews after the requested hiding rules are applied.", "required": [ - "page_id", - "components" + "field", + "value" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." + "field": { + "type": "string", + "enum": [ + "channel", + "snoozed_before", + "severity", + "responders", + "aggregate_alert_count" + ], + "description": "Incident-card field name.\n\n| Value | Meaning |\n|---|---|\n| `channel` | Name of the alert channel that produced the incident; returned only when non-empty. |\n| `snoozed_before` | Snooze-until timestamp formatted as `YYYY-MM-DD HH:MM:SS`; returned only while the incident is snoozed. |\n| `severity` | Incident severity label; returned only when non-empty. |\n| `responders` | Names of the current responders, separated by spaces; returned only when the incident has responders. |\n| `aggregate_alert_count` | Number of alerts aggregated into the incident; returned only when greater than 1. |" }, - "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." - }, - "available_since_seconds": { - "type": "integer", - "format": "int64", - "description": "Time the component became (or becomes) available, in Unix seconds. On create, defaults to the current time; on update, replaces the stored value." - } - } - }, - "minItems": 1 + "value": { + "type": "string", + "description": "Rendered display value for the fixed field." } } }, - "UpsertStatusPageComponentResponse": { + "FieldDeleteReference": { "type": "object", - "description": "Result of upserting status page components.", + "description": "Custom form that still references the field.", "required": [ - "component_ids" + "kind", + "name", + "href" ], "properties": { - "component_ids": { - "type": "array", - "items": { - "type": "string" - }, - "description": "IDs of the created or updated components, in the same order as the request." + "kind": { + "type": "string", + "const": "custom_form", + "description": "Referenced resource kind. Always `custom_form` for this response." + }, + "name": { + "type": "string", + "description": "Human label of the referencing custom form's type (a Chinese label, e.g. `解决故障` for the resolve form)." + }, + "href": { + "type": "string", + "description": "Console URL for the referencing custom form." } } }, - "UpsertStatusPageSectionRequest": { + "FieldDeleteReferenceError": { "type": "object", - "description": "Parameters for creating or updating one or more sections on a status page.", + "description": "Error response returned when a custom form still references the field.", "required": [ - "page_id", - "sections" + "request_id", + "error", + "data" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." + "request_id": { + "type": "string", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "description": "Trace ID of this request, identical to the `Flashcat-Request-Id` response header." }, - "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." + "error": { + "$ref": "#/components/schemas/DutyError" + }, + "data": { + "type": "object", + "required": [ + "refs" + ], + "properties": { + "refs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FieldDeleteReference" }, - "hide_all": { - "type": "boolean", - "description": "When true, the entire section is hidden from summary endpoints." - } + "description": "Custom forms that still reference the field, each with `kind`/`name`/`href`; all references must be removed before the field can be deleted." } }, - "minItems": 1 + "description": "Supplementary error payload; for this error it always contains the `refs` field." } } }, - "UpsertStatusPageSectionResponse": { + "ServiceDeskPlusRequestListRequest": { "type": "object", - "description": "Result of upserting status page sections.", - "required": [ - "section_ids" - ], + "description": "Filters for listing ServiceDeskPlus request synchronization records. A time window is optional when querying by incident ID; otherwise provide a Unix-second window no longer than 30 days.", "properties": { - "section_ids": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window start, Unix seconds. Optional when `incident_id` is provided." + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Window end, Unix seconds. Must be greater than or equal to `start_time`. Optional when `incident_id` is provided." + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "Filter by sync status: `success` or `failed`." + }, + "channel_ids": { "type": "array", "items": { - "type": "string" + "type": "integer", + "format": "int64" }, - "description": "IDs of the created or updated sections, in the same order as the request." + "description": "Channel IDs to filter by." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty incident ID. When set, the time window can be omitted." + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus request ID." + }, + "asc": { + "type": "boolean", + "description": "When `true`, sort by internal record ID ascending; otherwise descending." + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Page number starting at 1. Ignored when `search_after_ctx` is set." + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "Page size. Defaults to 20; maximum 100." + }, + "search_after_ctx": { + "type": "string", + "description": "Pagination cursor: leave empty for the first page, then pass the `search_after_ctx` returned by the previous response." } } }, - "UpsertStatusPageTemplateRequest": { + "ServiceDeskPlusRequestMappingItem": { "type": "object", - "description": "Parameters for creating or updating a status page template.", + "description": "A synchronization mapping between a ServiceDeskPlus request and a Flashduty incident.", "required": [ - "page_id", - "type", - "template" + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" ], "properties": { - "page_id": { + "created_at": { "type": "integer", "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." + "description": "Mapping record creation time, Unix seconds." }, - "type": { + "status": { "type": "string", "enum": [ - "pre_defined", - "message" + "success", + "failed" ], - "description": "Template category. `pre_defined` for predefined event templates; `message` for notification message templates." + "description": "Synchronization status." }, - "template": { - "oneOf": [ - { - "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" - }, - { - "$ref": "#/components/schemas/StatusPageMessageTemplate" - } - ], - "description": "Template content. Shape depends on `type`: a predefined event template for `pre_defined`, a message template for `message`." + "request_id": { + "type": "string", + "description": "ServiceDeskPlus request ID." + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus request detail URL." + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus integration ID." + }, + "incident_id": { + "type": "string", + "description": "Associated Flashduty incident ID." + }, + "incident_title": { + "type": "string", + "description": "Associated incident title." + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "Channel ID for the incident." + }, + "channel_name": { + "type": "string", + "description": "Channel name for the incident." + }, + "error_message": { + "type": "string", + "description": "Error message when synchronization failed. Usually absent on successful records." } } }, - "UpsertStatusPageTemplateResponse": { + "ServiceDeskPlusRequestListResponse": { "type": "object", - "description": "Result of upserting a status page template.", + "description": "Paginated list of ServiceDeskPlus request synchronization records.", "required": [ - "template_id" + "items", + "total", + "has_next_page" ], "properties": { - "template_id": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "Synchronization records on the current page." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching records, capped at 1,000 for counting." + }, + "has_next_page": { + "type": "boolean", + "description": "True when more results are available." + }, + "search_after_ctx": { "type": "string", - "description": "ID of the created or updated template." + "description": "Cursor for the next page. Empty when no more data is available." } } }, - "CreateStatusPageRequest": { + "IncidentCommentTypeItem": { "type": "object", + "description": "An account-level comment type that can be attached to incident comments.", "properties": { - "name": { - "type": "string", - "description": "Display name of the status page.", - "maxLength": 255 - }, - "url_name": { + "comment_type_id": { "type": "string", - "description": "URL-safe slug, unique per account and page type.", - "maxLength": 255 + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Comment type ID (24-character hex ObjectID)." }, - "type": { - "type": "string", - "description": "Visibility type: `public` accessible to anyone, `internal` restricted to logged-in members of this account.", - "enum": [ - "public", - "internal" - ] + "account_id": { + "type": "integer", + "format": "int64", + "description": "Account ID that owns the comment type." }, - "custom_domain": { + "name": { "type": "string", - "description": "Custom domain for a public status page.", - "maxLength": 255 + "maxLength": 40, + "description": "Display name of the comment type. Unique within the account (case-insensitive, trimmed)." }, - "page_title": { + "color": { "type": "string", - "description": "Browser title shown for the status page." + "pattern": "^#[0-9A-F]{6}$", + "description": "Label color as a hex value in #RRGGBB format (stored uppercase)." }, - "page_header": { - "type": "string", - "description": "Header content shown on the status page." + "position": { + "type": "integer", + "format": "int64", + "description": "1-based display position of the comment type." }, - "page_footer": { - "type": "string", - "description": "Footer content shown on the status page." + "creator_id": { + "type": "integer", + "format": "int64", + "description": "ID of the user who created the comment type." }, - "date_view": { - "type": "string", - "description": "How change dates are displayed: `calendar` calendar view, `list` list view.", - "enum": [ - "calendar", - "list" - ] + "updated_by": { + "type": "integer", + "format": "int64", + "description": "ID of the user who last updated the comment type." }, - "display_uptime_mode": { - "type": "string", - "description": "Uptime display mode: `chart_and_percentage` chart plus percentage, `chart` chart only, `none` hidden.", - "enum": [ - "chart_and_percentage", - "chart", - "none" - ] + "created_at": { + "type": "integer", + "format": "int64", + "description": "Creation time as a Unix timestamp in seconds." }, - "custom_links": { + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Last update time as a Unix timestamp in seconds." + } + }, + "required": [ + "comment_type_id", + "account_id", + "name", + "color", + "position", + "creator_id", + "updated_by", + "created_at", + "updated_at" + ] + }, + "ListIncidentCommentTypesRequest": { + "type": "object", + "description": "No parameters. The operation always returns every comment type of the calling account.", + "properties": {} + }, + "ListIncidentCommentTypesResponse": { + "type": "object", + "description": "Full list of the account's comment types, ordered by position.", + "properties": { + "items": { "type": "array", - "description": "Custom navigation links shown on the status page.", "items": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } + "$ref": "#/components/schemas/IncidentCommentTypeItem" + }, + "description": "All comment types of the account, ordered by position." + } + } + }, + "CreateIncidentCommentTypeRequest": { + "type": "object", + "description": "Parameters for creating a comment type. At most 10 comment types per account.", + "required": [ + "name", + "color" + ], + "properties": { + "name": { + "type": "string", + "maxLength": 40, + "description": "Display name. Trimmed before storing; must be unique within the account (case-insensitive). At most 40 characters." }, - "contact_info": { + "color": { "type": "string", - "description": "Get-in-touch contact, such as a mailto or website URL." + "pattern": "^#[0-9A-Fa-f]{6}$", + "description": "Label color as a hex value in #RRGGBB format. Normalized to uppercase." + } + } + }, + "CreateIncidentCommentTypeResponse": { + "type": "object", + "description": "Result of creating a comment type.", + "properties": { + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "ID of the created comment type (24-character hex ObjectID)." }, - "subscription": { - "$ref": "#/components/schemas/StatusPageSubscriptionItem", - "description": "Subscription channel toggles." + "item": { + "$ref": "#/components/schemas/IncidentCommentTypeItem" } }, "required": [ - "name", - "url_name", - "type", - "date_view", - "display_uptime_mode" + "comment_type_id", + "item" ] }, - "CreateStatusPageResponse": { + "UpdateIncidentCommentTypeRequest": { "type": "object", + "description": "Parameters for updating a comment type. Partial update: at least one of `name` or `color` must be provided.", + "required": [ + "comment_type_id" + ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "Created status page ID." + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "ID of the comment type to update (24-character hex ObjectID)." }, - "page_name": { + "name": { "type": "string", - "description": "Created status page name." + "maxLength": 40, + "description": "New display name. Trimmed before storing; must be unique within the account (case-insensitive). At most 40 characters." }, - "page_url_name": { + "color": { "type": "string", - "description": "Final URL-safe slug assigned to the status page." + "pattern": "^#[0-9A-Fa-f]{6}$", + "description": "New label color as a hex value in #RRGGBB format. Normalized to uppercase." } - }, + } + }, + "DeleteIncidentCommentTypeRequest": { + "type": "object", + "description": "Parameters for deleting a comment type.", "required": [ - "page_id", - "page_name", - "page_url_name" - ] + "comment_type_id" + ], + "properties": { + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "ID of the comment type to delete (24-character hex ObjectID)." + } + } }, - "UpdateStatusPageRequest": { + "ReorderIncidentCommentTypesRequest": { "type": "object", - "description": "Parameters for updating an existing status page. All fields except `page_id` are optional; omit a field or pass null to keep its existing value.", + "description": "Parameters for reordering comment types.", "required": [ - "page_id" + "comment_type_ids" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." - }, - "name": { - "type": [ - "string", - "null" - ], - "description": "Display name of the status page. Omit or pass null to keep the existing value.", - "maxLength": 255 - }, - "url_name": { - "type": [ - "string", - "null" - ], - "description": "URL-safe slug, unique per account and page type. Omit or pass null to keep the existing value.", - "maxLength": 255 - }, - "custom_domain": { - "type": [ - "string", - "null" - ], - "description": "Custom domain for a public status page. Omit or pass null to keep the existing value.", - "maxLength": 255 - }, - "page_title": { - "type": [ - "string", - "null" - ], - "description": "Browser title shown for the status page. Omit or pass null to keep the existing value." + "comment_type_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1, + "description": "IDs of every comment type of the account in the desired order (24-character hex ObjectIDs)." + } + } + }, + "WorkItemItem": { + "type": "object", + "description": "A structured incident work item (action or post-mortem follow-up) with its assignees.", + "required": [ + "work_item_id", + "item_type", + "incident_id", + "title", + "status", + "source_kind", + "version", + "assignee_ids", + "created_by", + "updated_by", + "created_at_seconds", + "updated_at_seconds" + ], + "properties": { + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." }, - "logo": { - "type": [ - "string", - "null" + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" ], - "description": "Logo image of the status page. Omit or pass null to keep the existing value." + "description": "`action` for an item anchored to an active incident; `follow_up` for a post-mortem follow-up." }, - "dark_logo": { - "type": [ - "string", - "null" - ], - "description": "Dark-mode logo image of the status page. Omit or pass null to keep the existing value." + "incident_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Incident ID (MongoDB ObjectID) the item is anchored to." }, - "logo_url": { - "type": [ - "string", - "null" - ], - "description": "URL opened when the logo is clicked. Omit or pass null to keep the existing value.", - "maxLength": 255 + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID (32-character hex string). Present on follow-up items once bound to a post-mortem." }, - "favicon": { - "type": [ - "string", - "null" - ], - "description": "Favicon of the status page. Omit or pass null to keep the existing value." + "title": { + "type": "string", + "maxLength": 512, + "description": "Item title (max 512 characters)." }, - "page_header": { - "type": [ - "string", - "null" - ], - "description": "Header content shown on the status page. Omit or pass null to keep the existing value." + "description": { + "type": "string", + "maxLength": 65535, + "description": "Optional longer description (max 65,535 characters)." }, - "page_footer": { - "type": [ - "string", - "null" - ], - "description": "Footer content shown on the status page. Omit or pass null to keep the existing value." + "status": { + "type": "string", + "maxLength": 64, + "description": "Client-defined status (max 64 characters). There is no fixed state machine." }, - "date_view": { - "type": [ - "string", - "null" - ], - "description": "How change dates are displayed. Leave empty to keep the current value. `calendar` uses a calendar view; `list` uses a list view.", - "enum": [ - "calendar", - "list" - ] + "priority": { + "type": "string", + "maxLength": 64, + "description": "Optional client-defined priority (max 64 characters)." }, - "display_uptime_mode": { - "type": [ - "string", - "null" - ], - "description": "How uptime is displayed. Leave empty to keep the current value. `chart_and_percentage` shows both chart and percentage; `chart` shows only the chart; `none` hides uptime.", + "source_kind": { + "type": "string", "enum": [ - "chart_and_percentage", - "chart", - "none" - ] + "native", + "legacy_follow_up" + ], + "description": "`native` for items created through this API; `legacy_follow_up` for items migrated from legacy post-mortem follow-ups." }, - "custom_links": { + "legacy_source_id": { + "type": "string", + "description": "Original identifier of the legacy follow-up this item was migrated from. Present only when `source_kind` is `legacy_follow_up`." + }, + "version": { + "type": "integer", + "format": "int64", + "description": "Optimistic-locking version, incremented on every mutation." + }, + "assignee_ids": { "type": "array", - "description": "Custom navigation links shown on the status page. Omit or pass an empty array to keep the current links.", "items": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } + "type": "integer", + "format": "int64" + }, + "description": "Member IDs of the current assignees. Never null; an empty array means unassigned." }, - "contact_info": { - "type": [ - "string", - "null" - ], - "description": "Get-in-touch contact, such as a mailto or website URL. Omit or pass null to keep the existing value." + "created_by": { + "type": "integer", + "format": "int64", + "description": "Member ID of the creator." }, - "subscription": { - "$ref": "#/components/schemas/StatusPageSubscriptionItem", - "description": "Subscription channel toggles. Omit or pass null to keep the existing value." + "updated_by": { + "type": "integer", + "format": "int64", + "description": "Member ID of the last updater." }, - "template_preference": { - "type": [ - "string", - "null" - ], - "description": "Preferred event template type: `pre_defined` or `message`. Omit or pass null to keep the existing value." - } - } - }, - "DeleteStatusPageRequest": { - "type": "object", - "description": "Parameters for deleting a status page.", - "required": [ - "page_id" - ], - "properties": { - "page_id": { + "converted_by": { "type": "integer", "format": "int64", - "description": "Status page ID; obtain it from `GET /status-page/list`." - } - } - }, - "CustomFieldValues": { - "type": "object", - "description": "Values keyed by account custom field name. The active form determines the allowed keys, types, and required fields.", - "additionalProperties": true - }, - "IncidentActionImage": { - "type": "object", - "description": "Image attached to an acknowledgement or resolution timeline entry.", - "required": [ - "src" - ], - "properties": { - "src": { - "type": "string", - "description": "Image source. Accepts an `img_` upload token, an `http(s)` URL, or an object-storage key beginning with `/`." + "description": "Member ID of the operator who converted the action into a follow-up. Present only after conversion." }, - "href": { - "type": "string", - "description": "Optional link that the image points to." + "converted_at_seconds": { + "type": "integer", + "format": "int64", + "description": "Conversion time as a Unix timestamp in seconds. Present only after conversion." }, - "alt": { - "type": "string", - "description": "Alternative text for the image." - } - } - }, - "IncidentCardHiddenFields": { - "type": "object", - "description": "Incident-card fields to hide, keyed by IM app type. Only supported IM app types and field names are accepted.", - "propertyNames": { - "type": "string", - "enum": [ - "feishu_app", - "dingtalk_app", - "slack_app", - "teams_app", - "wecom_app" - ] - }, - "additionalProperties": { - "type": "array", - "description": "Incident-card field names to hide for this IM app.", - "items": { - "type": "string", - "enum": [ - "channel", - "snoozed_before", - "severity", - "responders", - "aggregate_alert_count", - "detail", - "ai_analysis" - ] + "created_at_seconds": { + "type": "integer", + "format": "int64", + "description": "Creation time as a Unix timestamp in seconds." + }, + "updated_at_seconds": { + "type": "integer", + "format": "int64", + "description": "Last update time as a Unix timestamp in seconds." } } }, - "PreviewIncidentCardFixedField": { + "WorkItemCreateResult": { "type": "object", - "description": "Fixed incident-card fields returned for supported IM previews after the requested hiding rules are applied.", + "description": "Result of creating a work item.", "required": [ - "field", - "value" + "item" ], "properties": { - "field": { - "type": "string", - "enum": [ - "channel", - "snoozed_before", - "severity", - "responders", - "aggregate_alert_count" - ], - "description": "Incident-card field name.\n\n| Value | Meaning |\n|---|---|\n| `channel` | Name of the alert channel that produced the incident; returned only when non-empty. |\n| `snoozed_before` | Snooze-until timestamp formatted as `YYYY-MM-DD HH:MM:SS`; returned only while the incident is snoozed. |\n| `severity` | Incident severity label; returned only when non-empty. |\n| `responders` | Names of the current responders, separated by spaces; returned only when the incident has responders. |\n| `aggregate_alert_count` | Number of alerts aggregated into the incident; returned only when greater than 1. |" + "item": { + "$ref": "#/components/schemas/WorkItemItem" }, - "value": { - "type": "string", - "description": "Rendered display value for the fixed field." + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Assignee member IDs that were newly added (and notified)." + }, + "idempotent_replay": { + "type": "boolean", + "description": "True when the call replayed an earlier request with the same idempotency key and no new item was created." } } }, - "FieldDeleteReference": { + "WorkItemMutationResult": { "type": "object", - "description": "Custom form that still references the field.", - "required": [ - "kind", - "name", - "href" - ], + "description": "Result of mutating a work item.", "properties": { - "kind": { - "type": "string", - "const": "custom_form", - "description": "Referenced resource kind. Always `custom_form` for this response." + "item": { + "$ref": "#/components/schemas/WorkItemItem" }, - "name": { - "type": "string", - "description": "Human label of the referencing custom form's type (a Chinese label, e.g. `解决故障` for the resolve form)." + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Assignee member IDs that were newly added (and notified)." }, - "href": { - "type": "string", - "description": "Console URL for the referencing custom form." + "removed_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Assignee member IDs that were removed (never notified)." + }, + "idempotent_replay": { + "type": "boolean", + "description": "True when the call replayed an earlier request with the same idempotency key." } } }, - "FieldDeleteReferenceError": { + "WorkItemListResult": { "type": "object", - "description": "Error response returned when a custom form still references the field.", + "description": "Cursor-paginated list of work items.", "required": [ - "request_id", - "error", - "data" + "items", + "has_more" ], "properties": { - "request_id": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WorkItemItem" + }, + "description": "Work items for the current page." + }, + "next_cursor": { "type": "string", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "description": "Trace ID of this request, identical to the `Flashcat-Request-Id` response header." + "description": "Cursor for the next page. Pass it as `cursor`; absent when there are no more results." }, - "error": { - "$ref": "#/components/schemas/DutyError" + "has_more": { + "type": "boolean", + "description": "True when more results are available." }, - "data": { - "type": "object", - "required": [ - "refs" - ], - "properties": { - "refs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FieldDeleteReference" - }, - "description": "Custom forms that still reference the field, each with `kind`/`name`/`href`; all references must be removed before the field can be deleted." - } - }, - "description": "Supplementary error payload; for this error it always contains the `refs` field." + "idempotent_replay": { + "type": "boolean", + "description": "True when the call replayed an earlier request with the same idempotency key." } } }, - "ServiceDeskPlusRequestListRequest": { + "ListWorkItemRequest": { "type": "object", - "description": "Filters for listing ServiceDeskPlus request synchronization records. A time window is optional when querying by incident ID; otherwise provide a Unix-second window no longer than 30 days.", + "description": "Filters for listing work items. At least one of `incident_id`, `post_mortem_id`, or `assignee_id` is required.", "properties": { - "start_time": { + "incident_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Incident ID (MongoDB ObjectID). Also returns follow-ups anchored on the incident's post-mortem." + }, + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID (32-character hex string). Returns follow-ups bound to this post-mortem." + }, + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "Filter by work item type: `action` action item, `follow_up` post-mortem follow-up." + }, + "assignee_id": { "type": "integer", "format": "int64", - "minimum": 0, - "description": "Window start, Unix seconds. Optional when `incident_id` is provided." + "description": "Restrict results to items assigned to this member ID. Listing by assignee alone requires being that assignee or an account admin." }, - "end_time": { + "cursor": { + "type": "string", + "description": "Pagination cursor from a previous response's `next_cursor`." + }, + "limit": { "type": "integer", "format": "int64", "minimum": 0, - "description": "Window end, Unix seconds. Must be greater than or equal to `start_time`. Optional when `incident_id` is provided." - }, - "status": { + "maximum": 200, + "default": 50, + "description": "Page size, at most 200. Defaults to 50." + } + } + }, + "CreateWorkItemRequest": { + "type": "object", + "description": "Parameters for creating an incident work item.", + "required": [ + "item_type", + "title", + "incident_id", + "idempotency_key" + ], + "properties": { + "item_type": { "type": "string", "enum": [ - "success", - "failed" + "action", + "follow_up" ], - "description": "Filter by sync status: `success` or `failed`." + "description": "`action` anchors to an active incident and must not set `post_mortem_id`; `follow_up` requires `post_mortem_id`." }, - "channel_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Channel IDs to filter by." + "title": { + "type": "string", + "maxLength": 512, + "description": "Item title (max 512 characters)." }, - "integration_id": { - "type": "integer", - "format": "int64", - "minimum": 0, - "description": "ServiceDeskPlus integration ID." + "description": { + "type": "string", + "maxLength": 65535, + "description": "Optional longer description (max 65,535 characters)." }, - "incident_id": { + "status": { "type": "string", "maxLength": 64, - "description": "Flashduty incident ID. When set, the time window can be omitted." + "description": "Optional client-defined initial status (max 64 characters)." }, - "request_id": { + "priority": { "type": "string", "maxLength": 64, - "description": "ServiceDeskPlus request ID." + "description": "Optional client-defined priority (max 64 characters)." }, - "asc": { - "type": "boolean", - "description": "When `true`, sort by internal record ID ascending; otherwise descending." + "incident_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Incident ID (MongoDB ObjectID) the item is anchored to." }, - "p": { - "type": "integer", - "format": "int64", - "minimum": 0, - "description": "Page number starting at 1. Ignored when `search_after_ctx` is set." + "post_mortem_id": { + "type": "string", + "description": "Post-mortem ID (32-character hex string). Required for `follow_up`, forbidden for `action`. The post-mortem must be linked to `incident_id`." }, - "limit": { - "type": "integer", - "format": "int64", - "minimum": 0, - "maximum": 100, - "default": 20, - "description": "Page size. Defaults to 20; maximum 100." + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Initial assignee member IDs. Assignees must be active members who can already read the anchor; assignment never grants access." }, - "search_after_ctx": { + "idempotency_key": { "type": "string", - "description": "Pagination cursor: leave empty for the first page, then pass the `search_after_ctx` returned by the previous response." + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." } } }, - "ServiceDeskPlusRequestMappingItem": { + "UpdateWorkItemRequest": { "type": "object", - "description": "A synchronization mapping between a ServiceDeskPlus request and a Flashduty incident.", + "description": "Partial patch for a work item. Omitted fields stay unchanged; an explicit `null` clears the field.", "required": [ - "created_at", - "status", - "request_id", - "request_link", - "integration_id", - "incident_id", - "incident_title", - "channel_id", - "channel_name" + "work_item_id", + "version" ], "properties": { - "created_at": { + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." + }, + "version": { "type": "integer", "format": "int64", - "description": "Mapping record creation time, Unix seconds." + "description": "Current item version for optimistic locking. Must match the stored version." + }, + "title": { + "type": [ + "string", + "null" + ], + "description": "New title (max 512 characters).", + "maxLength": 512 + }, + "description": { + "type": [ + "string", + "null" + ], + "description": "New description (max 65,535 characters).", + "maxLength": 65535 }, "status": { - "type": "string", - "enum": [ - "success", - "failed" + "type": [ + "string", + "null" ], - "description": "Synchronization status." + "description": "New client-defined status (max 64 characters).", + "maxLength": 64 }, - "request_id": { + "priority": { + "type": [ + "string", + "null" + ], + "description": "New client-defined priority (max 64 characters).", + "maxLength": 64 + } + } + }, + "DeleteWorkItemRequest": { + "type": "object", + "description": "Parameters for soft-deleting a work item.", + "required": [ + "work_item_id", + "version" + ], + "properties": { + "work_item_id": { "type": "string", - "description": "ServiceDeskPlus request ID." + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." }, - "request_link": { + "version": { + "type": "integer", + "format": "int64", + "description": "Current item version for optimistic locking. Must match the stored version." + } + } + }, + "CompleteWorkItemRequest": { + "type": "object", + "description": "Parameters for completing a work item.", + "required": [ + "work_item_id", + "version", + "target_status", + "idempotency_key" + ], + "properties": { + "work_item_id": { "type": "string", - "description": "ServiceDeskPlus request detail URL." + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." }, - "integration_id": { + "version": { "type": "integer", "format": "int64", - "description": "ServiceDeskPlus integration ID." + "description": "Current item version for optimistic locking. Must match the stored version." }, - "incident_id": { + "target_status": { "type": "string", - "description": "Associated Flashduty incident ID." + "maxLength": 64, + "description": "Client-defined status to set (max 64 characters). There is no fixed state machine." }, - "incident_title": { + "idempotency_key": { "type": "string", - "description": "Associated incident title." + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." + } + } + }, + "ConvertWorkItemRequest": { + "type": "object", + "description": "Parameters for converting an action item into a post-mortem follow-up in place.", + "required": [ + "work_item_id", + "version", + "idempotency_key" + ], + "properties": { + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." }, - "channel_id": { + "version": { "type": "integer", "format": "int64", - "description": "Channel ID for the incident." + "description": "Current item version for optimistic locking. Must match the stored version." }, - "channel_name": { - "type": "string", - "description": "Channel name for the incident." + "target_status": { + "type": [ + "string", + "null" + ], + "description": "Optional client-defined status to set on the converted follow-up (max 64 characters).", + "maxLength": 64 }, - "error_message": { + "idempotency_key": { "type": "string", - "description": "Error message when synchronization failed. Usually absent on successful records." + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." } } }, - "ServiceDeskPlusRequestListResponse": { + "ResetWorkItemAssigneesRequest": { "type": "object", - "description": "Paginated list of ServiceDeskPlus request synchronization records.", + "description": "Full replacement of a work item's assignee set.", "required": [ - "items", - "total", - "has_next_page" + "work_item_id", + "version" ], "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" - }, - "description": "Synchronization records on the current page." + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "Work item ID (opaque string, max 128 characters)." }, - "total": { + "version": { "type": "integer", "format": "int64", - "description": "Total number of matching records, capped at 1,000 for counting." - }, - "has_next_page": { - "type": "boolean", - "description": "True when more results are available." + "description": "Current item version for optimistic locking. Must match the stored version." }, - "search_after_ctx": { - "type": "string", - "description": "Cursor for the next page. Empty when no more data is available." + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "New assignee member IDs, replacing the current set. An empty array clears all assignees." } } }, - "IncidentCommentTypeItem": { + "BindWorkItemPostMortemRequest": { "type": "object", - "description": "An account-level comment type that can be attached to incident comments.", + "description": "Parameters for bulk-binding an incident's unbound follow-ups to a post-mortem.", + "required": [ + "post_mortem_id", + "incident_id", + "idempotency_key" + ], "properties": { - "comment_type_id": { + "post_mortem_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Comment type ID (24-character hex ObjectID)." - }, - "account_id": { - "type": "integer", - "format": "int64", - "description": "Account ID that owns the comment type." + "description": "Post-mortem ID (32-character hex string) to bind the follow-ups to." }, - "name": { + "incident_id": { "type": "string", - "maxLength": 40, - "description": "Display name of the comment type. Unique within the account (case-insensitive, trimmed)." + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Incident ID (MongoDB ObjectID) whose converted-but-unbound follow-ups are bound." }, - "color": { + "idempotency_key": { "type": "string", - "pattern": "^#[0-9A-F]{6}$", - "description": "Label color as a hex value in #RRGGBB format (stored uppercase)." - }, - "position": { - "type": "integer", - "format": "int64", - "description": "1-based display position of the comment type." - }, - "creator_id": { - "type": "integer", - "format": "int64", - "description": "ID of the user who created the comment type." - }, - "updated_by": { - "type": "integer", - "format": "int64", - "description": "ID of the user who last updated the comment type." - }, - "created_at": { - "type": "integer", - "format": "int64", - "description": "Creation time as a Unix timestamp in seconds." - }, - "updated_at": { - "type": "integer", - "format": "int64", - "description": "Last update time as a Unix timestamp in seconds." - } - }, - "required": [ - "comment_type_id", - "account_id", - "name", - "color", - "position", - "creator_id", - "updated_by", - "created_at", - "updated_at" - ] - }, - "ListIncidentCommentTypesRequest": { - "type": "object", - "description": "No parameters. The operation always returns every comment type of the calling account.", - "properties": {} - }, - "ListIncidentCommentTypesResponse": { - "type": "object", - "description": "Full list of the account's comment types, ordered by position.", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentCommentTypeItem" - }, - "description": "All comment types of the account, ordered by position." + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." } } }, - "CreateIncidentCommentTypeRequest": { + "IncidentCommentTypeDisplay": { "type": "object", - "description": "Parameters for creating a comment type. At most 10 comment types per account.", + "description": "Resolved display of an account-level comment type, populated at read time from the current type definition.", "required": [ + "id", "name", "color" ], "properties": { + "id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Comment type ID (MongoDB ObjectID)." + }, "name": { "type": "string", "maxLength": 40, - "description": "Display name. Trimmed before storing; must be unique within the account (case-insensitive). At most 40 characters." + "description": "Display name of the comment type." }, "color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "Label color as a hex value in #RRGGBB format. Normalized to uppercase." + "description": "Badge color in #RRGGBB format." } } }, - "CreateIncidentCommentTypeResponse": { + "FeedDetailWorkItemCreated": { "type": "object", - "description": "Result of creating a comment type.", + "description": "Detail payload for `i_wi_created`.", "properties": { - "comment_type_id": { + "work_item_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "ID of the created comment type (24-character hex ObjectID)." + "description": "Work item ID." }, - "item": { - "$ref": "#/components/schemas/IncidentCommentTypeItem" + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type. `action`: an action item anchored to the incident itself, convertible to `follow_up` later; `follow_up`: an improvement item anchored to a post-mortem, requiring the incident to be linked to that post-mortem at creation." + }, + "title": { + "type": "string", + "description": "Work item title." + }, + "status": { + "type": "string", + "description": "Work item status label (e.g. `open`, `done`)." + }, + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Assignee member IDs." + }, + "post_mortem_id": { + "type": "string", + "description": "ID of the post-mortem the work item is bound to." } }, - "required": [ - "comment_type_id", - "item" - ] + "title": "i_wi_created" }, - "UpdateIncidentCommentTypeRequest": { + "FeedDetailWorkItemUpdated": { "type": "object", - "description": "Parameters for updating a comment type. Partial update: at least one of `name` or `color` must be provided.", - "required": [ - "comment_type_id" - ], + "description": "Detail payload for `i_wi_updated`. Only the fields that changed carry `from_*`/`to_*` values.", "properties": { - "comment_type_id": { + "work_item_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "ID of the comment type to update (24-character hex ObjectID)." + "description": "Work item ID." }, - "name": { + "item_type": { "type": "string", - "maxLength": 40, - "description": "New display name. Trimmed before storing; must be unique within the account (case-insensitive). At most 40 characters." + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." }, - "color": { + "title": { "type": "string", - "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "New label color as a hex value in #RRGGBB format. Normalized to uppercase." - } - } - }, - "DeleteIncidentCommentTypeRequest": { - "type": "object", - "description": "Parameters for deleting a comment type.", - "required": [ - "comment_type_id" - ], - "properties": { - "comment_type_id": { + "description": "Work item title." + }, + "from_title": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "ID of the comment type to delete (24-character hex ObjectID)." + "description": "Title before the update." + }, + "from_status": { + "type": "string", + "description": "Status label before the update." + }, + "to_status": { + "type": "string", + "description": "Status label after the update." + }, + "from_priority": { + "type": "string", + "description": "Priority label before the update." + }, + "to_priority": { + "type": "string", + "description": "Priority label after the update." + }, + "from_description": { + "type": "string", + "description": "Description before the update." + }, + "to_description": { + "type": "string", + "description": "Description after the update." } - } + }, + "title": "i_wi_updated" }, - "ReorderIncidentCommentTypesRequest": { + "FeedDetailWorkItemAssigneesChanged": { "type": "object", - "description": "Parameters for reordering comment types.", - "required": [ - "comment_type_ids" - ], + "description": "Detail payload for `i_wi_assignees`.", "properties": { - "comment_type_ids": { + "work_item_id": { + "type": "string", + "description": "Work item ID." + }, + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." + }, + "title": { + "type": "string", + "description": "Work item title." + }, + "assignee_ids": { "type": "array", "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" + "type": "integer", + "format": "int64" }, - "minItems": 1, - "description": "IDs of every comment type of the account in the desired order (24-character hex ObjectIDs)." + "description": "Assignee member IDs after the change." + }, + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Member IDs added as assignees." + }, + "removed_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Member IDs removed from assignees." } - } + }, + "title": "i_wi_assignees" }, - "WorkItemItem": { + "FeedDetailWorkItemCompleted": { "type": "object", - "description": "A structured incident work item (action or post-mortem follow-up) with its assignees.", - "required": [ - "work_item_id", - "item_type", - "incident_id", - "title", - "status", - "source_kind", - "version", - "assignee_ids", - "created_by", - "updated_by", - "created_at_seconds", - "updated_at_seconds" - ], + "description": "Detail payload for `i_wi_completed`.", "properties": { "work_item_id": { "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." + "description": "Work item ID." }, "item_type": { "type": "string", @@ -32537,1095 +33944,1142 @@ "action", "follow_up" ], - "description": "`action` for an item anchored to an active incident; `follow_up` for a post-mortem follow-up." + "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." }, - "incident_id": { + "title": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Incident ID (MongoDB ObjectID) the item is anchored to." + "description": "Work item title." }, - "post_mortem_id": { + "from_status": { "type": "string", - "description": "Post-mortem ID (32-character hex string). Present on follow-up items once bound to a post-mortem." + "description": "Status label before completion." }, - "title": { + "to_status": { "type": "string", - "maxLength": 512, - "description": "Item title (max 512 characters)." + "description": "Status label after completion." }, - "description": { + "post_mortem_id": { "type": "string", - "maxLength": 65535, - "description": "Optional longer description (max 65,535 characters)." - }, - "status": { + "description": "ID of the post-mortem the work item is bound to." + } + }, + "title": "i_wi_completed" + }, + "FeedDetailWorkItemConverted": { + "type": "object", + "description": "Detail payload for `i_wi_converted`.", + "properties": { + "work_item_id": { "type": "string", - "maxLength": 64, - "description": "Client-defined status (max 64 characters). There is no fixed state machine." + "description": "Work item ID." }, - "priority": { + "title": { "type": "string", - "maxLength": 64, - "description": "Optional client-defined priority (max 64 characters)." + "description": "Work item title." }, - "source_kind": { + "from_type": { "type": "string", "enum": [ - "native", - "legacy_follow_up" + "action", + "follow_up" ], - "description": "`native` for items created through this API; `legacy_follow_up` for items migrated from legacy post-mortem follow-ups." + "description": "Work item type before the conversion. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem. Conversion currently only supports `action` → `follow_up`, so `from_type` is always `action` in this event." }, - "legacy_source_id": { + "to_type": { "type": "string", - "description": "Original identifier of the legacy follow-up this item was migrated from. Present only when `source_kind` is `legacy_follow_up`." - }, - "version": { - "type": "integer", - "format": "int64", - "description": "Optimistic-locking version, incremented on every mutation." - }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Member IDs of the current assignees. Never null; an empty array means unassigned." - }, - "created_by": { - "type": "integer", - "format": "int64", - "description": "Member ID of the creator." + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type after the conversion. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem. Conversion currently only supports `action` → `follow_up`, so `to_type` is always `follow_up` in this event, and a successful conversion immediately tries to bind the incident's post-mortem." }, - "updated_by": { - "type": "integer", - "format": "int64", - "description": "Member ID of the last updater." + "post_mortem_id": { + "type": "string", + "description": "ID of the post-mortem the work item is bound to." }, - "converted_by": { - "type": "integer", - "format": "int64", - "description": "Member ID of the operator who converted the action into a follow-up. Present only after conversion." + "status": { + "type": "string", + "description": "Work item status label after the conversion." + } + }, + "title": "i_wi_converted" + }, + "FeedDetailWorkItemBound": { + "type": "object", + "description": "Detail payload for `i_wi_bound`.", + "properties": { + "work_item_id": { + "type": "string", + "description": "Work item ID." }, - "converted_at_seconds": { - "type": "integer", - "format": "int64", - "description": "Conversion time as a Unix timestamp in seconds. Present only after conversion." + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." }, - "created_at_seconds": { - "type": "integer", - "format": "int64", - "description": "Creation time as a Unix timestamp in seconds." + "title": { + "type": "string", + "description": "Work item title." }, - "updated_at_seconds": { - "type": "integer", - "format": "int64", - "description": "Last update time as a Unix timestamp in seconds." + "post_mortem_id": { + "type": "string", + "description": "ID of the post-mortem the work item is bound to." } - } + }, + "title": "i_wi_bound" }, - "WorkItemCreateResult": { + "FeedDetailWorkItemDeleted": { "type": "object", - "description": "Result of creating a work item.", - "required": [ - "item" - ], + "description": "Detail payload for `i_wi_deleted`.", "properties": { - "item": { - "$ref": "#/components/schemas/WorkItemItem" + "work_item_id": { + "type": "string", + "description": "Work item ID." }, - "added_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Assignee member IDs that were newly added (and notified)." + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." }, - "idempotent_replay": { - "type": "boolean", - "description": "True when the call replayed an earlier request with the same idempotency key and no new item was created." + "title": { + "type": "string", + "description": "Work item title." + }, + "post_mortem_id": { + "type": "string", + "description": "ID of the post-mortem the work item is bound to." } - } + }, + "title": "i_wi_deleted" }, - "WorkItemMutationResult": { + "FeedDetailAlertMerge": { "type": "object", - "description": "Result of mutating a work item.", + "title": "a_merge", + "description": "Detail payload for `a_merge`: an alert merged into an incident.", "properties": { - "item": { - "$ref": "#/components/schemas/WorkItemItem" + "comment": { + "type": "string", + "description": "Comment recorded with the merge. Omitted when empty." }, - "added_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Assignee member IDs that were newly added (and notified)." + "target_incident": { + "$ref": "#/components/schemas/IncidentShort", + "description": "Incident the alerts were merged into. Omitted when not recorded." }, - "removed_assignee_ids": { + "source_alerts": { "type": "array", "items": { - "type": "integer", - "format": "int64" + "$ref": "#/components/schemas/AlertShort" }, - "description": "Assignee member IDs that were removed (never notified)." + "description": "Source alerts merged into the target incident. Omitted when empty." }, - "idempotent_replay": { - "type": "boolean", - "description": "True when the call replayed an earlier request with the same idempotency key." + "owner_id": { + "type": "integer", + "format": "int64", + "description": "New owner member ID set on the target incident. Omitted when unchanged." + }, + "title": { + "type": "string", + "description": "New title set on the target incident. Omitted when unchanged." } } }, - "WorkItemListResult": { + "AlertShort": { "type": "object", - "description": "Cursor-paginated list of work items.", - "required": [ - "items", - "has_more" - ], + "description": "Brief alert reference.", "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WorkItemItem" - }, - "description": "Work items for the current page." - }, - "next_cursor": { + "alert_id": { "type": "string", - "description": "Cursor for the next page. Pass it as `cursor`; absent when there are no more results." + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Alert ID (ObjectID hex string)." }, - "has_more": { + "title": { + "type": "string", + "description": "Alert title, resolved at read time. Omitted when empty." + } + } + }, + "EventGroup": { + "type": "object", + "description": "Alert event merge configuration. When enabled, repeated incoming events of the same alert are merged into the existing alert within the time window instead of creating new alerts.", + "properties": { + "is_enabled": { "type": "boolean", - "description": "True when more results are available." + "description": "When true, repeated events merge into the existing alert; when false, every event creates a separate alert. Defaults to true." }, - "idempotent_replay": { - "type": "boolean", - "description": "True when the call replayed an earlier request with the same idempotency key." + "time_window": { + "type": "integer", + "minimum": 1, + "description": "Merge window in minutes, 1-1440 (24 h); accounts with the extended limit may use up to 10080 (7 days). Defaults to 1440." } } }, - "ListWorkItemRequest": { + "StatusPageInfoResponse": { "type": "object", - "description": "Filters for listing work items. At least one of `incident_id`, `post_mortem_id`, or `assignee_id` is required.", + "description": "Status page detail returned by `GET /status-page/info`: the full page configuration plus feature flags.", + "allOf": [ + { + "$ref": "#/components/schemas/StatusPageItem" + }, + { + "type": "object", + "properties": { + "managed_domain_feature_enabled": { + "type": "boolean", + "description": "Whether the managed custom-domain feature is enabled for this page. `true` for public pages, always `false` for internal pages." + } + }, + "required": [ + "managed_domain_feature_enabled" + ] + } + ] + }, + "StatusPagePreDefinedTemplate": { + "type": "object", + "description": "A predefined event template: a reusable draft of an event's title, type, status, and description. In `POST /status-page/template/upsert`, omit `template_id` to create and supply it to update; on update only non-empty fields are applied.", "properties": { - "incident_id": { + "template_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Incident ID (MongoDB ObjectID). Also returns follow-ups anchored on the incident's post-mortem." + "description": "Template ID. Omit to create a new template; supply to update an existing one." }, - "post_mortem_id": { + "title": { "type": "string", - "description": "Post-mortem ID (32-character hex string). Returns follow-ups bound to this post-mortem." + "description": "Template title." }, - "item_type": { + "type": { "type": "string", "enum": [ - "action", - "follow_up" + "incident", + "maintenance" ], - "description": "Filter by work item type: `action` action item, `follow_up` post-mortem follow-up." - }, - "assignee_id": { - "type": "integer", - "format": "int64", - "description": "Restrict results to items assigned to this member ID. Listing by assignee alone requires being that assignee or an account admin." + "description": "Change type the template applies to: `incident` unplanned incident, `maintenance` planned maintenance." }, - "cursor": { + "status": { "type": "string", - "description": "Pagination cursor from a previous response's `next_cursor`." + "enum": [ + "investigating", + "identified", + "monitoring", + "resolved", + "scheduled", + "ongoing", + "completed" + ], + "description": "Change status the template maps to. Incidents use `investigating`/`identified`/`monitoring`/`resolved`; maintenances use `scheduled`/`ongoing`/`completed`." }, - "limit": { - "type": "integer", - "format": "int64", - "minimum": 0, - "maximum": 200, - "default": 50, - "description": "Page size, at most 200. Defaults to 50." + "description": { + "type": "string", + "description": "Template body text (Markdown)." } } }, - "CreateWorkItemRequest": { + "StatusPageMessageTemplate": { "type": "object", - "description": "Parameters for creating an incident work item.", - "required": [ - "item_type", - "title", - "incident_id", - "idempotency_key" - ], + "description": "A message template: per-status notification texts for one change type. In `POST /status-page/template/upsert`, omit `template_id` to create and supply it to update; on update only non-empty fields are applied.", "properties": { - "item_type": { + "template_id": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "`action` anchors to an active incident and must not set `post_mortem_id`; `follow_up` requires `post_mortem_id`." + "description": "Template ID. Omit to create a new template; supply to update an existing one." }, "title": { "type": "string", - "maxLength": 512, - "description": "Item title (max 512 characters)." - }, - "description": { - "type": "string", - "maxLength": 65535, - "description": "Optional longer description (max 65,535 characters)." - }, - "status": { - "type": "string", - "maxLength": 64, - "description": "Optional client-defined initial status (max 64 characters)." - }, - "priority": { - "type": "string", - "maxLength": 64, - "description": "Optional client-defined priority (max 64 characters)." - }, - "incident_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Incident ID (MongoDB ObjectID) the item is anchored to." + "description": "Template title." }, - "post_mortem_id": { + "type": { "type": "string", - "description": "Post-mortem ID (32-character hex string). Required for `follow_up`, forbidden for `action`. The post-mortem must be linked to `incident_id`." + "enum": [ + "incident", + "maintenance" + ], + "description": "Change type the template applies to: `incident` unplanned incident, `maintenance` planned maintenance." }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" + "messages": { + "type": "object", + "additionalProperties": { + "type": "string" }, - "description": "Initial assignee member IDs. Assignees must be active members who can already read the anchor; assignment never grants access." - }, - "idempotency_key": { - "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." + "description": "Notification text (Markdown) per event status. Keys are change statuses valid for the template's `type` (for example `investigating` or `resolved` for incidents); the value is the text used when the event reaches that status." } } }, - "UpdateWorkItemRequest": { + "ListStatusPageTemplatesResponse": { "type": "object", - "description": "Partial patch for a work item. Omitted fields stay unchanged; an explicit `null` clears the field.", + "description": "Event template list. Item shape depends on the requested `type`: predefined event templates for `pre_defined`, message templates for `message`.", "required": [ - "work_item_id", - "version" + "items" ], "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." - }, - "version": { - "type": "integer", - "format": "int64", - "description": "Current item version for optimistic locking. Must match the stored version." - }, - "title": { - "type": [ - "string", - "null" - ], - "description": "New title (max 512 characters).", - "maxLength": 512 - }, - "description": { - "type": [ - "string", - "null" - ], - "description": "New description (max 65,535 characters).", - "maxLength": 65535 - }, - "status": { - "type": [ - "string", - "null" - ], - "description": "New client-defined status (max 64 characters).", - "maxLength": 64 + "items": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" + }, + { + "$ref": "#/components/schemas/StatusPageMessageTemplate" + } + ] + }, + "description": "Templates of the requested category." + } + } + }, + "FeedDetailAlertUpdate": { + "type": "object", + "title": "a_update", + "description": "Detail payload for `a_update`: severity/status after the update.", + "properties": { + "severity": { + "$ref": "#/components/schemas/FeedSeverity" }, - "priority": { - "type": [ - "string", - "null" - ], - "description": "New client-defined priority (max 64 characters).", - "maxLength": 64 + "status": { + "$ref": "#/components/schemas/FeedSeverity" } } }, - "DeleteWorkItemRequest": { + "FeedDetailAlertMuteBySilence": { "type": "object", - "description": "Parameters for soft-deleting a work item.", - "required": [ - "work_item_id", - "version" - ], + "title": "a_m_silence", + "description": "Detail payload for `a_m_silence`: the alert was muted by a silence rule.", "properties": { - "work_item_id": { + "rule_id": { "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Silence rule ID that muted the alert. Omitted when empty." }, - "version": { - "type": "integer", - "format": "int64", - "description": "Current item version for optimistic locking. Must match the stored version." + "rule_name": { + "type": "string", + "description": "Silence rule name, resolved at read time. Omitted when empty." } } }, - "CompleteWorkItemRequest": { + "FeedDetailAlertMuteByInhibit": { "type": "object", - "description": "Parameters for completing a work item.", - "required": [ - "work_item_id", - "version", - "target_status", - "idempotency_key" - ], + "title": "a_m_inhibit", + "description": "Detail payload for `a_m_inhibit`: the alert was inhibited by an inhibit rule because of a source alert.", "properties": { - "work_item_id": { + "rule_id": { "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." + "pattern": "^[0-9a-fA-F]{24}$", + "description": "Inhibit rule ID that muted the alert. Omitted when empty." }, - "version": { - "type": "integer", - "format": "int64", - "description": "Current item version for optimistic locking. Must match the stored version." + "rule_name": { + "type": "string", + "description": "Inhibit rule name, resolved at read time. Omitted when empty." }, - "target_status": { + "source_alert_id": { "type": "string", - "maxLength": 64, - "description": "Client-defined status to set (max 64 characters). There is no fixed state machine." + "pattern": "^[0-9a-fA-F]{24}$", + "description": "ID of the source alert that triggered the inhibition. Omitted when empty." }, - "idempotency_key": { + "source_alert_title": { "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." + "description": "Title of the source alert, resolved at read time. Omitted when empty." } } }, - "ConvertWorkItemRequest": { + "FeedDetailAlertMuteByFlapping": { "type": "object", - "description": "Parameters for converting an action item into a post-mortem follow-up in place.", - "required": [ - "work_item_id", - "version", - "idempotency_key" - ], + "title": "a_m_flapping", + "description": "Detail payload for `a_m_flapping` (historical): the alert was muted by flapping detection.", "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." - }, - "version": { + "max_changes": { "type": "integer", - "format": "int64", - "description": "Current item version for optimistic locking. Must match the stored version." + "description": "State-change count threshold that triggered flapping detection. Omitted when zero." }, - "target_status": { - "type": [ - "string", - "null" - ], - "description": "Optional client-defined status to set on the converted follow-up (max 64 characters).", - "maxLength": 64 + "in_secs": { + "type": "integer", + "description": "Window in seconds over which the state changes were counted. Omitted when zero." }, - "idempotency_key": { - "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." + "mute_secs": { + "type": "integer", + "description": "Mute duration in seconds. Omitted when zero." } } }, - "ResetWorkItemAssigneesRequest": { + "FeedDetailAlertAck": { "type": "object", - "description": "Full replacement of a work item's assignee set.", + "title": "a_ack", + "description": "Detail payload for `a_ack` (historical). No fields.", + "properties": {} + }, + "FeedDetailAlertUnack": { + "type": "object", + "title": "a_unack", + "description": "Detail payload for `a_unack` (historical). No fields.", + "properties": {} + }, + "ScheduleByPersonRequest": { + "type": "object", + "description": "Member on-call status request", + "properties": { + "person_id": { + "type": "integer", + "description": "Member ID whose on-call status is returned.", + "format": "int64" + } + }, "required": [ - "work_item_id", - "version" - ], + "person_id" + ] + }, + "ScheduleByPersonResponse": { + "type": "object", + "description": "The member's on-call status: the shift in progress, the next one, and every enabled schedule they participate in.", "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "Work item ID (opaque string, max 128 characters)." + "current": { + "$ref": "#/components/schemas/MemberOncallInterval" }, - "version": { - "type": "integer", - "format": "int64", - "description": "Current item version for optimistic locking. Must match the stored version." + "next": { + "$ref": "#/components/schemas/MemberOncallInterval" }, - "assignee_ids": { + "schedules": { "type": "array", + "description": "All enabled schedules the member participates in.", "items": { - "type": "integer", - "format": "int64" - }, - "description": "New assignee member IDs, replacing the current set. An empty array clears all assignees." + "$ref": "#/components/schemas/MemberScheduleItem" + } } - } + }, + "required": [ + "schedules" + ] }, - "BindWorkItemPostMortemRequest": { + "MemberScheduleItem": { "type": "object", - "description": "Parameters for bulk-binding an incident's unbound follow-ups to a post-mortem.", - "required": [ - "post_mortem_id", - "incident_id", - "idempotency_key" - ], + "description": "An enabled schedule the member participates in.", "properties": { - "post_mortem_id": { - "type": "string", - "description": "Post-mortem ID (32-character hex string) to bind the follow-ups to." - }, - "incident_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Incident ID (MongoDB ObjectID) whose converted-but-unbound follow-ups are bound." + "schedule_id": { + "type": "integer", + "description": "Schedule ID.", + "format": "int64" }, - "idempotency_key": { + "schedule_name": { "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "Client-generated idempotency key (max 128 characters; letters, digits, `_`, `-`, `.`, `:` only)." + "description": "Schedule name." } } }, - "IncidentCommentTypeDisplay": { + "MemberOncallInterval": { "type": "object", - "description": "Resolved display of an account-level comment type, populated at read time from the current type definition.", - "required": [ - "id", - "name", - "color" - ], + "description": "One on-call shift interval of a member.", "properties": { - "id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Comment type ID (MongoDB ObjectID)." + "schedule_id": { + "type": "integer", + "description": "Owning schedule ID.", + "format": "int64" }, - "name": { + "schedule_name": { "type": "string", - "maxLength": 40, - "description": "Display name of the comment type." + "description": "Owning schedule name." }, - "color": { - "type": "string", - "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "Badge color in #RRGGBB format." + "start_at": { + "type": "integer", + "description": "Unix timestamp in seconds - when the shift starts.", + "format": "int64" + }, + "end_at": { + "type": "integer", + "description": "Unix timestamp in seconds - when the shift ends. Absent while the shift is ongoing.", + "format": "int64" } } }, - "FeedDetailWorkItemCreated": { + "ListIntegrationTypesResponse": { "type": "object", - "description": "Detail payload for `i_wi_created`.", + "description": "A page of integration types.", + "required": [ + "p", + "limit", + "total", + "items" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "Work item ID." - }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself, convertible to `follow_up` later; `follow_up`: an improvement item anchored to a post-mortem, requiring the incident to be linked to that post-mortem at creation." - }, - "title": { - "type": "string", - "description": "Work item title." + "p": { + "type": "integer", + "description": "Page number echoed back." }, - "status": { - "type": "string", - "description": "Work item status label (e.g. `open`, `done`)." + "limit": { + "type": "integer", + "description": "Page size echoed back." }, - "assignee_ids": { + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching types." + }, + "items": { "type": "array", + "description": "Integration types on the current page.", "items": { - "type": "integer", - "format": "int64" - }, - "description": "Assignee member IDs." - }, - "post_mortem_id": { - "type": "string", - "description": "ID of the post-mortem the work item is bound to." + "$ref": "#/components/schemas/IntegrationTypeItem" + } } - }, - "title": "i_wi_created" + } }, - "FeedDetailWorkItemUpdated": { + "IntegrationTypeItem": { "type": "object", - "description": "Detail payload for `i_wi_updated`. Only the fields that changed carry `from_*`/`to_*` values.", + "description": "An integration type the account can configure.", + "required": [ + "plugin_type", + "plugin_type_name", + "plugin_type_logo_url", + "category", + "status", + "supports_api_create" + ], "properties": { - "work_item_id": { + "plugin_type": { "type": "string", - "description": "Work item ID." + "description": "Type identifier to pass as `plugin_type` when creating an integration.", + "example": "standard.alert" }, - "item_type": { + "plugin_type_name": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." + "description": "Display name of the type.", + "example": "Standard Alert" }, - "title": { + "plugin_type_logo_url": { "type": "string", - "description": "Work item title." + "description": "Logo URL of the type." }, - "from_title": { + "category": { "type": "string", - "description": "Title before the update." + "description": "Category the type belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks.", + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ] }, - "from_status": { + "status": { "type": "string", - "description": "Status label before the update." + "description": "Platform status of the type." }, - "to_status": { - "type": "string", - "description": "Status label after the update." + "supports_api_create": { + "type": "boolean", + "description": "Whether `POST /integration/create` accepts this type." + } + } + }, + "IntegrationTypeListRequest": { + "type": "object", + "description": "Filter parameters for listing integration types.", + "properties": { + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Page number, 1-based." }, - "from_priority": { - "type": "string", - "description": "Priority label before the update." + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20, + "description": "Page size. Defaults to 20, maximum 100." }, - "to_priority": { + "orderby": { "type": "string", - "description": "Priority label after the update." + "description": "Sort field. When omitted, types are returned in console ranking order.", + "enum": [ + "id", + "created_at", + "updated_at", + "name", + "type" + ] }, - "from_description": { + "category": { "type": "string", - "description": "Description before the update." + "description": "Filter by category. Accepts a comma-separated list, for example `event.alert,event.change`." }, - "to_description": { - "type": "string", - "description": "Description after the update." + "asc": { + "type": [ + "boolean", + "null" + ], + "default": true, + "description": "Sort ascending when `true` (the default); descending when `false`." } - }, - "title": "i_wi_updated" + } }, - "FeedDetailWorkItemAssigneesChanged": { + "ListIntegrationsResponse": { "type": "object", - "description": "Detail payload for `i_wi_assignees`.", + "description": "A page of integrations.", + "required": [ + "p", + "limit", + "total", + "items" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "Work item ID." - }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." - }, - "title": { - "type": "string", - "description": "Work item title." + "p": { + "type": "integer", + "description": "Page number echoed back." }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Assignee member IDs after the change." + "limit": { + "type": "integer", + "description": "Page size echoed back." }, - "added_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "Member IDs added as assignees." + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching integrations." }, - "removed_assignee_ids": { + "items": { "type": "array", + "description": "Integrations on the current page.", "items": { - "type": "integer", - "format": "int64" - }, - "description": "Member IDs removed from assignees." + "$ref": "#/components/schemas/IntegrationItem" + } } - }, - "title": "i_wi_assignees" + } }, - "FeedDetailWorkItemCompleted": { + "IntegrationItem": { "type": "object", - "description": "Detail payload for `i_wi_completed`.", + "description": "Public integration list item with full stored configuration. Timestamps are Unix epoch seconds.", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings", + "data_source_id", + "account_id", + "exclusive_data_source_id" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "Work item ID." + "integration_id": { + "type": "integer", + "format": "int64", + "description": "Integration ID." }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." + "team_id": { + "type": "integer", + "format": "int64", + "description": "ID of the team that owns the integration. `0` when it is not assigned to a team." }, - "title": { + "plugin_type": { "type": "string", - "description": "Work item title." + "description": "Integration type, for example `standard.alert` or `zabbix.alert`." }, - "from_status": { + "plugin_type_name": { "type": "string", - "description": "Status label before completion." + "description": "Display name of the integration type, in the language of the request." }, - "to_status": { + "category": { "type": "string", - "description": "Status label after completion." + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ], + "description": "Category the integration belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks." }, - "post_mortem_id": { - "type": "string", - "description": "ID of the post-mortem the work item is bound to." - } - }, - "title": "i_wi_completed" - }, - "FeedDetailWorkItemConverted": { - "type": "object", - "description": "Detail payload for `i_wi_converted`.", - "properties": { - "work_item_id": { + "name": { "type": "string", - "description": "Work item ID." + "description": "Integration name." }, - "title": { + "description": { "type": "string", - "description": "Work item title." + "description": "Free-form description." }, - "from_type": { + "status": { "type": "string", "enum": [ - "action", - "follow_up" + "enabled", + "disabled" ], - "description": "Work item type before the conversion. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem. Conversion currently only supports `action` → `follow_up`, so `from_type` is always `action` in this event." + "description": "Lifecycle status: `enabled` while the integration accepts events, `disabled` when it is paused." }, - "to_type": { + "ref_id": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type after the conversion. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem. Conversion currently only supports `action` → `follow_up`, so `to_type` is always `follow_up` in this event, and a successful conversion immediately tries to bind the incident's post-mortem." + "description": "Source reference ID, normally `a_` for an account-level integration; legacy `w_` references may also exist. Channel-owned `c_` integrations are excluded." + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was created." + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was last updated." + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds of the most recent event received. `0` when no event has arrived yet." + }, + "editable": { + "type": "boolean", + "description": "Whether the current caller passes the integration object-permission check; write calls also require Integrations Manage." + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "ID of the member who created the integration." + }, + "updated_by": { + "type": "integer", + "format": "int64", + "description": "ID of the member who last updated the integration." + }, + "no_editable": { + "type": "boolean", + "description": "Read-only flag. When true, the public APIs do not allow changes to this integration." + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "Internal integration type ID; use `plugin_type`, not this ID, when creating an integration." }, - "post_mortem_id": { + "integration_key": { "type": "string", - "description": "ID of the post-mortem the work item is bound to." + "description": "Decrypted integration key for inbound pushes. Empty when no key is stored; distinct from the account `app_key`." }, - "status": { - "type": "string", - "description": "Work item status label after the conversion." + "settings": { + "type": "object", + "additionalProperties": true, + "description": "Stored type-specific configuration, including credential values without masking; matches the legacy `/datasource/*` response behavior." + }, + "data_source_id": { + "type": "integer", + "format": "int64", + "description": "Legacy datasource ID, equal to `integration_id`." + }, + "account_id": { + "type": "integer", + "format": "int64", + "description": "ID of the account that owns the integration." + }, + "exclusive_data_source_id": { + "type": "integer", + "format": "int64", + "description": "Legacy compatibility field; `0` for items returned by this public-integration list." } - }, - "title": "i_wi_converted" + } }, - "FeedDetailWorkItemBound": { + "ListIntegrationsRequest": { "type": "object", - "description": "Detail payload for `i_wi_bound`.", + "description": "Filter parameters for listing integrations.", "properties": { - "work_item_id": { - "type": "string", - "description": "Work item ID." + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Page number, 1-based." }, - "item_type": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 100, + "description": "Page size. Defaults to 100, maximum 100." + }, + "orderby": { "type": "string", + "description": "Sort field. Defaults to `created_at`; `plugin_type` is sorted by the underlying plugin.", "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." + "created_at", + "updated_at", + "name", + "plugin_type", + "status" + ] }, - "title": { + "category": { "type": "string", - "description": "Work item title." + "description": "Filter by category. Accepts a comma-separated list." }, - "post_mortem_id": { - "type": "string", - "description": "ID of the post-mortem the work item is bound to." - } - }, - "title": "i_wi_bound" - }, - "FeedDetailWorkItemDeleted": { - "type": "object", - "description": "Detail payload for `i_wi_deleted`.", - "properties": { - "work_item_id": { + "type": { "type": "string", - "description": "Work item ID." + "description": "Deprecated. Merged into `plugin_type` when both are set." }, - "item_type": { + "plugin_type": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "Work item type. `action`: an action item anchored to the incident itself; `follow_up`: an improvement item anchored to a post-mortem." + "description": "Filter by integration type. Accepts a comma-separated list." }, - "title": { + "status": { "type": "string", - "description": "Work item title." + "description": "Filter by status. Accepts a comma-separated list." }, - "post_mortem_id": { - "type": "string", - "description": "ID of the post-mortem the work item is bound to." - } - }, - "title": "i_wi_deleted" - }, - "FeedDetailAlertMerge": { - "type": "object", - "title": "a_merge", - "description": "Detail payload for `a_merge`: an alert merged into an incident.", - "properties": { - "comment": { + "name": { "type": "string", - "description": "Comment recorded with the merge. Omitted when empty." - }, - "target_incident": { - "$ref": "#/components/schemas/IncidentShort", - "description": "Incident the alerts were merged into. Omitted when not recorded." + "description": "Filter by integration name." }, - "source_alerts": { + "ref_ids": { "type": "array", + "description": "Filter by source reference IDs. Each value must start with `c_` (channel), `a_` (account) or `w_`.", "items": { - "$ref": "#/components/schemas/AlertShort" - }, - "description": "Source alerts merged into the target incident. Omitted when empty." + "type": "string" + } }, - "owner_id": { - "type": "integer", - "format": "int64", - "description": "New owner member ID set on the target incident. Omitted when unchanged." + "asc": { + "type": "boolean", + "description": "Sort ascending when true, descending when false." }, - "title": { - "type": "string", - "description": "New title set on the target incident. Omitted when unchanged." - } - } - }, - "AlertShort": { - "type": "object", - "description": "Brief alert reference.", - "properties": { - "alert_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Alert ID (ObjectID hex string)." + "is_my_team": { + "type": "boolean", + "description": "Limit the result to integrations owned by your teams." }, - "title": { - "type": "string", - "description": "Alert title, resolved at read time. Omitted when empty." + "team_ids": { + "type": "array", + "description": "Filter by team IDs. With `is_my_team`, the values narrow that set further.", + "items": { + "type": "integer", + "format": "int64" + } } } }, - "EventGroup": { + "IntegrationDetail": { "type": "object", - "description": "Alert event merge configuration. When enabled, repeated incoming events of the same alert are merged into the existing alert within the time window instead of creating new alerts.", + "description": "Public integration detail with stored settings and its decrypted key. Timestamps are Unix epoch seconds.", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings" + ], "properties": { - "is_enabled": { - "type": "boolean", - "description": "When true, repeated events merge into the existing alert; when false, every event creates a separate alert. Defaults to true." + "integration_id": { + "type": "integer", + "format": "int64", + "description": "Integration ID." }, - "time_window": { + "team_id": { "type": "integer", - "minimum": 1, - "description": "Merge window in minutes, 1-1440 (24 h); accounts with the extended limit may use up to 10080 (7 days). Defaults to 1440." - } - } - }, - "StatusPageInfoResponse": { - "type": "object", - "description": "Status page detail returned by `GET /status-page/info`: the full page configuration plus feature flags.", - "allOf": [ - { - "$ref": "#/components/schemas/StatusPageItem" + "format": "int64", + "description": "ID of the team that owns the integration. `0` when it is not assigned to a team." }, - { - "type": "object", - "properties": { - "managed_domain_feature_enabled": { - "type": "boolean", - "description": "Whether the managed custom-domain feature is enabled for this page. `true` for public pages, always `false` for internal pages." - } - }, - "required": [ - "managed_domain_feature_enabled" - ] - } - ] - }, - "StatusPagePreDefinedTemplate": { - "type": "object", - "description": "A predefined event template: a reusable draft of an event's title, type, status, and description. In `POST /status-page/template/upsert`, omit `template_id` to create and supply it to update; on update only non-empty fields are applied.", - "properties": { - "template_id": { + "plugin_type": { "type": "string", - "description": "Template ID. Omit to create a new template; supply to update an existing one." + "description": "Integration type, for example `standard.alert` or `zabbix.alert`." }, - "title": { + "plugin_type_name": { "type": "string", - "description": "Template title." + "description": "Display name of the integration type, in the language of the request." }, - "type": { + "category": { "type": "string", "enum": [ - "incident", - "maintenance" + "event.alert", + "event.change", + "im", + "webhook" ], - "description": "Change type the template applies to: `incident` unplanned incident, `maintenance` planned maintenance." + "description": "Category the integration belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks." + }, + "name": { + "type": "string", + "description": "Integration name." + }, + "description": { + "type": "string", + "description": "Free-form description." }, "status": { "type": "string", "enum": [ - "investigating", - "identified", - "monitoring", - "resolved", - "scheduled", - "ongoing", - "completed" + "enabled", + "disabled" ], - "description": "Change status the template maps to. Incidents use `investigating`/`identified`/`monitoring`/`resolved`; maintenances use `scheduled`/`ongoing`/`completed`." + "description": "Lifecycle status: `enabled` while the integration accepts events, `disabled` when it is paused." }, - "description": { - "type": "string", - "description": "Template body text (Markdown)." - } - } - }, - "StatusPageMessageTemplate": { - "type": "object", - "description": "A message template: per-status notification texts for one change type. In `POST /status-page/template/upsert`, omit `template_id` to create and supply it to update; on update only non-empty fields are applied.", - "properties": { - "template_id": { + "ref_id": { "type": "string", - "description": "Template ID. Omit to create a new template; supply to update an existing one." + "description": "Source reference ID, normally `a_` for an account-level integration; legacy `w_` references may also exist. Channel-owned `c_` integrations are excluded." + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was created." + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was last updated." + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds of the most recent event received. `0` when no event has arrived yet." + }, + "editable": { + "type": "boolean", + "description": "Whether the current caller passes the integration object-permission check; write calls also require Integrations Manage." + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "ID of the member who created the integration." }, - "title": { - "type": "string", - "description": "Template title." + "updated_by": { + "type": "integer", + "format": "int64", + "description": "ID of the member who last updated the integration." }, - "type": { + "no_editable": { + "type": "boolean", + "description": "Read-only flag. When true, the public APIs do not allow changes to this integration." + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "Internal integration type ID; use `plugin_type`, not this ID, when creating an integration." + }, + "integration_key": { "type": "string", - "enum": [ - "incident", - "maintenance" - ], - "description": "Change type the template applies to: `incident` unplanned incident, `maintenance` planned maintenance." + "description": "Decrypted integration key for inbound pushes. Empty when no key is stored; distinct from the account `app_key`." }, - "messages": { + "settings": { "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "Notification text (Markdown) per event status. Keys are change statuses valid for the template's `type` (for example `investigating` or `resolved` for incidents); the value is the text used when the event reaches that status." + "additionalProperties": true, + "description": "Stored type-specific configuration, including credential values without masking; matches the legacy `/datasource/*` response behavior." + }, + "test": { + "type": "object", + "description": "Plugin test result, returned only when a test is performed.", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Whether the plugin test succeeded." + }, + "message": { + "type": "string", + "description": "Test failure message; empty on success." + } + } } } }, - "ListStatusPageTemplatesResponse": { + "GetIntegrationRequest": { "type": "object", - "description": "Event template list. Item shape depends on the requested `type`: predefined event templates for `pre_defined`, message templates for `message`.", + "description": "Identifies one integration.", "required": [ - "items" + "integration_id" ], "properties": { - "items": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" - }, - { - "$ref": "#/components/schemas/StatusPageMessageTemplate" - } - ] - }, - "description": "Templates of the requested category." + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 } } }, - "FeedDetailAlertUpdate": { + "CreateIntegrationResponse": { "type": "object", - "title": "a_update", - "description": "Detail payload for `a_update`: severity/status after the update.", + "description": "The created integration and its key.", + "required": [ + "integration_id", + "integration_key" + ], "properties": { - "severity": { - "$ref": "#/components/schemas/FeedSeverity" + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ID of the new integration.", + "example": 6113996590131 }, - "status": { - "$ref": "#/components/schemas/FeedSeverity" - } - } - }, - "FeedDetailAlertMuteBySilence": { - "type": "object", - "title": "a_m_silence", - "description": "Detail payload for `a_m_silence`: the alert was muted by a silence rule.", - "properties": { - "rule_id": { + "integration_key": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Silence rule ID that muted the alert. Omitted when empty." + "description": "Integration key for inbound pushes; also readable from `/integration/list` and `/integration/info`.", + "example": "0123456789abcdef0123456789abcdef100" }, - "rule_name": { - "type": "string", - "description": "Silence rule name, resolved at read time. Omitted when empty." + "test": { + "type": "object", + "description": "Plugin test result, returned only when a test is performed.", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Whether the plugin test succeeded." + }, + "message": { + "type": "string", + "description": "Test failure message; empty on success." + } + } } } }, - "FeedDetailAlertMuteByInhibit": { + "CreateIntegrationRequest": { "type": "object", - "title": "a_m_inhibit", - "description": "Detail payload for `a_m_inhibit`: the alert was inhibited by an inhibit rule because of a source alert.", + "description": "Payload for creating an integration.", + "required": [ + "plugin_type" + ], "properties": { - "rule_id": { + "plugin_type": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "Inhibit rule ID that muted the alert. Omitted when empty." + "description": "Integration type. Must be one listed by `POST /integration/type/list` with `supports_api_create: true`.", + "example": "standard.alert" }, - "rule_name": { + "name": { "type": "string", - "description": "Inhibit rule name, resolved at read time. Omitted when empty." + "minLength": 2, + "maxLength": 49, + "description": "Integration name, 2–49 characters when nonempty; defaults to the integration type name when omitted or empty.", + "example": "Prod metrics alerts" }, - "source_alert_id": { + "description": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "ID of the source alert that triggered the inhibition. Omitted when empty." + "maxLength": 499, + "description": "Free-form description, at most 499 characters." }, - "source_alert_title": { - "type": "string", - "description": "Title of the source alert, resolved at read time. Omitted when empty." - } - } - }, - "FeedDetailAlertMuteByFlapping": { - "type": "object", - "title": "a_m_flapping", - "description": "Detail payload for `a_m_flapping` (historical): the alert was muted by flapping detection.", - "properties": { - "max_changes": { + "team_id": { "type": "integer", - "description": "State-change count threshold that triggered flapping detection. Omitted when zero." + "format": "int64", + "minimum": 0, + "description": "Owning team ID; omit or use `0` for no team. A nonzero ID must belong to the current account.", + "example": 1467226103121 }, - "in_secs": { - "type": "integer", - "description": "Window in seconds over which the state changes were counted. Omitted when zero." + "settings": { + "type": "object", + "description": "Type-specific configuration; the accepted keys depend on `plugin_type`.", + "additionalProperties": true }, - "mute_secs": { - "type": "integer", - "description": "Mute duration in seconds. Omitted when zero." + "integration_key": { + "type": "string", + "minLength": 35, + "maxLength": 35, + "description": "Optional pre-generated key: 35 characters, ending with the account ID modulo 1000 padded to three digits; it must not already be in use. Omit to generate a key." + }, + "is_test": { + "type": "boolean", + "description": "Run the plugin test during creation; false when omitted. Inspect the returned `test.success` for the test outcome." } } }, - "FeedDetailAlertAck": { - "type": "object", - "title": "a_ack", - "description": "Detail payload for `a_ack` (historical). No fields.", - "properties": {} - }, - "FeedDetailAlertUnack": { - "type": "object", - "title": "a_unack", - "description": "Detail payload for `a_unack` (historical). No fields.", - "properties": {} - }, - "ScheduleByPersonRequest": { + "UpdateIntegrationRequest": { "type": "object", - "description": "Member on-call status request", - "properties": { - "person_id": { - "type": "integer", - "description": "Member ID whose on-call status is returned.", - "format": "int64" - } - }, + "description": "Payload for updating an integration. Only the fields you send are changed.", "required": [ - "person_id" - ] - }, - "ScheduleByPersonResponse": { - "type": "object", - "description": "The member's on-call status: the shift in progress, the next one, and every enabled schedule they participate in.", + "integration_id" + ], "properties": { - "current": { - "$ref": "#/components/schemas/MemberOncallInterval" + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 }, - "next": { - "$ref": "#/components/schemas/MemberOncallInterval" + "name": { + "type": [ + "string", + "null" + ], + "minLength": 2, + "maxLength": 49, + "description": "New name, 2–49 characters." }, - "schedules": { - "type": "array", - "description": "All enabled schedules the member participates in.", - "items": { - "$ref": "#/components/schemas/MemberScheduleItem" - } + "description": { + "type": [ + "string", + "null" + ], + "maxLength": 499, + "description": "New description, at most 499 characters." + }, + "team_id": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0, + "description": "New owning team ID; `0` clears the team assignment." + }, + "settings": { + "type": "object", + "description": "Replacement type-specific configuration. Known sensitive fields omitted or sent as `******` keep their stored value; an explicit empty headers object clears headers.", + "additionalProperties": true + }, + "is_test": { + "type": "boolean", + "description": "Run the plugin test when submitting `settings`; no test is performed for a metadata-only update." } - }, - "required": [ - "schedules" - ] + } }, - "MemberScheduleItem": { + "IntegrationLifecycleRequest": { "type": "object", - "description": "An enabled schedule the member participates in.", + "description": "Identifies the integration to act on.", + "required": [ + "integration_id" + ], "properties": { - "schedule_id": { + "integration_id": { "type": "integer", - "description": "Schedule ID.", - "format": "int64" - }, - "schedule_name": { - "type": "string", - "description": "Schedule name." + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 } } }, - "MemberOncallInterval": { + "RotateIntegrationKeyResponse": { "type": "object", - "description": "One on-call shift interval of a member.", + "description": "The newly issued integration key.", + "required": [ + "integration_key" + ], "properties": { - "schedule_id": { - "type": "integer", - "description": "Owning schedule ID.", - "format": "int64" - }, - "schedule_name": { + "integration_key": { "type": "string", - "description": "Owning schedule name." - }, - "start_at": { - "type": "integer", - "description": "Unix timestamp in seconds - when the shift starts.", - "format": "int64" - }, - "end_at": { - "type": "integer", - "description": "Unix timestamp in seconds - when the shift ends. Absent while the shift is ongoing.", - "format": "int64" + "description": "New integration key; the previous key stops working immediately. Also readable from `/integration/list` and `/integration/info`.", + "example": "0123456789abcdef0123456789abcdef100" } } } diff --git a/api-reference/on-call.openapi.zh.json b/api-reference/on-call.openapi.zh.json index e81c9fe7..3cc970ab 100644 --- a/api-reference/on-call.openapi.zh.json +++ b/api-reference/on-call.openapi.zh.json @@ -17411,6 +17411,769 @@ } } } + }, + "/integration/type/list": { + "post": { + "operationId": "integration-api-read-type-list", + "summary": "查询集成类型列表", + "description": "查询当前账户可配置的集成类型列表。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **集成中心查看**(`on-call`) |\n\n## 使用说明\n\n- 不传 `orderby` 时按控制台排序返回,此时 `p`/`limit` 依然生效。\n- `supports_api_create` 表示该类型能否通过 `POST /integration/create` 创建。", + "href": "/zh/api-reference/on-call/integrations/integration-api-read-type-list", + "metadata": { + "sidebarTitle": "查询集成类型列表" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListIntegrationTypesResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "p": 1, + "limit": 20, + "total": 2, + "items": [ + { + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "plugin_type_logo_url": "https://cdn.flashcat.cloud/plugin/standard-alert.svg", + "category": "event.alert", + "status": "enabled", + "supports_api_create": true + }, + { + "plugin_type": "jira.change", + "plugin_type_name": "Jira", + "plugin_type_logo_url": "https://cdn.flashcat.cloud/plugin/jira.svg", + "category": "event.change", + "status": "enabled", + "supports_api_create": true + } + ] + } + } + } + } + }, + "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/IntegrationTypeListRequest" + }, + "example": { + "p": 1, + "limit": 20, + "category": "event.alert" + } + } + } + } + } + }, + "/integration/list": { + "post": { + "operationId": "integration-api-read-list", + "summary": "查询集成列表", + "description": "查询公共集成列表,返回存储配置、解密 Key 与当前调用者的编辑权限。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **集成中心查看**(`on-call`) |\n\n## 使用说明\n\n- `orderby` 默认 `created_at`;`plugin_type` 按底层插件排序。\n- `plugin_type`、`status`、`category` 支持逗号分隔多值;`ref_ids` 每个值必须以 `c_`、`a_` 或 `w_` 开头;`c_` 过滤值通过格式校验,但不会返回协作空间专属集成。\n- 传入 `is_my_team` 时仅返回你所在团队的集成,`team_ids` 会在该范围内进一步收窄。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 列表项包含 `settings`、`integration_key`、`plugin_id`、`account_id` 及旧 ID 别名 `data_source_id`,凭据按原值返回,不打码。", + "href": "/zh/api-reference/on-call/integrations/integration-api-read-list", + "metadata": { + "sidebarTitle": "查询集成列表" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/ListIntegrationsResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "p": 1, + "limit": 20, + "total": 1, + "items": [ + { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775203200, + "last_time": 1775298600, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100", + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "data_source_id": 6113996590131, + "account_id": 100, + "exclusive_data_source_id": 0 + } + ] + } + } + } + } + }, + "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/ListIntegrationsRequest" + }, + "example": { + "p": 1, + "limit": 20, + "status": "enabled" + } + } + } + } + } + }, + "/integration/info": { + "post": { + "operationId": "integration-api-read-info", + "summary": "查询集成详情", + "description": "查询单个公共集成详情,返回存储配置及解密后的集成 Key。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **1,000 次/分钟**;**50 次/秒** |\n| 权限要求 | **集成中心查看**(`on-call`) |\n\n## 使用说明\n\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- settings 与集成 Key 按原值返回,不打码,与旧 datasource 详情接口行为一致。", + "href": "/zh/api-reference/on-call/integrations/integration-api-read-info", + "metadata": { + "sidebarTitle": "查询集成详情" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/IntegrationDetail" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775203200, + "last_time": 1775298600, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100" + } + } + } + } + }, + "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/GetIntegrationRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/create": { + "post": { + "operationId": "integration-api-write-create", + "summary": "创建集成", + "description": "创建支持的告警源、变更源、IM 或 Webhook 类型公共集成。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- `plugin_type` 必须是 `POST /integration/type/list` 中 `supports_api_create: true` 的类型,否则返回 `InvalidParameter`。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 不传 `integration_key` 时自动生成;传入时须满足长度、账户后缀与唯一性校验。\n- 传 `is_test: true` 时请检查 `test.success`,不能只根据 HTTP 200 判断插件测试成功。\n- 每次调用都会记录到账户审计日志。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-create", + "metadata": { + "sidebarTitle": "创建集成" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/CreateIntegrationResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "integration_key": "0123456789abcdef0123456789abcdef100", + "test": { + "success": true, + "message": "" + } + } + } + } + } + }, + "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/CreateIntegrationRequest" + }, + "example": { + "plugin_type": "standard.alert", + "name": "Prod metrics alerts", + "description": "Alerts pushed by the production Prometheus stack", + "team_id": 1467226103121, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "is_test": true + } + } + } + } + } + }, + "/integration/update": { + "post": { + "operationId": "integration-api-write-update", + "summary": "更新集成", + "description": "更新集成的名称、描述、所属团队或配置。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 仅发送的字段会被修改,未发送的字段保持原值。\n- 提交 `settings` 会替换配置;已识别的敏感字段不传或传 `******` 时保留原值。清空 Headers 请传 `headers: {}`;清空 Body 请使用该集成类型的显式空值。\n- 同时提交 `settings` 与 `is_test: true` 可获得插件测试结果,返回的 settings 不打码。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 写操作还需对象权限:主体账户、管理员、创建者或所属团队成员可操作;未设置团队时,拥有集成中心管理权限的成员可操作,只读集成不可修改。\n- 每次调用都会记录到账户审计日志。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-update", + "metadata": { + "sidebarTitle": "更新集成" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/IntegrationDetail" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_id": 6113996590131, + "team_id": 1467226103121, + "plugin_type": "standard.alert", + "plugin_type_name": "Standard Alert", + "category": "event.alert", + "name": "Prod metrics alerts (primary)", + "description": "Alerts pushed by the production Prometheus stack", + "status": "enabled", + "ref_id": "a_100", + "created_at": 1775116800, + "updated_at": 1775298600, + "last_time": 1775298600, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "editable": true, + "creator_id": 1467226103999, + "updated_by": 1467226103999, + "no_editable": false, + "plugin_id": 9, + "integration_key": "0123456789abcdef0123456789abcdef100", + "test": { + "success": true, + "message": "" + } + } + } + } + } + }, + "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/UpdateIntegrationRequest" + }, + "example": { + "integration_id": 6113996590131, + "name": "Prod metrics alerts (primary)", + "team_id": 1467226103121, + "settings": { + "field_mapping": {}, + "value_mapping": {} + }, + "is_test": true + } + } + } + } + } + }, + "/integration/delete": { + "post": { + "operationId": "integration-api-write-delete", + "summary": "删除集成", + "description": "删除指定的集成。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 若该集成仍被其他对象引用,删除会返回 HTTP 400,`error.code` 为 `ReferenceExist`,`data.refs` 列出引用方。\n- 每次调用都会记录到账户审计日志。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 写操作还需对象权限:主体账户、管理员、创建者或所属团队成员可操作;未设置团队时,拥有集成中心管理权限的成员可操作,只读集成不可修改。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-delete", + "metadata": { + "sidebarTitle": "删除集成" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/enable": { + "post": { + "operationId": "integration-api-write-enable", + "summary": "启用集成", + "description": "重新启用已禁用的集成,恢复接收事件。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 启用会恢复该集成的拉取任务与心跳,并要求当前套餐包含该集成类型。\n- 每次调用都会记录到账户审计日志。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 写操作还需对象权限:主体账户、管理员、创建者或所属团队成员可操作;未设置团队时,拥有集成中心管理权限的成员可操作,只读集成不可修改。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-enable", + "metadata": { + "sidebarTitle": "启用集成" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/disable": { + "post": { + "operationId": "integration-api-write-disable", + "summary": "禁用集成", + "description": "禁用集成,但保留其配置。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 禁用后停止接收事件并暂停定时拉取任务,配置保留,可再次启用。\n- 每次调用都会记录到账户审计日志。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 写操作还需对象权限:主体账户、管理员、创建者或所属团队成员可操作;未设置团队时,拥有集成中心管理权限的成员可操作,只读集成不可修改。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-disable", + "metadata": { + "sidebarTitle": "禁用集成" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyObject" + } + } + } + ] + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } + }, + "/integration/key/rotate": { + "post": { + "operationId": "integration-api-write-rotate-key", + "summary": "轮换集成 Key", + "description": "生成新的集成 Key,并使旧 Key 立即失效。", + "tags": [ + "On-call/集成中心" + ], + "x-mint": { + "content": "## 限制说明\n\n| 项目 | 说明 |\n| ---- | ---- |\n| 速率限制 | 每个账户 **300 次/分钟**;**20 次/秒** |\n| 权限要求 | **集成中心管理**(`on-call`) |\n\n## 使用说明\n\n- 旧 Key 会立即失效;轮换后请将推送端配置更新为新 Key。\n- 新 Key 也可通过 `/integration/list` 和 `/integration/info` 查询。\n- 这些接口仅管理公共(账户级)集成,不管理协作空间专属集成。\n- 写操作还需对象权限:主体账户、管理员、创建者或所属团队成员可操作;未设置团队时,拥有集成中心管理权限的成员可操作,只读集成不可修改。\n- 每次调用都会记录到账户审计日志。", + "href": "/zh/api-reference/on-call/integrations/integration-api-write-rotate-key", + "metadata": { + "sidebarTitle": "轮换集成 Key" + } + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/RotateIntegrationKeyResponse" + } + } + } + ] + }, + "example": { + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "data": { + "integration_key": "0123456789abcdef0123456789abcdef100" + } + } + } + } + }, + "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/IntegrationLifecycleRequest" + }, + "example": { + "integration_id": 6113996590131 + } + } + } + } + } } }, "components": { @@ -31323,189 +32086,562 @@ "incidents_latest_close_seconds": { "type": "integer", "format": "int64", - "minimum": 0, - "description": "最晚关联故障关闭时间的 Unix 秒级时间戳;仍未关闭时为 0。" + "minimum": 0, + "description": "最晚关联故障关闭时间的 Unix 秒级时间戳;仍未关闭时为 0。" + }, + "incidents_total_duration_seconds": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "故障总持续时间,单位秒。" + }, + "responder_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "写入报告的响应人成员 ID。" + } + } + }, + "ResetPostMortemContentRequest": { + "type": "object", + "description": "完整替换草稿状态故障复盘正文的参数。", + "required": [ + "post_mortem_id", + "markdown", + "expected_revision", + "idempotency_key" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "要重置的故障复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + }, + "markdown": { + "type": "string", + "description": "替换后的 Markdown 正文,最大 4 MiB。" + }, + "expected_revision": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0, + "description": "调用方预期的当前正文修订版本。首次写入从未保存过的文档时传 0。" + }, + "idempotency_key": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "用于安全重试这一次相同重置请求的非空键。" + } + } + }, + "ResetPostMortemFollowUpsRequest": { + "type": "object", + "description": "替换复盘后续行动项的参数。", + "required": [ + "post_mortem_id" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + }, + "follow_ups": { + "type": "string", + "description": "自由文本格式的后续行动项。" + } + } + }, + "ResetPostMortemStatusRequest": { + "type": "object", + "description": "更新复盘报告状态的参数。", + "required": [ + "post_mortem_id", + "status" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + }, + "status": { + "type": "string", + "enum": [ + "drafting", + "published" + ], + "description": "目标报告状态:`drafting` 草稿,`published` 已发布。" + } + } + }, + "ResetPostMortemTitleRequest": { + "type": "object", + "description": "更新复盘报告标题的参数。", + "required": [ + "post_mortem_id", + "title" + ], + "properties": { + "post_mortem_id": { + "type": "string", + "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + }, + "title": { + "type": "string", + "description": "新的报告标题。" + } + } + }, + "TryLinkPersonRequest": { + "type": "object", + "description": "尝试自动关联 IM 账号的参数。", + "required": [ + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "IM 集成 ID,可通过 `POST /datasource/im/war-room-enabled/list` 获取。" + } + } + }, + "TryLinkPersonResponse": { + "type": "object", + "description": "本次调用新关联的人员。如果没有成员可关联,响应中的 `new_linked_person_ids` 可能为空数组,或整个 `data` 字段被省略。", + "required": [ + "new_linked_person_ids" + ], + "properties": { + "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。创建新模板时省略;更新已有模板时传入。" + }, + "team_id": { + "type": "integer", + "format": "int64", + "description": "管理团队 ID。创建自定义模板时必填。" + }, + "name": { + "type": "string", + "description": "模板名称。" + }, + "description": { + "type": "string", + "description": "模板描述。" + }, + "content": { + "type": "string", + "description": "BlockNote JSON 模板内容。" + }, + "content_markdown": { + "type": "string", + "description": "模板内容的 Markdown 版本。" + } + } + }, + "DeleteStatusPageComponentRequest": { + "type": "object", + "description": "删除状态页服务组件的请求参数。", + "required": [ + "page_id", + "component_ids" + ], + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "incidents_total_duration_seconds": { + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "要删除的组件 ID 列表,可通过 `GET /status-page/info` 获取。", + "minItems": 1 + } + } + }, + "DeleteStatusPageSectionRequest": { + "type": "object", + "description": "删除状态页区域的请求参数。", + "required": [ + "page_id", + "section_ids" + ], + "properties": { + "page_id": { "type": "integer", "format": "int64", - "minimum": 0, - "description": "故障总持续时间,单位秒。" + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "responder_ids": { + "section_ids": { "type": "array", "items": { - "type": "integer", - "format": "int64" + "type": "string" }, - "description": "写入报告的响应人成员 ID。" + "description": "要删除的区域 ID 列表,可通过 `GET /status-page/info` 获取。", + "minItems": 1 } } }, - "ResetPostMortemContentRequest": { + "DeleteStatusPageTemplateRequest": { "type": "object", - "description": "完整替换草稿状态故障复盘正文的参数。", + "description": "删除状态页模板的请求参数。", "required": [ - "post_mortem_id", - "markdown", - "expected_revision", - "idempotency_key" + "page_id", + "type", + "template_id" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "要重置的故障复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "markdown": { + "type": { "type": "string", - "description": "替换后的 Markdown 正文,最大 4 MiB。" - }, - "expected_revision": { - "type": [ - "integer", - "null" + "enum": [ + "pre_defined", + "message" ], - "format": "int64", - "minimum": 0, - "description": "调用方预期的当前正文修订版本。首次写入从未保存过的文档时传 0。" + "description": "模板分类:`pre_defined` 预定义模板,`message` 消息模板。" }, - "idempotency_key": { + "template_id": { "type": "string", - "minLength": 1, - "maxLength": 128, - "description": "用于安全重试这一次相同重置请求的非空键。" + "description": "要删除的模板 ID,可通过 `GET /status-page/template/list` 获取。" } } }, - "ResetPostMortemFollowUpsRequest": { + "UpsertStatusPageComponentRequest": { "type": "object", - "description": "替换复盘后续行动项的参数。", + "description": "创建或更新状态页服务组件的请求参数。", "required": [ - "post_mortem_id" + "page_id", + "components" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "follow_ups": { - "type": "string", - "description": "自由文本格式的后续行动项。" + "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 时,在汇总接口中完全隐藏该组件。" + }, + "available_since_seconds": { + "type": "integer", + "format": "int64", + "description": "组件可用起始时间(Unix 秒)。创建时缺省取当前时间;更新时覆盖原值。" + } + } + }, + "minItems": 1 } } }, - "ResetPostMortemStatusRequest": { + "UpsertStatusPageComponentResponse": { "type": "object", - "description": "更新复盘报告状态的参数。", + "description": "创建或更新状态页组件的结果。", "required": [ - "post_mortem_id", - "status" + "component_ids" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" - }, - "status": { - "type": "string", - "enum": [ - "drafting", - "published" - ], - "description": "目标报告状态:`drafting` 草稿,`published` 已发布。" + "component_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "创建或更新的组件 ID 列表,顺序与请求一致。" } } }, - "ResetPostMortemTitleRequest": { + "UpsertStatusPageSectionRequest": { "type": "object", - "description": "更新复盘报告标题的参数。", + "description": "创建或更新状态页区域的请求参数。", "required": [ - "post_mortem_id", - "title" + "page_id", + "sections" ], "properties": { - "post_mortem_id": { - "type": "string", - "description": "复盘 ID,可通过 `POST /incident/post-mortem/list` 获取。" + "page_id": { + "type": "integer", + "format": "int64", + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "title": { - "type": "string", - "description": "新的报告标题。" + "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 时,在汇总接口中完全隐藏该区域。" + } + } + }, + "minItems": 1 } } }, - "TryLinkPersonRequest": { + "UpsertStatusPageSectionResponse": { "type": "object", - "description": "尝试自动关联 IM 账号的参数。", + "description": "创建或更新状态页区域的结果。", "required": [ - "integration_id" + "section_ids" ], "properties": { - "integration_id": { + "section_ids": { + "type": "array", + "items": { + "type": "string" + }, + "description": "创建或更新的区域 ID 列表,顺序与请求一致。" + } + } + }, + "UpsertStatusPageTemplateRequest": { + "type": "object", + "description": "创建或更新状态页模板的请求参数。", + "required": [ + "page_id", + "type", + "template" + ], + "properties": { + "page_id": { "type": "integer", "format": "int64", - "description": "IM 集成 ID,可通过 `POST /datasource/im/war-room-enabled/list` 获取。" + "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + }, + "type": { + "type": "string", + "enum": [ + "pre_defined", + "message" + ], + "description": "模板分类。`pre_defined` 为预定义事件模板;`message` 为通知消息模板。" + }, + "template": { + "oneOf": [ + { + "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" + }, + { + "$ref": "#/components/schemas/StatusPageMessageTemplate" + } + ], + "description": "模板内容。结构取决于 `type`:`pre_defined` 为预定义事件模板,`message` 为消息模板。" } } }, - "TryLinkPersonResponse": { + "UpsertStatusPageTemplateResponse": { "type": "object", - "description": "本次调用新关联的人员。如果没有成员可关联,响应中的 `new_linked_person_ids` 可能为空数组,或整个 `data` 字段被省略。", + "description": "创建或更新状态页模板的结果。", "required": [ - "new_linked_person_ids" + "template_id" ], "properties": { - "new_linked_person_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "本次调用中新关联成功的人员 ID。" + "template_id": { + "type": "string", + "description": "创建或更新的模板 ID。" } } }, - "UpsertPostMortemTemplateRequest": { + "CreateStatusPageRequest": { "type": "object", - "description": "创建或更新故障复盘模板的参数。", - "required": [ - "name", - "content" - ], "properties": { - "template_id": { + "name": { "type": "string", - "description": "模板 ID。创建新模板时省略;更新已有模板时传入。" + "description": "状态页展示名称。", + "maxLength": 255 }, - "team_id": { - "type": "integer", - "format": "int64", - "description": "管理团队 ID。创建自定义模板时必填。" + "url_name": { + "type": "string", + "description": "URL 安全的状态页路径,在账户和状态页类型内唯一。", + "maxLength": 255 }, - "name": { + "type": { "type": "string", - "description": "模板名称。" + "description": "状态页可见性类型:`public` 任何人可访问,`internal` 仅本账号登录成员可见。", + "enum": [ + "public", + "internal" + ] }, - "description": { + "custom_domain": { "type": "string", - "description": "模板描述。" + "description": "公开状态页使用的自定义域名。", + "maxLength": 255 }, - "content": { + "page_title": { "type": "string", - "description": "BlockNote JSON 模板内容。" + "description": "状态页浏览器标题。" }, - "content_markdown": { + "page_header": { "type": "string", - "description": "模板内容的 Markdown 版本。" + "description": "状态页页头内容。" + }, + "page_footer": { + "type": "string", + "description": "状态页页脚内容。" + }, + "date_view": { + "type": "string", + "description": "事件日期展示方式:`calendar` 日历视图,`list` 列表视图。", + "enum": [ + "calendar", + "list" + ] + }, + "display_uptime_mode": { + "type": "string", + "description": "可用率展示方式:`chart_and_percentage` 图表加百分比,`chart` 仅图表,`none` 不展示。", + "enum": [ + "chart_and_percentage", + "chart", + "none" + ] + }, + "custom_links": { + "type": "array", + "description": "状态页展示的自定义导航链接。", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "contact_info": { + "type": "string", + "description": "联系信息,例如 mailto 或网站 URL。" + }, + "subscription": { + "$ref": "#/components/schemas/StatusPageSubscriptionItem", + "description": "订阅渠道开关。" } - } + }, + "required": [ + "name", + "url_name", + "type", + "date_view", + "display_uptime_mode" + ] }, - "DeleteStatusPageComponentRequest": { + "CreateStatusPageResponse": { "type": "object", - "description": "删除状态页服务组件的请求参数。", + "properties": { + "page_id": { + "type": "integer", + "format": "int64", + "description": "创建的状态页 ID。" + }, + "page_name": { + "type": "string", + "description": "创建的状态页名称。" + }, + "page_url_name": { + "type": "string", + "description": "最终分配给状态页的 URL 安全路径。" + } + }, "required": [ "page_id", - "component_ids" + "page_name", + "page_url_name" + ] + }, + "UpdateStatusPageRequest": { + "type": "object", + "description": "更新已有状态页所需的参数。除 `page_id` 外均为可选字段;省略某字段或传 null 表示保持其原值。", + "required": [ + "page_id" ], "properties": { "page_id": { @@ -31513,1023 +32649,1294 @@ "format": "int64", "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" }, - "component_ids": { - "type": "array", - "items": { - "type": "string" - }, - "description": "要删除的组件 ID 列表,可通过 `GET /status-page/info` 获取。", - "minItems": 1 + "name": { + "type": [ + "string", + "null" + ], + "description": "状态页展示名称。省略或传 null 表示保持原值。", + "maxLength": 255 + }, + "url_name": { + "type": [ + "string", + "null" + ], + "description": "URL 安全的状态页路径,在账户和状态页类型内唯一。省略或传 null 表示保持原值。", + "maxLength": 255 + }, + "custom_domain": { + "type": [ + "string", + "null" + ], + "description": "公开状态页使用的自定义域名。省略或传 null 表示保持原值。", + "maxLength": 255 + }, + "page_title": { + "type": [ + "string", + "null" + ], + "description": "状态页浏览器标题。省略或传 null 表示保持原值。" + }, + "logo": { + "type": [ + "string", + "null" + ], + "description": "状态页 Logo 图片。省略或传 null 表示保持原值。" + }, + "dark_logo": { + "type": [ + "string", + "null" + ], + "description": "状态页暗色模式 Logo 图片。省略或传 null 表示保持原值。" + }, + "logo_url": { + "type": [ + "string", + "null" + ], + "description": "点击 Logo 时跳转的 URL。省略或传 null 表示保持原值。", + "maxLength": 255 + }, + "favicon": { + "type": [ + "string", + "null" + ], + "description": "状态页的网站图标。省略或传 null 表示保持原值。" + }, + "page_header": { + "type": [ + "string", + "null" + ], + "description": "状态页页头内容。省略或传 null 表示保持原值。" + }, + "page_footer": { + "type": [ + "string", + "null" + ], + "description": "状态页页脚内容。省略或传 null 表示保持原值。" + }, + "date_view": { + "type": [ + "string", + "null" + ], + "description": "事件日期展示方式。省略或传 null 表示保持原值。`calendar` 为日历视图;`list` 为列表视图。", + "enum": [ + "calendar", + "list" + ] + }, + "display_uptime_mode": { + "type": [ + "string", + "null" + ], + "description": "可用率展示方式。省略或传 null 表示保持原值。`chart_and_percentage` 同时展示图表与百分比;`chart` 仅展示图表;`none` 不展示。", + "enum": [ + "chart_and_percentage", + "chart", + "none" + ] + }, + "custom_links": { + "type": "array", + "description": "状态页展示的自定义导航链接。省略或传空数组表示保持当前链接。", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "contact_info": { + "type": [ + "string", + "null" + ], + "description": "联系信息,例如 mailto 或网站 URL。省略或传 null 表示保持原值。" + }, + "subscription": { + "$ref": "#/components/schemas/StatusPageSubscriptionItem", + "description": "订阅渠道开关。省略或传 null 表示保持原值。" + }, + "template_preference": { + "type": [ + "string", + "null" + ], + "description": "偏好的事件模板类型:`pre_defined` 或 `message`。省略或传 null 表示保持原值。" } } }, - "DeleteStatusPageSectionRequest": { + "DeleteStatusPageRequest": { "type": "object", - "description": "删除状态页区域的请求参数。", + "description": "删除状态页所需的参数。", "required": [ - "page_id", - "section_ids" + "page_id" ], "properties": { "page_id": { "type": "integer", "format": "int64", "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" - }, - "section_ids": { - "type": "array", - "items": { - "type": "string" - }, - "description": "要删除的区域 ID 列表,可通过 `GET /status-page/info` 获取。", - "minItems": 1 } } }, - "DeleteStatusPageTemplateRequest": { + "CustomFieldValues": { "type": "object", - "description": "删除状态页模板的请求参数。", + "description": "以账户自定义字段名为键的字段值。允许的字段、类型和必填规则由当前生效表单决定。", + "additionalProperties": true + }, + "IncidentActionImage": { + "type": "object", + "description": "附加到认领或解决故障时间线记录的图片。", "required": [ - "page_id", - "type", - "template_id" + "src" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "src": { + "type": "string", + "description": "图片来源。支持 `img_` 上传令牌、`http(s)` URL,或以 `/` 开头的对象存储键。" }, - "type": { + "href": { "type": "string", - "enum": [ - "pre_defined", - "message" - ], - "description": "模板分类:`pre_defined` 预定义模板,`message` 消息模板。" + "description": "图片指向的可选链接。" }, - "template_id": { + "alt": { "type": "string", - "description": "要删除的模板 ID,可通过 `GET /status-page/template/list` 获取。" + "description": "图片替代文本。" } } }, - "UpsertStatusPageComponentRequest": { + "IncidentCardHiddenFields": { "type": "object", - "description": "创建或更新状态页服务组件的请求参数。", + "description": "按 IM 应用类型隐藏的故障卡片字段。只接受受支持的 IM 应用类型和字段名。", + "propertyNames": { + "type": "string", + "enum": [ + "feishu_app", + "dingtalk_app", + "slack_app", + "teams_app", + "wecom_app" + ] + }, + "additionalProperties": { + "type": "array", + "description": "要为该 IM 应用隐藏的故障卡片字段名。", + "items": { + "type": "string", + "enum": [ + "channel", + "snoozed_before", + "severity", + "responders", + "aggregate_alert_count", + "detail", + "ai_analysis" + ] + } + } + }, + "PreviewIncidentCardFixedField": { + "type": "object", + "description": "已应用隐藏规则后,为受支持 IM 预览返回的固定故障卡片字段。", "required": [ - "page_id", - "components" + "field", + "value" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "field": { + "type": "string", + "enum": [ + "channel", + "snoozed_before", + "severity", + "responders", + "aggregate_alert_count" + ], + "description": "故障卡片字段名。\n\n| 值 | 含义 |\n|---|---|\n| `channel` | 触发该故障的告警来源通道名称;仅当通道名非空时返回。 |\n| `snoozed_before` | 故障暂缓(Snooze)截止时间,格式为 `YYYY-MM-DD HH:MM:SS`;仅当故障处于暂缓状态时返回。 |\n| `severity` | 故障等级标签;仅当等级非空时返回。 |\n| `responders` | 当前处理人姓名列表,以空格分隔;仅当存在处理人时返回。 |\n| `aggregate_alert_count` | 聚合到该故障的告警数量;仅当数量大于 1 时返回。 |" }, - "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 时,在汇总接口中完全隐藏该组件。" - }, - "available_since_seconds": { - "type": "integer", - "format": "int64", - "description": "组件可用起始时间(Unix 秒)。创建时缺省取当前时间;更新时覆盖原值。" - } - } - }, - "minItems": 1 + "value": { + "type": "string", + "description": "固定字段的渲染显示值。" } } }, - "UpsertStatusPageComponentResponse": { + "FieldDeleteReference": { "type": "object", - "description": "创建或更新状态页组件的结果。", + "description": "仍引用该字段的自定义表单。", "required": [ - "component_ids" + "kind", + "name", + "href" ], "properties": { - "component_ids": { - "type": "array", - "items": { - "type": "string" - }, - "description": "创建或更新的组件 ID 列表,顺序与请求一致。" + "kind": { + "type": "string", + "const": "custom_form", + "description": "被引用资源类型。在此响应中始终为 `custom_form`。" + }, + "name": { + "type": "string", + "description": "引用该字段的自定义表单类型名称(如 `解决故障` 表示解决故障表单)。" + }, + "href": { + "type": "string", + "description": "引用该字段的自定义表单控制台 URL。" } } }, - "UpsertStatusPageSectionRequest": { + "FieldDeleteReferenceError": { "type": "object", - "description": "创建或更新状态页区域的请求参数。", + "description": "自定义表单仍引用该字段时返回的错误响应。", "required": [ - "page_id", - "sections" + "request_id", + "error", + "data" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "request_id": { + "type": "string", + "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", + "description": "本次请求的追踪 ID,与 `Flashcat-Request-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 时,隐藏该区域下所有组件的可用率数据。" + "error": { + "$ref": "#/components/schemas/DutyError" + }, + "data": { + "type": "object", + "required": [ + "refs" + ], + "properties": { + "refs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FieldDeleteReference" }, - "hide_all": { - "type": "boolean", - "description": "为 true 时,在汇总接口中完全隐藏该区域。" - } + "description": "仍引用该字段的自定义表单列表,每项含 `kind`/`name`/`href`;需先解除全部引用才能删除该字段。" } }, - "minItems": 1 + "description": "附加错误数据;本错误下固定包含 `refs` 字段。" } } }, - "UpsertStatusPageSectionResponse": { + "ServiceDeskPlusRequestListRequest": { "type": "object", - "description": "创建或更新状态页区域的结果。", - "required": [ - "section_ids" - ], + "description": "查询 ServiceDeskPlus 请求同步记录的过滤条件。按故障 ID 查询时可不传时间窗口;否则必须传入不超过 30 天的 Unix 秒时间窗口。", "properties": { - "section_ids": { + "start_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口起点(Unix 秒)。按 `incident_id` 查询时可省略。" + }, + "end_time": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "时间窗口终点(Unix 秒),必须大于等于 `start_time`。按 `incident_id` 查询时可省略。" + }, + "status": { + "type": "string", + "enum": [ + "success", + "failed" + ], + "description": "按同步状态过滤:`success` 成功,`failed` 失败。" + }, + "channel_ids": { "type": "array", "items": { - "type": "string" + "type": "integer", + "format": "int64" }, - "description": "创建或更新的区域 ID 列表,顺序与请求一致。" + "description": "协作空间 ID 列表。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "maxLength": 64, + "description": "Flashduty 故障 ID。提供后可不传时间窗口。" + }, + "request_id": { + "type": "string", + "maxLength": 64, + "description": "ServiceDeskPlus 请求 ID。" + }, + "asc": { + "type": "boolean", + "description": "为 `true` 时按内部记录 ID 升序返回;否则降序。" + }, + "p": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "页码,从 1 开始。使用 `search_after_ctx` 时忽略。" + }, + "limit": { + "type": "integer", + "format": "int64", + "minimum": 0, + "maximum": 100, + "default": 20, + "description": "分页大小,默认 20,最大 100。" + }, + "search_after_ctx": { + "type": "string", + "description": "分页游标:首页留空,翻页时传上一页响应中的 `search_after_ctx`。" } } }, - "UpsertStatusPageTemplateRequest": { + "ServiceDeskPlusRequestMappingItem": { "type": "object", - "description": "创建或更新状态页模板的请求参数。", + "description": "ServiceDeskPlus 请求与 Flashduty 故障之间的一条同步映射记录。", "required": [ - "page_id", - "type", - "template" + "created_at", + "status", + "request_id", + "request_link", + "integration_id", + "incident_id", + "incident_title", + "channel_id", + "channel_name" ], "properties": { - "page_id": { + "created_at": { "type": "integer", "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "description": "映射记录创建时间(Unix 秒)。" }, - "type": { + "status": { "type": "string", "enum": [ - "pre_defined", - "message" + "success", + "failed" ], - "description": "模板分类。`pre_defined` 为预定义事件模板;`message` 为通知消息模板。" + "description": "同步状态。" }, - "template": { - "oneOf": [ - { - "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" - }, - { - "$ref": "#/components/schemas/StatusPageMessageTemplate" - } - ], - "description": "模板内容。结构取决于 `type`:`pre_defined` 为预定义事件模板,`message` 为消息模板。" + "request_id": { + "type": "string", + "description": "ServiceDeskPlus 请求 ID。" + }, + "request_link": { + "type": "string", + "description": "ServiceDeskPlus 请求详情链接。" + }, + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ServiceDeskPlus 集成 ID。" + }, + "incident_id": { + "type": "string", + "description": "关联的 Flashduty 故障 ID。" + }, + "incident_title": { + "type": "string", + "description": "关联故障标题。" + }, + "channel_id": { + "type": "integer", + "format": "int64", + "description": "故障所属协作空间 ID。" + }, + "channel_name": { + "type": "string", + "description": "故障所属协作空间名称。" + }, + "error_message": { + "type": "string", + "description": "同步失败时的错误信息。成功记录通常不返回该字段。" } } }, - "UpsertStatusPageTemplateResponse": { + "ServiceDeskPlusRequestListResponse": { "type": "object", - "description": "创建或更新状态页模板的结果。", + "description": "分页的 ServiceDeskPlus 请求同步记录列表。", "required": [ - "template_id" + "items", + "total", + "has_next_page" ], "properties": { - "template_id": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" + }, + "description": "当前页同步记录。" + }, + "total": { + "type": "integer", + "format": "int64", + "description": "匹配记录总数,最多统计 1000 条。" + }, + "has_next_page": { + "type": "boolean", + "description": "是否还有更多页。" + }, + "search_after_ctx": { "type": "string", - "description": "创建或更新的模板 ID。" + "description": "下一页翻页游标。无更多数据时为空。" } } }, - "CreateStatusPageRequest": { + "IncidentCommentTypeItem": { "type": "object", + "description": "账户级评论类型,可附加到故障评论。", "properties": { - "name": { - "type": "string", - "description": "状态页展示名称。", - "maxLength": 255 - }, - "url_name": { - "type": "string", - "description": "URL 安全的状态页路径,在账户和状态页类型内唯一。", - "maxLength": 255 - }, - "type": { - "type": "string", - "description": "状态页可见性类型:`public` 任何人可访问,`internal` 仅本账号登录成员可见。", - "enum": [ - "public", - "internal" - ] - }, - "custom_domain": { + "comment_type_id": { "type": "string", - "description": "公开状态页使用的自定义域名。", - "maxLength": 255 + "pattern": "^[0-9a-fA-F]{24}$", + "description": "评论类型 ID(24 位十六进制 ObjectID)。" }, - "page_title": { - "type": "string", - "description": "状态页浏览器标题。" + "account_id": { + "type": "integer", + "format": "int64", + "description": "评论类型所属的账户 ID。" }, - "page_header": { + "name": { "type": "string", - "description": "状态页页头内容。" + "maxLength": 40, + "description": "评论类型展示名称。账户内唯一(不区分大小写,忽略首尾空白)。" }, - "page_footer": { + "color": { "type": "string", - "description": "状态页页脚内容。" + "pattern": "^#[0-9A-F]{6}$", + "description": "标签颜色,#RRGGBB 格式十六进制值(存储为大写)。" }, - "date_view": { - "type": "string", - "description": "事件日期展示方式:`calendar` 日历视图,`list` 列表视图。", - "enum": [ - "calendar", - "list" - ] + "position": { + "type": "integer", + "format": "int64", + "description": "评论类型的展示位置,从 1 开始。" }, - "display_uptime_mode": { - "type": "string", - "description": "可用率展示方式:`chart_and_percentage` 图表加百分比,`chart` 仅图表,`none` 不展示。", - "enum": [ - "chart_and_percentage", - "chart", - "none" - ] + "creator_id": { + "type": "integer", + "format": "int64", + "description": "创建该评论类型的用户 ID。" }, - "custom_links": { - "type": "array", - "description": "状态页展示的自定义导航链接。", - "items": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } + "updated_by": { + "type": "integer", + "format": "int64", + "description": "最后更新该评论类型的用户 ID。" }, - "contact_info": { - "type": "string", - "description": "联系信息,例如 mailto 或网站 URL。" + "created_at": { + "type": "integer", + "format": "int64", + "description": "创建时间,Unix 秒级时间戳。" }, - "subscription": { - "$ref": "#/components/schemas/StatusPageSubscriptionItem", - "description": "订阅渠道开关。" + "updated_at": { + "type": "integer", + "format": "int64", + "description": "最后更新时间,Unix 秒级时间戳。" } }, "required": [ + "comment_type_id", + "account_id", "name", - "url_name", - "type", - "date_view", - "display_uptime_mode" + "color", + "position", + "creator_id", + "updated_by", + "created_at", + "updated_at" ] }, - "CreateStatusPageResponse": { + "ListIncidentCommentTypesRequest": { + "type": "object", + "description": "无参数。该接口始终返回调用账户的全部评论类型。", + "properties": {} + }, + "ListIncidentCommentTypesResponse": { "type": "object", + "description": "账户评论类型的完整列表,按展示位置排序。", "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "创建的状态页 ID。" - }, - "page_name": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IncidentCommentTypeItem" + }, + "description": "账户的全部评论类型,按展示位置排序。" + } + } + }, + "CreateIncidentCommentTypeRequest": { + "type": "object", + "description": "创建评论类型的参数。每个账户最多 10 个评论类型。", + "required": [ + "name", + "color" + ], + "properties": { + "name": { "type": "string", - "description": "创建的状态页名称。" + "maxLength": 40, + "description": "展示名称。存储前去除首尾空白;账户内唯一(不区分大小写)。最多 40 个字符。" }, - "page_url_name": { + "color": { "type": "string", - "description": "最终分配给状态页的 URL 安全路径。" + "pattern": "^#[0-9A-Fa-f]{6}$", + "description": "标签颜色,#RRGGBB 格式十六进制值,统一转为大写。" + } + } + }, + "CreateIncidentCommentTypeResponse": { + "type": "object", + "description": "创建评论类型的结果。", + "properties": { + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "新建评论类型的 ID(24 位十六进制 ObjectID)。" + }, + "item": { + "$ref": "#/components/schemas/IncidentCommentTypeItem" } }, "required": [ - "page_id", - "page_name", - "page_url_name" + "comment_type_id", + "item" ] }, - "UpdateStatusPageRequest": { + "UpdateIncidentCommentTypeRequest": { "type": "object", - "description": "更新已有状态页所需的参数。除 `page_id` 外均为可选字段;省略某字段或传 null 表示保持其原值。", + "description": "更新评论类型的参数。部分更新:`name` 和 `color` 至少提供一个。", "required": [ - "page_id" + "comment_type_id" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "要更新的评论类型 ID(24 位十六进制 ObjectID)。" }, "name": { - "type": [ - "string", - "null" - ], - "description": "状态页展示名称。省略或传 null 表示保持原值。", - "maxLength": 255 - }, - "url_name": { - "type": [ - "string", - "null" - ], - "description": "URL 安全的状态页路径,在账户和状态页类型内唯一。省略或传 null 表示保持原值。", - "maxLength": 255 - }, - "custom_domain": { - "type": [ - "string", - "null" - ], - "description": "公开状态页使用的自定义域名。省略或传 null 表示保持原值。", - "maxLength": 255 - }, - "page_title": { - "type": [ - "string", - "null" - ], - "description": "状态页浏览器标题。省略或传 null 表示保持原值。" - }, - "logo": { - "type": [ - "string", - "null" - ], - "description": "状态页 Logo 图片。省略或传 null 表示保持原值。" - }, - "dark_logo": { - "type": [ - "string", - "null" - ], - "description": "状态页暗色模式 Logo 图片。省略或传 null 表示保持原值。" - }, - "logo_url": { - "type": [ - "string", - "null" - ], - "description": "点击 Logo 时跳转的 URL。省略或传 null 表示保持原值。", - "maxLength": 255 - }, - "favicon": { - "type": [ - "string", - "null" - ], - "description": "状态页的网站图标。省略或传 null 表示保持原值。" - }, - "page_header": { - "type": [ - "string", - "null" - ], - "description": "状态页页头内容。省略或传 null 表示保持原值。" - }, - "page_footer": { - "type": [ - "string", - "null" - ], - "description": "状态页页脚内容。省略或传 null 表示保持原值。" - }, - "date_view": { - "type": [ - "string", - "null" - ], - "description": "事件日期展示方式。省略或传 null 表示保持原值。`calendar` 为日历视图;`list` 为列表视图。", - "enum": [ - "calendar", - "list" - ] - }, - "display_uptime_mode": { - "type": [ - "string", - "null" - ], - "description": "可用率展示方式。省略或传 null 表示保持原值。`chart_and_percentage` 同时展示图表与百分比;`chart` 仅展示图表;`none` 不展示。", - "enum": [ - "chart_and_percentage", - "chart", - "none" - ] - }, - "custom_links": { - "type": "array", - "description": "状态页展示的自定义导航链接。省略或传空数组表示保持当前链接。", - "items": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - }, - "contact_info": { - "type": [ - "string", - "null" - ], - "description": "联系信息,例如 mailto 或网站 URL。省略或传 null 表示保持原值。" - }, - "subscription": { - "$ref": "#/components/schemas/StatusPageSubscriptionItem", - "description": "订阅渠道开关。省略或传 null 表示保持原值。" + "type": "string", + "maxLength": 40, + "description": "新的展示名称。存储前去除首尾空白;账户内唯一(不区分大小写)。最多 40 个字符。" }, - "template_preference": { - "type": [ - "string", - "null" - ], - "description": "偏好的事件模板类型:`pre_defined` 或 `message`。省略或传 null 表示保持原值。" + "color": { + "type": "string", + "pattern": "^#[0-9A-Fa-f]{6}$", + "description": "新的标签颜色,#RRGGBB 格式十六进制值,统一转为大写。" } } }, - "DeleteStatusPageRequest": { + "DeleteIncidentCommentTypeRequest": { "type": "object", - "description": "删除状态页所需的参数。", + "description": "删除评论类型的参数。", "required": [ - "page_id" + "comment_type_id" ], "properties": { - "page_id": { - "type": "integer", - "format": "int64", - "description": "状态页 ID,可通过 `GET /status-page/list` 获取。" + "comment_type_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "要删除的评论类型 ID(24 位十六进制 ObjectID)。" } } }, - "CustomFieldValues": { + "ReorderIncidentCommentTypesRequest": { "type": "object", - "description": "以账户自定义字段名为键的字段值。允许的字段、类型和必填规则由当前生效表单决定。", - "additionalProperties": true + "description": "调整评论类型顺序的参数。", + "required": [ + "comment_type_ids" + ], + "properties": { + "comment_type_ids": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$" + }, + "minItems": 1, + "description": "账户全部评论类型的 ID,按期望顺序排列(24 位十六进制 ObjectID)。" + } + } }, - "IncidentActionImage": { + "WorkItemItem": { "type": "object", - "description": "附加到认领或解决故障时间线记录的图片。", + "description": "结构化的故障跟进事项(行动项或复盘后续行动)及其负责人。", "required": [ - "src" + "work_item_id", + "item_type", + "incident_id", + "title", + "status", + "source_kind", + "version", + "assignee_ids", + "created_by", + "updated_by", + "created_at_seconds", + "updated_at_seconds" ], "properties": { - "src": { + "work_item_id": { "type": "string", - "description": "图片来源。支持 `img_` 上传令牌、`http(s)` URL,或以 `/` 开头的对象存储键。" + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" }, - "href": { + "item_type": { "type": "string", - "description": "图片指向的可选链接。" + "enum": [ + "action", + "follow_up" + ], + "description": "`action` 表示锚定在活动故障上的行动项;`follow_up` 表示复盘后续行动。" }, - "alt": { + "incident_id": { "type": "string", - "description": "图片替代文本。" - } - } - }, - "IncidentCardHiddenFields": { - "type": "object", - "description": "按 IM 应用类型隐藏的故障卡片字段。只接受受支持的 IM 应用类型和字段名。", - "propertyNames": { - "type": "string", - "enum": [ - "feishu_app", - "dingtalk_app", - "slack_app", - "teams_app", - "wecom_app" - ] - }, - "additionalProperties": { - "type": "array", - "description": "要为该 IM 应用隐藏的故障卡片字段名。", - "items": { + "pattern": "^[0-9a-fA-F]{24}$", + "description": "事项锚定的故障 ID(MongoDB ObjectID)。" + }, + "post_mortem_id": { + "type": "string", + "description": "故障复盘 ID(32 位十六进制字符串)。后续行动绑定复盘后返回。" + }, + "title": { + "type": "string", + "maxLength": 512, + "description": "事项标题(最长 512 字符)。" + }, + "description": { + "type": "string", + "maxLength": 65535, + "description": "可选的详细描述(最长 65,535 字符)。" + }, + "status": { + "type": "string", + "maxLength": 64, + "description": "客户端自定义状态(最长 64 字符),没有固定状态机。" + }, + "priority": { + "type": "string", + "maxLength": 64, + "description": "可选的客户端自定义优先级(最长 64 字符)。" + }, + "source_kind": { "type": "string", "enum": [ - "channel", - "snoozed_before", - "severity", - "responders", - "aggregate_alert_count", - "detail", - "ai_analysis" - ] + "native", + "legacy_follow_up" + ], + "description": "`native` 表示通过本 API 创建的事项;`legacy_follow_up` 表示从旧版复盘后续行动迁移而来的事项。" + }, + "legacy_source_id": { + "type": "string", + "description": "该事项迁移自旧版后续行动的原始标识。仅当 `source_kind` 为 `legacy_follow_up` 时返回。" + }, + "version": { + "type": "integer", + "format": "int64", + "description": "乐观锁版本号,每次变更递增。" + }, + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "当前负责人的成员 ID 列表。不会为 null;空数组表示未指派。" + }, + "created_by": { + "type": "integer", + "format": "int64", + "description": "创建者成员 ID。" + }, + "updated_by": { + "type": "integer", + "format": "int64", + "description": "最后更新人成员 ID。" + }, + "converted_by": { + "type": "integer", + "format": "int64", + "description": "将行动项转化为后续行动的操作人成员 ID。仅转化后返回。" + }, + "converted_at_seconds": { + "type": "integer", + "format": "int64", + "description": "转化时间,Unix 秒级时间戳。仅转化后返回。" + }, + "created_at_seconds": { + "type": "integer", + "format": "int64", + "description": "创建时间,Unix 秒级时间戳。" + }, + "updated_at_seconds": { + "type": "integer", + "format": "int64", + "description": "最后更新时间,Unix 秒级时间戳。" } } }, - "PreviewIncidentCardFixedField": { + "WorkItemCreateResult": { "type": "object", - "description": "已应用隐藏规则后,为受支持 IM 预览返回的固定故障卡片字段。", + "description": "创建跟进事项的结果。", "required": [ - "field", - "value" + "item" ], "properties": { - "field": { - "type": "string", - "enum": [ - "channel", - "snoozed_before", - "severity", - "responders", - "aggregate_alert_count" - ], - "description": "故障卡片字段名。\n\n| 值 | 含义 |\n|---|---|\n| `channel` | 触发该故障的告警来源通道名称;仅当通道名非空时返回。 |\n| `snoozed_before` | 故障暂缓(Snooze)截止时间,格式为 `YYYY-MM-DD HH:MM:SS`;仅当故障处于暂缓状态时返回。 |\n| `severity` | 故障等级标签;仅当等级非空时返回。 |\n| `responders` | 当前处理人姓名列表,以空格分隔;仅当存在处理人时返回。 |\n| `aggregate_alert_count` | 聚合到该故障的告警数量;仅当数量大于 1 时返回。 |" + "item": { + "$ref": "#/components/schemas/WorkItemItem" }, - "value": { - "type": "string", - "description": "固定字段的渲染显示值。" + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "新添加(并已通知)的负责人成员 ID。" + }, + "idempotent_replay": { + "type": "boolean", + "description": "为 true 表示本次调用以相同幂等键重放了之前的请求,未创建新事项。" } } }, - "FieldDeleteReference": { + "WorkItemMutationResult": { "type": "object", - "description": "仍引用该字段的自定义表单。", - "required": [ - "kind", - "name", - "href" - ], + "description": "变更跟进事项的结果。", "properties": { - "kind": { - "type": "string", - "const": "custom_form", - "description": "被引用资源类型。在此响应中始终为 `custom_form`。" + "item": { + "$ref": "#/components/schemas/WorkItemItem" }, - "name": { - "type": "string", - "description": "引用该字段的自定义表单类型名称(如 `解决故障` 表示解决故障表单)。" + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "新添加(并已通知)的负责人成员 ID。" }, - "href": { - "type": "string", - "description": "引用该字段的自定义表单控制台 URL。" + "removed_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "被移除(不通知)的负责人成员 ID。" + }, + "idempotent_replay": { + "type": "boolean", + "description": "为 true 表示本次调用以相同幂等键重放了之前的请求。" } } }, - "FieldDeleteReferenceError": { + "WorkItemListResult": { "type": "object", - "description": "自定义表单仍引用该字段时返回的错误响应。", + "description": "游标分页的跟进事项列表。", "required": [ - "request_id", - "error", - "data" + "items", + "has_more" ], "properties": { - "request_id": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WorkItemItem" + }, + "description": "当前页的跟进事项。" + }, + "next_cursor": { "type": "string", - "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4", - "description": "本次请求的追踪 ID,与 `Flashcat-Request-Id` 响应头一致。" + "description": "下一页游标,作为 `cursor` 传入;没有更多结果时不返回。" }, - "error": { - "$ref": "#/components/schemas/DutyError" + "has_more": { + "type": "boolean", + "description": "为 true 表示还有更多结果。" }, - "data": { - "type": "object", - "required": [ - "refs" - ], - "properties": { - "refs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FieldDeleteReference" - }, - "description": "仍引用该字段的自定义表单列表,每项含 `kind`/`name`/`href`;需先解除全部引用才能删除该字段。" - } - }, - "description": "附加错误数据;本错误下固定包含 `refs` 字段。" + "idempotent_replay": { + "type": "boolean", + "description": "为 true 表示本次调用以相同幂等键重放了之前的请求。" } } }, - "ServiceDeskPlusRequestListRequest": { + "ListWorkItemRequest": { "type": "object", - "description": "查询 ServiceDeskPlus 请求同步记录的过滤条件。按故障 ID 查询时可不传时间窗口;否则必须传入不超过 30 天的 Unix 秒时间窗口。", + "description": "查询跟进事项的过滤条件。`incident_id`、`post_mortem_id`、`assignee_id` 至少提供一个。", "properties": { - "start_time": { + "incident_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "故障 ID(MongoDB ObjectID)。同时返回锚定在该故障复盘上的后续行动。" + }, + "post_mortem_id": { + "type": "string", + "description": "故障复盘 ID(32 位十六进制字符串)。返回绑定到该复盘的后续行动。" + }, + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "按事项类型过滤:`action` 行动项,`follow_up` 复盘跟进项。" + }, + "assignee_id": { "type": "integer", "format": "int64", - "minimum": 0, - "description": "时间窗口起点(Unix 秒)。按 `incident_id` 查询时可省略。" + "description": "按负责人成员 ID 过滤结果。仅按负责人查询时,须为本人或账户管理员。" }, - "end_time": { + "cursor": { + "type": "string", + "description": "分页游标,取自上一次响应的 `next_cursor`。" + }, + "limit": { "type": "integer", "format": "int64", "minimum": 0, - "description": "时间窗口终点(Unix 秒),必须大于等于 `start_time`。按 `incident_id` 查询时可省略。" - }, - "status": { + "maximum": 200, + "default": 50, + "description": "每页条数,最多 200,默认 50。" + } + } + }, + "CreateWorkItemRequest": { + "type": "object", + "description": "创建故障跟进事项的参数。", + "required": [ + "item_type", + "title", + "incident_id", + "idempotency_key" + ], + "properties": { + "item_type": { "type": "string", "enum": [ - "success", - "failed" + "action", + "follow_up" ], - "description": "按同步状态过滤:`success` 成功,`failed` 失败。" + "description": "`action` 锚定活动故障,不得设置 `post_mortem_id`;`follow_up` 必须设置 `post_mortem_id`。" }, - "channel_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "协作空间 ID 列表。" + "title": { + "type": "string", + "maxLength": 512, + "description": "事项标题(最长 512 字符)。" }, - "integration_id": { - "type": "integer", - "format": "int64", - "minimum": 0, - "description": "ServiceDeskPlus 集成 ID。" + "description": { + "type": "string", + "maxLength": 65535, + "description": "可选的详细描述(最长 65,535 字符)。" }, - "incident_id": { + "status": { "type": "string", "maxLength": 64, - "description": "Flashduty 故障 ID。提供后可不传时间窗口。" + "description": "可选的客户端自定义初始状态(最长 64 字符)。" }, - "request_id": { + "priority": { "type": "string", "maxLength": 64, - "description": "ServiceDeskPlus 请求 ID。" + "description": "可选的客户端自定义优先级(最长 64 字符)。" }, - "asc": { - "type": "boolean", - "description": "为 `true` 时按内部记录 ID 升序返回;否则降序。" + "incident_id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "事项锚定的故障 ID(MongoDB ObjectID)。" }, - "p": { - "type": "integer", - "format": "int64", - "minimum": 0, - "description": "页码,从 1 开始。使用 `search_after_ctx` 时忽略。" + "post_mortem_id": { + "type": "string", + "description": "故障复盘 ID(32 位十六进制字符串)。`follow_up` 必填,`action` 禁止填写。该复盘必须关联到 `incident_id`。" }, - "limit": { - "type": "integer", - "format": "int64", - "minimum": 0, - "maximum": 100, - "default": 20, - "description": "分页大小,默认 20,最大 100。" + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "初始负责人成员 ID 列表。负责人须为已能查看锚定对象的活跃成员;指派不会授予访问权限。" }, - "search_after_ctx": { + "idempotency_key": { "type": "string", - "description": "分页游标:首页留空,翻页时传上一页响应中的 `search_after_ctx`。" + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" } } }, - "ServiceDeskPlusRequestMappingItem": { + "UpdateWorkItemRequest": { "type": "object", - "description": "ServiceDeskPlus 请求与 Flashduty 故障之间的一条同步映射记录。", + "description": "跟进事项的部分更新。未提供的字段保持不变;显式传 `null` 则清空该字段。", "required": [ - "created_at", - "status", - "request_id", - "request_link", - "integration_id", - "incident_id", - "incident_title", - "channel_id", - "channel_name" + "work_item_id", + "version" ], "properties": { - "created_at": { + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" + }, + "version": { "type": "integer", "format": "int64", - "description": "映射记录创建时间(Unix 秒)。" + "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + }, + "title": { + "type": [ + "string", + "null" + ], + "description": "新标题(最长 512 字符)。", + "maxLength": 512 + }, + "description": { + "type": [ + "string", + "null" + ], + "description": "新描述(最长 65,535 字符)。", + "maxLength": 65535 }, "status": { - "type": "string", - "enum": [ - "success", - "failed" + "type": [ + "string", + "null" ], - "description": "同步状态。" + "description": "新的客户端自定义状态(最长 64 字符)。", + "maxLength": 64 }, - "request_id": { + "priority": { + "type": [ + "string", + "null" + ], + "description": "新的客户端自定义优先级(最长 64 字符)。", + "maxLength": 64 + } + } + }, + "DeleteWorkItemRequest": { + "type": "object", + "description": "软删除跟进事项的参数。", + "required": [ + "work_item_id", + "version" + ], + "properties": { + "work_item_id": { "type": "string", - "description": "ServiceDeskPlus 请求 ID。" + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" }, - "request_link": { + "version": { + "type": "integer", + "format": "int64", + "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + } + } + }, + "CompleteWorkItemRequest": { + "type": "object", + "description": "完成跟进事项的参数。", + "required": [ + "work_item_id", + "version", + "target_status", + "idempotency_key" + ], + "properties": { + "work_item_id": { "type": "string", - "description": "ServiceDeskPlus 请求详情链接。" + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" }, - "integration_id": { + "version": { "type": "integer", "format": "int64", - "description": "ServiceDeskPlus 集成 ID。" + "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" }, - "incident_id": { + "target_status": { "type": "string", - "description": "关联的 Flashduty 故障 ID。" + "maxLength": 64, + "description": "要设置的客户端自定义状态(最长 64 字符),没有固定状态机。" }, - "incident_title": { + "idempotency_key": { "type": "string", - "description": "关联故障标题。" + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" + } + } + }, + "ConvertWorkItemRequest": { + "type": "object", + "description": "将行动项原地转化为复盘后续行动的参数。", + "required": [ + "work_item_id", + "version", + "idempotency_key" + ], + "properties": { + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" }, - "channel_id": { + "version": { "type": "integer", "format": "int64", - "description": "故障所属协作空间 ID。" + "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" }, - "channel_name": { - "type": "string", - "description": "故障所属协作空间名称。" + "target_status": { + "type": [ + "string", + "null" + ], + "description": "可选,设置在转化后后续行动上的客户端自定义状态(最长 64 字符)。", + "maxLength": 64 }, - "error_message": { + "idempotency_key": { "type": "string", - "description": "同步失败时的错误信息。成功记录通常不返回该字段。" + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" } } }, - "ServiceDeskPlusRequestListResponse": { + "ResetWorkItemAssigneesRequest": { "type": "object", - "description": "分页的 ServiceDeskPlus 请求同步记录列表。", + "description": "整体替换跟进事项的负责人集合。", "required": [ - "items", - "total", - "has_next_page" + "work_item_id", + "version" ], "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceDeskPlusRequestMappingItem" - }, - "description": "当前页同步记录。" + "work_item_id": { + "type": "string", + "maxLength": 128, + "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" }, - "total": { + "version": { "type": "integer", "format": "int64", - "description": "匹配记录总数,最多统计 1000 条。" - }, - "has_next_page": { - "type": "boolean", - "description": "是否还有更多页。" + "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" }, - "search_after_ctx": { - "type": "string", - "description": "下一页翻页游标。无更多数据时为空。" + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "新的负责人成员 ID 列表,整体替换当前集合。空数组表示清空所有负责人。" } } }, - "IncidentCommentTypeItem": { + "BindWorkItemPostMortemRequest": { "type": "object", - "description": "账户级评论类型,可附加到故障评论。", + "description": "将故障下未绑定的后续行动批量绑定到复盘的参数。", + "required": [ + "post_mortem_id", + "incident_id", + "idempotency_key" + ], "properties": { - "comment_type_id": { + "post_mortem_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "评论类型 ID(24 位十六进制 ObjectID)。" - }, - "account_id": { - "type": "integer", - "format": "int64", - "description": "评论类型所属的账户 ID。" + "description": "要绑定后续行动的故障复盘 ID(32 位十六进制字符串)。" }, - "name": { + "incident_id": { "type": "string", - "maxLength": 40, - "description": "评论类型展示名称。账户内唯一(不区分大小写,忽略首尾空白)。" + "pattern": "^[0-9a-fA-F]{24}$", + "description": "故障 ID(MongoDB ObjectID),其已转化但未绑定的后续行动将被绑定。" }, - "color": { + "idempotency_key": { "type": "string", - "pattern": "^#[0-9A-F]{6}$", - "description": "标签颜色,#RRGGBB 格式十六进制值(存储为大写)。" - }, - "position": { - "type": "integer", - "format": "int64", - "description": "评论类型的展示位置,从 1 开始。" - }, - "creator_id": { - "type": "integer", - "format": "int64", - "description": "创建该评论类型的用户 ID。" - }, - "updated_by": { - "type": "integer", - "format": "int64", - "description": "最后更新该评论类型的用户 ID。" - }, - "created_at": { - "type": "integer", - "format": "int64", - "description": "创建时间,Unix 秒级时间戳。" - }, - "updated_at": { - "type": "integer", - "format": "int64", - "description": "最后更新时间,Unix 秒级时间戳。" - } - }, - "required": [ - "comment_type_id", - "account_id", - "name", - "color", - "position", - "creator_id", - "updated_by", - "created_at", - "updated_at" - ] - }, - "ListIncidentCommentTypesRequest": { - "type": "object", - "description": "无参数。该接口始终返回调用账户的全部评论类型。", - "properties": {} - }, - "ListIncidentCommentTypesResponse": { - "type": "object", - "description": "账户评论类型的完整列表,按展示位置排序。", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IncidentCommentTypeItem" - }, - "description": "账户的全部评论类型,按展示位置排序。" + "maxLength": 128, + "pattern": "^[A-Za-z0-9_\\-.:]+$", + "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" } } }, - "CreateIncidentCommentTypeRequest": { + "IncidentCommentTypeDisplay": { "type": "object", - "description": "创建评论类型的参数。每个账户最多 10 个评论类型。", + "description": "账户级评论类型的解析后展示信息,读取时根据当前类型定义填充。", "required": [ + "id", "name", "color" ], "properties": { + "id": { + "type": "string", + "pattern": "^[0-9a-fA-F]{24}$", + "description": "评论类型 ID(MongoDB ObjectID)。" + }, "name": { "type": "string", "maxLength": 40, - "description": "展示名称。存储前去除首尾空白;账户内唯一(不区分大小写)。最多 40 个字符。" + "description": "评论类型展示名称。" }, "color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "标签颜色,#RRGGBB 格式十六进制值,统一转为大写。" + "description": "徽标颜色,#RRGGBB 格式。" } } }, - "CreateIncidentCommentTypeResponse": { + "FeedDetailWorkItemCreated": { "type": "object", - "description": "创建评论类型的结果。", + "description": "`i_wi_created` 的 detail 载荷。", "properties": { - "comment_type_id": { + "work_item_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "新建评论类型的 ID(24 位十六进制 ObjectID)。" + "description": "跟进事项 ID。" }, - "item": { - "$ref": "#/components/schemas/IncidentCommentTypeItem" + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项,可直接转换为 `follow_up`;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项,创建时要求故障已关联到该复盘。" + }, + "title": { + "type": "string", + "description": "跟进事项标题。" + }, + "status": { + "type": "string", + "description": "跟进事项状态标签(如 `open`、`done`)。" + }, + "assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "负责人成员 ID 列表。" + }, + "post_mortem_id": { + "type": "string", + "description": "跟进事项绑定的故障复盘 ID。" } }, - "required": [ - "comment_type_id", - "item" - ] + "title": "i_wi_created" }, - "UpdateIncidentCommentTypeRequest": { + "FeedDetailWorkItemUpdated": { "type": "object", - "description": "更新评论类型的参数。部分更新:`name` 和 `color` 至少提供一个。", - "required": [ - "comment_type_id" - ], + "description": "`i_wi_updated` 的 detail 载荷。仅发生变化的字段携带 `from_*`/`to_*` 值。", "properties": { - "comment_type_id": { + "work_item_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "要更新的评论类型 ID(24 位十六进制 ObjectID)。" + "description": "跟进事项 ID。" }, - "name": { + "item_type": { "type": "string", - "maxLength": 40, - "description": "新的展示名称。存储前去除首尾空白;账户内唯一(不区分大小写)。最多 40 个字符。" + "enum": [ + "action", + "follow_up" + ], + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" }, - "color": { + "title": { "type": "string", - "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "新的标签颜色,#RRGGBB 格式十六进制值,统一转为大写。" - } - } - }, - "DeleteIncidentCommentTypeRequest": { - "type": "object", - "description": "删除评论类型的参数。", - "required": [ - "comment_type_id" - ], - "properties": { - "comment_type_id": { + "description": "跟进事项标题。" + }, + "from_title": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "要删除的评论类型 ID(24 位十六进制 ObjectID)。" + "description": "更新前的标题。" + }, + "from_status": { + "type": "string", + "description": "更新前的状态标签。" + }, + "to_status": { + "type": "string", + "description": "更新后的状态标签。" + }, + "from_priority": { + "type": "string", + "description": "更新前的优先级标签。" + }, + "to_priority": { + "type": "string", + "description": "更新后的优先级标签。" + }, + "from_description": { + "type": "string", + "description": "更新前的描述。" + }, + "to_description": { + "type": "string", + "description": "更新后的描述。" } - } + }, + "title": "i_wi_updated" }, - "ReorderIncidentCommentTypesRequest": { + "FeedDetailWorkItemAssigneesChanged": { "type": "object", - "description": "调整评论类型顺序的参数。", - "required": [ - "comment_type_ids" - ], + "description": "`i_wi_assignees` 的 detail 载荷。", "properties": { - "comment_type_ids": { + "work_item_id": { + "type": "string", + "description": "跟进事项 ID。" + }, + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" + }, + "title": { + "type": "string", + "description": "跟进事项标题。" + }, + "assignee_ids": { "type": "array", "items": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$" + "type": "integer", + "format": "int64" }, - "minItems": 1, - "description": "账户全部评论类型的 ID,按期望顺序排列(24 位十六进制 ObjectID)。" + "description": "变更后的负责人成员 ID 列表。" + }, + "added_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "新增为负责人的成员 ID。" + }, + "removed_assignee_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "从负责人中移除的成员 ID。" } - } + }, + "title": "i_wi_assignees" }, - "WorkItemItem": { + "FeedDetailWorkItemCompleted": { "type": "object", - "description": "结构化的故障跟进事项(行动项或复盘后续行动)及其负责人。", - "required": [ - "work_item_id", - "item_type", - "incident_id", - "title", - "status", - "source_kind", - "version", - "assignee_ids", - "created_by", - "updated_by", - "created_at_seconds", - "updated_at_seconds" - ], + "description": "`i_wi_completed` 的 detail 载荷。", "properties": { "work_item_id": { "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" + "description": "跟进事项 ID。" }, "item_type": { "type": "string", @@ -32537,1095 +33944,1142 @@ "action", "follow_up" ], - "description": "`action` 表示锚定在活动故障上的行动项;`follow_up` 表示复盘后续行动。" + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" }, - "incident_id": { + "title": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "事项锚定的故障 ID(MongoDB ObjectID)。" + "description": "跟进事项标题。" }, - "post_mortem_id": { + "from_status": { "type": "string", - "description": "故障复盘 ID(32 位十六进制字符串)。后续行动绑定复盘后返回。" + "description": "完成前的状态标签。" }, - "title": { + "to_status": { "type": "string", - "maxLength": 512, - "description": "事项标题(最长 512 字符)。" + "description": "完成后的状态标签。" }, - "description": { + "post_mortem_id": { "type": "string", - "maxLength": 65535, - "description": "可选的详细描述(最长 65,535 字符)。" - }, - "status": { + "description": "跟进事项绑定的故障复盘 ID。" + } + }, + "title": "i_wi_completed" + }, + "FeedDetailWorkItemConverted": { + "type": "object", + "description": "`i_wi_converted` 的 detail 载荷。", + "properties": { + "work_item_id": { "type": "string", - "maxLength": 64, - "description": "客户端自定义状态(最长 64 字符),没有固定状态机。" + "description": "跟进事项 ID。" }, - "priority": { + "title": { "type": "string", - "maxLength": 64, - "description": "可选的客户端自定义优先级(最长 64 字符)。" + "description": "跟进事项标题。" }, - "source_kind": { + "from_type": { "type": "string", "enum": [ - "native", - "legacy_follow_up" + "action", + "follow_up" ], - "description": "`native` 表示通过本 API 创建的事项;`legacy_follow_up` 表示从旧版复盘后续行动迁移而来的事项。" + "description": "转化前的事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。当前转换方向仅支持 `action` → `follow_up`,因此该事件中 `from_type` 恒为 `action`。" }, - "legacy_source_id": { + "to_type": { "type": "string", - "description": "该事项迁移自旧版后续行动的原始标识。仅当 `source_kind` 为 `legacy_follow_up` 时返回。" - }, - "version": { - "type": "integer", - "format": "int64", - "description": "乐观锁版本号,每次变更递增。" - }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "当前负责人的成员 ID 列表。不会为 null;空数组表示未指派。" - }, - "created_by": { - "type": "integer", - "format": "int64", - "description": "创建者成员 ID。" + "enum": [ + "action", + "follow_up" + ], + "description": "转化后的事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。当前转换方向仅支持 `action` → `follow_up`,因此该事件中 `to_type` 恒为 `follow_up`,且转换成功后会立即尝试绑定故障对应的复盘。" }, - "updated_by": { - "type": "integer", - "format": "int64", - "description": "最后更新人成员 ID。" + "post_mortem_id": { + "type": "string", + "description": "跟进事项绑定的故障复盘 ID。" }, - "converted_by": { - "type": "integer", - "format": "int64", - "description": "将行动项转化为后续行动的操作人成员 ID。仅转化后返回。" + "status": { + "type": "string", + "description": "转化后的事项状态标签。" + } + }, + "title": "i_wi_converted" + }, + "FeedDetailWorkItemBound": { + "type": "object", + "description": "`i_wi_bound` 的 detail 载荷。", + "properties": { + "work_item_id": { + "type": "string", + "description": "跟进事项 ID。" }, - "converted_at_seconds": { - "type": "integer", - "format": "int64", - "description": "转化时间,Unix 秒级时间戳。仅转化后返回。" + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" }, - "created_at_seconds": { - "type": "integer", - "format": "int64", - "description": "创建时间,Unix 秒级时间戳。" + "title": { + "type": "string", + "description": "跟进事项标题。" }, - "updated_at_seconds": { - "type": "integer", - "format": "int64", - "description": "最后更新时间,Unix 秒级时间戳。" + "post_mortem_id": { + "type": "string", + "description": "跟进事项绑定的故障复盘 ID。" } - } + }, + "title": "i_wi_bound" }, - "WorkItemCreateResult": { + "FeedDetailWorkItemDeleted": { "type": "object", - "description": "创建跟进事项的结果。", - "required": [ - "item" - ], + "description": "`i_wi_deleted` 的 detail 载荷。", "properties": { - "item": { - "$ref": "#/components/schemas/WorkItemItem" + "work_item_id": { + "type": "string", + "description": "跟进事项 ID。" }, - "added_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "新添加(并已通知)的负责人成员 ID。" + "item_type": { + "type": "string", + "enum": [ + "action", + "follow_up" + ], + "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" }, - "idempotent_replay": { - "type": "boolean", - "description": "为 true 表示本次调用以相同幂等键重放了之前的请求,未创建新事项。" + "title": { + "type": "string", + "description": "跟进事项标题。" + }, + "post_mortem_id": { + "type": "string", + "description": "跟进事项绑定的故障复盘 ID。" } - } + }, + "title": "i_wi_deleted" }, - "WorkItemMutationResult": { + "FeedDetailAlertMerge": { "type": "object", - "description": "变更跟进事项的结果。", + "title": "a_merge", + "description": "`a_merge` 的详情数据:告警被合并到故障。", "properties": { - "item": { - "$ref": "#/components/schemas/WorkItemItem" + "comment": { + "type": "string", + "description": "合并时记录的评论。为空时不返回。" + }, + "target_incident": { + "$ref": "#/components/schemas/IncidentShort", + "description": "告警合并到的目标故障。未记录时不返回。" }, - "added_assignee_ids": { + "source_alerts": { "type": "array", "items": { - "type": "integer", - "format": "int64" + "$ref": "#/components/schemas/AlertShort" }, - "description": "新添加(并已通知)的负责人成员 ID。" + "description": "被合并进目标故障的源告警。为空时不返回。" }, - "removed_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "被移除(不通知)的负责人成员 ID。" + "owner_id": { + "type": "integer", + "format": "int64", + "description": "目标故障被设置的新负责人成员 ID。未变更时不返回。" }, - "idempotent_replay": { - "type": "boolean", - "description": "为 true 表示本次调用以相同幂等键重放了之前的请求。" + "title": { + "type": "string", + "description": "目标故障被设置的新标题。未变更时不返回。" } } }, - "WorkItemListResult": { + "AlertShort": { "type": "object", - "description": "游标分页的跟进事项列表。", - "required": [ - "items", - "has_more" - ], + "description": "告警简要引用。", "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WorkItemItem" - }, - "description": "当前页的跟进事项。" - }, - "next_cursor": { + "alert_id": { "type": "string", - "description": "下一页游标,作为 `cursor` 传入;没有更多结果时不返回。" + "pattern": "^[0-9a-fA-F]{24}$", + "description": "告警 ID(ObjectID 十六进制字符串)。" }, - "has_more": { + "title": { + "type": "string", + "description": "告警标题,读取时解析填充。为空时不返回。" + } + } + }, + "EventGroup": { + "type": "object", + "description": "告警事件合并配置。启用后,同一告警的重复事件会在时间窗口内并入已有告警,而不是新建告警。", + "properties": { + "is_enabled": { "type": "boolean", - "description": "为 true 表示还有更多结果。" + "description": "为 true 时,重复事件并入已有告警;为 false 时,每个事件都单独生成告警。默认为 true。" }, - "idempotent_replay": { - "type": "boolean", - "description": "为 true 表示本次调用以相同幂等键重放了之前的请求。" + "time_window": { + "type": "integer", + "minimum": 1, + "description": "合并窗口,单位分钟,范围 1-1440(24 小时);开通扩展额度的账号最大可设 10080(7 天)。默认 1440。" } } }, - "ListWorkItemRequest": { + "StatusPageInfoResponse": { "type": "object", - "description": "查询跟进事项的过滤条件。`incident_id`、`post_mortem_id`、`assignee_id` 至少提供一个。", + "description": "`GET /status-page/info` 返回的状态页详情:完整页面配置及特性开关。", + "allOf": [ + { + "$ref": "#/components/schemas/StatusPageItem" + }, + { + "type": "object", + "properties": { + "managed_domain_feature_enabled": { + "type": "boolean", + "description": "该页面是否启用托管自定义域名特性。公开页面为 `true`,内部页面恒为 `false`。" + } + }, + "required": [ + "managed_domain_feature_enabled" + ] + } + ] + }, + "StatusPagePreDefinedTemplate": { + "type": "object", + "description": "预定义事件模板:可复用的事件草稿(标题、类型、状态、描述)。在 `POST /status-page/template/upsert` 中,省略 `template_id` 表示创建,提供则表示更新;更新时仅应用非空字段。", "properties": { - "incident_id": { + "template_id": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "故障 ID(MongoDB ObjectID)。同时返回锚定在该故障复盘上的后续行动。" + "description": "模板 ID。省略表示创建新模板;提供表示更新已有模板。" }, - "post_mortem_id": { + "title": { "type": "string", - "description": "故障复盘 ID(32 位十六进制字符串)。返回绑定到该复盘的后续行动。" + "description": "模板标题。" }, - "item_type": { + "type": { "type": "string", "enum": [ - "action", - "follow_up" + "incident", + "maintenance" ], - "description": "按事项类型过滤:`action` 行动项,`follow_up` 复盘跟进项。" - }, - "assignee_id": { - "type": "integer", - "format": "int64", - "description": "按负责人成员 ID 过滤结果。仅按负责人查询时,须为本人或账户管理员。" + "description": "模板适用的事件类型:`incident` 故障,`maintenance` 计划维护。" }, - "cursor": { + "status": { "type": "string", - "description": "分页游标,取自上一次响应的 `next_cursor`。" + "enum": [ + "investigating", + "identified", + "monitoring", + "resolved", + "scheduled", + "ongoing", + "completed" + ], + "description": "模板对应的事件状态。故障事件支持 `investigating`/`identified`/`monitoring`/`resolved`;维护事件支持 `scheduled`/`ongoing`/`completed`。" }, - "limit": { - "type": "integer", - "format": "int64", - "minimum": 0, - "maximum": 200, - "default": 50, - "description": "每页条数,最多 200,默认 50。" + "description": { + "type": "string", + "description": "模板正文(Markdown)。" } } }, - "CreateWorkItemRequest": { + "StatusPageMessageTemplate": { "type": "object", - "description": "创建故障跟进事项的参数。", - "required": [ - "item_type", - "title", - "incident_id", - "idempotency_key" - ], + "description": "消息模板:某一事件类型下、按状态划分的通知文案。在 `POST /status-page/template/upsert` 中,省略 `template_id` 表示创建,提供则表示更新;更新时仅应用非空字段。", "properties": { - "item_type": { + "template_id": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "`action` 锚定活动故障,不得设置 `post_mortem_id`;`follow_up` 必须设置 `post_mortem_id`。" + "description": "模板 ID。省略表示创建新模板;提供表示更新已有模板。" }, "title": { "type": "string", - "maxLength": 512, - "description": "事项标题(最长 512 字符)。" - }, - "description": { - "type": "string", - "maxLength": 65535, - "description": "可选的详细描述(最长 65,535 字符)。" - }, - "status": { - "type": "string", - "maxLength": 64, - "description": "可选的客户端自定义初始状态(最长 64 字符)。" - }, - "priority": { - "type": "string", - "maxLength": 64, - "description": "可选的客户端自定义优先级(最长 64 字符)。" - }, - "incident_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "事项锚定的故障 ID(MongoDB ObjectID)。" + "description": "模板标题。" }, - "post_mortem_id": { + "type": { "type": "string", - "description": "故障复盘 ID(32 位十六进制字符串)。`follow_up` 必填,`action` 禁止填写。该复盘必须关联到 `incident_id`。" + "enum": [ + "incident", + "maintenance" + ], + "description": "模板适用的事件类型:`incident` 故障,`maintenance` 计划维护。" }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" + "messages": { + "type": "object", + "additionalProperties": { + "type": "string" }, - "description": "初始负责人成员 ID 列表。负责人须为已能查看锚定对象的活跃成员;指派不会授予访问权限。" - }, - "idempotency_key": { - "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" + "description": "按事件状态划分的通知文案(Markdown)。键为与模板 `type` 匹配的事件状态(如故障事件的 `investigating`、`resolved`),值为事件进入该状态时使用的文本。" } } }, - "UpdateWorkItemRequest": { + "ListStatusPageTemplatesResponse": { "type": "object", - "description": "跟进事项的部分更新。未提供的字段保持不变;显式传 `null` 则清空该字段。", + "description": "事件模板列表。条目结构取决于请求的 `type`:`pre_defined` 为预定义事件模板,`message` 为消息模板。", "required": [ - "work_item_id", - "version" + "items" ], "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" - }, - "version": { - "type": "integer", - "format": "int64", - "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" - }, - "title": { - "type": [ - "string", - "null" - ], - "description": "新标题(最长 512 字符)。", - "maxLength": 512 - }, - "description": { - "type": [ - "string", - "null" - ], - "description": "新描述(最长 65,535 字符)。", - "maxLength": 65535 + "items": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" + }, + { + "$ref": "#/components/schemas/StatusPageMessageTemplate" + } + ] + }, + "description": "所请求类别的模板列表。" + } + } + }, + "FeedDetailAlertUpdate": { + "type": "object", + "title": "a_update", + "description": "`a_update` 的详情数据:更新后的严重程度/状态。", + "properties": { + "severity": { + "$ref": "#/components/schemas/FeedSeverity" }, "status": { - "type": [ - "string", - "null" - ], - "description": "新的客户端自定义状态(最长 64 字符)。", - "maxLength": 64 - }, - "priority": { - "type": [ - "string", - "null" - ], - "description": "新的客户端自定义优先级(最长 64 字符)。", - "maxLength": 64 + "$ref": "#/components/schemas/FeedSeverity" } } }, - "DeleteWorkItemRequest": { + "FeedDetailAlertMuteBySilence": { "type": "object", - "description": "软删除跟进事项的参数。", - "required": [ - "work_item_id", - "version" - ], + "title": "a_m_silence", + "description": "`a_m_silence` 的详情数据:告警被静默规则收敛。", "properties": { - "work_item_id": { + "rule_id": { "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" + "pattern": "^[0-9a-fA-F]{24}$", + "description": "收敛该告警的静默规则 ID。为空时不返回。" }, - "version": { - "type": "integer", - "format": "int64", - "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + "rule_name": { + "type": "string", + "description": "静默规则名称,读取时解析填充。为空时不返回。" } } }, - "CompleteWorkItemRequest": { + "FeedDetailAlertMuteByInhibit": { "type": "object", - "description": "完成跟进事项的参数。", - "required": [ - "work_item_id", - "version", - "target_status", - "idempotency_key" - ], + "title": "a_m_inhibit", + "description": "`a_m_inhibit` 的详情数据:告警因源告警被抑制规则收敛。", "properties": { - "work_item_id": { + "rule_id": { "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" + "pattern": "^[0-9a-fA-F]{24}$", + "description": "收敛该告警的抑制规则 ID。为空时不返回。" }, - "version": { - "type": "integer", - "format": "int64", - "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + "rule_name": { + "type": "string", + "description": "抑制规则名称,读取时解析填充。为空时不返回。" }, - "target_status": { + "source_alert_id": { "type": "string", - "maxLength": 64, - "description": "要设置的客户端自定义状态(最长 64 字符),没有固定状态机。" + "pattern": "^[0-9a-fA-F]{24}$", + "description": "触发抑制的源告警 ID。为空时不返回。" }, - "idempotency_key": { + "source_alert_title": { "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" + "description": "源告警标题,读取时解析填充。为空时不返回。" } } }, - "ConvertWorkItemRequest": { + "FeedDetailAlertMuteByFlapping": { "type": "object", - "description": "将行动项原地转化为复盘后续行动的参数。", - "required": [ - "work_item_id", - "version", - "idempotency_key" - ], + "title": "a_m_flapping", + "description": "`a_m_flapping` 的详情数据(历史):告警被抖动检测收敛。", "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" - }, - "version": { + "max_changes": { "type": "integer", - "format": "int64", - "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + "description": "触发抖动检测的状态变化次数阈值。为 0 时不返回。" }, - "target_status": { - "type": [ - "string", - "null" - ], - "description": "可选,设置在转化后后续行动上的客户端自定义状态(最长 64 字符)。", - "maxLength": 64 + "in_secs": { + "type": "integer", + "description": "统计状态变化的时间窗口(秒)。为 0 时不返回。" }, - "idempotency_key": { - "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" + "mute_secs": { + "type": "integer", + "description": "静默时长(秒)。为 0 时不返回。" } } }, - "ResetWorkItemAssigneesRequest": { + "FeedDetailAlertAck": { "type": "object", - "description": "整体替换跟进事项的负责人集合。", + "title": "a_ack", + "description": "`a_ack` 的详情数据(历史),无字段。", + "properties": {} + }, + "FeedDetailAlertUnack": { + "type": "object", + "title": "a_unack", + "description": "`a_unack` 的详情数据(历史),无字段。", + "properties": {} + }, + "ScheduleByPersonRequest": { + "type": "object", + "description": "成员值班状态查询请求", + "properties": { + "person_id": { + "type": "integer", + "description": "要查询值班状态的成员 ID。", + "format": "int64" + } + }, "required": [ - "work_item_id", - "version" - ], + "person_id" + ] + }, + "ScheduleByPersonResponse": { + "type": "object", + "description": "成员的值班状态:正在值班的班次、下一次值班,以及其参与的全部启用排班。", "properties": { - "work_item_id": { - "type": "string", - "maxLength": 128, - "description": "跟进事项 ID(不透明字符串,最长 128 字符)。" + "current": { + "$ref": "#/components/schemas/MemberOncallInterval" }, - "version": { - "type": "integer", - "format": "int64", - "description": "事项当前版本号,用于乐观锁。必须与存储的版本一致。" + "next": { + "$ref": "#/components/schemas/MemberOncallInterval" }, - "assignee_ids": { + "schedules": { "type": "array", + "description": "该成员参与的全部启用排班。", "items": { - "type": "integer", - "format": "int64" - }, - "description": "新的负责人成员 ID 列表,整体替换当前集合。空数组表示清空所有负责人。" + "$ref": "#/components/schemas/MemberScheduleItem" + } } - } + }, + "required": [ + "schedules" + ] }, - "BindWorkItemPostMortemRequest": { + "MemberScheduleItem": { "type": "object", - "description": "将故障下未绑定的后续行动批量绑定到复盘的参数。", - "required": [ - "post_mortem_id", - "incident_id", - "idempotency_key" - ], + "description": "该成员参与的一个启用中的排班。", "properties": { - "post_mortem_id": { - "type": "string", - "description": "要绑定后续行动的故障复盘 ID(32 位十六进制字符串)。" - }, - "incident_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "故障 ID(MongoDB ObjectID),其已转化但未绑定的后续行动将被绑定。" + "schedule_id": { + "type": "integer", + "description": "排班 ID。", + "format": "int64" }, - "idempotency_key": { + "schedule_name": { "type": "string", - "maxLength": 128, - "pattern": "^[A-Za-z0-9_\\-.:]+$", - "description": "客户端生成的幂等键(最长 128 字符;仅限字母、数字、`_`、`-`、`.`、`:`)。" + "description": "排班名称。" } } }, - "IncidentCommentTypeDisplay": { + "MemberOncallInterval": { "type": "object", - "description": "账户级评论类型的解析后展示信息,读取时根据当前类型定义填充。", - "required": [ - "id", - "name", - "color" - ], + "description": "成员的一个值班班次区间。", "properties": { - "id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "评论类型 ID(MongoDB ObjectID)。" + "schedule_id": { + "type": "integer", + "description": "所属排班 ID。", + "format": "int64" }, - "name": { + "schedule_name": { "type": "string", - "maxLength": 40, - "description": "评论类型展示名称。" + "description": "所属排班名称。" }, - "color": { - "type": "string", - "pattern": "^#[0-9A-Fa-f]{6}$", - "description": "徽标颜色,#RRGGBB 格式。" + "start_at": { + "type": "integer", + "description": "Unix 时间戳(秒)—— 班次开始时间。", + "format": "int64" + }, + "end_at": { + "type": "integer", + "description": "Unix 时间戳(秒)—— 班次结束时间。值班进行中时缺省。", + "format": "int64" } } }, - "FeedDetailWorkItemCreated": { + "ListIntegrationTypesResponse": { "type": "object", - "description": "`i_wi_created` 的 detail 载荷。", + "description": "集成类型列表的一页。", + "required": [ + "p", + "limit", + "total", + "items" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "跟进事项 ID。" - }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项,可直接转换为 `follow_up`;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项,创建时要求故障已关联到该复盘。" + "p": { + "type": "integer", + "description": "当前页码。" }, - "title": { - "type": "string", - "description": "跟进事项标题。" + "limit": { + "type": "integer", + "description": "当前每页条数。" }, - "status": { - "type": "string", - "description": "跟进事项状态标签(如 `open`、`done`)。" + "total": { + "type": "integer", + "format": "int64", + "description": "匹配的类型总数。" }, - "assignee_ids": { + "items": { "type": "array", + "description": "当前页的集成类型。", "items": { - "type": "integer", - "format": "int64" - }, - "description": "负责人成员 ID 列表。" - }, - "post_mortem_id": { - "type": "string", - "description": "跟进事项绑定的故障复盘 ID。" + "$ref": "#/components/schemas/IntegrationTypeItem" + } } - }, - "title": "i_wi_created" + } }, - "FeedDetailWorkItemUpdated": { + "IntegrationTypeItem": { "type": "object", - "description": "`i_wi_updated` 的 detail 载荷。仅发生变化的字段携带 `from_*`/`to_*` 值。", + "description": "账户可配置的一种集成类型。", + "required": [ + "plugin_type", + "plugin_type_name", + "plugin_type_logo_url", + "category", + "status", + "supports_api_create" + ], "properties": { - "work_item_id": { + "plugin_type": { "type": "string", - "description": "跟进事项 ID。" + "description": "创建集成时作为 `plugin_type` 传入的类型标识。", + "example": "standard.alert" }, - "item_type": { + "plugin_type_name": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" + "description": "类型显示名。", + "example": "Standard Alert" }, - "title": { + "plugin_type_logo_url": { "type": "string", - "description": "跟进事项标题。" + "description": "类型 Logo 地址。" }, - "from_title": { + "category": { "type": "string", - "description": "更新前的标题。" + "description": "类型所属分类:`event.alert` 告警事件,`event.change` 变更事件,`im` IM 机器人,`webhook` 自定义 Webhook。", + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ] }, - "from_status": { + "status": { "type": "string", - "description": "更新前的状态标签。" + "description": "该类型在平台侧的状态。" }, - "to_status": { - "type": "string", - "description": "更新后的状态标签。" + "supports_api_create": { + "type": "boolean", + "description": "该类型能否通过 `POST /integration/create` 创建。" + } + } + }, + "IntegrationTypeListRequest": { + "type": "object", + "description": "查询集成类型列表的过滤参数。", + "properties": { + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "页码,从 1 开始。" }, - "from_priority": { - "type": "string", - "description": "更新前的优先级标签。" + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20, + "description": "每页条数,默认 20,最大 100。" }, - "to_priority": { + "orderby": { "type": "string", - "description": "更新后的优先级标签。" + "description": "排序字段;不传时按控制台排序返回。", + "enum": [ + "id", + "created_at", + "updated_at", + "name", + "type" + ] }, - "from_description": { + "category": { "type": "string", - "description": "更新前的描述。" + "description": "按分类过滤,支持逗号分隔多个值,例如 `event.alert,event.change`。" }, - "to_description": { - "type": "string", - "description": "更新后的描述。" + "asc": { + "type": [ + "boolean", + "null" + ], + "default": true, + "description": "`true`(默认)升序,`false` 降序。" } - }, - "title": "i_wi_updated" + } }, - "FeedDetailWorkItemAssigneesChanged": { + "ListIntegrationsResponse": { "type": "object", - "description": "`i_wi_assignees` 的 detail 载荷。", + "description": "集成列表的一页。", + "required": [ + "p", + "limit", + "total", + "items" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "跟进事项 ID。" - }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" - }, - "title": { - "type": "string", - "description": "跟进事项标题。" + "p": { + "type": "integer", + "description": "当前页码。" }, - "assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "变更后的负责人成员 ID 列表。" + "limit": { + "type": "integer", + "description": "当前每页条数。" }, - "added_assignee_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - }, - "description": "新增为负责人的成员 ID。" + "total": { + "type": "integer", + "format": "int64", + "description": "匹配的集成总数。" }, - "removed_assignee_ids": { + "items": { "type": "array", + "description": "当前页的集成。", "items": { - "type": "integer", - "format": "int64" - }, - "description": "从负责人中移除的成员 ID。" + "$ref": "#/components/schemas/IntegrationItem" + } } - }, - "title": "i_wi_assignees" + } }, - "FeedDetailWorkItemCompleted": { + "IntegrationItem": { "type": "object", - "description": "`i_wi_completed` 的 detail 载荷。", + "description": "公共集成列表项,包含完整存储配置;时间字段为 Unix 时间戳(秒)。", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings", + "data_source_id", + "account_id", + "exclusive_data_source_id" + ], "properties": { - "work_item_id": { - "type": "string", - "description": "跟进事项 ID。" + "integration_id": { + "type": "integer", + "format": "int64", + "description": "集成 ID。" }, - "item_type": { - "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" + "team_id": { + "type": "integer", + "format": "int64", + "description": "所属团队 ID;未归属团队时为 `0`。" }, - "title": { + "plugin_type": { "type": "string", - "description": "跟进事项标题。" + "description": "集成类型,例如 `standard.alert`、`zabbix.alert`。" }, - "from_status": { + "plugin_type_name": { "type": "string", - "description": "完成前的状态标签。" + "description": "集成类型显示名,随请求语言变化。" }, - "to_status": { + "category": { "type": "string", - "description": "完成后的状态标签。" + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ], + "description": "集成所属分类:`event.alert` 告警事件,`event.change` 变更事件,`im` IM 机器人,`webhook` 自定义 Webhook。" }, - "post_mortem_id": { - "type": "string", - "description": "跟进事项绑定的故障复盘 ID。" - } - }, - "title": "i_wi_completed" - }, - "FeedDetailWorkItemConverted": { - "type": "object", - "description": "`i_wi_converted` 的 detail 载荷。", - "properties": { - "work_item_id": { + "name": { "type": "string", - "description": "跟进事项 ID。" + "description": "集成名称。" }, - "title": { + "description": { "type": "string", - "description": "跟进事项标题。" + "description": "集成描述。" }, - "from_type": { + "status": { "type": "string", "enum": [ - "action", - "follow_up" + "enabled", + "disabled" ], - "description": "转化前的事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。当前转换方向仅支持 `action` → `follow_up`,因此该事件中 `from_type` 恒为 `action`。" + "description": "状态:`enabled` 正常接收事件,`disabled` 已暂停。" }, - "to_type": { + "ref_id": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "转化后的事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。当前转换方向仅支持 `action` → `follow_up`,因此该事件中 `to_type` 恒为 `follow_up`,且转换成功后会立即尝试绑定故障对应的复盘。" + "description": "来源引用 ID,账户级集成通常为 `a_`,旧记录也可能使用 `w_`;本接口不返回 `c_` 开头的专属集成。" + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "创建时间的 Unix 时间戳(秒)。" + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "最近更新时间的 Unix 时间戳(秒)。" + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "最近收到事件时间的 Unix 时间戳(秒),尚未收到事件时为 `0`。" + }, + "editable": { + "type": "boolean", + "description": "当前调用者是否通过集成对象权限校验;执行写操作还需集成中心管理权限。" + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "创建集成的成员 ID。" + }, + "updated_by": { + "type": "integer", + "format": "int64", + "description": "最近更新集成的成员 ID。" + }, + "no_editable": { + "type": "boolean", + "description": "只读标记;为 true 时公开接口不允许修改该集成。" + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "集成类型的内部 ID;创建集成使用 `plugin_type`,不使用此 ID。" }, - "post_mortem_id": { + "integration_key": { "type": "string", - "description": "跟进事项绑定的故障复盘 ID。" + "description": "解密后的集成 Key,用于事件推送;未存储 Key 时为空字符串,与账户 `app_key` 不同。" }, - "status": { - "type": "string", - "description": "转化后的事项状态标签。" + "settings": { + "type": "object", + "additionalProperties": true, + "description": "按存储值返回的类型专属配置,凭据不打码,与旧 `/datasource/*` 返回行为一致。" + }, + "data_source_id": { + "type": "integer", + "format": "int64", + "description": "旧 datasource ID,与 `integration_id` 相同。" + }, + "account_id": { + "type": "integer", + "format": "int64", + "description": "集成所属账户 ID。" + }, + "exclusive_data_source_id": { + "type": "integer", + "format": "int64", + "description": "旧接口兼容字段;此公共集成列表返回的值为 `0`。" } - }, - "title": "i_wi_converted" + } }, - "FeedDetailWorkItemBound": { + "ListIntegrationsRequest": { "type": "object", - "description": "`i_wi_bound` 的 detail 载荷。", + "description": "查询集成列表的过滤参数。", "properties": { - "work_item_id": { - "type": "string", - "description": "跟进事项 ID。" + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "页码,从 1 开始。" }, - "item_type": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 100, + "description": "每页条数,默认 100,最大 100。" + }, + "orderby": { "type": "string", + "description": "排序字段,默认 `created_at`;`plugin_type` 按底层插件排序。", "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" + "created_at", + "updated_at", + "name", + "plugin_type", + "status" + ] }, - "title": { + "category": { "type": "string", - "description": "跟进事项标题。" + "description": "按分类过滤,支持逗号分隔多个值。" }, - "post_mortem_id": { - "type": "string", - "description": "跟进事项绑定的故障复盘 ID。" - } - }, - "title": "i_wi_bound" - }, - "FeedDetailWorkItemDeleted": { - "type": "object", - "description": "`i_wi_deleted` 的 detail 载荷。", - "properties": { - "work_item_id": { + "type": { "type": "string", - "description": "跟进事项 ID。" + "description": "已废弃;与 `plugin_type` 同时传入时会合并生效。" }, - "item_type": { + "plugin_type": { "type": "string", - "enum": [ - "action", - "follow_up" - ], - "description": "跟进事项类型。`action`:挂在故障上的处置行动事项;`follow_up`:挂在故障复盘(Post-mortem)上的改进事项。" + "description": "按集成类型过滤,支持逗号分隔多个值。" }, - "title": { + "status": { "type": "string", - "description": "跟进事项标题。" + "description": "按状态过滤,支持逗号分隔多个值。" }, - "post_mortem_id": { - "type": "string", - "description": "跟进事项绑定的故障复盘 ID。" - } - }, - "title": "i_wi_deleted" - }, - "FeedDetailAlertMerge": { - "type": "object", - "title": "a_merge", - "description": "`a_merge` 的详情数据:告警被合并到故障。", - "properties": { - "comment": { + "name": { "type": "string", - "description": "合并时记录的评论。为空时不返回。" - }, - "target_incident": { - "$ref": "#/components/schemas/IncidentShort", - "description": "告警合并到的目标故障。未记录时不返回。" + "description": "按集成名称过滤。" }, - "source_alerts": { + "ref_ids": { "type": "array", + "description": "按来源引用 ID 过滤;每个值必须以 `c_`(协作空间)、`a_`(账户)或 `w_` 开头。", "items": { - "$ref": "#/components/schemas/AlertShort" - }, - "description": "被合并进目标故障的源告警。为空时不返回。" + "type": "string" + } }, - "owner_id": { - "type": "integer", - "format": "int64", - "description": "目标故障被设置的新负责人成员 ID。未变更时不返回。" + "asc": { + "type": "boolean", + "description": "`true` 升序,`false` 降序。" }, - "title": { - "type": "string", - "description": "目标故障被设置的新标题。未变更时不返回。" - } - } - }, - "AlertShort": { - "type": "object", - "description": "告警简要引用。", - "properties": { - "alert_id": { - "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "告警 ID(ObjectID 十六进制字符串)。" + "is_my_team": { + "type": "boolean", + "description": "仅返回你所在团队拥有的集成。" }, - "title": { - "type": "string", - "description": "告警标题,读取时解析填充。为空时不返回。" + "team_ids": { + "type": "array", + "description": "按团队 ID 过滤;与 `is_my_team` 同时使用时在其结果内进一步收窄。", + "items": { + "type": "integer", + "format": "int64" + } } } }, - "EventGroup": { + "IntegrationDetail": { "type": "object", - "description": "告警事件合并配置。启用后,同一告警的重复事件会在时间窗口内并入已有告警,而不是新建告警。", + "description": "公共集成详情,包含存储配置与解密 Key;时间字段为 Unix 时间戳(秒)。", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings" + ], "properties": { - "is_enabled": { - "type": "boolean", - "description": "为 true 时,重复事件并入已有告警;为 false 时,每个事件都单独生成告警。默认为 true。" + "integration_id": { + "type": "integer", + "format": "int64", + "description": "集成 ID。" }, - "time_window": { + "team_id": { "type": "integer", - "minimum": 1, - "description": "合并窗口,单位分钟,范围 1-1440(24 小时);开通扩展额度的账号最大可设 10080(7 天)。默认 1440。" - } - } - }, - "StatusPageInfoResponse": { - "type": "object", - "description": "`GET /status-page/info` 返回的状态页详情:完整页面配置及特性开关。", - "allOf": [ - { - "$ref": "#/components/schemas/StatusPageItem" + "format": "int64", + "description": "所属团队 ID;未归属团队时为 `0`。" }, - { - "type": "object", - "properties": { - "managed_domain_feature_enabled": { - "type": "boolean", - "description": "该页面是否启用托管自定义域名特性。公开页面为 `true`,内部页面恒为 `false`。" - } - }, - "required": [ - "managed_domain_feature_enabled" - ] - } - ] - }, - "StatusPagePreDefinedTemplate": { - "type": "object", - "description": "预定义事件模板:可复用的事件草稿(标题、类型、状态、描述)。在 `POST /status-page/template/upsert` 中,省略 `template_id` 表示创建,提供则表示更新;更新时仅应用非空字段。", - "properties": { - "template_id": { + "plugin_type": { "type": "string", - "description": "模板 ID。省略表示创建新模板;提供表示更新已有模板。" + "description": "集成类型,例如 `standard.alert`、`zabbix.alert`。" }, - "title": { + "plugin_type_name": { "type": "string", - "description": "模板标题。" + "description": "集成类型显示名,随请求语言变化。" }, - "type": { + "category": { "type": "string", "enum": [ - "incident", - "maintenance" + "event.alert", + "event.change", + "im", + "webhook" ], - "description": "模板适用的事件类型:`incident` 故障,`maintenance` 计划维护。" + "description": "集成所属分类:`event.alert` 告警事件,`event.change` 变更事件,`im` IM 机器人,`webhook` 自定义 Webhook。" + }, + "name": { + "type": "string", + "description": "集成名称。" + }, + "description": { + "type": "string", + "description": "集成描述。" }, "status": { "type": "string", "enum": [ - "investigating", - "identified", - "monitoring", - "resolved", - "scheduled", - "ongoing", - "completed" + "enabled", + "disabled" ], - "description": "模板对应的事件状态。故障事件支持 `investigating`/`identified`/`monitoring`/`resolved`;维护事件支持 `scheduled`/`ongoing`/`completed`。" + "description": "状态:`enabled` 正常接收事件,`disabled` 已暂停。" }, - "description": { - "type": "string", - "description": "模板正文(Markdown)。" - } - } - }, - "StatusPageMessageTemplate": { - "type": "object", - "description": "消息模板:某一事件类型下、按状态划分的通知文案。在 `POST /status-page/template/upsert` 中,省略 `template_id` 表示创建,提供则表示更新;更新时仅应用非空字段。", - "properties": { - "template_id": { + "ref_id": { "type": "string", - "description": "模板 ID。省略表示创建新模板;提供表示更新已有模板。" + "description": "来源引用 ID,账户级集成通常为 `a_`,旧记录也可能使用 `w_`;本接口不返回 `c_` 开头的专属集成。" + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "创建时间的 Unix 时间戳(秒)。" + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "最近更新时间的 Unix 时间戳(秒)。" + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "最近收到事件时间的 Unix 时间戳(秒),尚未收到事件时为 `0`。" + }, + "editable": { + "type": "boolean", + "description": "当前调用者是否通过集成对象权限校验;执行写操作还需集成中心管理权限。" + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "创建集成的成员 ID。" }, - "title": { - "type": "string", - "description": "模板标题。" + "updated_by": { + "type": "integer", + "format": "int64", + "description": "最近更新集成的成员 ID。" }, - "type": { + "no_editable": { + "type": "boolean", + "description": "只读标记;为 true 时公开接口不允许修改该集成。" + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "集成类型的内部 ID;创建集成使用 `plugin_type`,不使用此 ID。" + }, + "integration_key": { "type": "string", - "enum": [ - "incident", - "maintenance" - ], - "description": "模板适用的事件类型:`incident` 故障,`maintenance` 计划维护。" + "description": "解密后的集成 Key,用于事件推送;未存储 Key 时为空字符串,与账户 `app_key` 不同。" }, - "messages": { + "settings": { "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "按事件状态划分的通知文案(Markdown)。键为与模板 `type` 匹配的事件状态(如故障事件的 `investigating`、`resolved`),值为事件进入该状态时使用的文本。" + "additionalProperties": true, + "description": "按存储值返回的类型专属配置,凭据不打码,与旧 `/datasource/*` 返回行为一致。" + }, + "test": { + "type": "object", + "description": "执行插件测试时返回的测试结果。", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "插件测试是否成功。" + }, + "message": { + "type": "string", + "description": "测试失败信息;成功时为空字符串。" + } + } } } }, - "ListStatusPageTemplatesResponse": { + "GetIntegrationRequest": { "type": "object", - "description": "事件模板列表。条目结构取决于请求的 `type`:`pre_defined` 为预定义事件模板,`message` 为消息模板。", + "description": "指定一个集成。", "required": [ - "items" + "integration_id" ], "properties": { - "items": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/StatusPagePreDefinedTemplate" - }, - { - "$ref": "#/components/schemas/StatusPageMessageTemplate" - } - ] - }, - "description": "所请求类别的模板列表。" + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "集成 ID。", + "example": 6113996590131 } } }, - "FeedDetailAlertUpdate": { + "CreateIntegrationResponse": { "type": "object", - "title": "a_update", - "description": "`a_update` 的详情数据:更新后的严重程度/状态。", + "description": "创建结果与集成 Key。", + "required": [ + "integration_id", + "integration_key" + ], "properties": { - "severity": { - "$ref": "#/components/schemas/FeedSeverity" + "integration_id": { + "type": "integer", + "format": "int64", + "description": "新建集成的 ID。", + "example": 6113996590131 }, - "status": { - "$ref": "#/components/schemas/FeedSeverity" - } - } - }, - "FeedDetailAlertMuteBySilence": { - "type": "object", - "title": "a_m_silence", - "description": "`a_m_silence` 的详情数据:告警被静默规则收敛。", - "properties": { - "rule_id": { + "integration_key": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "收敛该告警的静默规则 ID。为空时不返回。" + "description": "用于事件推送的集成 Key,也可通过 `/integration/list` 和 `/integration/info` 查询。", + "example": "0123456789abcdef0123456789abcdef100" }, - "rule_name": { - "type": "string", - "description": "静默规则名称,读取时解析填充。为空时不返回。" + "test": { + "type": "object", + "description": "执行插件测试时返回的测试结果。", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "插件测试是否成功。" + }, + "message": { + "type": "string", + "description": "测试失败信息;成功时为空字符串。" + } + } } } }, - "FeedDetailAlertMuteByInhibit": { + "CreateIntegrationRequest": { "type": "object", - "title": "a_m_inhibit", - "description": "`a_m_inhibit` 的详情数据:告警因源告警被抑制规则收敛。", + "description": "创建集成的请求体。", + "required": [ + "plugin_type" + ], "properties": { - "rule_id": { + "plugin_type": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "收敛该告警的抑制规则 ID。为空时不返回。" + "description": "集成类型,必须是 `POST /integration/type/list` 中 `supports_api_create: true` 的类型。", + "example": "standard.alert" }, - "rule_name": { + "name": { "type": "string", - "description": "抑制规则名称,读取时解析填充。为空时不返回。" + "minLength": 2, + "maxLength": 49, + "description": "集成名称,非空时为 2–49 字符;不传或为空时使用集成类型名称。", + "example": "Prod metrics alerts" }, - "source_alert_id": { + "description": { "type": "string", - "pattern": "^[0-9a-fA-F]{24}$", - "description": "触发抑制的源告警 ID。为空时不返回。" + "maxLength": 499, + "description": "集成描述,最长 499 个字符。" }, - "source_alert_title": { - "type": "string", - "description": "源告警标题,读取时解析填充。为空时不返回。" - } - } - }, - "FeedDetailAlertMuteByFlapping": { - "type": "object", - "title": "a_m_flapping", - "description": "`a_m_flapping` 的详情数据(历史):告警被抖动检测收敛。", - "properties": { - "max_changes": { + "team_id": { "type": "integer", - "description": "触发抖动检测的状态变化次数阈值。为 0 时不返回。" + "format": "int64", + "minimum": 0, + "description": "所属团队 ID;不传或传 `0` 表示不设置团队,非零 ID 必须属于当前账户。", + "example": 1467226103121 }, - "in_secs": { - "type": "integer", - "description": "统计状态变化的时间窗口(秒)。为 0 时不返回。" + "settings": { + "type": "object", + "description": "集成类型专属配置,可传字段取决于 `plugin_type`。", + "additionalProperties": true }, - "mute_secs": { - "type": "integer", - "description": "静默时长(秒)。为 0 时不返回。" + "integration_key": { + "type": "string", + "minLength": 35, + "maxLength": 35, + "description": "可选预生成 Key,长度 35,末尾为账户 ID 对 1000 取余后补零至三位,且不能已被使用;不传时自动生成。" + }, + "is_test": { + "type": "boolean", + "description": "创建时执行插件测试;不传时为 false,测试结果查看返回的 `test.success`。" } } }, - "FeedDetailAlertAck": { - "type": "object", - "title": "a_ack", - "description": "`a_ack` 的详情数据(历史),无字段。", - "properties": {} - }, - "FeedDetailAlertUnack": { - "type": "object", - "title": "a_unack", - "description": "`a_unack` 的详情数据(历史),无字段。", - "properties": {} - }, - "ScheduleByPersonRequest": { + "UpdateIntegrationRequest": { "type": "object", - "description": "成员值班状态查询请求", - "properties": { - "person_id": { - "type": "integer", - "description": "要查询值班状态的成员 ID。", - "format": "int64" - } - }, + "description": "更新集成的请求体;仅发送的字段会被修改。", "required": [ - "person_id" - ] - }, - "ScheduleByPersonResponse": { - "type": "object", - "description": "成员的值班状态:正在值班的班次、下一次值班,以及其参与的全部启用排班。", + "integration_id" + ], "properties": { - "current": { - "$ref": "#/components/schemas/MemberOncallInterval" + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "集成 ID。", + "example": 6113996590131 }, - "next": { - "$ref": "#/components/schemas/MemberOncallInterval" + "name": { + "type": [ + "string", + "null" + ], + "minLength": 2, + "maxLength": 49, + "description": "新的集成名称,2–49 个字符。" }, - "schedules": { - "type": "array", - "description": "该成员参与的全部启用排班。", - "items": { - "$ref": "#/components/schemas/MemberScheduleItem" - } + "description": { + "type": [ + "string", + "null" + ], + "maxLength": 499, + "description": "新的集成描述,最长 499 个字符。" + }, + "team_id": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0, + "description": "新的所属团队 ID;传 `0` 表示清除团队归属。" + }, + "settings": { + "type": "object", + "description": "替换类型专属配置;已识别的敏感字段不传或传 `******` 时保留原值,显式传空 headers 对象可清空 Headers。", + "additionalProperties": true + }, + "is_test": { + "type": "boolean", + "description": "提交 `settings` 时执行插件测试;仅更新名称、描述或团队时不执行测试。" } - }, - "required": [ - "schedules" - ] + } }, - "MemberScheduleItem": { + "IntegrationLifecycleRequest": { "type": "object", - "description": "该成员参与的一个启用中的排班。", + "description": "指定要操作的集成。", + "required": [ + "integration_id" + ], "properties": { - "schedule_id": { + "integration_id": { "type": "integer", - "description": "排班 ID。", - "format": "int64" - }, - "schedule_name": { - "type": "string", - "description": "排班名称。" + "format": "int64", + "minimum": 1, + "description": "集成 ID。", + "example": 6113996590131 } } }, - "MemberOncallInterval": { + "RotateIntegrationKeyResponse": { "type": "object", - "description": "成员的一个值班班次区间。", + "description": "新生成的集成 Key。", + "required": [ + "integration_key" + ], "properties": { - "schedule_id": { - "type": "integer", - "description": "所属排班 ID。", - "format": "int64" - }, - "schedule_name": { + "integration_key": { "type": "string", - "description": "所属排班名称。" - }, - "start_at": { - "type": "integer", - "description": "Unix 时间戳(秒)—— 班次开始时间。", - "format": "int64" - }, - "end_at": { - "type": "integer", - "description": "Unix 时间戳(秒)—— 班次结束时间。值班进行中时缺省。", - "format": "int64" + "description": "新的集成 Key,旧 Key 立即失效;新 Key 也可通过 `/integration/list` 和 `/integration/info` 查询。", + "example": "0123456789abcdef0123456789abcdef100" } } } diff --git a/api-reference/openapi.en.json b/api-reference/openapi.en.json index fe8675f9..1fcc8cc0 100644 --- a/api-reference/openapi.en.json +++ b/api-reference/openapi.en.json @@ -29396,6 +29396,697 @@ ] } } + }, + "ListIntegrationTypesResponse": { + "type": "object", + "description": "A page of integration types.", + "required": [ + "p", + "limit", + "total", + "items" + ], + "properties": { + "p": { + "type": "integer", + "description": "Page number echoed back." + }, + "limit": { + "type": "integer", + "description": "Page size echoed back." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching types." + }, + "items": { + "type": "array", + "description": "Integration types on the current page.", + "items": { + "$ref": "#/components/schemas/IntegrationTypeItem" + } + } + } + }, + "IntegrationTypeItem": { + "type": "object", + "description": "An integration type the account can configure.", + "required": [ + "plugin_type", + "plugin_type_name", + "plugin_type_logo_url", + "category", + "status", + "supports_api_create" + ], + "properties": { + "plugin_type": { + "type": "string", + "description": "Type identifier to pass as `plugin_type` when creating an integration.", + "example": "standard.alert" + }, + "plugin_type_name": { + "type": "string", + "description": "Display name of the type.", + "example": "Standard Alert" + }, + "plugin_type_logo_url": { + "type": "string", + "description": "Logo URL of the type." + }, + "category": { + "type": "string", + "description": "Category the type belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks.", + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ] + }, + "status": { + "type": "string", + "description": "Platform status of the type." + }, + "supports_api_create": { + "type": "boolean", + "description": "Whether `POST /integration/create` accepts this type." + } + } + }, + "IntegrationTypeListRequest": { + "type": "object", + "description": "Filter parameters for listing integration types.", + "properties": { + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Page number, 1-based." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20, + "description": "Page size. Defaults to 20, maximum 100." + }, + "orderby": { + "type": "string", + "description": "Sort field. When omitted, types are returned in console ranking order.", + "enum": [ + "id", + "created_at", + "updated_at", + "name", + "type" + ] + }, + "category": { + "type": "string", + "description": "Filter by category. Accepts a comma-separated list, for example `event.alert,event.change`." + }, + "asc": { + "type": [ + "boolean", + "null" + ], + "default": true, + "description": "Sort ascending when `true` (the default); descending when `false`." + } + } + }, + "ListIntegrationsResponse": { + "type": "object", + "description": "A page of integrations.", + "required": [ + "p", + "limit", + "total", + "items" + ], + "properties": { + "p": { + "type": "integer", + "description": "Page number echoed back." + }, + "limit": { + "type": "integer", + "description": "Page size echoed back." + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching integrations." + }, + "items": { + "type": "array", + "description": "Integrations on the current page.", + "items": { + "$ref": "#/components/schemas/IntegrationItem" + } + } + } + }, + "IntegrationItem": { + "type": "object", + "description": "Public integration list item with full stored configuration. Timestamps are Unix epoch seconds.", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings", + "data_source_id", + "account_id", + "exclusive_data_source_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "Integration ID." + }, + "team_id": { + "type": "integer", + "format": "int64", + "description": "ID of the team that owns the integration. `0` when it is not assigned to a team." + }, + "plugin_type": { + "type": "string", + "description": "Integration type, for example `standard.alert` or `zabbix.alert`." + }, + "plugin_type_name": { + "type": "string", + "description": "Display name of the integration type, in the language of the request." + }, + "category": { + "type": "string", + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ], + "description": "Category the integration belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks." + }, + "name": { + "type": "string", + "description": "Integration name." + }, + "description": { + "type": "string", + "description": "Free-form description." + }, + "status": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ], + "description": "Lifecycle status: `enabled` while the integration accepts events, `disabled` when it is paused." + }, + "ref_id": { + "type": "string", + "description": "Source reference ID, normally `a_` for an account-level integration; legacy `w_` references may also exist. Channel-owned `c_` integrations are excluded." + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was created." + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was last updated." + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds of the most recent event received. `0` when no event has arrived yet." + }, + "editable": { + "type": "boolean", + "description": "Whether the current caller passes the integration object-permission check; write calls also require Integrations Manage." + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "ID of the member who created the integration." + }, + "updated_by": { + "type": "integer", + "format": "int64", + "description": "ID of the member who last updated the integration." + }, + "no_editable": { + "type": "boolean", + "description": "Read-only flag. When true, the public APIs do not allow changes to this integration." + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "Internal integration type ID; use `plugin_type`, not this ID, when creating an integration." + }, + "integration_key": { + "type": "string", + "description": "Decrypted integration key for inbound pushes. Empty when no key is stored; distinct from the account `app_key`." + }, + "settings": { + "type": "object", + "additionalProperties": true, + "description": "Stored type-specific configuration, including credential values without masking; matches the legacy `/datasource/*` response behavior." + }, + "data_source_id": { + "type": "integer", + "format": "int64", + "description": "Legacy datasource ID, equal to `integration_id`." + }, + "account_id": { + "type": "integer", + "format": "int64", + "description": "ID of the account that owns the integration." + }, + "exclusive_data_source_id": { + "type": "integer", + "format": "int64", + "description": "Legacy compatibility field; `0` for items returned by this public-integration list." + } + } + }, + "ListIntegrationsRequest": { + "type": "object", + "description": "Filter parameters for listing integrations.", + "properties": { + "p": { + "type": "integer", + "minimum": 1, + "default": 1, + "description": "Page number, 1-based." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 100, + "description": "Page size. Defaults to 100, maximum 100." + }, + "orderby": { + "type": "string", + "description": "Sort field. Defaults to `created_at`; `plugin_type` is sorted by the underlying plugin.", + "enum": [ + "created_at", + "updated_at", + "name", + "plugin_type", + "status" + ] + }, + "category": { + "type": "string", + "description": "Filter by category. Accepts a comma-separated list." + }, + "type": { + "type": "string", + "description": "Deprecated. Merged into `plugin_type` when both are set." + }, + "plugin_type": { + "type": "string", + "description": "Filter by integration type. Accepts a comma-separated list." + }, + "status": { + "type": "string", + "description": "Filter by status. Accepts a comma-separated list." + }, + "name": { + "type": "string", + "description": "Filter by integration name." + }, + "ref_ids": { + "type": "array", + "description": "Filter by source reference IDs. Each value must start with `c_` (channel), `a_` (account) or `w_`.", + "items": { + "type": "string" + } + }, + "asc": { + "type": "boolean", + "description": "Sort ascending when true, descending when false." + }, + "is_my_team": { + "type": "boolean", + "description": "Limit the result to integrations owned by your teams." + }, + "team_ids": { + "type": "array", + "description": "Filter by team IDs. With `is_my_team`, the values narrow that set further.", + "items": { + "type": "integer", + "format": "int64" + } + } + } + }, + "IntegrationDetail": { + "type": "object", + "description": "Public integration detail with stored settings and its decrypted key. Timestamps are Unix epoch seconds.", + "required": [ + "integration_id", + "team_id", + "plugin_type", + "plugin_type_name", + "category", + "name", + "description", + "status", + "ref_id", + "created_at", + "updated_at", + "last_time", + "editable", + "creator_id", + "updated_by", + "no_editable", + "plugin_id", + "integration_key", + "settings" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "Integration ID." + }, + "team_id": { + "type": "integer", + "format": "int64", + "description": "ID of the team that owns the integration. `0` when it is not assigned to a team." + }, + "plugin_type": { + "type": "string", + "description": "Integration type, for example `standard.alert` or `zabbix.alert`." + }, + "plugin_type_name": { + "type": "string", + "description": "Display name of the integration type, in the language of the request." + }, + "category": { + "type": "string", + "enum": [ + "event.alert", + "event.change", + "im", + "webhook" + ], + "description": "Category the integration belongs to: `event.alert` alert events, `event.change` change events, `im` IM bots, `webhook` custom webhooks." + }, + "name": { + "type": "string", + "description": "Integration name." + }, + "description": { + "type": "string", + "description": "Free-form description." + }, + "status": { + "type": "string", + "enum": [ + "enabled", + "disabled" + ], + "description": "Lifecycle status: `enabled` while the integration accepts events, `disabled` when it is paused." + }, + "ref_id": { + "type": "string", + "description": "Source reference ID, normally `a_` for an account-level integration; legacy `w_` references may also exist. Channel-owned `c_` integrations are excluded." + }, + "created_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was created." + }, + "updated_at": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds when the integration was last updated." + }, + "last_time": { + "type": "integer", + "format": "int64", + "description": "Unix timestamp in seconds of the most recent event received. `0` when no event has arrived yet." + }, + "editable": { + "type": "boolean", + "description": "Whether the current caller passes the integration object-permission check; write calls also require Integrations Manage." + }, + "creator_id": { + "type": "integer", + "format": "int64", + "description": "ID of the member who created the integration." + }, + "updated_by": { + "type": "integer", + "format": "int64", + "description": "ID of the member who last updated the integration." + }, + "no_editable": { + "type": "boolean", + "description": "Read-only flag. When true, the public APIs do not allow changes to this integration." + }, + "plugin_id": { + "type": "integer", + "format": "int64", + "description": "Internal integration type ID; use `plugin_type`, not this ID, when creating an integration." + }, + "integration_key": { + "type": "string", + "description": "Decrypted integration key for inbound pushes. Empty when no key is stored; distinct from the account `app_key`." + }, + "settings": { + "type": "object", + "additionalProperties": true, + "description": "Stored type-specific configuration, including credential values without masking; matches the legacy `/datasource/*` response behavior." + }, + "test": { + "type": "object", + "description": "Plugin test result, returned only when a test is performed.", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Whether the plugin test succeeded." + }, + "message": { + "type": "string", + "description": "Test failure message; empty on success." + } + } + } + } + }, + "GetIntegrationRequest": { + "type": "object", + "description": "Identifies one integration.", + "required": [ + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 + } + } + }, + "CreateIntegrationResponse": { + "type": "object", + "description": "The created integration and its key.", + "required": [ + "integration_id", + "integration_key" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "description": "ID of the new integration.", + "example": 6113996590131 + }, + "integration_key": { + "type": "string", + "description": "Integration key for inbound pushes; also readable from `/integration/list` and `/integration/info`.", + "example": "0123456789abcdef0123456789abcdef100" + }, + "test": { + "type": "object", + "description": "Plugin test result, returned only when a test is performed.", + "x-flashduty-preserve-absence": true, + "required": [ + "success", + "message" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Whether the plugin test succeeded." + }, + "message": { + "type": "string", + "description": "Test failure message; empty on success." + } + } + } + } + }, + "CreateIntegrationRequest": { + "type": "object", + "description": "Payload for creating an integration.", + "required": [ + "plugin_type" + ], + "properties": { + "plugin_type": { + "type": "string", + "description": "Integration type. Must be one listed by `POST /integration/type/list` with `supports_api_create: true`.", + "example": "standard.alert" + }, + "name": { + "type": "string", + "minLength": 2, + "maxLength": 49, + "description": "Integration name, 2–49 characters when nonempty; defaults to the integration type name when omitted or empty.", + "example": "Prod metrics alerts" + }, + "description": { + "type": "string", + "maxLength": 499, + "description": "Free-form description, at most 499 characters." + }, + "team_id": { + "type": "integer", + "format": "int64", + "minimum": 0, + "description": "Owning team ID; omit or use `0` for no team. A nonzero ID must belong to the current account.", + "example": 1467226103121 + }, + "settings": { + "type": "object", + "description": "Type-specific configuration; the accepted keys depend on `plugin_type`.", + "additionalProperties": true + }, + "integration_key": { + "type": "string", + "minLength": 35, + "maxLength": 35, + "description": "Optional pre-generated key: 35 characters, ending with the account ID modulo 1000 padded to three digits; it must not already be in use. Omit to generate a key." + }, + "is_test": { + "type": "boolean", + "description": "Run the plugin test during creation; false when omitted. Inspect the returned `test.success` for the test outcome." + } + } + }, + "UpdateIntegrationRequest": { + "type": "object", + "description": "Payload for updating an integration. Only the fields you send are changed.", + "required": [ + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 + }, + "name": { + "type": [ + "string", + "null" + ], + "minLength": 2, + "maxLength": 49, + "description": "New name, 2–49 characters." + }, + "description": { + "type": [ + "string", + "null" + ], + "maxLength": 499, + "description": "New description, at most 499 characters." + }, + "team_id": { + "type": [ + "integer", + "null" + ], + "format": "int64", + "minimum": 0, + "description": "New owning team ID; `0` clears the team assignment." + }, + "settings": { + "type": "object", + "description": "Replacement type-specific configuration. Known sensitive fields omitted or sent as `******` keep their stored value; an explicit empty headers object clears headers.", + "additionalProperties": true + }, + "is_test": { + "type": "boolean", + "description": "Run the plugin test when submitting `settings`; no test is performed for a metadata-only update." + } + } + }, + "IntegrationLifecycleRequest": { + "type": "object", + "description": "Identifies the integration to act on.", + "required": [ + "integration_id" + ], + "properties": { + "integration_id": { + "type": "integer", + "format": "int64", + "minimum": 1, + "description": "Integration ID.", + "example": 6113996590131 + } + } + }, + "RotateIntegrationKeyResponse": { + "type": "object", + "description": "The newly issued integration key.", + "required": [ + "integration_key" + ], + "properties": { + "integration_key": { + "type": "string", + "description": "New integration key; the previous key stops working immediately. Also readable from `/integration/list` and `/integration/info`.", + "example": "0123456789abcdef0123456789abcdef100" + } + } } }, "securitySchemes": { @@ -54028,7 +54719,299 @@ { "properties": { "data": { - "$ref": "#/components/schemas/MCPServerItem" + "$ref": "#/components/schemas/MCPServerItem" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "security": [ + { + "AppKeyAuth": [] + } + ], + "summary": "Update MCP server", + "tags": [ + "AI SRE/MCP servers" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **MCP Manage** (`ai-sre`) |\n\n## Usage\n\n- Masked secret values in `env`/`headers` are preserved — sending the masked value back does not overwrite the stored secret.\n- `environments` is a tri-state partial-update field: omit (null) to leave it unchanged; send a list to set it — an empty list clears the restriction back to all environments.\n- Changing `team_id` requires reassignment permission on the destination team; if `environments` is left unchanged, the current environments must still be selectable by the caller under the new team or the update is rejected.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-update", + "metadata": { + "sidebarTitle": "Update MCP server" + } + } + } + }, + "/safari/session/delete": { + "post": { + "description": "Delete a session by ID.", + "operationId": "session-write-delete", + "requestBody": { + "content": { + "application/json": { + "example": { + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + }, + "schema": { + "$ref": "#/components/schemas/SessionDeleteRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": null, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/ResponseEnvelope" + }, + { + "properties": { + "data": { + "description": "Always null on success.", + "type": "null" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "security": [ + { + "AppKeyAuth": [] + } + ], + "summary": "Delete session", + "tags": [ + "AI SRE/Sessions" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Personal sessions can be deleted only by their creator; team sessions can be deleted by the creator, an account admin, or a member of the owning team.\n- This is a soft delete: it also cascades to delete child subagent sessions and any presented files; the underlying S3/MinIO blobs are removed best-effort after the transaction commits, so an orphaned blob is possible on partial failure.\n", + "href": "/en/api-reference/ai-sre/sessions/session-write-delete", + "metadata": { + "sidebarTitle": "Delete session" + } + } + } + }, + "/safari/session/export": { + "post": { + "description": "Stream a session's full event transcript as newline-delimited JSON.", + "operationId": "session-read-export", + "requestBody": { + "content": { + "application/json": { + "example": { + "include_subagents": false, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + }, + "schema": { + "$ref": "#/components/schemas/SessionExportRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/x-ndjson": { + "schema": { + "description": "Newline-delimited JSON stream. Parse line-by-line; do not buffer the whole body.", + "type": "string" + } + } + }, + "description": "Streaming NDJSON (application/x-ndjson). One JSON object per line, terminated by a newline. The first line is always a `session_meta` envelope; subsequent lines are session events." + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "security": [ + { + "AppKeyAuth": [] + } + ], + "summary": "Export session transcript", + "tags": [ + "AI SRE/Sessions" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/day**; **200 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Personal sessions are exportable only by their creator; team sessions can be exported by same-account callers with the `session_id`.\n- The response is `application/x-ndjson` — parse line-by-line and write to a file; do not buffer the whole body in memory.\n- The first line is always a `session_meta` envelope; `include_subagents=true` inlines each child session's stream after its dispatch line.\n- Requests are capped at a 60-second execution timeout; very large sessions may not finish exporting within that window.\n- If the stream fails partway through, the response ends with a JSON error line instead of a proper error envelope (headers are already sent) — check for this trailing line to detect truncation.\n", + "href": "/en/api-reference/ai-sre/sessions/session-read-export", + "metadata": { + "sidebarTitle": "Export session transcript" + } + } + } + }, + "/safari/session/get": { + "post": { + "description": "Fetch one session plus a backward-paged window of its most recent events.", + "operationId": "session-read-info", + "requestBody": { + "content": { + "application/json": { + "example": { + "num_recent_events": 50, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + }, + "schema": { + "$ref": "#/components/schemas/SessionGetRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "events": [ + { + "author": "user", + "created_at": 1780367971241, + "event_id": "evt_3aZQ9p", + "partial": false, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", + "status": "normal", + "turn_complete": false + }, + { + "author": "ai-sre", + "content": { + "parts": [ + { + "text": "..." + } + ], + "role": "model" + }, + "created_at": 1780367992649, + "event_id": "evt_7bWk2r", + "partial": false, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", + "status": "normal", + "turn_complete": true + } + ], + "has_more_older": false, + "session": { + "access_source": "manager", + "app_name": "ai-sre", + "archived_at": 0, + "can_continue": true, + "can_fork": true, + "can_manage": true, + "can_view": true, + "context_window": 0, + "created_at": 1780367971228, + "current_context_tokens": 14948, + "current_turn_active_ms": 0, + "current_turn_started_at": 0, + "current_turn_tokens": 0, + "current_turn_wait_ms": 0, + "entry_kind": "web", + "has_unread": true, + "incognito": false, + "is_mine": false, + "is_running": false, + "last_event_at": 1780367992649, + "person_id": "3790925372131", + "pinned_at": 0, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", + "session_name": "Investigate cloud-assistant first heartbeat", + "share_enabled": true, + "share_version": 3, + "shared_at": 1780367971000, + "shared_by": 3790925372131, + "status": "enabled", + "team_id": 0, + "token_usage": { + "cached_tokens": 11520, + "input_tokens": 14948, + "output_tokens": 888, + "reasoning_tokens": 351 + }, + "updated_at": 1780367993457 + }, + "suggest_init": false + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/ResponseEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/SessionGetResponse" } }, "type": "object" @@ -54060,31 +55043,34 @@ "AppKeyAuth": [] } ], - "summary": "Update MCP server", + "summary": "Get session detail", "tags": [ - "AI SRE/MCP servers" + "AI SRE/Sessions" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **MCP Manage** (`ai-sre`) |\n\n## Usage\n\n- Masked secret values in `env`/`headers` are preserved — sending the masked value back does not overwrite the stored secret.\n- `environments` is a tri-state partial-update field: omit (null) to leave it unchanged; send a list to set it — an empty list clears the restriction back to all environments.\n- Changing `team_id` requires reassignment permission on the destination team; if `environments` is left unchanged, the current environments must still be selectable by the caller under the new team or the update is rejected.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-update", + "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 |\n\n## Usage\n\n- Personal sessions are readable only by their creator; team sessions can be read by same-account callers with the `session_id`.\n- Page older history with `search_after_ctx` from the previous response.\n- `limit` (or legacy `num_recent_events`) caps the event page; default 100, max 1000.\n- A malformed `search_after_ctx` returns 400 immediately, before any DB work.\n- `current_turn_*` fields are populated only while the session `is_running`; `suggest_init` is the same account-wide onboarding flag as `session/list`.\n", + "href": "/en/api-reference/ai-sre/sessions/session-read-info", "metadata": { - "sidebarTitle": "Update MCP server" + "sidebarTitle": "Get session detail" } } } }, - "/safari/session/delete": { + "/safari/session/list": { "post": { - "description": "Delete a session by ID.", - "operationId": "session-write-delete", + "description": "List agent sessions visible to the caller, filtered by app, surface, archive status, and team.", + "operationId": "session-read-list", "requestBody": { "content": { "application/json": { "example": { - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + "app_name": "ai-sre", + "limit": 2, + "orderby": "updated_at", + "scope": "all" }, "schema": { - "$ref": "#/components/schemas/SessionDeleteRequest" + "$ref": "#/components/schemas/SessionListRequest" } } }, @@ -54095,7 +55081,51 @@ "content": { "application/json": { "example": { - "data": null, + "data": { + "sessions": [ + { + "access_source": "manager", + "app_name": "ai-sre", + "archived_at": 0, + "can_continue": true, + "can_fork": true, + "can_manage": true, + "can_view": true, + "context_window": 0, + "created_at": 1780367971228, + "current_context_tokens": 14948, + "current_turn_active_ms": 0, + "current_turn_started_at": 0, + "current_turn_tokens": 0, + "current_turn_wait_ms": 0, + "entry_kind": "web", + "has_unread": true, + "incognito": false, + "is_mine": false, + "is_running": false, + "last_event_at": 1780367992649, + "person_id": "3790925372131", + "pinned_at": 0, + "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", + "session_name": "Investigate cloud-assistant first heartbeat", + "share_enabled": true, + "share_version": 3, + "shared_at": 1780367971000, + "shared_by": 3790925372131, + "status": "enabled", + "team_id": 0, + "token_usage": { + "cached_tokens": 11520, + "input_tokens": 14948, + "output_tokens": 888, + "reasoning_tokens": 351 + }, + "updated_at": 1780367993457 + } + ], + "suggest_init": false, + "total": 988 + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54106,8 +55136,7 @@ { "properties": { "data": { - "description": "Always null on success.", - "type": "null" + "$ref": "#/components/schemas/SessionListResponse" } }, "type": "object" @@ -54139,32 +55168,31 @@ "AppKeyAuth": [] } ], - "summary": "Delete session", + "summary": "List sessions", "tags": [ "AI SRE/Sessions" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Personal sessions can be deleted only by their creator; team sessions can be deleted by the creator, an account admin, or a member of the owning team.\n- This is a soft delete: it also cascades to delete child subagent sessions and any presented files; the underlying S3/MinIO blobs are removed best-effort after the transaction commits, so an orphaned blob is possible on partial failure.\n", - "href": "/en/api-reference/ai-sre/sessions/session-write-delete", + "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 |\n\n## Usage\n\n- Pagination uses `p`/`limit` (max 100); `scope` defaults to `all`.\n- `all` returns your personal sessions plus team sessions you can access; account admins see all team sessions, but not other users' personal sessions.\n- `team_ids` narrows the visible set and never expands access.\n- `is_running` reflects the live run-set; `has_unread` is computed per calling user; the `current_turn_*` fields are always zero here — only `session/get` computes them while a session is running.\n- `suggest_init` is an account-wide onboarding flag (true only when the account has zero knowledge packs anywhere) — it doesn't depend on the list filters.\n", + "href": "/en/api-reference/ai-sre/sessions/session-read-list", "metadata": { - "sidebarTitle": "Delete session" + "sidebarTitle": "List sessions" } } } }, - "/safari/session/export": { + "/safari/skill/delete": { "post": { - "description": "Stream a session's full event transcript as newline-delimited JSON.", - "operationId": "session-read-export", + "description": "Delete a skill by ID.", + "operationId": "skill-write-delete", "requestBody": { "content": { "application/json": { "example": { - "include_subagents": false, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" }, "schema": { - "$ref": "#/components/schemas/SessionExportRequest" + "$ref": "#/components/schemas/SkillDeleteRequest" } } }, @@ -54173,14 +55201,30 @@ "responses": { "200": { "content": { - "application/x-ndjson": { + "application/json": { + "example": { + "data": null, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, "schema": { - "description": "Newline-delimited JSON stream. Parse line-by-line; do not buffer the whole body.", - "type": "string" + "allOf": [ + { + "$ref": "#/components/schemas/ResponseEnvelope" + }, + { + "properties": { + "data": { + "description": "Always null on success.", + "type": "null" + } + }, + "type": "object" + } + ] } } }, - "description": "Streaming NDJSON (application/x-ndjson). One JSON object per line, terminated by a newline. The first line is always a `session_meta` envelope; subsequent lines are session events." + "description": "Success" }, "400": { "$ref": "#/components/responses/BadRequest" @@ -54203,113 +55247,42 @@ "AppKeyAuth": [] } ], - "summary": "Export session transcript", + "summary": "Delete skill", "tags": [ - "AI SRE/Sessions" + "AI SRE/Skills" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/day**; **200 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Personal sessions are exportable only by their creator; team sessions can be exported by same-account callers with the `session_id`.\n- The response is `application/x-ndjson` — parse line-by-line and write to a file; do not buffer the whole body in memory.\n- The first line is always a `session_meta` envelope; `include_subagents=true` inlines each child session's stream after its dispatch line.\n- Requests are capped at a 60-second execution timeout; very large sessions may not finish exporting within that window.\n- If the stream fails partway through, the response ends with a JSON error line instead of a proper error envelope (headers are already sent) — check for this trailing line to detect truncation.\n", - "href": "/en/api-reference/ai-sre/sessions/session-read-export", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Soft delete only: sets `status` to `deleted` and renames the row to free its name for reuse; the skill's zip archive is not removed from object storage.\n- Deleting an already-deleted or nonexistent `skill_id` returns `ResourceNotFound`, since the lookup excludes deleted rows before the delete itself runs.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/skills/skill-write-delete", "metadata": { - "sidebarTitle": "Export session transcript" + "sidebarTitle": "Delete skill" } } } }, - "/safari/session/get": { + "/safari/skill/disable": { "post": { - "description": "Fetch one session plus a backward-paged window of its most recent events.", - "operationId": "session-read-info", + "description": "Disable an enabled skill so the agent stops loading it.", + "operationId": "skill-write-disable", "requestBody": { "content": { "application/json": { "example": { - "num_recent_events": 50, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u" + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" }, "schema": { - "$ref": "#/components/schemas/SessionGetRequest" + "$ref": "#/components/schemas/SkillStatusRequest" } } }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "example": { - "data": { - "events": [ - { - "author": "user", - "created_at": 1780367971241, - "event_id": "evt_3aZQ9p", - "partial": false, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", - "status": "normal", - "turn_complete": false - }, - { - "author": "ai-sre", - "content": { - "parts": [ - { - "text": "..." - } - ], - "role": "model" - }, - "created_at": 1780367992649, - "event_id": "evt_7bWk2r", - "partial": false, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", - "status": "normal", - "turn_complete": true - } - ], - "has_more_older": false, - "session": { - "access_source": "manager", - "app_name": "ai-sre", - "archived_at": 0, - "can_continue": true, - "can_fork": true, - "can_manage": true, - "can_view": true, - "context_window": 0, - "created_at": 1780367971228, - "current_context_tokens": 14948, - "current_turn_active_ms": 0, - "current_turn_started_at": 0, - "current_turn_tokens": 0, - "current_turn_wait_ms": 0, - "entry_kind": "web", - "has_unread": true, - "incognito": false, - "is_mine": false, - "is_running": false, - "last_event_at": 1780367992649, - "person_id": "3790925372131", - "pinned_at": 0, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", - "session_name": "Investigate cloud-assistant first heartbeat", - "share_enabled": true, - "share_version": 3, - "shared_at": 1780367971000, - "shared_by": 3790925372131, - "status": "enabled", - "team_id": 0, - "token_usage": { - "cached_tokens": 11520, - "input_tokens": 14948, - "output_tokens": 888, - "reasoning_tokens": 351 - }, - "updated_at": 1780367993457 - }, - "suggest_init": false - }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": null, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54320,7 +55293,8 @@ { "properties": { "data": { - "$ref": "#/components/schemas/SessionGetResponse" + "description": "Always null on success.", + "type": "null" } }, "type": "object" @@ -54352,34 +55326,31 @@ "AppKeyAuth": [] } ], - "summary": "Get session detail", + "summary": "Disable skill", "tags": [ - "AI SRE/Sessions" + "AI SRE/Skills" ], "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 |\n\n## Usage\n\n- Personal sessions are readable only by their creator; team sessions can be read by same-account callers with the `session_id`.\n- Page older history with `search_after_ctx` from the previous response.\n- `limit` (or legacy `num_recent_events`) caps the event page; default 100, max 1000.\n- A malformed `search_after_ctx` returns 400 immediately, before any DB work.\n- `current_turn_*` fields are populated only while the session `is_running`; `suggest_init` is the same account-wide onboarding flag as `session/list`.\n", - "href": "/en/api-reference/ai-sre/sessions/session-read-info", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only an `enabled` skill can be disabled; an already-disabled skill returns `InvalidParameter`.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/skills/skill-write-disable", "metadata": { - "sidebarTitle": "Get session detail" + "sidebarTitle": "Disable skill" } } } }, - "/safari/session/list": { + "/safari/skill/enable": { "post": { - "description": "List agent sessions visible to the caller, filtered by app, surface, archive status, and team.", - "operationId": "session-read-list", + "description": "Enable a disabled skill so the agent can load it.", + "operationId": "skill-read-enable", "requestBody": { "content": { "application/json": { "example": { - "app_name": "ai-sre", - "limit": 2, - "orderby": "updated_at", - "scope": "all" + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" }, "schema": { - "$ref": "#/components/schemas/SessionListRequest" + "$ref": "#/components/schemas/SkillStatusRequest" } } }, @@ -54390,51 +55361,7 @@ "content": { "application/json": { "example": { - "data": { - "sessions": [ - { - "access_source": "manager", - "app_name": "ai-sre", - "archived_at": 0, - "can_continue": true, - "can_fork": true, - "can_manage": true, - "can_view": true, - "context_window": 0, - "created_at": 1780367971228, - "current_context_tokens": 14948, - "current_turn_active_ms": 0, - "current_turn_started_at": 0, - "current_turn_tokens": 0, - "current_turn_wait_ms": 0, - "entry_kind": "web", - "has_unread": true, - "incognito": false, - "is_mine": false, - "is_running": false, - "last_event_at": 1780367992649, - "person_id": "3790925372131", - "pinned_at": 0, - "session_id": "sess_f8oDvqiG64uur6sBNsTc4u", - "session_name": "Investigate cloud-assistant first heartbeat", - "share_enabled": true, - "share_version": 3, - "shared_at": 1780367971000, - "shared_by": 3790925372131, - "status": "enabled", - "team_id": 0, - "token_usage": { - "cached_tokens": 11520, - "input_tokens": 14948, - "output_tokens": 888, - "reasoning_tokens": 351 - }, - "updated_at": 1780367993457 - } - ], - "suggest_init": false, - "total": 988 - }, + "data": null, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54445,7 +55372,8 @@ { "properties": { "data": { - "$ref": "#/components/schemas/SessionListResponse" + "description": "Always null on success.", + "type": "null" } }, "type": "object" @@ -54477,23 +55405,23 @@ "AppKeyAuth": [] } ], - "summary": "List sessions", + "summary": "Enable skill", "tags": [ - "AI SRE/Sessions" + "AI SRE/Skills" ], "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 |\n\n## Usage\n\n- Pagination uses `p`/`limit` (max 100); `scope` defaults to `all`.\n- `all` returns your personal sessions plus team sessions you can access; account admins see all team sessions, but not other users' personal sessions.\n- `team_ids` narrows the visible set and never expands access.\n- `is_running` reflects the live run-set; `has_unread` is computed per calling user; the `current_turn_*` fields are always zero here — only `session/get` computes them while a session is running.\n- `suggest_init` is an account-wide onboarding flag (true only when the account has zero knowledge packs anywhere) — it doesn't depend on the list filters.\n", - "href": "/en/api-reference/ai-sre/sessions/session-read-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only a `disabled` skill can be enabled; an already-enabled skill returns `InvalidParameter`.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/skills/skill-read-enable", "metadata": { - "sidebarTitle": "List sessions" + "sidebarTitle": "Enable skill" } } } }, - "/safari/skill/delete": { + "/safari/skill/get": { "post": { - "description": "Delete a skill by ID.", - "operationId": "skill-write-delete", + "description": "Get one skill including its full SKILL.md content.", + "operationId": "skill-read-get", "requestBody": { "content": { "application/json": { @@ -54501,7 +55429,7 @@ "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" }, "schema": { - "$ref": "#/components/schemas/SkillDeleteRequest" + "$ref": "#/components/schemas/SkillGetRequest" } } }, @@ -54512,7 +55440,32 @@ "content": { "application/json": { "example": { - "data": null, + "data": { + "account_id": 10023, + "author": "sre-team", + "can_edit": true, + "content": "---\nname: k8s-triage\ndescription: ...\n---\n# Triage steps", + "created_at": 1716960000000, + "created_by": 80011, + "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", + "description_en": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", + "is_modified": false, + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", + "skill_name": "k8s-triage", + "status": "enabled", + "tags": [ + "kubernetes", + "triage" + ], + "team_id": 0, + "tools": [ + "bash", + "mcp:prometheus/query" + ], + "update_available": false, + "updated_at": 1717046400000, + "version": "1.2.0" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54523,8 +55476,7 @@ { "properties": { "data": { - "description": "Always null on success.", - "type": "null" + "$ref": "#/components/schemas/SkillItem" } }, "type": "object" @@ -54541,9 +55493,6 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -54556,31 +55505,33 @@ "AppKeyAuth": [] } ], - "summary": "Delete skill", + "summary": "Get skill detail", "tags": [ "AI SRE/Skills" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Soft delete only: sets `status` to `deleted` and renames the row to free its name for reuse; the skill's zip archive is not removed from object storage.\n- Deleting an already-deleted or nonexistent `skill_id` returns `ResourceNotFound`, since the lookup excludes deleted rows before the delete itself runs.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/skills/skill-write-delete", + "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 |\n\n## Usage\n\n- Returns `ResourceNotFound` if the skill does not exist or has already been deleted.\n- `can_edit` reflects team membership, but read access itself is open to any caller regardless of team.\n", + "href": "/en/api-reference/ai-sre/skills/skill-read-get", "metadata": { - "sidebarTitle": "Delete skill" + "sidebarTitle": "Get skill detail" } } } }, - "/safari/skill/disable": { + "/safari/skill/list": { "post": { - "description": "Disable an enabled skill so the agent stops loading it.", - "operationId": "skill-write-disable", + "description": "List AI SRE skills visible to the caller across account and team scopes, with pagination.", + "operationId": "skill-read-list", "requestBody": { "content": { "application/json": { "example": { - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" + "include_account": true, + "limit": 20, + "p": 1 }, "schema": { - "$ref": "#/components/schemas/SkillStatusRequest" + "$ref": "#/components/schemas/SkillListRequest" } } }, @@ -54591,7 +55542,35 @@ "content": { "application/json": { "example": { - "data": null, + "data": { + "skills": [ + { + "account_id": 10023, + "author": "sre-team", + "can_edit": true, + "created_at": 1716960000000, + "created_by": 80011, + "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", + "is_modified": false, + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", + "skill_name": "k8s-triage", + "status": "enabled", + "tags": [ + "kubernetes", + "triage" + ], + "team_id": 0, + "tools": [ + "bash", + "mcp:prometheus/query" + ], + "update_available": false, + "updated_at": 1717046400000, + "version": "1.2.0" + } + ], + "total": 1 + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54602,8 +55581,7 @@ { "properties": { "data": { - "description": "Always null on success.", - "type": "null" + "$ref": "#/components/schemas/SkillListResponse" } }, "type": "object" @@ -54620,9 +55598,6 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -54635,31 +55610,32 @@ "AppKeyAuth": [] } ], - "summary": "Disable skill", + "summary": "List skills", "tags": [ "AI SRE/Skills" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only an `enabled` skill can be disabled; an already-disabled skill returns `InvalidParameter`.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/skills/skill-write-disable", + "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 |\n\n## Usage\n\n- The `content` field is omitted in list rows; fetch a single skill to read its body.\n- `scope` selects `all` (default), `account`-only, or `team`-only, overriding `include_account`; non-admins requesting specific `team_ids` are silently filtered down to the teams they belong to.\n- `update_available` compares against the marketplace catalog once per call; if the catalog fails to load, the badge is simply suppressed rather than the request failing.\n", + "href": "/en/api-reference/ai-sre/skills/skill-read-list", "metadata": { - "sidebarTitle": "Disable skill" + "sidebarTitle": "List skills" } } } }, - "/safari/skill/enable": { + "/safari/skill/update": { "post": { - "description": "Enable a disabled skill so the agent can load it.", - "operationId": "skill-read-enable", + "description": "Update a skill's descriptions or reassign its team scope.", + "operationId": "skill-write-update", "requestBody": { "content": { "application/json": { "example": { + "description": "Updated triage runbook.", "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" }, "schema": { - "$ref": "#/components/schemas/SkillStatusRequest" + "$ref": "#/components/schemas/SkillUpdateRequest" } } }, @@ -54670,7 +55646,30 @@ "content": { "application/json": { "example": { - "data": null, + "data": { + "account_id": 10023, + "author": "sre-team", + "can_edit": true, + "created_at": 1716960000000, + "created_by": 80011, + "description": "Updated triage runbook.", + "is_modified": false, + "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", + "skill_name": "k8s-triage", + "status": "enabled", + "tags": [ + "kubernetes", + "triage" + ], + "team_id": 0, + "tools": [ + "bash", + "mcp:prometheus/query" + ], + "update_available": false, + "updated_at": 1717046400000, + "version": "1.2.0" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -54681,8 +55680,7 @@ { "properties": { "data": { - "description": "Always null on success.", - "type": "null" + "$ref": "#/components/schemas/SkillItem" } }, "type": "object" @@ -54714,31 +55712,32 @@ "AppKeyAuth": [] } ], - "summary": "Enable skill", + "summary": "Update skill", "tags": [ "AI SRE/Skills" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only a `disabled` skill can be enabled; an already-enabled skill returns `InvalidParameter`.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/skills/skill-read-enable", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only `description`, `description_en`, and `team_id` are editable; the skill body is changed by re-uploading.\n- `description` only updates when non-empty — there is no way to clear it via this field; `description_en` is nilable, so send an empty string to explicitly clear it.\n- Reassigning `team_id` to a different team runs a second authorization check beyond edit access, verifying the caller may target the destination team.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/skills/skill-write-update", "metadata": { - "sidebarTitle": "Enable skill" + "sidebarTitle": "Update skill" } } } }, - "/safari/skill/get": { + "/safari/skill/upload": { "post": { - "description": "Get one skill including its full SKILL.md content.", - "operationId": "skill-read-get", + "description": "Upload a skill archive (.skill/.zip/.tar.gz/.tgz) to create or replace a skill.", + "operationId": "skill-write-upload", "requestBody": { "content": { - "application/json": { + "multipart/form-data": { "example": { - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" + "replace": false, + "team_id": 0 }, "schema": { - "$ref": "#/components/schemas/SkillGetRequest" + "$ref": "#/components/schemas/SkillUploadRequest" } } }, @@ -54753,11 +55752,9 @@ "account_id": 10023, "author": "sre-team", "can_edit": true, - "content": "---\nname: k8s-triage\ndescription: ...\n---\n# Triage steps", "created_at": 1716960000000, "created_by": 80011, "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", - "description_en": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", "is_modified": false, "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", "skill_name": "k8s-triage", @@ -54802,6 +55799,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -54814,33 +55814,31 @@ "AppKeyAuth": [] } ], - "summary": "Get skill detail", + "summary": "Upload skill", "tags": [ "AI SRE/Skills" ], "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 |\n\n## Usage\n\n- Returns `ResourceNotFound` if the skill does not exist or has already been deleted.\n- `can_edit` reflects team membership, but read access itself is open to any caller regardless of team.\n", - "href": "/en/api-reference/ai-sre/skills/skill-read-get", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **30 requests/minute**; **3 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Send as `multipart/form-data` with a `file` part; accepted archive types are `.skill`, `.zip`, `.tar.gz`, `.tgz`, capped at 100MB (oversized files are rejected before the body is read).\n- `skill_id` + `replace=true` targets and overwrites that specific skill, skipping the team-authorship check since the caller already owns the row.\n- `replace=true` without `skill_id` upserts by matching skill name; omitting `replace` always creates a new skill — both paths require the caller to be allowed to author into the target `team_id`.\n- The response always stamps `can_edit: true`.\n- Every call is recorded in the account audit log.\n", + "href": "/en/api-reference/ai-sre/skills/skill-write-upload", "metadata": { - "sidebarTitle": "Get skill detail" + "sidebarTitle": "Upload skill" } } } }, - "/safari/skill/list": { + "/schedule/by-person": { "post": { - "description": "List AI SRE skills visible to the caller across account and team scopes, with pagination.", - "operationId": "skill-read-list", + "description": "Get a member's current and next on-call shifts and every enabled schedule they participate in.", + "operationId": "scheduleByPerson", "requestBody": { "content": { "application/json": { "example": { - "include_account": true, - "limit": 20, - "p": 1 + "person_id": 2476444212131 }, "schema": { - "$ref": "#/components/schemas/SkillListRequest" + "$ref": "#/components/schemas/ScheduleByPersonRequest" } } }, @@ -54852,45 +55850,36 @@ "application/json": { "example": { "data": { - "skills": [ + "current": { + "end_at": 1773532799, + "schedule_id": 2539108069860, + "schedule_name": "Open Source Q&A", + "start_at": 1773446400 + }, + "next": { + "end_at": 1773619199, + "schedule_id": 2539108069860, + "schedule_name": "Open Source Q&A", + "start_at": 1773532800 + }, + "schedules": [ { - "account_id": 10023, - "author": "sre-team", - "can_edit": true, - "created_at": 1716960000000, - "created_by": 80011, - "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", - "is_modified": false, - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", - "skill_name": "k8s-triage", - "status": "enabled", - "tags": [ - "kubernetes", - "triage" - ], - "team_id": 0, - "tools": [ - "bash", - "mcp:prometheus/query" - ], - "update_available": false, - "updated_at": 1717046400000, - "version": "1.2.0" + "schedule_id": 2539108069860, + "schedule_name": "Open Source Q&A" } - ], - "total": 1 + ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { "allOf": [ { - "$ref": "#/components/schemas/ResponseEnvelope" + "$ref": "#/components/schemas/SuccessEnvelope" }, { "properties": { "data": { - "$ref": "#/components/schemas/SkillListResponse" + "$ref": "#/components/schemas/ScheduleByPersonResponse" } }, "type": "object" @@ -54914,37 +55903,102 @@ "$ref": "#/components/responses/ServerError" } }, - "security": [ - { - "AppKeyAuth": [] - } - ], - "summary": "List skills", + "summary": "Get member on-call status", "tags": [ - "AI SRE/Skills" + "On-call/Schedules" ], "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 |\n\n## Usage\n\n- The `content` field is omitted in list rows; fetch a single skill to read its body.\n- `scope` selects `all` (default), `account`-only, or `team`-only, overriding `include_account`; non-admins requesting specific `team_ids` are silently filtered down to the teams they belong to.\n- `update_available` compares against the marketplace catalog once per call; if the catalog fails to load, the badge is simply suppressed rather than the request failing.\n", - "href": "/en/api-reference/ai-sre/skills/skill-read-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |\n\n## Usage\n\n- `current` carries the shift in progress with its true start time; `next` is the upcoming shift, absent when nothing is scheduled within the lookup window.\n- Disabled schedules are not listed.", + "href": "/en/api-reference/on-call/schedules/schedule-by-person", "metadata": { - "sidebarTitle": "List skills" + "sidebarTitle": "Get member on-call status" } } } }, - "/safari/skill/update": { + "/schedule/create": { "post": { - "description": "Update a skill's descriptions or reassign its team scope.", - "operationId": "skill-write-update", + "description": "Create a new on-call schedule (escalation rule schedule).", + "operationId": "scheduleCreate", "requestBody": { "content": { "application/json": { "example": { - "description": "Updated triage runbook.", - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m" + "description": "Primary on-call rotation for the production team", + "layers": [ + { + "day_mask": { + "repeat": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + "enable_time": 1712000000, + "expire_time": 0, + "fair_rotation": false, + "groups": [ + { + "end": 0, + "group_name": "A", + "members": [ + { + "person_ids": [ + 2451002751131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 0 + }, + { + "end": 0, + "group_name": "B", + "members": [ + { + "person_ids": [ + 2476123212131 + ], + "role_id": 0 + } + ], + "name": "B", + "start": 0 + } + ], + "handoff_time": 0, + "hidden": 0, + "layer_name": "Layer 1", + "mask_continuous_enabled": false, + "mode": 0, + "name": "Layer 1", + "restrict_end": 0, + "restrict_mode": 0, + "restrict_periods": [], + "restrict_start": 0, + "rotation_duration": 86400, + "rotation_unit": "day", + "rotation_value": 1, + "weight": 0 + } + ], + "notify": { + "advance_in_time": 300, + "by": { + "follow_preference": true, + "personal_channels": null + }, + "fixed_time": null, + "webhooks": null + }, + "schedule_name": "Production On-Call", + "team_id": 4291079133131 }, "schema": { - "$ref": "#/components/schemas/SkillUpdateRequest" + "$ref": "#/components/schemas/ScheduleUpsertRequest" } } }, @@ -54956,40 +56010,19 @@ "application/json": { "example": { "data": { - "account_id": 10023, - "author": "sre-team", - "can_edit": true, - "created_at": 1716960000000, - "created_by": 80011, - "description": "Updated triage runbook.", - "is_modified": false, - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", - "skill_name": "k8s-triage", - "status": "enabled", - "tags": [ - "kubernetes", - "triage" - ], - "team_id": 0, - "tools": [ - "bash", - "mcp:prometheus/query" - ], - "update_available": false, - "updated_at": 1717046400000, - "version": "1.2.0" + "schedule_id": 6294534917601 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { "allOf": [ { - "$ref": "#/components/schemas/ResponseEnvelope" + "$ref": "#/components/schemas/SuccessEnvelope" }, { "properties": { "data": { - "$ref": "#/components/schemas/SkillItem" + "$ref": "#/components/schemas/ScheduleIDResponse" } }, "type": "object" @@ -55006,9 +56039,6 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -55016,37 +56046,33 @@ "$ref": "#/components/responses/ServerError" } }, - "security": [ - { - "AppKeyAuth": [] - } - ], - "summary": "Update skill", + "summary": "Create schedule", "tags": [ - "AI SRE/Skills" + "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Only `description`, `description_en`, and `team_id` are editable; the skill body is changed by re-uploading.\n- `description` only updates when non-empty — there is no way to clear it via this field; `description_en` is nilable, so send an empty string to explicitly clear it.\n- Reassigning `team_id` to a different team runs a second authorization check beyond edit access, verifying the caller may target the destination team.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/skills/skill-write-update", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-create", "metadata": { - "sidebarTitle": "Update skill" + "sidebarTitle": "Create schedule" } } } }, - "/safari/skill/upload": { + "/schedule/delete": { "post": { - "description": "Upload a skill archive (.skill/.zip/.tar.gz/.tgz) to create or replace a skill.", - "operationId": "skill-write-upload", + "description": "Delete one or more on-call schedules by ID.", + "operationId": "scheduleDelete", "requestBody": { "content": { - "multipart/form-data": { + "application/json": { "example": { - "replace": false, - "team_id": 0 + "schedule_ids": [ + 2001 + ] }, "schema": { - "$ref": "#/components/schemas/SkillUploadRequest" + "$ref": "#/components/schemas/ScheduleIDsBodyRequest" } } }, @@ -55057,41 +56083,18 @@ "content": { "application/json": { "example": { - "data": { - "account_id": 10023, - "author": "sre-team", - "can_edit": true, - "created_at": 1716960000000, - "created_by": 80011, - "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.", - "is_modified": false, - "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m", - "skill_name": "k8s-triage", - "status": "enabled", - "tags": [ - "kubernetes", - "triage" - ], - "team_id": 0, - "tools": [ - "bash", - "mcp:prometheus/query" - ], - "update_available": false, - "updated_at": 1717046400000, - "version": "1.2.0" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { "allOf": [ { - "$ref": "#/components/schemas/ResponseEnvelope" + "$ref": "#/components/schemas/SuccessEnvelope" }, { "properties": { "data": { - "$ref": "#/components/schemas/SkillItem" + "$ref": "#/components/schemas/ScheduleEmptyObject" } }, "type": "object" @@ -55108,9 +56111,6 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -55118,36 +56118,33 @@ "$ref": "#/components/responses/ServerError" } }, - "security": [ - { - "AppKeyAuth": [] - } - ], - "summary": "Upload skill", + "summary": "Delete schedules", "tags": [ - "AI SRE/Skills" + "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **30 requests/minute**; **3 requests/second** per account |\n| Permissions | **Skill Manage** (`ai-sre`) |\n\n## Usage\n\n- Send as `multipart/form-data` with a `file` part; accepted archive types are `.skill`, `.zip`, `.tar.gz`, `.tgz`, capped at 100MB (oversized files are rejected before the body is read).\n- `skill_id` + `replace=true` targets and overwrites that specific skill, skipping the team-authorship check since the caller already owns the row.\n- `replace=true` without `skill_id` upserts by matching skill name; omitting `replace` always creates a new skill — both paths require the caller to be allowed to author into the target `team_id`.\n- The response always stamps `can_edit: true`.\n- Every call is recorded in the account audit log.\n", - "href": "/en/api-reference/ai-sre/skills/skill-write-upload", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-delete", "metadata": { - "sidebarTitle": "Upload skill" + "sidebarTitle": "Delete schedules" } } } }, - "/schedule/by-person": { + "/schedule/info": { "post": { - "description": "Get a member's current and next on-call shifts and every enabled schedule they participate in.", - "operationId": "scheduleByPerson", + "description": "Return details of an on-call schedule including the computed schedule layers for the requested time window (max 45 days).", + "operationId": "scheduleInfo", "requestBody": { "content": { "application/json": { "example": { - "person_id": 2476444212131 + "end": 1712086400, + "schedule_id": 2001, + "start": 1712000000 }, "schema": { - "$ref": "#/components/schemas/ScheduleByPersonRequest" + "$ref": "#/components/schemas/ScheduleInfoRequest" } } }, @@ -55159,24 +56156,256 @@ "application/json": { "example": { "data": { - "current": { - "end_at": 1773532799, - "schedule_id": 2539108069860, - "schedule_name": "Open Source Q&A", - "start_at": 1773446400 + "account_id": 2451002751131, + "create_at": 1766110836, + "create_by": 2476123212131, + "cur_oncall": { + "end": 1776009600, + "group": { + "end": 1776009600, + "group_name": "A", + "members": [ + { + "person_ids": [ + 2451002751131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 1775972040 + }, + "index": 0, + "start": 1775972040, + "update_at": 0, + "weight": 0 }, - "next": { - "end_at": 1773619199, - "schedule_id": 2539108069860, - "schedule_name": "Open Source Q&A", - "start_at": 1773532800 + "description": "abc", + "disabled": 0, + "final_schedule": { + "layer_name": "", + "mode": 0, + "name": "", + "schedules": [ + { + "end": 1776096000, + "group": { + "end": 1776096000, + "group_name": "A", + "members": [ + { + "person_ids": [ + 3122470302131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 1776009600 + }, + "index": 0, + "start": 1776009600 + } + ] }, - "schedules": [ + "group_id": 4291079133131, + "id": 5789640530410, + "layer_schedules": [ { - "schedule_id": 2539108069860, - "schedule_name": "Open Source Q&A" + "layer_name": "Layer 1", + "mode": 0, + "name": "Layer 1", + "schedules": [ + { + "end": 1776096000, + "group": { + "end": 1776096000, + "group_name": "A", + "members": [ + { + "person_ids": [ + 3122470302131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 1776009600 + }, + "index": 0, + "start": 1776009600 + } + ] + } + ], + "layers": [ + { + "account_id": 2451002751131, + "create_at": 1775205795, + "create_by": 2476123212131, + "day_mask": { + "repeat": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + "enable_time": 1767542400, + "expire_time": 0, + "fair_rotation": false, + "groups": [ + { + "end": 0, + "group_name": "A", + "members": [ + { + "person_ids": [ + 3122470302131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 0 + }, + { + "end": 0, + "group_name": "B", + "members": [ + { + "person_ids": [ + 2659460982131 + ], + "role_id": 0 + } + ], + "name": "B", + "start": 0 + } + ], + "handoff_time": 0, + "hidden": 0, + "layer_end": null, + "layer_name": "Layer 1", + "layer_start": 1767542400, + "mask_continuous_enabled": false, + "mode": 0, + "name": "Layer 1", + "restrict_end": 0, + "restrict_mode": 0, + "restrict_periods": [], + "restrict_start": 0, + "rotation_duration": 86400, + "rotation_unit": "day", + "rotation_value": 1, + "schedule_id": 5789640530410, + "update_at": 1775205795, + "update_by": 2476123212131, + "weight": 0 + } + ], + "name": "test-000001", + "next_oncall": { + "end": 1776096000, + "group": { + "end": 1776096000, + "group_name": "A", + "members": [ + { + "person_ids": [ + 3122470302131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 1776009600 + }, + "index": 0, + "start": 1776009600, + "update_at": 0, + "weight": 0 + }, + "notify": { + "advance_in_time": 300, + "by": { + "follow_preference": false, + "personal_channels": [ + "email" + ] + }, + "fixed_time": null, + "webhooks": [ + { + "settings": { + "alias": "", + "chat_ids": [ + "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" + ], + "data_source_id": 5427276014131, + "sign_secret": "", + "token": "", + "verify_token": "" + }, + "type": "feishu_app" + } + ] + }, + "schedule_id": 5789640530410, + "schedule_layers": [ + { + "layer_name": "Layer 1", + "mode": 0, + "name": "Layer 1", + "schedules": [ + { + "end": 1776096000, + "group": { + "end": 1776096000, + "group_name": "A", + "members": [ + { + "person_ids": [ + 3122470302131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 1776009600 + }, + "index": 0, + "start": 1776009600 + }, + { + "end": 1776182400, + "group": { + "end": 1776182400, + "group_name": "B", + "members": [ + { + "person_ids": [ + 2659460982131 + ], + "role_id": 0 + } + ], + "name": "B", + "start": 1776096000 + }, + "index": 0, + "start": 1776096000 + } + ] } - ] + ], + "schedule_name": "test-000001", + "status": 0, + "team_id": 4291079133131, + "update_at": 1775205795, + "update_by": 2476123212131 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -55188,7 +56417,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleByPersonResponse" + "$ref": "#/components/schemas/ScheduleItem" } }, "type": "object" @@ -55212,102 +56441,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get member on-call status", + "summary": "Get schedule info", "tags": [ "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |\n\n## Usage\n\n- `current` carries the shift in progress with its true start time; `next` is the upcoming shift, absent when nothing is scheduled within the lookup window.\n- Disabled schedules are not listed.", - "href": "/en/api-reference/on-call/schedules/schedule-by-person", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-info", "metadata": { - "sidebarTitle": "Get member on-call status" + "sidebarTitle": "Get schedule info" } } } }, - "/schedule/create": { + "/schedule/infos": { "post": { - "description": "Create a new on-call schedule (escalation rule schedule).", - "operationId": "scheduleCreate", + "description": "Return details of multiple on-call schedules by their IDs.", + "operationId": "scheduleInfos", "requestBody": { "content": { "application/json": { "example": { - "description": "Primary on-call rotation for the production team", - "layers": [ - { - "day_mask": { - "repeat": [ - 1, - 2, - 3, - 4, - 5 - ] - }, - "enable_time": 1712000000, - "expire_time": 0, - "fair_rotation": false, - "groups": [ - { - "end": 0, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 0 - }, - { - "end": 0, - "group_name": "B", - "members": [ - { - "person_ids": [ - 2476123212131 - ], - "role_id": 0 - } - ], - "name": "B", - "start": 0 - } - ], - "handoff_time": 0, - "hidden": 0, - "layer_name": "Layer 1", - "mask_continuous_enabled": false, - "mode": 0, - "name": "Layer 1", - "restrict_end": 0, - "restrict_mode": 0, - "restrict_periods": [], - "restrict_start": 0, - "rotation_duration": 86400, - "rotation_unit": "day", - "rotation_value": 1, - "weight": 0 - } - ], - "notify": { - "advance_in_time": 300, - "by": { - "follow_preference": true, - "personal_channels": null - }, - "fixed_time": null, - "webhooks": null - }, - "schedule_name": "Production On-Call", - "team_id": 4291079133131 + "schedule_ids": [ + 2001, + 2002, + 2003 + ] }, "schema": { - "$ref": "#/components/schemas/ScheduleUpsertRequest" + "$ref": "#/components/schemas/ScheduleIDsRequest" } } }, @@ -55319,7 +56481,60 @@ "application/json": { "example": { "data": { - "schedule_id": 6294534917601 + "items": [ + { + "account_id": 2451002751131, + "create_at": 1766110836, + "create_by": 2476123212131, + "cur_oncall": null, + "description": "abc", + "disabled": 0, + "final_schedule": { + "layer_name": "", + "mode": 0, + "name": "", + "schedules": null + }, + "group_id": 4291079133131, + "id": 5789640530410, + "layer_schedules": null, + "layers": null, + "name": "test-000001", + "next_oncall": null, + "notify": { + "advance_in_time": 300, + "by": { + "follow_preference": false, + "personal_channels": [ + "email" + ] + }, + "fixed_time": null, + "webhooks": [ + { + "settings": { + "alias": "", + "chat_ids": [ + "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" + ], + "data_source_id": 5427276014131, + "sign_secret": "", + "token": "", + "verify_token": "" + }, + "type": "feishu_app" + } + ] + }, + "schedule_id": 5789640530410, + "schedule_layers": null, + "schedule_name": "test-000001", + "status": 0, + "team_id": 4291079133131, + "update_at": 1775205795, + "update_by": 2476123212131 + } + ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -55331,7 +56546,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleIDResponse" + "$ref": "#/components/schemas/ScheduleSelfResponse" } }, "type": "object" @@ -55355,33 +56570,34 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Create schedule", + "summary": "Batch get schedules", "tags": [ "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-create", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-infos", "metadata": { - "sidebarTitle": "Create schedule" + "sidebarTitle": "Batch get schedules" } } } }, - "/schedule/delete": { + "/schedule/list": { "post": { - "description": "Delete one or more on-call schedules by ID.", - "operationId": "scheduleDelete", + "description": "Return a paginated list of on-call schedules. When both start and end are provided (max 45 days apart), computed layer schedules are included.", + "operationId": "scheduleList", "requestBody": { "content": { "application/json": { "example": { - "schedule_ids": [ - 2001 - ] + "is_my_team": true, + "limit": 20, + "p": 1, + "query": "production" }, "schema": { - "$ref": "#/components/schemas/ScheduleIDsBodyRequest" + "$ref": "#/components/schemas/ScheduleListRequest" } } }, @@ -55392,7 +56608,99 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "items": [ + { + "account_id": 2451002751131, + "create_at": 1766110836, + "create_by": 2476123212131, + "cur_oncall": null, + "description": "abc", + "disabled": 0, + "final_schedule": { + "layer_name": "", + "mode": 0, + "name": "", + "schedules": null + }, + "group_id": 4291079133131, + "id": 5789640530410, + "layer_schedules": null, + "layers": null, + "name": "test-000001", + "next_oncall": null, + "notify": { + "advance_in_time": 300, + "by": { + "follow_preference": false, + "personal_channels": [ + "email" + ] + }, + "fixed_time": null, + "webhooks": [ + { + "settings": { + "alias": "", + "chat_ids": [ + "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" + ], + "data_source_id": 5427276014131, + "sign_secret": "", + "token": "", + "verify_token": "" + }, + "type": "feishu_app" + } + ] + }, + "schedule_id": 5789640530410, + "schedule_layers": null, + "schedule_name": "test-000001", + "status": 0, + "team_id": 4291079133131, + "update_at": 1775205795, + "update_by": 2476123212131 + }, + { + "account_id": 2451002751131, + "create_at": 1759132037, + "create_by": 2476123212131, + "cur_oncall": null, + "description": "", + "disabled": 0, + "final_schedule": { + "layer_name": "", + "mode": 0, + "name": "", + "schedules": null + }, + "group_id": 2477033058131, + "id": 5432326025106, + "layer_schedules": null, + "layers": null, + "name": "test-2509300001", + "next_oncall": null, + "notify": { + "advance_in_time": 300, + "by": { + "follow_preference": true, + "personal_channels": null + }, + "fixed_time": null, + "webhooks": null + }, + "schedule_id": 5432326025106, + "schedule_layers": null, + "schedule_name": "test-2509300001", + "status": 0, + "team_id": 2477033058131, + "update_at": 1775207501, + "update_by": 2476123212131 + } + ], + "total": 41 + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -55403,7 +56711,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleEmptyObject" + "$ref": "#/components/schemas/ScheduleListResponse" } }, "type": "object" @@ -55427,33 +56735,79 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete schedules", + "summary": "List schedules", "tags": [ "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-delete", + "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/schedules/schedule-list", "metadata": { - "sidebarTitle": "Delete schedules" + "sidebarTitle": "List schedules" } } } }, - "/schedule/info": { + "/schedule/preview": { "post": { - "description": "Return details of an on-call schedule including the computed schedule layers for the requested time window (max 45 days).", - "operationId": "scheduleInfo", + "description": "Preview the coverage generated by a schedule configuration without persisting it. The request accepts the same body as create/update plus a required start/end window (max 45 days).", + "operationId": "schedulePreview", "requestBody": { "content": { "application/json": { "example": { "end": 1712086400, - "schedule_id": 2001, + "layers": [ + { + "day_mask": { + "repeat": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + "enable_time": 1712000000, + "expire_time": 0, + "fair_rotation": false, + "groups": [ + { + "end": 0, + "group_name": "A", + "members": [ + { + "person_ids": [ + 2451002751131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 0 + } + ], + "handoff_time": 0, + "hidden": 0, + "layer_name": "Layer 1", + "mask_continuous_enabled": false, + "mode": 0, + "name": "Layer 1", + "restrict_end": 0, + "restrict_mode": 0, + "restrict_periods": [], + "restrict_start": 0, + "rotation_duration": 86400, + "rotation_unit": "day", + "rotation_value": 1, + "weight": 0 + } + ], + "schedule_name": "Preview Schedule", "start": 1712000000 }, "schema": { - "$ref": "#/components/schemas/ScheduleInfoRequest" + "$ref": "#/components/schemas/ScheduleUpsertRequest" } } }, @@ -55465,32 +56819,13 @@ "application/json": { "example": { "data": { - "account_id": 2451002751131, - "create_at": 1766110836, - "create_by": 2476123212131, - "cur_oncall": { - "end": 1776009600, - "group": { - "end": 1776009600, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 1775972040 - }, - "index": 0, - "start": 1775972040, - "update_at": 0, - "weight": 0 - }, - "description": "abc", - "disabled": 0, + "account_id": 0, + "create_at": 0, + "create_by": 0, + "cur_oncall": null, + "description": null, + "disabled": null, + "end": 1776240000, "final_schedule": { "layer_name": "", "mode": 0, @@ -55504,7 +56839,7 @@ "members": [ { "person_ids": [ - 3122470302131 + 2451002751131 ], "role_id": 0 } @@ -55517,41 +56852,14 @@ } ] }, - "group_id": 4291079133131, - "id": 5789640530410, - "layer_schedules": [ - { - "layer_name": "Layer 1", - "mode": 0, - "name": "Layer 1", - "schedules": [ - { - "end": 1776096000, - "group": { - "end": 1776096000, - "group_name": "A", - "members": [ - { - "person_ids": [ - 3122470302131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 1776009600 - }, - "index": 0, - "start": 1776009600 - } - ] - } - ], + "group_id": null, + "id": null, + "layer_schedules": null, "layers": [ { - "account_id": 2451002751131, - "create_at": 1775205795, - "create_by": 2476123212131, + "account_id": 0, + "create_at": 0, + "create_by": 0, "day_mask": { "repeat": [ 1, @@ -55561,7 +56869,7 @@ 5 ] }, - "enable_time": 1767542400, + "enable_time": 1775980800, "expire_time": 0, "fair_rotation": false, "groups": [ @@ -55571,7 +56879,7 @@ "members": [ { "person_ids": [ - 3122470302131 + 2451002751131 ], "role_id": 0 } @@ -55585,7 +56893,7 @@ "members": [ { "person_ids": [ - 2659460982131 + 2476123212131 ], "role_id": 0 } @@ -55598,71 +56906,27 @@ "hidden": 0, "layer_end": null, "layer_name": "Layer 1", - "layer_start": 1767542400, + "layer_start": 1775980800, "mask_continuous_enabled": false, "mode": 0, "name": "Layer 1", - "restrict_end": 0, - "restrict_mode": 0, - "restrict_periods": [], - "restrict_start": 0, - "rotation_duration": 86400, - "rotation_unit": "day", - "rotation_value": 1, - "schedule_id": 5789640530410, - "update_at": 1775205795, - "update_by": 2476123212131, - "weight": 0 - } - ], - "name": "test-000001", - "next_oncall": { - "end": 1776096000, - "group": { - "end": 1776096000, - "group_name": "A", - "members": [ - { - "person_ids": [ - 3122470302131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 1776009600 - }, - "index": 0, - "start": 1776009600, - "update_at": 0, - "weight": 0 - }, - "notify": { - "advance_in_time": 300, - "by": { - "follow_preference": false, - "personal_channels": [ - "email" - ] - }, - "fixed_time": null, - "webhooks": [ - { - "settings": { - "alias": "", - "chat_ids": [ - "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" - ], - "data_source_id": 5427276014131, - "sign_secret": "", - "token": "", - "verify_token": "" - }, - "type": "feishu_app" - } - ] - }, - "schedule_id": 5789640530410, + "restrict_end": 0, + "restrict_mode": 0, + "restrict_periods": [], + "restrict_start": 0, + "rotation_duration": 86400, + "rotation_unit": "day", + "rotation_value": 1, + "schedule_id": 0, + "update_at": 0, + "update_by": 0, + "weight": 0 + } + ], + "name": null, + "next_oncall": null, + "notify": null, + "schedule_id": 0, "schedule_layers": [ { "layer_name": "Layer 1", @@ -55677,7 +56941,7 @@ "members": [ { "person_ids": [ - 3122470302131 + 2451002751131 ], "role_id": 0 } @@ -55696,7 +56960,7 @@ "members": [ { "person_ids": [ - 2659460982131 + 2476123212131 ], "role_id": 0 } @@ -55710,11 +56974,185 @@ ] } ], - "schedule_name": "test-000001", - "status": 0, - "team_id": 4291079133131, - "update_at": 1775205795, - "update_by": 2476123212131 + "schedule_name": null, + "start": 1775980800, + "status": null, + "team_id": null, + "update_at": 0, + "update_by": 0 + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/ScheduleItem" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "Preview schedule", + "tags": [ + "On-call/Schedules" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **60 requests/minute**; **10 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-preview", + "metadata": { + "sidebarTitle": "Preview schedule" + } + } + } + }, + "/schedule/self": { + "post": { + "description": "Return on-call schedules where the current user is assigned.", + "operationId": "scheduleSelf", + "requestBody": { + "content": { + "application/json": { + "example": { + "end": 1712086400, + "start": 1712000000 + }, + "schema": { + "$ref": "#/components/schemas/ScheduleSelfRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "items": [ + { + "account_id": 2451002751131, + "create_at": 1702623874, + "create_by": 2451002751131, + "cur_oncall": null, + "description": "", + "disabled": 0, + "final_schedule": { + "layer_name": "", + "mode": 0, + "name": "", + "schedules": null + }, + "group_id": 2477033058131, + "id": 2539108069860, + "layer_schedules": null, + "layers": [ + { + "account_id": 2451002751131, + "create_at": 1702623874, + "create_by": 2451002751131, + "day_mask": { + "repeat": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + "enable_time": 1702623874, + "expire_time": 0, + "fair_rotation": false, + "groups": [ + { + "end": 0, + "group_name": "A", + "members": [ + { + "person_ids": [ + 2476444212131 + ], + "role_id": 0 + } + ], + "name": "A", + "start": 0 + }, + { + "end": 0, + "group_name": "B", + "members": [ + { + "person_ids": [ + 2469167612131 + ], + "role_id": 0 + } + ], + "name": "B", + "start": 0 + } + ], + "handoff_time": 0, + "hidden": 0, + "layer_end": null, + "layer_name": "Rule 1", + "layer_start": 1702623874, + "mask_continuous_enabled": false, + "mode": 0, + "name": "Rule 1", + "restrict_end": 0, + "restrict_mode": 0, + "restrict_periods": [], + "restrict_start": 0, + "rotation_duration": 86400, + "rotation_unit": "day", + "rotation_value": 1, + "schedule_id": 2539108069860, + "update_at": 1710468081, + "update_by": 2476444212131, + "weight": 0 + } + ], + "name": "Open Source Q&A", + "next_oncall": null, + "notify": { + "by": null, + "fixed_time": null, + "webhooks": null + }, + "schedule_id": 2539108069860, + "schedule_layers": null, + "schedule_name": "Open Source Q&A", + "status": 0, + "team_id": 2477033058131, + "update_at": 1710468081, + "update_by": 2476444212131 + } + ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -55726,7 +57164,80 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleItem" + "$ref": "#/components/schemas/ScheduleSelfResponse" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "List my schedules", + "tags": [ + "On-call/Schedules" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-self", + "metadata": { + "sidebarTitle": "List my schedules" + } + } + } + }, + "/schedule/update": { + "post": { + "description": "Update an existing on-call schedule. Provide schedule_id to identify the schedule.", + "operationId": "scheduleUpdate", + "requestBody": { + "content": { + "application/json": { + "example": { + "description": "Updated primary on-call rotation", + "schedule_id": 2001, + "schedule_name": "Production On-Call (Updated)", + "team_id": 4291079133131 + }, + "schema": { + "$ref": "#/components/schemas/ScheduleUpsertRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": {}, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/ScheduleEmptyObject" } }, "type": "object" @@ -55750,35 +57261,38 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get schedule info", + "summary": "Update schedule", "tags": [ "On-call/Schedules" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-info", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/schedules/schedule-update", "metadata": { - "sidebarTitle": "Get schedule info" + "sidebarTitle": "Update schedule" } } } }, - "/schedule/infos": { + "/sourcemap/list": { "post": { - "description": "Return details of multiple on-call schedules by their IDs.", - "operationId": "scheduleInfos", + "description": "Return a paginated list of uploaded sourcemap files filtered by platform type, service, and version.", + "operationId": "sourcemap-read-list", "requestBody": { "content": { "application/json": { "example": { - "schedule_ids": [ - 2001, - 2002, - 2003 - ] + "end_time": 1712700000000, + "limit": 20, + "p": 1, + "services": [ + "my-web-app" + ], + "start_time": 1712000000000, + "type": "browser" }, "schema": { - "$ref": "#/components/schemas/ScheduleIDsRequest" + "$ref": "#/components/schemas/SourcemapListRequest" } } }, @@ -55792,58 +57306,19 @@ "data": { "items": [ { - "account_id": 2451002751131, - "create_at": 1766110836, - "create_by": 2476123212131, - "cur_oncall": null, - "description": "abc", - "disabled": 0, - "final_schedule": { - "layer_name": "", - "mode": 0, - "name": "", - "schedules": null - }, - "group_id": 4291079133131, - "id": 5789640530410, - "layer_schedules": null, - "layers": null, - "name": "test-000001", - "next_oncall": null, - "notify": { - "advance_in_time": 300, - "by": { - "follow_preference": false, - "personal_channels": [ - "email" - ] - }, - "fixed_time": null, - "webhooks": [ - { - "settings": { - "alias": "", - "chat_ids": [ - "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" - ], - "data_source_id": 5427276014131, - "sign_secret": "", - "token": "", - "verify_token": "" - }, - "type": "feishu_app" - } - ] - }, - "schedule_id": 5789640530410, - "schedule_layers": null, - "schedule_name": "test-000001", - "status": 0, - "team_id": 4291079133131, - "update_at": 1775205795, - "update_by": 2476123212131 + "created_at": 1712700000, + "git_commit_sha": "abc1234def5678", + "git_repository_url": "https://github.com/example/my-web-app", + "key": "browser/my-web-app/1.0.0/main.js.map", + "metadata": {}, + "service": "my-web-app", + "size": 204800, + "type": "browser", + "updated_at": 1712700000, + "version": "1.0.0" } - ] + ], + "total": 3 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -55855,7 +57330,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleSelfResponse" + "$ref": "#/components/schemas/SourcemapListResponse" } }, "type": "object" @@ -55879,34 +57354,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Batch get schedules", + "summary": "List sourcemaps", "tags": [ - "On-call/Schedules" + "RUM/Sourcemaps" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-infos", + "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 |\n\n## Usage\n\n- `start_time` and `end_time` are required — both use Unix epoch **milliseconds**. Maximum window is 365 days.\n- The `type` field selects the platform: `browser` (JavaScript), `android`, or `ios`. Defaults to `browser` when omitted.\n- Default page size is 20; maximum is 100. Default sort is `created_at` descending.\n- For Android, `build_id` matches the Gradle plugin build identifier. For iOS, `uuid` matches the dSYM bundle UUID.", + "href": "/en/api-reference/rum/sourcemaps/sourcemap-read-list", "metadata": { - "sidebarTitle": "Batch get schedules" + "sidebarTitle": "List sourcemaps" } } } }, - "/schedule/list": { + "/sourcemap/stack/enrich": { "post": { - "description": "Return a paginated list of on-call schedules. When both start and end are provided (max 45 days apart), computed layer schedules are included.", - "operationId": "scheduleList", + "description": "Symbolicate or deobfuscate a browser, Android, iOS, Mini Program, or HarmonyOS stack trace.", + "operationId": "sourcemap-read-stack-enrich", "requestBody": { "content": { "application/json": { "example": { - "is_my_team": true, - "limit": 20, - "p": 1, - "query": "production" + "near": 3, + "service": "my-web-app", + "stack": "TypeError: Cannot read properties of undefined\n at render (https://cdn.example.com/app.min.js:1:2345)", + "type": "browser", + "version": "1.0.0" }, "schema": { - "$ref": "#/components/schemas/ScheduleListRequest" + "$ref": "#/components/schemas/SourcemapStackEnrichRequest" } } }, @@ -55918,97 +57394,31 @@ "application/json": { "example": { "data": { - "items": [ - { - "account_id": 2451002751131, - "create_at": 1766110836, - "create_by": 2476123212131, - "cur_oncall": null, - "description": "abc", - "disabled": 0, - "final_schedule": { - "layer_name": "", - "mode": 0, - "name": "", - "schedules": null - }, - "group_id": 4291079133131, - "id": 5789640530410, - "layer_schedules": null, - "layers": null, - "name": "test-000001", - "next_oncall": null, - "notify": { - "advance_in_time": 300, - "by": { - "follow_preference": false, - "personal_channels": [ - "email" - ] - }, - "fixed_time": null, - "webhooks": [ - { - "settings": { - "alias": "", - "chat_ids": [ - "oc_60a6dc4c6e4e5cbc4934ef08aa7ff76d" - ], - "data_source_id": 5427276014131, - "sign_secret": "", - "token": "", - "verify_token": "" - }, - "type": "feishu_app" - } - ] - }, - "schedule_id": 5789640530410, - "schedule_layers": null, - "schedule_name": "test-000001", - "status": 0, - "team_id": 4291079133131, - "update_at": 1775205795, - "update_by": 2476123212131 - }, + "frames": [ { - "account_id": 2451002751131, - "create_at": 1759132037, - "create_by": 2476123212131, - "cur_oncall": null, - "description": "", - "disabled": 0, - "final_schedule": { - "layer_name": "", - "mode": 0, - "name": "", - "schedules": null - }, - "group_id": 2477033058131, - "id": 5432326025106, - "layer_schedules": null, - "layers": null, - "name": "test-2509300001", - "next_oncall": null, - "notify": { - "advance_in_time": 300, - "by": { - "follow_preference": true, - "personal_channels": null + "code_snippets": [ + { + "code": "const cart = props.cart;", + "line": 41 }, - "fixed_time": null, - "webhooks": null - }, - "schedule_id": 5432326025106, - "schedule_layers": null, - "schedule_name": "test-2509300001", - "status": 0, - "team_id": 2477033058131, - "update_at": 1775207501, - "update_by": 2476123212131 + { + "code": "return cart.items.map(renderItem);", + "line": 42 + } + ], + "column": 17, + "converted": true, + "file": "src/pages/checkout.tsx", + "function": "renderCheckout", + "line": 42, + "original_frame": { + "column": 2345, + "file": "https://cdn.example.com/app.min.js", + "function": "render", + "line": 1 + } } - ], - "total": 41 + ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -56020,7 +57430,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleListResponse" + "$ref": "#/components/schemas/SourcemapStackEnrichResponse" } }, "type": "object" @@ -56044,251 +57454,182 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List schedules", + "summary": "Enrich a stack trace", "tags": [ - "On-call/Schedules" + "RUM/Sourcemaps" ], "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/schedules/schedule-list", + "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 |\n\n## Usage\n\n- `type` defaults to `browser` when omitted for backward compatibility.\n- Set `near` from 1 to 20 to include source-code snippets around converted frames.\n- For Android NDK native crashes, provide `arch` and `source_type: ndk` so the backend routes to native symbolication.\n- For iOS crash stacks, pass `binary_images` so addresses can be relocated against the uploaded dSYM files.\n- `no_cache` is intended for debugging and bypasses cached enrich results.", + "href": "/en/api-reference/rum/sourcemaps/sourcemap-read-stack-enrich", "metadata": { - "sidebarTitle": "List schedules" + "sidebarTitle": "Enrich a stack trace" } } } }, - "/schedule/preview": { - "post": { - "description": "Preview the coverage generated by a schedule configuration without persisting it. The request accepts the same body as create/update plus a required start/end window (max 45 days).", - "operationId": "schedulePreview", - "requestBody": { - "content": { - "application/json": { - "example": { - "end": 1712086400, - "layers": [ - { - "day_mask": { - "repeat": [ - 1, - 2, - 3, - 4, - 5 - ] - }, - "enable_time": 1712000000, - "expire_time": 0, - "fair_rotation": false, - "groups": [ - { - "end": 0, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 0 - } - ], - "handoff_time": 0, - "hidden": 0, - "layer_name": "Layer 1", - "mask_continuous_enabled": false, - "mode": 0, - "name": "Layer 1", - "restrict_end": 0, - "restrict_mode": 0, - "restrict_periods": [], - "restrict_start": 0, - "rotation_duration": 86400, - "rotation_unit": "day", - "rotation_value": 1, - "weight": 0 - } - ], - "schedule_name": "Preview Schedule", - "start": 1712000000 - }, - "schema": { - "$ref": "#/components/schemas/ScheduleUpsertRequest" - } + "/status-page/change/active/list": { + "get": { + "description": "List in-progress (non-terminal) events of a given type for a status page.", + "operationId": "statusPageChangeActiveList", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" } }, - "required": true - }, + { + "description": "Event type filter. Required. Returns only in-progress (non-terminal) events — `investigating`/`identified`/`monitoring` for `incident`, `scheduled`/`ongoing` for `maintenance`.", + "in": "query", + "name": "type", + "required": true, + "schema": { + "enum": [ + "incident", + "maintenance" + ], + "type": "string" + } + } + ], "responses": { "200": { "content": { "application/json": { "example": { "data": { - "account_id": 0, - "create_at": 0, - "create_by": 0, - "cur_oncall": null, - "description": null, - "disabled": null, - "end": 1776240000, - "final_schedule": { - "layer_name": "", - "mode": 0, - "name": "", - "schedules": [ - { - "end": 1776096000, - "group": { - "end": 1776096000, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 1776009600 - }, - "index": 0, - "start": 1776009600 - } - ] - }, - "group_id": null, - "id": null, - "layer_schedules": null, - "layers": [ - { - "account_id": 0, - "create_at": 0, - "create_by": 0, - "day_mask": { - "repeat": [ - 1, - 2, - 3, - 4, - 5 - ] - }, - "enable_time": 1775980800, - "expire_time": 0, - "fair_rotation": false, - "groups": [ - { - "end": 0, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 0 - }, - { - "end": 0, - "group_name": "B", - "members": [ - { - "person_ids": [ - 2476123212131 - ], - "role_id": 0 - } - ], - "name": "B", - "start": 0 - } - ], - "handoff_time": 0, - "hidden": 0, - "layer_end": null, - "layer_name": "Layer 1", - "layer_start": 1775980800, - "mask_continuous_enabled": false, - "mode": 0, - "name": "Layer 1", - "restrict_end": 0, - "restrict_mode": 0, - "restrict_periods": [], - "restrict_start": 0, - "rotation_duration": 86400, - "rotation_unit": "day", - "rotation_value": 1, - "schedule_id": 0, - "update_at": 0, - "update_by": 0, - "weight": 0 - } - ], - "name": null, - "next_oncall": null, - "notify": null, - "schedule_id": 0, - "schedule_layers": [ + "items": [ { - "layer_name": "Layer 1", - "mode": 0, - "name": "Layer 1", - "schedules": [ - { - "end": 1776096000, - "group": { - "end": 1776096000, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2451002751131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 1776009600 - }, - "index": 0, - "start": 1776009600 - }, + "affected_components": [ { - "end": 1776182400, - "group": { - "end": 1776182400, - "group_name": "B", - "members": [ - { - "person_ids": [ - 2476123212131 - ], - "role_id": 0 - } - ], - "name": "B", - "start": 1776096000 - }, - "index": 0, - "start": 1776096000 + "available_since_seconds": 1765349358, + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "name": "Web Console", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "status": "degraded" + } + ], + "change_id": 5821693893131, + "description": "We are currently investigating an issue affecting some services.", + "notify_subscribers": true, + "page_id": 5750613685214, + "start_at_seconds": 1766736878, + "status": "investigating", + "title": "Web Console Degraded Performance", + "type": "incident", + "updates": [ + { + "at_seconds": 1766736876, + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "component_name": "Web Console", + "status": "degraded" + } + ], + "description": "We are currently investigating an issue affecting some services.", + "status": "investigating", + "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" } ] } + ] + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/StatusPageChangeListResponse" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "List active status page events", + "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-change-active-list", + "metadata": { + "sidebarTitle": "List active status page events" + } + } + } + }, + "/status-page/change/create": { + "post": { + "description": "Create a new incident or maintenance event on a status page.", + "operationId": "statusPageChangeCreate", + "requestBody": { + "content": { + "application/json": { + "example": { + "description": "We are investigating degraded performance affecting the web console.", + "notify_subscribers": true, + "page_id": 5750613685214, + "start_at_seconds": 1712000000, + "status": "investigating", + "title": "Web Console Degraded Performance", + "type": "incident", + "updates": [ + { + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "status": "degraded" + } ], - "schedule_name": null, - "start": 1775980800, - "status": null, - "team_id": null, - "update_at": 0, - "update_by": 0 + "description": "We are currently investigating an issue affecting some users.", + "status": "investigating" + } + ] + }, + "schema": { + "$ref": "#/components/schemas/CreateStatusPageChangeRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "change_id": 6294539747131, + "change_name": "API Test Incident" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -56300,7 +57641,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleItem" + "$ref": "#/components/schemas/StatusPageChangeCreateResponse" } }, "type": "object" @@ -56324,142 +57665,167 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Preview schedule", + "summary": "Create status page event", "tags": [ - "On-call/Schedules" + "On-call/Status pages" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **60 requests/minute**; **10 requests/second** per account |\n| Permissions | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-preview", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Events Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-change-create", "metadata": { - "sidebarTitle": "Preview schedule" + "sidebarTitle": "Create status page event" } } } }, - "/schedule/self": { + "/status-page/change/delete": { "post": { - "description": "Return on-call schedules where the current user is assigned.", - "operationId": "scheduleSelf", + "description": "Delete a status page event.", + "operationId": "statusPageChangeDelete", "requestBody": { "content": { "application/json": { "example": { - "end": 1712086400, - "start": 1712000000 + "change_id": 5821693893131, + "page_id": 5750613685214 }, "schema": { - "$ref": "#/components/schemas/ScheduleSelfRequest" + "$ref": "#/components/schemas/DeleteStatusPageChangeRequest" } } }, "required": true }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": {}, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/EmptyResponse" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "Delete status page event", + "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 Events Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-change-delete", + "metadata": { + "sidebarTitle": "Delete status page event" + } + } + } + }, + "/status-page/change/info": { + "get": { + "description": "Retrieve details of a specific status page event (incident or maintenance).", + "operationId": "statusPageChangeInfo", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + } + }, + { + "description": "Event (change) ID.", + "in": "query", + "name": "change_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + } + } + ], "responses": { "200": { "content": { "application/json": { "example": { "data": { - "items": [ + "affected_components": [ + { + "available_since_seconds": 1765349358, + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "name": "Web Console", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "status": "operational" + } + ], + "change_id": 5821693893131, + "close_at_seconds": 1775529742, + "description": "The issue has been resolved, and all services are operating normally.\n\nThank you for your patience.", + "notify_subscribers": true, + "page_id": 5750613685214, + "start_at_seconds": 1766736878, + "status": "resolved", + "title": "Web Console Degraded Performance", + "type": "incident", + "updates": [ + { + "at_seconds": 1766736876, + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "component_name": "Web Console", + "status": "degraded" + } + ], + "description": "We are currently investigating an issue affecting some services.", + "status": "investigating", + "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" + }, { - "account_id": 2451002751131, - "create_at": 1702623874, - "create_by": 2451002751131, - "cur_oncall": null, - "description": "", - "disabled": 0, - "final_schedule": { - "layer_name": "", - "mode": 0, - "name": "", - "schedules": null - }, - "group_id": 2477033058131, - "id": 2539108069860, - "layer_schedules": null, - "layers": [ + "at_seconds": 1775529742, + "component_changes": [ { - "account_id": 2451002751131, - "create_at": 1702623874, - "create_by": 2451002751131, - "day_mask": { - "repeat": [ - 1, - 2, - 3, - 4, - 5 - ] - }, - "enable_time": 1702623874, - "expire_time": 0, - "fair_rotation": false, - "groups": [ - { - "end": 0, - "group_name": "A", - "members": [ - { - "person_ids": [ - 2476444212131 - ], - "role_id": 0 - } - ], - "name": "A", - "start": 0 - }, - { - "end": 0, - "group_name": "B", - "members": [ - { - "person_ids": [ - 2469167612131 - ], - "role_id": 0 - } - ], - "name": "B", - "start": 0 - } - ], - "handoff_time": 0, - "hidden": 0, - "layer_end": null, - "layer_name": "Rule 1", - "layer_start": 1702623874, - "mask_continuous_enabled": false, - "mode": 0, - "name": "Rule 1", - "restrict_end": 0, - "restrict_mode": 0, - "restrict_periods": [], - "restrict_start": 0, - "rotation_duration": 86400, - "rotation_unit": "day", - "rotation_value": 1, - "schedule_id": 2539108069860, - "update_at": 1710468081, - "update_by": 2476444212131, - "weight": 0 + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "component_name": "Web Console", + "status": "operational" } ], - "name": "Open Source Q&A", - "next_oncall": null, - "notify": { - "by": null, - "fixed_time": null, - "webhooks": null - }, - "schedule_id": 2539108069860, - "schedule_layers": null, - "schedule_name": "Open Source Q&A", - "status": 0, - "team_id": 2477033058131, - "update_at": 1710468081, - "update_by": 2476444212131 + "description": "The issue has been resolved, and all services are operating normally.", + "status": "resolved", + "update_id": "01KNJX3KW873ZZSRZC14SGFYS3" } ] }, @@ -56473,7 +57839,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleSelfResponse" + "$ref": "#/components/schemas/StatusPageChangeItem" } }, "type": "object" @@ -56497,45 +57863,144 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List my schedules", + "summary": "Get status page event detail", "tags": [ - "On-call/Schedules" + "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 | **Schedules Read** (`on-call`) or **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-self", + "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-change-info", "metadata": { - "sidebarTitle": "List my schedules" + "sidebarTitle": "Get status page event detail" } } } }, - "/schedule/update": { - "post": { - "description": "Update an existing on-call schedule. Provide schedule_id to identify the schedule.", - "operationId": "scheduleUpdate", - "requestBody": { - "content": { - "application/json": { - "example": { - "description": "Updated primary on-call rotation", - "schedule_id": 2001, - "schedule_name": "Production On-Call (Updated)", - "team_id": 4291079133131 - }, - "schema": { - "$ref": "#/components/schemas/ScheduleUpsertRequest" - } + "/status-page/change/list": { + "get": { + "description": "List status page events for console management. Unlike the public display endpoints, the response includes hidden components.", + "operationId": "statusPageChangeList", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" } }, - "required": true - }, + { + "description": "Lower bound of the event activity window: only events still open at, or closed at or after, this Unix timestamp (seconds) are returned.", + "in": "query", + "name": "start_at_seconds", + "required": false, + "schema": { + "format": "int64", + "type": "integer" + } + }, + { + "description": "Upper bound of the event activity window: only events started at or before this Unix timestamp (seconds) are returned.", + "in": "query", + "name": "end_at_seconds", + "required": false, + "schema": { + "format": "int64", + "type": "integer" + } + }, + { + "description": "Event type filter. Required.", + "in": "query", + "name": "type", + "required": true, + "schema": { + "enum": [ + "incident", + "maintenance" + ], + "type": "string" + } + }, + { + "description": "Event status filter. Required. Must be a status valid for the given `type` (`investigating`/`identified`/`monitoring`/`resolved` for `incident`; `scheduled`/`ongoing`/`completed` for `maintenance`).", + "in": "query", + "name": "status", + "required": true, + "schema": { + "enum": [ + "investigating", + "identified", + "monitoring", + "resolved", + "scheduled", + "ongoing", + "completed" + ], + "type": "string" + } + } + ], "responses": { "200": { "content": { "application/json": { "example": { - "data": {}, + "data": { + "items": [ + { + "affected_components": [ + { + "available_since_seconds": 1765349358, + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "name": "Web Console", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", + "status": "operational" + } + ], + "change_id": 5821693893131, + "close_at_seconds": 1775529742, + "description": "The issue has been resolved, and all services are operating normally.", + "notify_subscribers": true, + "page_id": 5750613685214, + "start_at_seconds": 1766736878, + "status": "resolved", + "title": "Web Console Degraded Performance", + "type": "incident", + "updates": [ + { + "at_seconds": 1766736876, + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "component_name": "Web Console", + "status": "degraded" + } + ], + "description": "We are currently investigating an issue affecting some services.", + "status": "investigating", + "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" + }, + { + "at_seconds": 1775529742, + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "component_name": "Web Console", + "status": "operational" + } + ], + "description": "The issue has been resolved, and all services are operating normally.", + "status": "resolved", + "update_id": "01KNJX3KW873ZZSRZC14SGFYS3" + } + ] + } + ] + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -56546,7 +58011,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ScheduleEmptyObject" + "$ref": "#/components/schemas/StatusPageChangeListResponse" } }, "type": "object" @@ -56570,38 +58035,41 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Update schedule", + "summary": "List status page events", "tags": [ - "On-call/Schedules" + "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 | **Schedules Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/schedules/schedule-update", + "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-change-list", "metadata": { - "sidebarTitle": "Update schedule" + "sidebarTitle": "List status page events" } } } }, - "/sourcemap/list": { + "/status-page/change/timeline/create": { "post": { - "description": "Return a paginated list of uploaded sourcemap files filtered by platform type, service, and version.", - "operationId": "sourcemap-read-list", + "description": "Add a timeline update to a status page event.", + "operationId": "statusPageChangeTimelineCreate", "requestBody": { "content": { "application/json": { "example": { - "end_time": 1712700000000, - "limit": 20, - "p": 1, - "services": [ - "my-web-app" + "at_seconds": 1712003600, + "change_id": 5821693893131, + "component_changes": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "status": "partial_outage" + } ], - "start_time": 1712000000000, - "type": "browser" + "description": "We have identified the root cause and are working on a fix.", + "page_id": 5750613685214, + "status": "identified" }, "schema": { - "$ref": "#/components/schemas/SourcemapListRequest" + "$ref": "#/components/schemas/CreateStatusPageChangeTimelineRequest" } } }, @@ -56613,21 +58081,7 @@ "application/json": { "example": { "data": { - "items": [ - { - "created_at": 1712700000, - "git_commit_sha": "abc1234def5678", - "git_repository_url": "https://github.com/example/my-web-app", - "key": "browser/my-web-app/1.0.0/main.js.map", - "metadata": {}, - "service": "my-web-app", - "size": 204800, - "type": "browser", - "updated_at": 1712700000, - "version": "1.0.0" - } - ], - "total": 3 + "update_id": "01KP0311872NVYFRRQ82FWXAP4" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -56639,7 +58093,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/SourcemapListResponse" + "$ref": "#/components/schemas/StatusPageChangeTimelineCreateResponse" } }, "type": "object" @@ -56663,35 +58117,33 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List sourcemaps", + "summary": "Create event timeline entry", "tags": [ - "RUM/Sourcemaps" + "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 |\n\n## Usage\n\n- `start_time` and `end_time` are required — both use Unix epoch **milliseconds**. Maximum window is 365 days.\n- The `type` field selects the platform: `browser` (JavaScript), `android`, or `ios`. Defaults to `browser` when omitted.\n- Default page size is 20; maximum is 100. Default sort is `created_at` descending.\n- For Android, `build_id` matches the Gradle plugin build identifier. For iOS, `uuid` matches the dSYM bundle UUID.", - "href": "/en/api-reference/rum/sourcemaps/sourcemap-read-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Events Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-create", "metadata": { - "sidebarTitle": "List sourcemaps" + "sidebarTitle": "Create event timeline entry" } } } }, - "/sourcemap/stack/enrich": { + "/status-page/change/timeline/delete": { "post": { - "description": "Symbolicate or deobfuscate a browser, Android, iOS, Mini Program, or HarmonyOS stack trace.", - "operationId": "sourcemap-read-stack-enrich", + "description": "Delete a timeline entry from a status page event.", + "operationId": "statusPageChangeTimelineDelete", "requestBody": { "content": { "application/json": { "example": { - "near": 3, - "service": "my-web-app", - "stack": "TypeError: Cannot read properties of undefined\n at render (https://cdn.example.com/app.min.js:1:2345)", - "type": "browser", - "version": "1.0.0" + "change_id": 5821693893131, + "page_id": 5750613685214, + "update_id": "01KP0311872NVYFRRQ82FWXAP4" }, "schema": { - "$ref": "#/components/schemas/SourcemapStackEnrichRequest" + "$ref": "#/components/schemas/DeleteStatusPageChangeTimelineRequest" } } }, @@ -56702,33 +58154,7 @@ "content": { "application/json": { "example": { - "data": { - "frames": [ - { - "code_snippets": [ - { - "code": "const cart = props.cart;", - "line": 41 - }, - { - "code": "return cart.items.map(renderItem);", - "line": 42 - } - ], - "column": 17, - "converted": true, - "file": "src/pages/checkout.tsx", - "function": "renderCheckout", - "line": 42, - "original_frame": { - "column": 2345, - "file": "https://cdn.example.com/app.min.js", - "function": "render", - "line": 1 - } - } - ] - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -56739,7 +58165,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/SourcemapStackEnrichResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -56763,92 +58189,46 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Enrich a stack trace", + "summary": "Delete event timeline entry", "tags": [ - "RUM/Sourcemaps" + "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 |\n\n## Usage\n\n- `type` defaults to `browser` when omitted for backward compatibility.\n- Set `near` from 1 to 20 to include source-code snippets around converted frames.\n- For Android NDK native crashes, provide `arch` and `source_type: ndk` so the backend routes to native symbolication.\n- For iOS crash stacks, pass `binary_images` so addresses can be relocated against the uploaded dSYM files.\n- `no_cache` is intended for debugging and bypasses cached enrich results.", - "href": "/en/api-reference/rum/sourcemaps/sourcemap-read-stack-enrich", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Events Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-delete", "metadata": { - "sidebarTitle": "Enrich a stack trace" + "sidebarTitle": "Delete event timeline entry" } } } }, - "/status-page/change/active/list": { - "get": { - "description": "List in-progress (non-terminal) events of a given type for a status page.", - "operationId": "statusPageChangeActiveList", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" + "/status-page/change/timeline/update": { + "post": { + "description": "Update a timeline entry for a status page event.", + "operationId": "statusPageChangeTimelineUpdate", + "requestBody": { + "content": { + "application/json": { + "example": { + "at_seconds": 1712003600, + "change_id": 5821693893131, + "description": "Corrected description: root cause identified in database layer.", + "page_id": 5750613685214, + "update_id": "01KP0311872NVYFRRQ82FWXAP4" + }, + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageChangeTimelineRequest" + } } }, - { - "description": "Event type filter. Required. Returns only in-progress (non-terminal) events — `investigating`/`identified`/`monitoring` for `incident`, `scheduled`/`ongoing` for `maintenance`.", - "in": "query", - "name": "type", - "required": true, - "schema": { - "enum": [ - "incident", - "maintenance" - ], - "type": "string" - } - } - ], + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { - "data": { - "items": [ - { - "affected_components": [ - { - "available_since_seconds": 1765349358, - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "name": "Web Console", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", - "status": "degraded" - } - ], - "change_id": 5821693893131, - "description": "We are currently investigating an issue affecting some services.", - "notify_subscribers": true, - "page_id": 5750613685214, - "start_at_seconds": 1766736878, - "status": "investigating", - "title": "Web Console Degraded Performance", - "type": "incident", - "updates": [ - { - "at_seconds": 1766736876, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "component_name": "Web Console", - "status": "degraded" - } - ], - "description": "We are currently investigating an issue affecting some services.", - "status": "investigating", - "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" - } - ] - } - ] - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -56859,7 +58239,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageChangeListResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -56883,49 +58263,33 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List active status page events", + "summary": "Update event timeline entry", "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-change-active-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Status Pages Events Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-update", "metadata": { - "sidebarTitle": "List active status page events" + "sidebarTitle": "Update event timeline entry" } } } }, - "/status-page/change/create": { + "/status-page/change/update": { "post": { - "description": "Create a new incident or maintenance event on a status page.", - "operationId": "statusPageChangeCreate", + "description": "Update an existing status page event.", + "operationId": "statusPageChangeUpdate", "requestBody": { "content": { "application/json": { "example": { - "description": "We are investigating degraded performance affecting the web console.", - "notify_subscribers": true, + "change_id": 5821693893131, "page_id": 5750613685214, - "start_at_seconds": 1712000000, - "status": "investigating", - "title": "Web Console Degraded Performance", - "type": "incident", - "updates": [ - { - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "status": "degraded" - } - ], - "description": "We are currently investigating an issue affecting some users.", - "status": "investigating" - } - ] + "title": "Web Console Degraded Performance (Updated)" }, "schema": { - "$ref": "#/components/schemas/CreateStatusPageChangeRequest" + "$ref": "#/components/schemas/UpdateStatusPageChangeRequest" } } }, @@ -56936,10 +58300,7 @@ "content": { "application/json": { "example": { - "data": { - "change_id": 6294539747131, - "change_name": "API Test Incident" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -56950,7 +58311,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageChangeCreateResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -56974,32 +58335,34 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Create status page event", + "summary": "Update status page event", "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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-create", + "href": "/en/api-reference/on-call/status-pages/status-page-change-update", "metadata": { - "sidebarTitle": "Create status page event" + "sidebarTitle": "Update status page event" } } } }, - "/status-page/change/delete": { + "/status-page/component/delete": { "post": { - "description": "Delete a status page event.", - "operationId": "statusPageChangeDelete", + "description": "Delete a service component from a status page.", + "operationId": "statusPageComponentDelete", "requestBody": { "content": { "application/json": { "example": { - "change_id": 5821693893131, + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" + ], "page_id": 5750613685214 }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageChangeRequest" + "$ref": "#/components/schemas/DeleteStatusPageComponentRequest" } } }, @@ -57045,97 +58408,52 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete status page event", + "summary": "Delete status page component", "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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-delete", + "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 event" + "sidebarTitle": "Delete status page component" } } } }, - "/status-page/change/info": { - "get": { - "description": "Retrieve details of a specific status page event (incident or maintenance).", - "operationId": "statusPageChangeInfo", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" + "/status-page/component/upsert": { + "post": { + "description": "Create or update a service component on a status page.", + "operationId": "statusPageComponentUpsert", + "requestBody": { + "content": { + "application/json": { + "example": { + "components": [ + { + "description": "Main web interface", + "name": "Web Console", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" + } + ], + "page_id": 5750613685214 + }, + "schema": { + "$ref": "#/components/schemas/UpsertStatusPageComponentRequest" + } } }, - { - "description": "Event (change) ID.", - "in": "query", - "name": "change_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" - } - } - ], + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { "data": { - "affected_components": [ - { - "available_since_seconds": 1765349358, - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "name": "Web Console", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", - "status": "operational" - } - ], - "change_id": 5821693893131, - "close_at_seconds": 1775529742, - "description": "The issue has been resolved, and all services are operating normally.\n\nThank you for your patience.", - "notify_subscribers": true, - "page_id": 5750613685214, - "start_at_seconds": 1766736878, - "status": "resolved", - "title": "Web Console Degraded Performance", - "type": "incident", - "updates": [ - { - "at_seconds": 1766736876, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "component_name": "Web Console", - "status": "degraded" - } - ], - "description": "We are currently investigating an issue affecting some services.", - "status": "investigating", - "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" - }, - { - "at_seconds": 1775529742, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "component_name": "Web Console", - "status": "operational" - } - ], - "description": "The issue has been resolved, and all services are operating normally.", - "status": "resolved", - "update_id": "01KNJX3KW873ZZSRZC14SGFYS3" - } + "component_ids": [ + "01KP032KMN9YFBMPWANJMFZFG1" ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" @@ -57148,7 +58466,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageChangeItem" + "$ref": "#/components/schemas/UpsertStatusPageComponentResponse" } }, "type": "object" @@ -57172,143 +58490,49 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get status page event detail", + "summary": "Upsert status page component", "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-change-info", + "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": "Get status page event detail" + "sidebarTitle": "Upsert status page component" } } } }, - "/status-page/change/list": { - "get": { - "description": "List status page events for console management. Unlike the public display endpoints, the response includes hidden components.", - "operationId": "statusPageChangeList", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" - } - }, - { - "description": "Lower bound of the event activity window: only events still open at, or closed at or after, this Unix timestamp (seconds) are returned.", - "in": "query", - "name": "start_at_seconds", - "required": false, - "schema": { - "format": "int64", - "type": "integer" - } - }, - { - "description": "Upper bound of the event activity window: only events started at or before this Unix timestamp (seconds) are returned.", - "in": "query", - "name": "end_at_seconds", - "required": false, - "schema": { - "format": "int64", - "type": "integer" - } - }, - { - "description": "Event type filter. Required.", - "in": "query", - "name": "type", - "required": true, - "schema": { - "enum": [ - "incident", - "maintenance" - ], - "type": "string" - } - }, - { - "description": "Event status filter. Required. Must be a status valid for the given `type` (`investigating`/`identified`/`monitoring`/`resolved` for `incident`; `scheduled`/`ongoing`/`completed` for `maintenance`).", - "in": "query", - "name": "status", - "required": true, - "schema": { - "enum": [ - "investigating", - "identified", - "monitoring", - "resolved", - "scheduled", - "ongoing", - "completed" - ], - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "example": { - "data": { - "items": [ - { - "affected_components": [ - { - "available_since_seconds": 1765349358, - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "name": "Web Console", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2", - "status": "operational" - } - ], - "change_id": 5821693893131, - "close_at_seconds": 1775529742, - "description": "The issue has been resolved, and all services are operating normally.", - "notify_subscribers": true, - "page_id": 5750613685214, - "start_at_seconds": 1766736878, - "status": "resolved", - "title": "Web Console Degraded Performance", - "type": "incident", - "updates": [ - { - "at_seconds": 1766736876, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "component_name": "Web Console", - "status": "degraded" - } - ], - "description": "We are currently investigating an issue affecting some services.", - "status": "investigating", - "update_id": "01KDCVJQ88SZPHWPTDV2Z2AZW8" - }, - { - "at_seconds": 1775529742, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "component_name": "Web Console", - "status": "operational" - } - ], - "description": "The issue has been resolved, and all services are operating normally.", - "status": "resolved", - "update_id": "01KNJX3KW873ZZSRZC14SGFYS3" - } - ] - } - ] + "/status-page/create": { + "post": { + "description": "Create a new status page.", + "operationId": "statusPageCreate", + "requestBody": { + "content": { + "application/json": { + "example": { + "contact_info": "mailto:support@example.com", + "name": "My Status Page", + "page_header": "Welcome to our status page", + "type": "public", + "url_name": "my-status-page" + }, + "schema": { + "$ref": "#/components/schemas/CreateStatusPageRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "page_id": 6294565612043, + "page_name": "My Status Page", + "page_url_name": "my-status-page" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -57320,7 +58544,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageChangeListResponse" + "$ref": "#/components/schemas/CreateStatusPageResponse" } }, "type": "object" @@ -57344,41 +58568,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List status page events", + "summary": "Create 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-change-list", + "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": "List status page events" + "sidebarTitle": "Create status page" } } } }, - "/status-page/change/timeline/create": { + "/status-page/delete": { "post": { - "description": "Add a timeline update to a status page event.", - "operationId": "statusPageChangeTimelineCreate", + "description": "Delete a status page.", + "operationId": "statusPageDelete", "requestBody": { "content": { "application/json": { "example": { - "at_seconds": 1712003600, - "change_id": 5821693893131, - "component_changes": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "status": "partial_outage" - } - ], - "description": "We have identified the root cause and are working on a fix.", - "page_id": 5750613685214, - "status": "identified" + "page_id": 5750613685214 }, "schema": { - "$ref": "#/components/schemas/CreateStatusPageChangeTimelineRequest" + "$ref": "#/components/schemas/DeleteStatusPageRequest" } } }, @@ -57389,9 +58603,7 @@ "content": { "application/json": { "example": { - "data": { - "update_id": "01KP0311872NVYFRRQ82FWXAP4" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57402,7 +58614,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageChangeTimelineCreateResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -57426,33 +58638,44 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Create event timeline entry", + "summary": "Delete 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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-create", + "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": "Create event timeline entry" + "sidebarTitle": "Delete status page" } } } }, - "/status-page/change/timeline/delete": { + "/status-page/draft/create": { "post": { - "description": "Delete a timeline entry from a status page event.", - "operationId": "statusPageChangeTimelineDelete", + "description": "Store a status page event draft so a human can review and publish it from the console.", + "operationId": "statusPageDraftCreate", "requestBody": { "content": { "application/json": { "example": { - "change_id": 5821693893131, - "page_id": 5750613685214, - "update_id": "01KP0311872NVYFRRQ82FWXAP4" + "draft": { + "affected_components": [ + { + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "status": "degraded" + } + ], + "message": "We are investigating degraded performance affecting the web console.", + "name": "Web Console Degraded Performance", + "page_id": 5750613685214, + "type": "incident", + "v": 1 + }, + "source": "ai_sre:sess_01KC3H2A9ZQ8W7E6R5T4Y3U2I1" }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageChangeTimelineRequest" + "$ref": "#/components/schemas/CreateStatusPageDraftRequest" } } }, @@ -57463,7 +58686,226 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "created_at": 1788000000, + "draft_id": "draft_3xK9mQ2vN7pR4wT8yH1sJ5" + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/StatusPageDraftCreateResponse" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "Create status page draft", + "tags": [ + "On-call/Status pages" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- The `draft` payload is stored verbatim (up to 64 KB); the console publish form reads it back to prefill the event.\n- A draft lives for 30 days and is consumed exactly once when the event is published.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/status-pages/status-page-draft-create", + "metadata": { + "sidebarTitle": "Create status page draft" + } + } + } + }, + "/status-page/info": { + "get": { + "description": "Retrieve detailed configuration for a specific status page.", + "operationId": "statusPageInfo", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "components": [ + { + "available_since_seconds": 1765349358, + "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", + "name": "Web Console", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" + } + ], + "contact_info": "mailto:support@example.com", + "custom_domain": "status.example.com", + "custom_links": [ + { + "key": "Documentation", + "value": "https://docs.example.com" + } + ], + "date_view": "list", + "display_uptime_mode": "chart_and_percentage", + "favicon": "https://cdn.example.com/favicon.png", + "logo": "https://cdn.example.com/logo.png", + "managed_domain_feature_enabled": true, + "name": "Flashduty Status Page", + "page_footer": "2025 Example Corp", + "page_header": "Welcome to our status page", + "page_id": 5750613685214, + "sections": [ + { + "description": "Our core services", + "hide_all": false, + "hide_uptime": false, + "name": "Core Services", + "order_id": 1, + "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" + } + ], + "subscription": { + "email": true, + "im": false + }, + "template_preference": "message", + "type": "public", + "url_name": "flashduty-statuspage" + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/StatusPageInfoResponse" + } + }, + "type": "object" + } + ] + } + } + }, + "description": "Success" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" + } + }, + "summary": "Get status page detail", + "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" + } + } + } + }, + "/status-page/list": { + "get": { + "description": "List all status pages owned by the account, including their components and sections.", + "operationId": "status-page-read-page-list", + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "items": [ + { + "components": [ + { + "available_since_seconds": 1716962400, + "component_id": "cmp_001", + "description": "Core API service", + "hide_all": false, + "hide_uptime": false, + "name": "API", + "order_id": 1, + "section_id": "sec_001" + } + ], + "contact_info": "mailto:support@acme.com", + "custom_domain": "status.acme.com", + "custom_links": [ + { + "name": "Home", + "url": "https://acme.com" + } + ], + "date_view": "calendar", + "display_uptime_mode": "chart_and_percentage", + "logo_url": "https://acme.com", + "name": "Acme Status", + "page_header": "Acme System Status", + "page_id": 7001, + "sections": [ + { + "hide_all": false, + "hide_uptime": false, + "name": "Core Services", + "order_id": 1, + "section_id": "sec_001" + } + ], + "subscription": { + "email": true, + "im": false + }, + "type": "public", + "url_name": "acme" + } + ] + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57474,7 +58916,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/ListStatusPageResponse" } }, "type": "object" @@ -57498,35 +58940,33 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete event timeline entry", + "summary": "List status pages", "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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-delete", + "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 |\n", + "href": "/en/api-reference/on-call/status-pages/status-page-read-page-list", "metadata": { - "sidebarTitle": "Delete event timeline entry" + "sidebarTitle": "List status pages" } } } }, - "/status-page/change/timeline/update": { + "/status-page/migrate-email-subscribers": { "post": { - "description": "Update a timeline entry for a status page event.", - "operationId": "statusPageChangeTimelineUpdate", + "description": "Start a migration job that imports email subscribers from an Atlassian Statuspage into an existing Flashduty status page.", + "operationId": "statusPageMigrateEmailSubscribers", "requestBody": { "content": { "application/json": { "example": { - "at_seconds": 1712003600, - "change_id": 5821693893131, - "description": "Corrected description: root cause identified in database layer.", - "page_id": 5750613685214, - "update_id": "01KP0311872NVYFRRQ82FWXAP4" + "api_key": "sk-stsp-xxxxxxxxxxxxxxxxxxxx", + "source_page_id": "abcdefghij", + "target_page_id": 5750613685214 }, "schema": { - "$ref": "#/components/schemas/UpdateStatusPageChangeTimelineRequest" + "$ref": "#/components/schemas/MigrateStatusPageEmailSubscribersRequest" } } }, @@ -57537,7 +58977,9 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "job_id": "01KP0311872NVYFRRQ82FW0002" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57548,7 +58990,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/StatusPageMigrationStartResponse" } }, "type": "object" @@ -57572,33 +59014,32 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Update event timeline entry", + "summary": "Migrate email subscribers", "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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-timeline-update", + "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-migrate-email-subscribers", "metadata": { - "sidebarTitle": "Update event timeline entry" + "sidebarTitle": "Migrate email subscribers" } } } }, - "/status-page/change/update": { + "/status-page/migrate-structure": { "post": { - "description": "Update an existing status page event.", - "operationId": "statusPageChangeUpdate", + "description": "Start a migration job that imports the structure and historical events of an Atlassian Statuspage into a new Flashduty status page.", + "operationId": "statusPageMigrateStructure", "requestBody": { "content": { "application/json": { "example": { - "change_id": 5821693893131, - "page_id": 5750613685214, - "title": "Web Console Degraded Performance (Updated)" + "api_key": "sk-stsp-xxxxxxxxxxxxxxxxxxxx", + "source_page_id": "abcdefghij" }, "schema": { - "$ref": "#/components/schemas/UpdateStatusPageChangeRequest" + "$ref": "#/components/schemas/MigrateStatusPageStructureRequest" } } }, @@ -57609,7 +59050,9 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "job_id": "01KP0311872NVYFRRQ82FW0001" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57620,7 +59063,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/StatusPageMigrationStartResponse" } }, "type": "object" @@ -57644,34 +59087,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Update status page event", + "summary": "Migrate status page structure", "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 Events Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-change-update", + "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-migrate-structure", "metadata": { - "sidebarTitle": "Update status page event" + "sidebarTitle": "Migrate status page structure" } } } }, - "/status-page/component/delete": { + "/status-page/migration/cancel": { "post": { - "description": "Delete a service component from a status page.", - "operationId": "statusPageComponentDelete", + "description": "Cancel an in-progress status page migration job. Only jobs currently in the `running` state can be cancelled.", + "operationId": "statusPageMigrationCancel", "requestBody": { "content": { "application/json": { "example": { - "component_ids": [ - "01KP032KMN9YFBMPWANJMFZFG1" - ], - "page_id": 5750613685214 + "job_id": "01KP0311872NVYFRRQ82FW0001" }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageComponentRequest" + "$ref": "#/components/schemas/CancelStatusPageMigrationRequest" } } }, @@ -57717,53 +59157,59 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete status page component", + "summary": "Cancel status page migration", "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", + "href": "/en/api-reference/on-call/status-pages/status-page-migration-cancel", "metadata": { - "sidebarTitle": "Delete status page component" + "sidebarTitle": "Cancel status page migration" } } } }, - "/status-page/component/upsert": { - "post": { - "description": "Create or update a service component on a status page.", - "operationId": "statusPageComponentUpsert", - "requestBody": { - "content": { - "application/json": { - "example": { - "components": [ - { - "description": "Main web interface", - "name": "Web Console", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" - } - ], - "page_id": 5750613685214 - }, - "schema": { - "$ref": "#/components/schemas/UpsertStatusPageComponentRequest" - } + "/status-page/migration/status": { + "get": { + "description": "Get the current status and progress of a status page migration job.", + "operationId": "statusPageMigrationStatus", + "parameters": [ + { + "description": "Migration job ID returned by `migrate-structure` or `migrate-email-subscribers`.", + "in": "query", + "name": "job_id", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "content": { "application/json": { "example": { "data": { - "component_ids": [ - "01KP032KMN9YFBMPWANJMFZFG1" - ] + "account_id": 2451002751131, + "created_at": 1766736878, + "job_id": "01KP0311872NVYFRRQ82FW0001", + "phase": "history", + "progress": { + "completed_steps": 5, + "components_imported": 8, + "incidents_imported": 12, + "maintenances_imported": 2, + "sections_imported": 3, + "subscribers_imported": 0, + "subscribers_skipped": 0, + "templates_imported": 0, + "total_steps": 5 + }, + "source_page_id": "abcdefghij", + "status": "completed", + "target_page_id": 5750613685214, + "updated_at": 1766740000 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -57775,7 +59221,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/UpsertStatusPageComponentResponse" + "$ref": "#/components/schemas/StatusPageMigrationJob" } }, "type": "object" @@ -57799,35 +59245,34 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Upsert status page component", + "summary": "Get migration status", "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", + "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-migration-status", "metadata": { - "sidebarTitle": "Upsert status page component" + "sidebarTitle": "Get migration status" } } } }, - "/status-page/create": { + "/status-page/section/delete": { "post": { - "description": "Create a new status page.", - "operationId": "statusPageCreate", + "description": "Delete a section from a status page.", + "operationId": "statusPageSectionDelete", "requestBody": { "content": { "application/json": { "example": { - "contact_info": "mailto:support@example.com", - "name": "My Status Page", - "page_header": "Welcome to our status page", - "type": "public", - "url_name": "my-status-page" + "page_id": 5750613685214, + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] }, "schema": { - "$ref": "#/components/schemas/CreateStatusPageRequest" + "$ref": "#/components/schemas/DeleteStatusPageSectionRequest" } } }, @@ -57838,11 +59283,7 @@ "content": { "application/json": { "example": { - "data": { - "page_id": 6294565612043, - "page_name": "My Status Page", - "page_url_name": "my-status-page" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57853,7 +59294,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/CreateStatusPageResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -57877,31 +59318,38 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Create status page", + "summary": "Delete status page section", "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", + "href": "/en/api-reference/on-call/status-pages/status-page-section-delete", "metadata": { - "sidebarTitle": "Create status page" + "sidebarTitle": "Delete status page section" } } } }, - "/status-page/delete": { + "/status-page/section/upsert": { "post": { - "description": "Delete a status page.", - "operationId": "statusPageDelete", + "description": "Create or update a section on a status page.", + "operationId": "statusPageSectionUpsert", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5750613685214 + "page_id": 5750613685214, + "sections": [ + { + "description": "Our core services", + "name": "Core Services", + "order_id": 1 + } + ] }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageRequest" + "$ref": "#/components/schemas/UpsertStatusPageSectionRequest" } } }, @@ -57912,7 +59360,11 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "section_ids": [ + "01KP032J1FV2H8DDGN0QSJ1CAR" + ] + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -57923,7 +59375,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/UpsertStatusPageSectionResponse" } }, "type": "object" @@ -57947,44 +59399,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete status page", + "summary": "Upsert status page section", "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", + "href": "/en/api-reference/on-call/status-pages/status-page-section-upsert", "metadata": { - "sidebarTitle": "Delete status page" + "sidebarTitle": "Upsert status page section" } } } }, - "/status-page/draft/create": { + "/status-page/subscriber/export": { "post": { - "description": "Store a status page event draft so a human can review and publish it from the console.", - "operationId": "statusPageDraftCreate", + "description": "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.", + "operationId": "statusPageSubscriberExport", "requestBody": { "content": { "application/json": { "example": { - "draft": { - "affected_components": [ - { - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "status": "degraded" - } - ], - "message": "We are investigating degraded performance affecting the web console.", - "name": "Web Console Degraded Performance", - "page_id": 5750613685214, - "type": "incident", - "v": 1 - }, - "source": "ai_sre:sess_01KC3H2A9ZQ8W7E6R5T4Y3U2I1" + "page_id": 5750613685214 }, "schema": { - "$ref": "#/components/schemas/CreateStatusPageDraftRequest" + "$ref": "#/components/schemas/ExportStatusPageSubscribersRequest" } } }, @@ -57993,32 +59432,14 @@ "responses": { "200": { "content": { - "application/json": { - "example": { - "data": { - "created_at": 1788000000, - "draft_id": "draft_3xK9mQ2vN7pR4wT8yH1sJ5" - }, - "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" - }, + "text/csv": { + "example": "Method,Recipient,Components,Subscribe All,Locale\nemail,alice@example.com,,Yes,zh-CN\nemail,bob@example.com,\"Core Services › API\",No,en-US", "schema": { - "allOf": [ - { - "$ref": "#/components/schemas/SuccessEnvelope" - }, - { - "properties": { - "data": { - "$ref": "#/components/schemas/StatusPageDraftCreateResponse" - } - }, - "type": "object" - } - ] + "$ref": "#/components/schemas/StatusPageSubscriberExportResponse" } } }, - "description": "Success" + "description": "Success. CSV attachment, not a JSON envelope." }, "400": { "$ref": "#/components/responses/BadRequest" @@ -58033,85 +59454,58 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Create status page draft", + "summary": "Export subscribers", "tags": [ "On-call/Status pages" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- The `draft` payload is stored verbatim (up to 64 KB); the console publish form reads it back to prefill the event.\n- A draft lives for 30 days and is consumed exactly once when the event is published.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", - "href": "/en/api-reference/on-call/status-pages/status-page-draft-create", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **100 requests/day**; **20 requests/minute**; **10 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-subscriber-export", "metadata": { - "sidebarTitle": "Create status page draft" + "sidebarTitle": "Export subscribers" } } } }, - "/status-page/info": { - "get": { - "description": "Retrieve detailed configuration for a specific status page.", - "operationId": "statusPageInfo", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" + "/status-page/subscriber/import": { + "post": { + "description": "Bulk import subscribers for a status page. The account must be allowlisted for subscriber import; otherwise the call is rejected with an access-denied error.", + "operationId": "statusPageSubscriberImport", + "requestBody": { + "content": { + "application/json": { + "example": { + "method": "email", + "page_id": 5750613685214, + "subscribers": [ + { + "all": true, + "locale": "en-US", + "recipient": "alice@example.com" + }, + { + "all": false, + "component_ids": [ + "01KC3GAZ6ZJE40H55GM31RPWZE" + ], + "locale": "zh-CN", + "recipient": "bob@example.com" + } + ] + }, + "schema": { + "$ref": "#/components/schemas/ImportStatusPageSubscribersRequest" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { - "data": { - "components": [ - { - "available_since_seconds": 1765349358, - "component_id": "01KC3GAZ6ZJE40H55GM31RPWZE", - "name": "Web Console", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" - } - ], - "contact_info": "mailto:support@example.com", - "custom_domain": "status.example.com", - "custom_links": [ - { - "key": "Documentation", - "value": "https://docs.example.com" - } - ], - "date_view": "list", - "display_uptime_mode": "chart_and_percentage", - "favicon": "https://cdn.example.com/favicon.png", - "logo": "https://cdn.example.com/logo.png", - "managed_domain_feature_enabled": true, - "name": "Flashduty Status Page", - "page_footer": "2025 Example Corp", - "page_header": "Welcome to our status page", - "page_id": 5750613685214, - "sections": [ - { - "description": "Our core services", - "hide_all": false, - "hide_uptime": false, - "name": "Core Services", - "order_id": 1, - "section_id": "01KC3FKKX5TSVG6Z3X1QNGF6V2" - } - ], - "subscription": { - "email": true, - "im": false - }, - "template_preference": "message", - "type": "public", - "url_name": "flashduty-statuspage" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -58122,7 +59516,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageInfoResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -58146,74 +59540,93 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get status page detail", + "summary": "Import subscribers", "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **20 requests/minute**; **2 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", + "href": "/en/api-reference/on-call/status-pages/status-page-subscriber-import", "metadata": { - "sidebarTitle": "Get status page detail" + "sidebarTitle": "Import subscribers" } } } }, - "/status-page/list": { + "/status-page/subscriber/list": { "get": { - "description": "List all status pages owned by the account, including their components and sections.", - "operationId": "status-page-read-page-list", - "responses": { - "200": { - "content": { - "application/json": { - "example": { - "data": { - "items": [ - { - "components": [ - { - "available_since_seconds": 1716962400, - "component_id": "cmp_001", - "description": "Core API service", - "hide_all": false, - "hide_uptime": false, - "name": "API", - "order_id": 1, - "section_id": "sec_001" - } - ], - "contact_info": "mailto:support@acme.com", - "custom_domain": "status.acme.com", - "custom_links": [ - { - "name": "Home", - "url": "https://acme.com" - } - ], - "date_view": "calendar", - "display_uptime_mode": "chart_and_percentage", - "logo_url": "https://acme.com", - "name": "Acme Status", - "page_header": "Acme System Status", - "page_id": 7001, - "sections": [ - { - "hide_all": false, - "hide_uptime": false, - "name": "Core Services", - "order_id": 1, - "section_id": "sec_001" - } - ], - "subscription": { - "email": true, - "im": false - }, - "type": "public", - "url_name": "acme" + "description": "List subscribers who have signed up for status page notifications.", + "operationId": "statusPageSubscriberList", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" + } + }, + { + "description": "Comma-separated component IDs to filter subscribers by.", + "in": "query", + "name": "component_ids", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Page number (1-based).", + "in": "query", + "name": "p", + "required": false, + "schema": { + "default": 1, + "format": "int64", + "minimum": 1, + "type": "integer" + } + }, + { + "description": "Page size (1-100).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 10, + "format": "int64", + "maximum": 100, + "minimum": 1, + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "example": { + "data": { + "has_next_page": false, + "items": [ + { + "all": true, + "components": [], + "locale": "zh-CN", + "method": "email", + "recipient": "alice@example.com" + }, + { + "all": true, + "components": [], + "locale": "en-US", + "method": "email", + "recipient": "bob@example.com" } - ] + ], + "total": 2 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -58225,7 +59638,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ListStatusPageResponse" + "$ref": "#/components/schemas/StatusPageSubscriberListResponse" } }, "type": "object" @@ -58249,33 +59662,33 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List status pages", + "summary": "List status page subscribers", "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 |\n", - "href": "/en/api-reference/on-call/status-pages/status-page-read-page-list", + "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-subscriber-list", "metadata": { - "sidebarTitle": "List status pages" + "sidebarTitle": "List status page subscribers" } } } }, - "/status-page/migrate-email-subscribers": { + "/status-page/template/delete": { "post": { - "description": "Start a migration job that imports email subscribers from an Atlassian Statuspage into an existing Flashduty status page.", - "operationId": "statusPageMigrateEmailSubscribers", + "description": "Delete an event template from a status page.", + "operationId": "statusPageTemplateDelete", "requestBody": { "content": { "application/json": { "example": { - "api_key": "sk-stsp-xxxxxxxxxxxxxxxxxxxx", - "source_page_id": "abcdefghij", - "target_page_id": 5750613685214 + "page_id": 5720156736380, + "template_id": "01KP0339G5XDEPM4R86T2B23EP", + "type": "pre_defined" }, "schema": { - "$ref": "#/components/schemas/MigrateStatusPageEmailSubscribersRequest" + "$ref": "#/components/schemas/DeleteStatusPageTemplateRequest" } } }, @@ -58286,9 +59699,7 @@ "content": { "application/json": { "example": { - "data": { - "job_id": "01KP0311872NVYFRRQ82FW0002" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -58299,7 +59710,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageMigrationStartResponse" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -58323,44 +59734,63 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Migrate email subscribers", + "summary": "Delete status page template", "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-migrate-email-subscribers", + "href": "/en/api-reference/on-call/status-pages/status-page-template-delete", "metadata": { - "sidebarTitle": "Migrate email subscribers" + "sidebarTitle": "Delete status page template" } } } }, - "/status-page/migrate-structure": { - "post": { - "description": "Start a migration job that imports the structure and historical events of an Atlassian Statuspage into a new Flashduty status page.", - "operationId": "statusPageMigrateStructure", - "requestBody": { - "content": { - "application/json": { - "example": { - "api_key": "sk-stsp-xxxxxxxxxxxxxxxxxxxx", - "source_page_id": "abcdefghij" - }, - "schema": { - "$ref": "#/components/schemas/MigrateStatusPageStructureRequest" - } + "/status-page/template/list": { + "get": { + "description": "List all event templates for a status page.", + "operationId": "statusPageTemplateList", + "parameters": [ + { + "description": "Status page ID.", + "in": "query", + "name": "page_id", + "required": true, + "schema": { + "format": "int64", + "type": "integer" } }, - "required": true - }, + { + "description": "Template category. `pre_defined` returns predefined event templates; `message` returns message notification templates.", + "in": "query", + "name": "type", + "required": true, + "schema": { + "enum": [ + "pre_defined", + "message" + ], + "type": "string" + } + } + ], "responses": { "200": { "content": { "application/json": { "example": { "data": { - "job_id": "01KP0311872NVYFRRQ82FW0001" + "items": [ + { + "description": "We have identified the root cause.", + "status": "identified", + "template_id": "01KC8KP6PHVPSCAB0BTKZBN2HR", + "title": "Service Disruption", + "type": "incident" + } + ] }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -58372,7 +59802,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageMigrationStartResponse" + "$ref": "#/components/schemas/ListStatusPageTemplatesResponse" } }, "type": "object" @@ -58396,31 +59826,38 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Migrate status page structure", + "summary": "List status page templates", "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-migrate-structure", + "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": "Migrate status page structure" + "sidebarTitle": "List status page templates" } } } }, - "/status-page/migration/cancel": { + "/status-page/template/upsert": { "post": { - "description": "Cancel an in-progress status page migration job. Only jobs currently in the `running` state can be cancelled.", - "operationId": "statusPageMigrationCancel", + "description": "Create or update an event template for a status page.", + "operationId": "statusPageTemplateUpsert", "requestBody": { "content": { "application/json": { "example": { - "job_id": "01KP0311872NVYFRRQ82FW0001" + "page_id": 5720156736380, + "template": { + "description": "We are investigating a service disruption affecting some users.", + "status": "investigating", + "title": "Service Disruption", + "type": "incident" + }, + "type": "pre_defined" }, "schema": { - "$ref": "#/components/schemas/CancelStatusPageMigrationRequest" + "$ref": "#/components/schemas/UpsertStatusPageTemplateRequest" } } }, @@ -58431,7 +59868,9 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "template_id": "01KP0339G5XDEPM4R86T2B23EP" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -58442,7 +59881,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/UpsertStatusPageTemplateResponse" } }, "type": "object" @@ -58466,60 +59905,45 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Cancel status page migration", + "summary": "Upsert status page template", "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-migration-cancel", + "href": "/en/api-reference/on-call/status-pages/status-page-template-upsert", "metadata": { - "sidebarTitle": "Cancel status page migration" + "sidebarTitle": "Upsert status page template" } } } }, - "/status-page/migration/status": { - "get": { - "description": "Get the current status and progress of a status page migration job.", - "operationId": "statusPageMigrationStatus", - "parameters": [ - { - "description": "Migration job ID returned by `migrate-structure` or `migrate-email-subscribers`.", - "in": "query", - "name": "job_id", - "required": true, - "schema": { - "type": "string" + "/status-page/update": { + "post": { + "description": "Update an existing status page configuration.", + "operationId": "statusPageUpdate", + "requestBody": { + "content": { + "application/json": { + "example": { + "contact_info": "mailto:support@example.com", + "name": "Flashduty Status Page (Updated)", + "page_header": "Updated status page header", + "page_id": 5750613685214 + }, + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageRequest" + } } - } - ], + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { - "data": { - "account_id": 2451002751131, - "created_at": 1766736878, - "job_id": "01KP0311872NVYFRRQ82FW0001", - "phase": "history", - "progress": { - "completed_steps": 5, - "components_imported": 8, - "incidents_imported": 12, - "maintenances_imported": 2, - "sections_imported": 3, - "subscribers_imported": 0, - "subscribers_skipped": 0, - "templates_imported": 0, - "total_steps": 5 - }, - "source_page_id": "abcdefghij", - "status": "completed", - "target_page_id": 5750613685214, - "updated_at": 1766740000 - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -58530,7 +59954,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageMigrationJob" + "$ref": "#/components/schemas/EmptyResponse" } }, "type": "object" @@ -58554,34 +59978,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get migration status", + "summary": "Update 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-migration-status", + "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": "Get migration status" + "sidebarTitle": "Update status page" } } } }, - "/status-page/section/delete": { + "/team/delete": { "post": { - "description": "Delete a section from a status page.", - "operationId": "statusPageSectionDelete", + "description": "Permanently delete a team by ID, name, or external reference ID.", + "operationId": "team-write-delete", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5750613685214, - "section_ids": [ - "01KP032J1FV2H8DDGN0QSJ1CAR" - ] + "team_id": 1001 }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageSectionRequest" + "$ref": "#/components/schemas/TeamDeleteRequest" } } }, @@ -58603,7 +60024,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/PlatformEmptyObject" } }, "type": "object" @@ -58620,6 +60041,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -58627,38 +60051,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete status page section", + "summary": "Delete a team", "tags": [ - "On-call/Status pages" + "Platform/Teams" ], "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Teams Manage** (`organization`) |\n\n## Usage\n\n- At least one of `team_id`, `team_name`, or `ref_id` must be provided.\n- Fails with `400 ReferenceExist` if the team is still referenced by schedules, escalation rules, or other resources.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/platform/teams/team-write-delete", "metadata": { - "sidebarTitle": "Delete status page section" + "sidebarTitle": "Delete a team" } } } }, - "/status-page/section/upsert": { + "/team/info": { "post": { - "description": "Create or update a section on a status page.", - "operationId": "statusPageSectionUpsert", + "description": "Return a single team by ID, name, or external reference ID.", + "operationId": "team-read-info", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5750613685214, - "sections": [ - { - "description": "Our core services", - "name": "Core Services", - "order_id": 1 - } - ] + "team_id": 1001 }, "schema": { - "$ref": "#/components/schemas/UpsertStatusPageSectionRequest" + "$ref": "#/components/schemas/TeamInfoRequest" } } }, @@ -58670,9 +60087,22 @@ "application/json": { "example": { "data": { - "section_ids": [ - "01KP032J1FV2H8DDGN0QSJ1CAR" - ] + "account_id": 10023, + "created_at": 1710000000, + "creator_id": 80011, + "creator_name": "alice", + "description": "Backend reliability engineering team", + "person_ids": [ + 80011, + 80012 + ], + "ref_id": "", + "status": "enabled", + "team_id": 1001, + "team_name": "Backend SRE", + "updated_at": 1712000000, + "updated_by": 80011, + "updated_by_name": "alice" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -58684,7 +60114,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/UpsertStatusPageSectionResponse" + "$ref": "#/components/schemas/TeamItem" } }, "type": "object" @@ -58708,31 +60138,34 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Upsert status page section", + "summary": "Get team detail", "tags": [ - "On-call/Status pages" + "Platform/Teams" ], "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", + "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 |\n\n## Usage\n\n- At least one of `team_id`, `team_name`, or `ref_id` must be provided.", + "href": "/en/api-reference/platform/teams/team-read-info", "metadata": { - "sidebarTitle": "Upsert status page section" + "sidebarTitle": "Get team detail" } } } }, - "/status-page/subscriber/export": { + "/team/infos": { "post": { - "description": "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.", - "operationId": "statusPageSubscriberExport", + "description": "Return basic info for multiple teams by their IDs in a single request.", + "operationId": "team-read-infos", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5750613685214 + "team_ids": [ + 1001, + 1002 + ] }, "schema": { - "$ref": "#/components/schemas/ExportStatusPageSubscribersRequest" + "$ref": "#/components/schemas/TeamInfosRequest" } } }, @@ -58741,14 +60174,47 @@ "responses": { "200": { "content": { - "text/csv": { - "example": "Method,Recipient,Components,Subscribe All,Locale\nemail,alice@example.com,,Yes,zh-CN\nemail,bob@example.com,\"Core Services › API\",No,en-US", + "application/json": { + "example": { + "data": { + "items": [ + { + "person_ids": [ + 80011, + 80012 + ], + "team_id": 1001, + "team_name": "Backend SRE" + }, + { + "person_ids": [ + 80013 + ], + "team_id": 1002, + "team_name": "Frontend" + } + ] + }, + "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" + }, "schema": { - "$ref": "#/components/schemas/StatusPageSubscriberExportResponse" + "allOf": [ + { + "$ref": "#/components/schemas/SuccessEnvelope" + }, + { + "properties": { + "data": { + "$ref": "#/components/schemas/TeamInfosResponse" + } + }, + "type": "object" + } + ] } } }, - "description": "Success. CSV attachment, not a JSON envelope." + "description": "Success" }, "400": { "$ref": "#/components/responses/BadRequest" @@ -58763,47 +60229,34 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Export subscribers", + "summary": "Batch get teams", "tags": [ - "On-call/Status pages" + "Platform/Teams" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **100 requests/day**; **20 requests/minute**; **10 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-subscriber-export", + "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 |\n\n## Usage\n\n- Duplicate IDs are deduplicated; IDs that match no team are ignored.", + "href": "/en/api-reference/platform/teams/team-read-infos", "metadata": { - "sidebarTitle": "Export subscribers" + "sidebarTitle": "Batch get teams" } } } }, - "/status-page/subscriber/import": { + "/team/list": { "post": { - "description": "Bulk import subscribers for a status page. The account must be allowlisted for subscriber import; otherwise the call is rejected with an access-denied error.", - "operationId": "statusPageSubscriberImport", + "description": "Return a paginated list of teams in the current account.", + "operationId": "team-read-list", "requestBody": { "content": { "application/json": { "example": { - "method": "email", - "page_id": 5750613685214, - "subscribers": [ - { - "all": true, - "locale": "en-US", - "recipient": "alice@example.com" - }, - { - "all": false, - "component_ids": [ - "01KC3GAZ6ZJE40H55GM31RPWZE" - ], - "locale": "zh-CN", - "recipient": "bob@example.com" - } - ] + "asc": false, + "limit": 20, + "orderby": "created_at", + "p": 1 }, "schema": { - "$ref": "#/components/schemas/ImportStatusPageSubscribersRequest" + "$ref": "#/components/schemas/TeamListRequest" } } }, @@ -58814,7 +60267,30 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "items": [ + { + "account_id": 10023, + "created_at": 1710000000, + "creator_id": 80011, + "creator_name": "alice", + "description": "", + "person_ids": [ + 80011 + ], + "ref_id": "", + "status": "enabled", + "team_id": 1001, + "team_name": "Backend SRE", + "updated_at": 1712000000, + "updated_by": 0, + "updated_by_name": "" + } + ], + "limit": 20, + "p": 1, + "total": 5 + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -58825,7 +60301,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/TeamListResponse" } }, "type": "object" @@ -58835,107 +60311,63 @@ } }, "description": "Success" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "429": { - "$ref": "#/components/responses/TooManyRequests" - }, - "500": { - "$ref": "#/components/responses/ServerError" - } - }, - "summary": "Import subscribers", - "tags": [ - "On-call/Status pages" - ], - "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **20 requests/minute**; **2 requests/second** per account |\n| Permissions | **Status Pages Manage** (`on-call`) |", - "href": "/en/api-reference/on-call/status-pages/status-page-subscriber-import", - "metadata": { - "sidebarTitle": "Import subscribers" - } - } - } - }, - "/status-page/subscriber/list": { - "get": { - "description": "List subscribers who have signed up for status page notifications.", - "operationId": "statusPageSubscriberList", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" - } - }, - { - "description": "Comma-separated component IDs to filter subscribers by.", - "in": "query", - "name": "component_ids", - "required": false, - "schema": { - "type": "string" - } - }, - { - "description": "Page number (1-based).", - "in": "query", - "name": "p", - "required": false, - "schema": { - "default": 1, - "format": "int64", - "minimum": 1, - "type": "integer" - } - }, - { - "description": "Page size (1-100).", - "in": "query", - "name": "limit", - "required": false, - "schema": { - "default": 10, - "format": "int64", - "maximum": 100, - "minimum": 1, - "type": "integer" - } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "429": { + "$ref": "#/components/responses/TooManyRequests" + }, + "500": { + "$ref": "#/components/responses/ServerError" } + }, + "summary": "List teams", + "tags": [ + "Platform/Teams" ], + "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 |\n\n## Usage\n\n- Filter by `person_id` to return teams that a specific person belongs to.\n- Defaults: p=1, limit=20.", + "href": "/en/api-reference/platform/teams/team-read-list", + "metadata": { + "sidebarTitle": "List teams" + } + } + } + }, + "/team/upsert": { + "post": { + "description": "Create a new team or update an existing one. Pass `team_id` to update.", + "operationId": "team-write-upsert", + "requestBody": { + "content": { + "application/json": { + "example": { + "description": "Backend reliability engineering team", + "person_ids": [ + 80011, + 80012 + ], + "team_name": "Backend SRE" + }, + "schema": { + "$ref": "#/components/schemas/TeamUpsertRequest" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { "data": { - "has_next_page": false, - "items": [ - { - "all": true, - "components": [], - "locale": "zh-CN", - "method": "email", - "recipient": "alice@example.com" - }, - { - "all": true, - "components": [], - "locale": "en-US", - "method": "email", - "recipient": "bob@example.com" - } - ], - "total": 2 + "team_id": 1001, + "team_name": "Backend SRE" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -58947,7 +60379,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/StatusPageSubscriberListResponse" + "$ref": "#/components/schemas/TeamUpsertResponse" } }, "type": "object" @@ -58964,6 +60396,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -58971,33 +60406,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List status page subscribers", + "summary": "Create or update a team", "tags": [ - "On-call/Status pages" + "Platform/Teams" ], "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-subscriber-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Teams Manage** (`organization`) |\n\n## Usage\n\n- Omit `team_id` (or set to 0) to create a new team; pass an existing ID to update.\n- `team_name` must be 1–39 characters and unique within the account.\n- Pass `person_ids` to set team membership; this replaces the entire member list.\n- Pass `emails` or `phones` to add existing members by contact; contacts that match no member are ignored — nobody is invited.\n- `ref_id` is an external identifier for integration with third-party HR systems.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/platform/teams/team-write-upsert", "metadata": { - "sidebarTitle": "List status page subscribers" + "sidebarTitle": "Create or update a team" } } } }, - "/status-page/template/delete": { + "/template/create": { "post": { - "description": "Delete an event template from a status page.", - "operationId": "statusPageTemplateDelete", + "description": "Create a new notification template.", + "operationId": "template-write-create", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5720156736380, - "template_id": "01KP0339G5XDEPM4R86T2B23EP", - "type": "pre_defined" + "description": "Default template for production incidents.", + "email": "Incident {{ .IncidentName }} on {{ .Severity }}", + "sms": "[Flashduty] {{ .IncidentName }} — {{ .Severity }}", + "team_id": 0, + "template_name": "Prod incident default" }, "schema": { - "$ref": "#/components/schemas/DeleteStatusPageTemplateRequest" + "$ref": "#/components/schemas/TemplateCreateRequest" } } }, @@ -59008,7 +60445,10 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "template_id": "6605a1b2c3d4e5f6a7b8c9d0", + "template_name": "Prod incident default" + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -59019,7 +60459,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/TemplateCreateResponse" } }, "type": "object" @@ -59043,64 +60483,42 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete status page template", + "summary": "Create a template", "tags": [ - "On-call/Status pages" + "On-call/Notification templates" ], "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Templates Manage** (`on-call`) |\n\n## Usage\n\n- `template_name` must be unique within the account; duplicates return `InvalidParameter`.\n- The server validates every non-empty channel template by rendering it against a mock incident — a syntactic error in any channel fails the whole request with `InvalidParameter`.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/notification-templates/template-write-create", "metadata": { - "sidebarTitle": "Delete status page template" + "sidebarTitle": "Create a template" } } } }, - "/status-page/template/list": { - "get": { - "description": "List all event templates for a status page.", - "operationId": "statusPageTemplateList", - "parameters": [ - { - "description": "Status page ID.", - "in": "query", - "name": "page_id", - "required": true, - "schema": { - "format": "int64", - "type": "integer" + "/template/delete": { + "post": { + "description": "Soft-delete a template by ID.", + "operationId": "template-write-delete", + "requestBody": { + "content": { + "application/json": { + "example": { + "template_id": "6605a1b2c3d4e5f6a7b8c9d0" + }, + "schema": { + "$ref": "#/components/schemas/TemplateIDRequest" + } } }, - { - "description": "Template category. `pre_defined` returns predefined event templates; `message` returns message notification templates.", - "in": "query", - "name": "type", - "required": true, - "schema": { - "enum": [ - "pre_defined", - "message" - ], - "type": "string" - } - } - ], + "required": true + }, "responses": { "200": { "content": { "application/json": { "example": { - "data": { - "items": [ - { - "description": "We have identified the root cause.", - "status": "identified", - "template_id": "01KC8KP6PHVPSCAB0BTKZBN2HR", - "title": "Service Disruption", - "type": "incident" - } - ] - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -59111,7 +60529,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/ListStatusPageTemplatesResponse" + "$ref": "#/components/schemas/EmptyObject" } }, "type": "object" @@ -59128,6 +60546,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -59135,38 +60556,31 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List status page templates", + "summary": "Delete a template", "tags": [ - "On-call/Status pages" + "On-call/Notification templates" ], "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Templates Manage** (`on-call`) |\n\n## Usage\n\n- Fails with `400 ReferenceExist` if the template is still referenced by any channel, escalation rule, or notification subscription.\n- Deletion is soft — `deleted_at` is set. The record remains for audit, but the template stops appearing in listings.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/notification-templates/template-write-delete", "metadata": { - "sidebarTitle": "List status page templates" + "sidebarTitle": "Delete a template" } } } }, - "/status-page/template/upsert": { + "/template/info": { "post": { - "description": "Create or update an event template for a status page.", - "operationId": "statusPageTemplateUpsert", + "description": "Return a single notification template by ID.", + "operationId": "template-read-info", "requestBody": { "content": { "application/json": { "example": { - "page_id": 5720156736380, - "template": { - "description": "We are investigating a service disruption affecting some users.", - "status": "investigating", - "title": "Service Disruption", - "type": "incident" - }, - "type": "pre_defined" + "template_id": "6605a1b2c3d4e5f6a7b8c9d0" }, "schema": { - "$ref": "#/components/schemas/UpsertStatusPageTemplateRequest" + "$ref": "#/components/schemas/TemplateIDRequest" } } }, @@ -59178,7 +60592,30 @@ "application/json": { "example": { "data": { - "template_id": "01KP0339G5XDEPM4R86T2B23EP" + "account_id": 10023, + "created_at": 1712700000, + "creator_id": 80011, + "description": "Default template for production incidents.", + "dingtalk": "", + "dingtalk_app": "", + "email": "Incident {{ .IncidentName }} on {{ .Severity }}", + "feishu": "", + "feishu_app": "", + "slack": "", + "slack_app": "", + "sms": "[Flashduty] {{ .IncidentName }} — {{ .Severity }}", + "status": "enabled", + "team_id": 0, + "teams_app": "", + "telegram": "", + "template_id": "6605a1b2c3d4e5f6a7b8c9d0", + "template_name": "Prod incident default", + "updated_at": 1712702400, + "updated_by": 80011, + "voice": "", + "wecom": "", + "wecom_app": "", + "zoom": "" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -59190,7 +60627,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/UpsertStatusPageTemplateResponse" + "$ref": "#/components/schemas/TemplateItem" } }, "type": "object" @@ -59214,34 +60651,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Upsert status page template", + "summary": "Get template detail", "tags": [ - "On-call/Status pages" + "On-call/Notification templates" ], "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Templates Read** (`on-call`) |\n\n## Usage\n\n- Pass `000000000000000000000001` as `template_id` to retrieve the built-in preset template for the caller's account locale.", + "href": "/en/api-reference/on-call/notification-templates/template-read-info", "metadata": { - "sidebarTitle": "Upsert status page template" + "sidebarTitle": "Get template detail" } } } }, - "/status-page/update": { + "/template/list": { "post": { - "description": "Update an existing status page configuration.", - "operationId": "statusPageUpdate", + "description": "Return a paginated list of notification templates.", + "operationId": "template-read-list", "requestBody": { "content": { "application/json": { "example": { - "contact_info": "mailto:support@example.com", - "name": "Flashduty Status Page (Updated)", - "page_header": "Updated status page header", - "page_id": 5750613685214 + "asc": false, + "is_my_team": false, + "limit": 20, + "orderby": "updated_at", + "p": 1 }, "schema": { - "$ref": "#/components/schemas/UpdateStatusPageRequest" + "$ref": "#/components/schemas/TemplateListRequest" } } }, @@ -59252,7 +60690,38 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "has_next_page": true, + "items": [ + { + "account_id": 10023, + "created_at": 1712700000, + "creator_id": 80011, + "description": "Default template for production incidents.", + "dingtalk": "", + "dingtalk_app": "", + "email": "Incident {{ .IncidentName }} on {{ .Severity }}", + "feishu": "", + "feishu_app": "", + "slack": "", + "slack_app": "", + "sms": "[Flashduty] {{ .IncidentName }} — {{ .Severity }}", + "status": "enabled", + "team_id": 0, + "teams_app": "", + "telegram": "", + "template_id": "6605a1b2c3d4e5f6a7b8c9d0", + "template_name": "Prod incident default", + "updated_at": 1712702400, + "updated_by": 80011, + "voice": "", + "wecom": "", + "wecom_app": "", + "zoom": "" + } + ], + "total": 47 + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -59263,7 +60732,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/EmptyResponse" + "$ref": "#/components/schemas/TemplateListResponse" } }, "type": "object" @@ -59287,31 +60756,38 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Update status page", + "summary": "List templates", "tags": [ - "On-call/Status pages" + "On-call/Notification templates" ], "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", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Templates Read** (`on-call`) or **Templates Manage** (`on-call`) |\n\n## Usage\n\n- Pagination defaults to page 1 with 20 rows. The response's `has_next_page` tells you whether another page exists without needing a separate count request.\n- When `is_my_team` is `true`, `team_ids` is ignored.", + "href": "/en/api-reference/on-call/notification-templates/template-read-list", "metadata": { - "sidebarTitle": "Update status page" + "sidebarTitle": "List templates" } } } }, - "/team/delete": { + "/template/preview": { "post": { - "description": "Permanently delete a team by ID, name, or external reference ID.", - "operationId": "team-write-delete", + "description": "Render a notification template against incident data or mock data and return the output.", + "operationId": "template-read-preview", "requestBody": { "content": { "application/json": { "example": { - "team_id": 1001 + "content": "Incident {{.Title}} is {{.Status}}", + "incident_card_hidden_fields": { + "feishu_app": [ + "responders" + ] + }, + "incident_id": "664a1b2c3d4e5f6a7b8c9d0e", + "type": "feishu_app" }, "schema": { - "$ref": "#/components/schemas/TeamDeleteRequest" + "$ref": "#/components/schemas/PreviewTemplateRequest" } } }, @@ -59322,7 +60798,17 @@ "content": { "application/json": { "example": { - "data": {}, + "data": { + "content": "Incident Database latency spike is Critical", + "fixed_fields": [ + { + "field": "channel", + "value": "Payment Alerts" + } + ], + "message": "", + "success": true + }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -59333,7 +60819,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/PlatformEmptyObject" + "$ref": "#/components/schemas/PreviewTemplateResponse" } }, "type": "object" @@ -59350,9 +60836,6 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -59360,31 +60843,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Delete a team", + "summary": "Preview template", "tags": [ - "Platform/Teams" + "On-call/Notification templates" ], "x-mint": { - "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Teams Manage** (`organization`) |\n\n## Usage\n\n- At least one of `team_id`, `team_name`, or `ref_id` must be provided.\n- Fails with `400 ReferenceExist` if the team is still referenced by schedules, escalation rules, or other resources.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", - "href": "/en/api-reference/platform/teams/team-write-delete", + "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- `incident_card_hidden_fields` applies only to supported IM-card previews; unsupported app types or field names return `InvalidParameter`.\n- `fixed_fields` is returned only when the selected IM preview has a non-empty fixed incident-card value.", + "href": "/en/api-reference/on-call/notification-templates/template-read-preview", "metadata": { - "sidebarTitle": "Delete a team" + "sidebarTitle": "Preview template" } } } }, - "/team/info": { + "/template/update": { "post": { - "description": "Return a single team by ID, name, or external reference ID.", - "operationId": "team-read-info", + "description": "Update an existing template. Only the fields present in the request are written: a channel you omit keeps its current content, and an explicit empty string clears it.", + "operationId": "template-write-update", "requestBody": { "content": { "application/json": { "example": { - "team_id": 1001 + "description": "Updated description.", + "email": "Incident {{ .IncidentName }} on {{ .Severity }}", + "sms": "[Flashduty] {{ .IncidentName }} — {{ .Severity }}", + "template_id": "6605a1b2c3d4e5f6a7b8c9d0", + "template_name": "Prod incident default" }, "schema": { - "$ref": "#/components/schemas/TeamInfoRequest" + "$ref": "#/components/schemas/TemplateUpdateRequest" } } }, @@ -59395,24 +60882,7 @@ "content": { "application/json": { "example": { - "data": { - "account_id": 10023, - "created_at": 1710000000, - "creator_id": 80011, - "creator_name": "alice", - "description": "Backend reliability engineering team", - "person_ids": [ - 80011, - 80012 - ], - "ref_id": "", - "status": "enabled", - "team_id": 1001, - "team_name": "Backend SRE", - "updated_at": 1712000000, - "updated_by": 80011, - "updated_by_name": "alice" - }, + "data": {}, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, "schema": { @@ -59423,7 +60893,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/TeamItem" + "$ref": "#/components/schemas/EmptyObject" } }, "type": "object" @@ -59440,6 +60910,9 @@ "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "429": { "$ref": "#/components/responses/TooManyRequests" }, @@ -59447,34 +60920,32 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Get team detail", + "summary": "Update a template", "tags": [ - "Platform/Teams" + "On-call/Notification templates" ], "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 |\n\n## Usage\n\n- At least one of `team_id`, `team_name`, or `ref_id` must be provided.", - "href": "/en/api-reference/platform/teams/team-read-info", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Templates Manage** (`on-call`) |\n\n## Usage\n\n- Only the fields present in the request are written. A channel you omit keeps its current content; send it as an empty string to clear it.\n- The caller needs data-permission on the template's team; otherwise the response is `AccessDenied`.\n- Every call is recorded in the account audit log. Don't put secrets in request fields.", + "href": "/en/api-reference/on-call/notification-templates/template-write-update", "metadata": { - "sidebarTitle": "Get team detail" + "sidebarTitle": "Update a template" } } } }, - "/team/infos": { + "/webhook/history/detail": { "post": { - "description": "Return basic info for multiple teams by their IDs in a single request.", - "operationId": "team-read-infos", + "description": "Retrieve the detailed payload and response for a specific webhook delivery attempt.", + "operationId": "webhookHistoryDetail", "requestBody": { "content": { "application/json": { "example": { - "team_ids": [ - 1001, - 1002 - ] + "event_id": "20260412Xatt9hrXsgmFkBR78WF655", + "integration_id": 6113996590131 }, "schema": { - "$ref": "#/components/schemas/TeamInfosRequest" + "$ref": "#/components/schemas/GetWebhookHistoryDetailRequest" } } }, @@ -59486,23 +60957,24 @@ "application/json": { "example": { "data": { - "items": [ - { - "person_ids": [ - 80011, - 80012 - ], - "team_id": 1001, - "team_name": "Backend SRE" - }, - { - "person_ids": [ - 80013 - ], - "team_id": 1002, - "team_name": "Frontend" - } - ] + "attempt": 1, + "channel_id": 2551105804131, + "channel_name": "Production Alerts", + "duration": 132, + "endpoint": "https://example.com/webhook", + "event_id": "20260412Xatt9hrXsgmFkBR78WF655", + "event_time": "2026-04-12 13:31:11.357472", + "event_type": "a_update", + "integration_id": 5321026051131, + "ref_id": "69da3f0ef77b1b51f40e83cc", + "ref_title": "High CPU Usage on host-01", + "request_body": "{\"event_type\":\"a_update\",\"event_id\":\"d789d65951c0532ea9b6a1d99b707054\"}", + "request_headers": "{\"Content-Type\":\"application/json\"}", + "response_body": "{\"ok\":true}", + "response_headers": "{\"Content-Type\":\"application/json\"}", + "status": "success", + "status_code": 200, + "webhook_type": "alert" }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -59514,7 +60986,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/TeamInfosResponse" + "$ref": "#/components/schemas/WebhookHistoryDetail" } }, "type": "object" @@ -59538,34 +61010,35 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "Batch get teams", + "summary": "Get webhook delivery detail", "tags": [ - "Platform/Teams" + "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 | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Duplicate IDs are deduplicated; IDs that match no team are ignored.", - "href": "/en/api-reference/platform/teams/team-read-infos", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Integrations Read** (`on-call`) |", + "href": "/en/api-reference/on-call/integrations/webhook-history-detail", "metadata": { - "sidebarTitle": "Batch get teams" + "sidebarTitle": "Get webhook delivery detail" } } } }, - "/team/list": { + "/webhook/history/list": { "post": { - "description": "Return a paginated list of teams in the current account.", - "operationId": "team-read-list", + "description": "List the delivery history for outbound webhook notifications.", + "operationId": "webhookHistoryList", "requestBody": { "content": { "application/json": { "example": { - "asc": false, + "end_time": 1775203200000, + "integration_id": 6113996590131, "limit": 20, - "orderby": "created_at", - "p": 1 + "start_time": 1775116800000, + "status": "success" }, "schema": { - "$ref": "#/components/schemas/TeamListRequest" + "$ref": "#/components/schemas/ListWebhookHistoryRequest" } } }, @@ -59579,26 +61052,22 @@ "data": { "items": [ { - "account_id": 10023, - "created_at": 1710000000, - "creator_id": 80011, - "creator_name": "alice", - "description": "", - "person_ids": [ - 80011 - ], - "ref_id": "", - "status": "enabled", - "team_id": 1001, - "team_name": "Backend SRE", - "updated_at": 1712000000, - "updated_by": 0, - "updated_by_name": "" + "attempt": 1, + "channel_id": 2551105804131, + "duration": 132, + "endpoint": "https://example.com/webhook", + "event_id": "20260412Xatt9hrXsgmFkBR78WF655", + "event_time": "2026-04-12 13:31:11.357472", + "event_type": "a_update", + "integration_id": 5321026051131, + "ref_id": "69da3f0ef77b1b51f40e83cc", + "status": "success", + "status_code": 200, + "webhook_type": "alert" } ], - "limit": 20, - "p": 1, - "total": 5 + "search_after_ctx": "eyJldmVudF90aW1lIjoiMjAyNi0wNC0xMlQxMzoxNToyNi4zODI1NDcrMDg6MDAiLCJldmVudF9pZCI6IjIwMjYwNDEybUdzeFAzZHJwRmZzNFpDUWQycFNEcCJ9", + "total": 346 }, "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4" }, @@ -59610,7 +61079,7 @@ { "properties": { "data": { - "$ref": "#/components/schemas/TeamListResponse" + "$ref": "#/components/schemas/ListWebhookHistoryResponse" } }, "type": "object" @@ -59634,73 +61103,89 @@ "$ref": "#/components/responses/ServerError" } }, - "summary": "List teams", + "summary": "List webhook delivery history", "tags": [ - "Platform/Teams" + "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 | None — any valid `app_key` can call this operation |\n\n## Usage\n\n- Filter by `person_id` to return teams that a specific person belongs to.\n- Defaults: p=1, limit=20.", - "href": "/en/api-reference/platform/teams/team-read-list", + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | **Integrations Read** (`on-call`) |", + "href": "/en/api-reference/on-call/integrations/webhook-history-list", "metadata": { - "sidebarTitle": "List teams" + "sidebarTitle": "List webhook delivery history" } } } }, - "/team/upsert": { + "/member/notify": { "post": { - "description": "Create a new team or update an existing one. Pass `team_id` to update.", - "operationId": "team-write-upsert", - "requestBody": { - "content": { - "application/json": { - "example": { - "description": "Backend reliability engineering team", - "person_ids": [ - 80011, - 80012 - ], - "team_name": "Backend SRE" - }, - "schema": { - "$ref": "#/components/schemas/TeamUpsertRequest" - } - } - }, - "required": true + "operationId": "memberNotify", + "summary": "Notify members", + "description": "Send an email to account members on behalf of the caller, with content the caller supplies. Only callable with a credential minted for an AI SRE session; any other credential is rejected with `AccessDenied`. Delivery is asynchronous — `accepted` means the email was queued, not that it was delivered.", + "tags": [ + "Platform/Members" + ], + "x-mint": { + "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **200 requests/minute**; **10 requests/second** per account |\n| Permissions | None — callable only with an AI SRE session credential; any other credential is rejected with `AccessDenied` |\n\n## Usage\n\n- Recipients that are not active members of the caller's account, or that have no email address on file, are skipped rather than failing the whole request.\n- Whether email is included follows each recipient's own notification preferences for this kind of message; a recipient with no preference set defaults to receiving it.\n- Recipients receive exactly the sanitized `html` as the email body, with nothing added around it. The sender name shows the caller's name followed by \"(via AI SRE)\".\n- Before sending, the server inspects the submitted `html` and rejects the request with `400` / `InvalidParameter` when it contains constructs whose removal would change what recipients see (`