{
  "openapi": "3.1.0",
  "info": {
    "title": "Flashduty Open API",
    "description": "Public HTTP API for the Flashduty AI SRE platform — skills, MCP servers (connectors), A2A agents, and sessions. Every operation is authenticated with an `app_key` query parameter issued from the Flashduty console.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.flashcat.cloud",
      "description": "Flashduty Open API"
    }
  ],
  "security": [
    {
      "AppKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "AI SRE/Skills"
    },
    {
      "name": "AI SRE/MCP servers"
    },
    {
      "name": "AI SRE/A2A agents"
    },
    {
      "name": "AI SRE/Sessions"
    },
    {
      "name": "AI SRE/Automations"
    }
  ],
  "paths": {
    "/safari/a2a-agent/create": {
      "post": {
        "operationId": "remote-agent-write-create",
        "summary": "Create A2A agent",
        "description": "Register a new A2A remote agent from its agent-card URL.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Agent Manage** (`ai-sre`) |\n\n## Usage\n\n- `instructions` is required; a deprecated `description` field is still accepted for legacy clients and, if both are sent, must exactly match `instructions`.\n- `card_url` must be an absolute `http`/`https` URL with a non-empty host (reachability is enforced by the execution environment, not here); `auth_type` accepts only `none`, `api_key`, or `bearer`.\n- `environment_kind` accepts only empty (automatic) or `byoc`; `cloud` is rejected. `byoc` requires `environment_id`, and the runner must be visible to the caller.\n- Creating into a team (`team_id > 0`) requires the caller to actually belong to that team; only the account owner/admin may create at account scope (`team_id=0`).\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-write-create",
          "metadata": {
            "sidebarTitle": "Create A2A agent"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/A2AAgentCreateResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D"
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A2AAgentCreateRequest"
              },
              "example": {
                "agent_name": "deploy-bot",
                "instructions": "Inspect deployment pipelines and propose rollbacks when a canary fails health checks.",
                "card_url": "https://agents.example.com/deploy-bot/card",
                "auth_type": "bearer",
                "streaming": true,
                "team_id": 0,
                "environment_kind": "byoc",
                "environment_id": "env_8s7Hn2kLpQ3xYbVc4Wd2m"
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/delete": {
      "post": {
        "operationId": "remote-agent-write-delete",
        "summary": "Delete A2A agent",
        "description": "Soft-delete an A2A agent by ID.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Agent Manage** (`ai-sre`) |\n\n## Usage\n\n- Delete is a soft delete; the agent stops appearing in list/get and can no longer be dispatched once removed.\n- Requires edit permission (`access.CanEdit`) on the agent's team.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-write-delete",
          "metadata": {
            "sidebarTitle": "Delete A2A agent"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A2AAgentIDRequest"
              },
              "example": {
                "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D"
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/disable": {
      "post": {
        "operationId": "remote-agent-write-disable",
        "summary": "Disable A2A agent",
        "description": "Disable an enabled A2A agent.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Agent Manage** (`ai-sre`) |\n\n## Usage\n\n- Requires edit permission (`access.CanEdit`) on the agent's team.\n- Returns `InvalidParameter` if the agent is already disabled.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-write-disable",
          "metadata": {
            "sidebarTitle": "Disable A2A agent"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A2AAgentIDRequest"
              },
              "example": {
                "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D"
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/enable": {
      "post": {
        "operationId": "remote-agent-write-enable",
        "summary": "Enable A2A agent",
        "description": "Enable a disabled A2A agent.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Agent Manage** (`ai-sre`) |\n\n## Usage\n\n- Requires edit permission (`access.CanEdit`) on the agent's team, not just visibility into it.\n- Returns `InvalidParameter` if the agent is already enabled.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-write-enable",
          "metadata": {
            "sidebarTitle": "Enable A2A agent"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A2AAgentIDRequest"
              },
              "example": {
                "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D"
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/get": {
      "post": {
        "operationId": "remote-agent-read-get",
        "summary": "Get A2A agent detail",
        "description": "Get one A2A agent by ID.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- `card_resolve_timeout` and `task_timeout` are always `0` today — the API does not yet expose a way to set them.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-read-get",
          "metadata": {
            "sidebarTitle": "Get A2A agent detail"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/A2AAgentItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D",
                    "account_id": 10023,
                    "team_id": 0,
                    "can_edit": true,
                    "environment_kind": "",
                    "environment_id": "",
                    "agent_name": "deploy-bot",
                    "instructions": "Inspect deployment pipelines and propose rollbacks when a canary fails health checks.",
                    "card_url": "https://agents.example.com/deploy-bot/card",
                    "auth_type": "bearer",
                    "streaming": true,
                    "status": "enabled",
                    "agent_card_name": "Deploy Bot",
                    "agent_card_skills": [
                      "rollback",
                      "diff"
                    ],
                    "card_resolve_timeout": 0,
                    "task_timeout": 0,
                    "auth_mode": "shared",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000
                  }
                }
              }
            }
          },
          "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/A2AAgentIDRequest"
              },
              "example": {
                "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D"
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/list": {
      "post": {
        "operationId": "remote-agent-read-list",
        "summary": "List A2A agents",
        "description": "List A2A agents visible to the caller across account and team scopes, with pagination.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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 `offset`/`limit` (not `p`/`limit`).\n- `scope=account` restricts to account-scoped agents; `scope=team` restricts to the caller's visible teams; the default `all` combines both, subject to `include_account`.\n- `query` performs a case-insensitive substring search across agent name, instructions, card URL, agent ID, and the resolved card name.\n- `card_resolve_timeout` and `task_timeout` are always `0` today — the API does not yet expose a way to set them.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-read-list",
          "metadata": {
            "sidebarTitle": "List A2A agents"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/A2AAgentListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "items": [
                      {
                        "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D",
                        "account_id": 10023,
                        "team_id": 0,
                        "can_edit": true,
                        "environment_kind": "",
                        "environment_id": "",
                        "agent_name": "deploy-bot",
                        "instructions": "Inspect deployment pipelines and propose rollbacks when a canary fails health checks.",
                        "card_url": "https://agents.example.com/deploy-bot/card",
                        "auth_type": "bearer",
                        "streaming": true,
                        "status": "enabled",
                        "agent_card_name": "Deploy Bot",
                        "agent_card_skills": [
                          "rollback",
                          "diff"
                        ],
                        "card_resolve_timeout": 0,
                        "task_timeout": 0,
                        "auth_mode": "shared",
                        "created_by": 80011,
                        "created_at": 1716960000000,
                        "updated_at": 1717046400000
                      }
                    ],
                    "total": 1
                  }
                }
              }
            }
          },
          "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/A2AAgentListRequest"
              },
              "example": {
                "offset": 0,
                "limit": 20,
                "include_account": true
              }
            }
          }
        }
      }
    },
    "/safari/a2a-agent/update": {
      "post": {
        "operationId": "remote-agent-write-update",
        "summary": "Update A2A agent",
        "description": "Apply a partial update to an A2A agent. Omit a field to leave it unchanged.",
        "tags": [
          "en"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | **Agent Manage** (`ai-sre`) |\n\n## Usage\n\n- Requires edit permission (`access.CanEdit`) on the agent's *current* team before any field may change.\n- Reassigning `team_id` requires rights on the destination team; if the team changes without also sending a new environment binding, the existing runner binding must remain selectable by the caller or the update is rejected.\n- Changing `auth_mode` always rewrites `secret_schema` together with it; omitting `oauth_metadata` alongside a new `auth_mode` clears it to empty.\n- Sending back a masked or empty value for a sensitive `auth_config` key (`api_key`, `token`, `client_secret`) keeps the stored secret instead of overwriting it.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/a2a-agents/remote-agent-write-update",
          "metadata": {
            "sidebarTitle": "Update A2A agent"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A2AAgentUpdateRequest"
              },
              "example": {
                "agent_id": "a2a_6mWqZ2pK9nLcR3tY8uVb4D",
                "instructions": "Inspect deployment pipelines and propose rollbacks."
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/create": {
      "post": {
        "operationId": "automation-rule-write-create",
        "summary": "Create Automation rule",
        "description": "Create an Automation rule with schedule, HTTP POST, and On-call incident triggers.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | Valid `app_key`; management operations require the caller to manage the target rule |\n\n## Usage\n\n- A caller may create personal rules and rules for any team in the current account; `team_id` is immutable after creation.\n- `cron_expr` is evaluated in `timezone` if provided, else the caller's member timezone, else the account timezone, else UTC.\n- `http_post_trigger_enabled=true` creates and enables an HTTP POST trigger; the response's `http_post_token` is a one-time value returned only on creation — save it immediately.\n- `oncall_incident_trigger_enabled=true` requires at least one `oncall_incident_channel_ids` entry and one `oncall_incident_severities` value; matching incidents run with `trigger_kind=oncall_incident`.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-write-create",
          "metadata": {
            "sidebarTitle": "Create Automation rule"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationRuleItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                    "account_id": 10023,
                    "team_id": 123,
                    "owner_id": 80011,
                    "name": "Weekly on-call review",
                    "enabled": true,
                    "run_scope": "team",
                    "cron_expr": "0 9 * * 1",
                    "timezone": "Asia/Shanghai",
                    "prompt": "Summarize last week's alert noise and escalation load.",
                    "environment_kind": "",
                    "environment_id": "",
                    "schedule_trigger_id": "atrig_6aKp3wT9mQ2xVc8bR1nY7z",
                    "schedule_trigger_enabled": true,
                    "http_post_trigger_id": "atrig_2bLq4xT8mP1sWd9cN3rF6y",
                    "http_post_trigger_url": "/safari/automation/triggers/atrig_2bLq4xT8mP1sWd9cN3rF6y/fire",
                    "http_post_trigger_enabled": true,
                    "can_edit": true,
                    "created_at": 1780367971228,
                    "updated_at": 1780367971228,
                    "http_post_token": "sat_yQ9p8V7n6M5k4J3h2G1f0E9d8C7b6A5z4Y3x2W1v0U",
                    "schedule_next_fire_at_ms": 1780630800000,
                    "oncall_incident_trigger_id": "atrig_9cVb2mN7qKs4dEa8T1rY5p",
                    "oncall_incident_trigger_enabled": true,
                    "oncall_incident_channel_ids": [
                      456
                    ],
                    "oncall_incident_severities": [
                      "Critical",
                      "Warning"
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleCreateRequest"
              },
              "example": {
                "name": "Weekly on-call review",
                "team_id": 123,
                "enabled": true,
                "cron_expr": "0 9 * * 1",
                "timezone": "Asia/Shanghai",
                "schedule_trigger_enabled": true,
                "prompt": "Summarize last week's alert noise and escalation load.",
                "http_post_trigger_enabled": true,
                "oncall_incident_trigger_enabled": true,
                "oncall_incident_channel_ids": [
                  456
                ],
                "oncall_incident_severities": [
                  "Critical",
                  "Warning"
                ]
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/delete": {
      "post": {
        "operationId": "automation-rule-write-delete",
        "summary": "Delete Automation rule",
        "description": "Delete an Automation rule.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | Valid `app_key`; management operations require the caller to manage the target rule |\n\n## Usage\n\n- Deleting a rule also removes its schedule, HTTP POST, and On-call incident triggers; a deleted HTTP POST trigger's token stops working immediately.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-write-delete",
          "metadata": {
            "sidebarTitle": "Delete Automation rule"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleIDRequest"
              },
              "example": {
                "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b"
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/get": {
      "post": {
        "operationId": "automation-rule-read-get",
        "summary": "Get Automation rule",
        "description": "Get one Automation rule by ID.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Valid `app_key`; caller must manage the target rule |\n\n## Usage\n\n- Manage rights mean the personal rule owner; for team rules, an account admin or a member of the rule's team.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-read-get",
          "metadata": {
            "sidebarTitle": "Get Automation rule"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationRuleItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                    "account_id": 10023,
                    "team_id": 123,
                    "owner_id": 80011,
                    "name": "Weekly on-call review",
                    "enabled": true,
                    "run_scope": "team",
                    "cron_expr": "0 9 * * 1",
                    "timezone": "Asia/Shanghai",
                    "prompt": "Summarize last week's alert noise and escalation load.",
                    "environment_kind": "",
                    "environment_id": "",
                    "schedule_trigger_id": "atrig_6aKp3wT9mQ2xVc8bR1nY7z",
                    "schedule_trigger_enabled": true,
                    "http_post_trigger_id": "atrig_2bLq4xT8mP1sWd9cN3rF6y",
                    "http_post_trigger_url": "/safari/automation/triggers/atrig_2bLq4xT8mP1sWd9cN3rF6y/fire",
                    "http_post_trigger_enabled": true,
                    "can_edit": true,
                    "created_at": 1780367971228,
                    "updated_at": 1780367971228,
                    "http_post_token": "sat_yQ9p8V7n6M5k4J3h2G1f0E9d8C7b6A5z4Y3x2W1v0U",
                    "schedule_next_fire_at_ms": 1780630800000,
                    "oncall_incident_trigger_id": "atrig_9cVb2mN7qKs4dEa8T1rY5p",
                    "oncall_incident_trigger_enabled": true,
                    "oncall_incident_channel_ids": [
                      456
                    ],
                    "oncall_incident_severities": [
                      "Critical",
                      "Warning"
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleIDRequest"
              },
              "example": {
                "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b"
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/list": {
      "post": {
        "operationId": "automation-rule-read-list",
        "summary": "List Automation rules",
        "description": "List Automation rules visible to the caller.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Valid `app_key`; results are filtered to the caller's visible scope |\n\n## Usage\n\n- `all` returns your personal rules plus team rules you can access.\n- Account admins see all team rules in list results, but not other users' personal rules.\n- `team_ids` narrows the visible set and never expands access.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-read-list",
          "metadata": {
            "sidebarTitle": "List Automation rules"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationRuleListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "total": 1,
                    "rules": [
                      {
                        "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                        "account_id": 10023,
                        "team_id": 123,
                        "owner_id": 80011,
                        "name": "Weekly on-call review",
                        "enabled": true,
                        "run_scope": "team",
                        "cron_expr": "0 9 * * 1",
                        "timezone": "Asia/Shanghai",
                        "prompt": "Summarize last week's alert noise and escalation load.",
                        "environment_kind": "",
                        "environment_id": "",
                        "schedule_trigger_id": "atrig_6aKp3wT9mQ2xVc8bR1nY7z",
                        "schedule_trigger_enabled": true,
                        "http_post_trigger_id": "atrig_2bLq4xT8mP1sWd9cN3rF6y",
                        "http_post_trigger_url": "/safari/automation/triggers/atrig_2bLq4xT8mP1sWd9cN3rF6y/fire",
                        "http_post_trigger_enabled": true,
                        "can_edit": true,
                        "created_at": 1780367971228,
                        "updated_at": 1780367971228,
                        "http_post_token": "sat_yQ9p8V7n6M5k4J3h2G1f0E9d8C7b6A5z4Y3x2W1v0U",
                        "schedule_next_fire_at_ms": 1780630800000,
                        "oncall_incident_trigger_id": "atrig_9cVb2mN7qKs4dEa8T1rY5p",
                        "oncall_incident_trigger_enabled": true,
                        "oncall_incident_channel_ids": [
                          456
                        ],
                        "oncall_incident_severities": [
                          "Critical",
                          "Warning"
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleListRequest"
              },
              "example": {
                "scope": "all",
                "limit": 20
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/run": {
      "post": {
        "operationId": "automation-rule-write-run",
        "summary": "Run Automation rule",
        "description": "Manually run an Automation rule immediately, outside its schedule.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **100 requests/minute**; **5 requests/second** per account |\n| Permissions | Valid `app_key`; caller must manage the target rule |\n\n## Usage\n\n- Rate-limited to at most once per minute per rule; a second call within that window returns `429` with `code: \"RequestTooFrequently\"`.\n- Only enabled rules can run manually; a disabled or misconfigured rule fails preflight with a `400` error before any run is created.\n- The call returns once the underlying agent session starts, not once the run finishes; the run continues asynchronously — use List Automation runs to check completion status.\n- `trigger_kind` is always `manual` for runs started this way, distinguishing them from `schedule`, `http_post`, and `oncall_incident` runs in run history.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-write-run",
          "metadata": {
            "sidebarTitle": "Run Automation rule"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ManualRunRuleResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                    "trigger_kind": "manual",
                    "preflight": {
                      "ok": true,
                      "checks": [
                        "rule_loaded",
                        "actor_authorized",
                        "app_allowed",
                        "runtime_scope_resolved",
                        "rule_config_valid"
                      ],
                      "scope": "team",
                      "owner_id": 80011,
                      "team_id": 123,
                      "app_name": "ai-sre"
                    },
                    "run": {
                      "run_id": "trun_5oDvqiG64uur6sBNsTc4u",
                      "session_id": "sess_f8oDvqiG64uur6sBNsTc4u"
                    }
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleIDRequest"
              },
              "example": {
                "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b"
              }
            }
          }
        }
      }
    },
    "/safari/automation/rule/update": {
      "post": {
        "operationId": "automation-rule-write-update",
        "summary": "Update Automation rule",
        "description": "Update mutable Automation rule fields, including HTTP POST and On-call incident trigger settings.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **300 requests/minute**; **20 requests/second** per account |\n| Permissions | Valid `app_key`; management operations require the caller to manage the target rule |\n\n## Usage\n\n- Omitted or `null` fields are left unchanged; `team_id` cannot be changed from its current value.\n- `cron_expr` and `timezone` can be updated independently — sending only one keeps the other at its current stored value.\n- `rotate_http_post_trigger_token=true` issues a fresh webhook token, returned only in this response.\n- To trigger from On-call incidents, send `oncall_incident_trigger_enabled`, `oncall_incident_channel_ids`, and `oncall_incident_severities`; matching events run with `trigger_kind=oncall_incident`.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-rule-write-update",
          "metadata": {
            "sidebarTitle": "Update Automation rule"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationRuleItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                    "account_id": 10023,
                    "team_id": 123,
                    "owner_id": 80011,
                    "name": "Weekly on-call review",
                    "enabled": true,
                    "run_scope": "team",
                    "cron_expr": "0 9 * * 1",
                    "timezone": "Asia/Shanghai",
                    "prompt": "Summarize last week's alert noise and escalation load.",
                    "environment_kind": "",
                    "environment_id": "",
                    "schedule_trigger_id": "atrig_6aKp3wT9mQ2xVc8bR1nY7z",
                    "schedule_trigger_enabled": true,
                    "http_post_trigger_id": "atrig_2bLq4xT8mP1sWd9cN3rF6y",
                    "http_post_trigger_url": "/safari/automation/triggers/atrig_2bLq4xT8mP1sWd9cN3rF6y/fire",
                    "http_post_trigger_enabled": true,
                    "can_edit": true,
                    "created_at": 1780367971228,
                    "updated_at": 1780367971228,
                    "http_post_token": "sat_yQ9p8V7n6M5k4J3h2G1f0E9d8C7b6A5z4Y3x2W1v0U",
                    "schedule_next_fire_at_ms": 1780630800000,
                    "oncall_incident_trigger_id": "atrig_9cVb2mN7qKs4dEa8T1rY5p",
                    "oncall_incident_trigger_enabled": true,
                    "oncall_incident_channel_ids": [
                      456
                    ],
                    "oncall_incident_severities": [
                      "Critical",
                      "Warning"
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRuleUpdateRequest"
              },
              "example": {
                "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                "enabled": true,
                "cron_expr": "15 9 * * 1",
                "rotate_http_post_trigger_token": true,
                "oncall_incident_trigger_enabled": true,
                "oncall_incident_severities": [
                  "Critical",
                  "Warning"
                ],
                "oncall_incident_channel_ids": [
                  456
                ]
              }
            }
          }
        }
      }
    },
    "/safari/automation/run/list": {
      "post": {
        "operationId": "automation-run-read-list",
        "summary": "List Automation runs",
        "description": "List run history for a rule the caller can manage.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Valid `app_key`; caller must manage the target rule |\n\n## Usage\n\n- Run history is visible only when the caller can manage the rule: the personal rule owner; for team rules, an account admin or a member of the rule's team.\n",
          "href": "/en/api-reference/ai-sre/automations/automation-run-read-list",
          "metadata": {
            "sidebarTitle": "List Automation runs"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationRunListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "total": 1,
                    "runs": [
                      {
                        "run_id": "trun_5oDvqiG64uur6sBNsTc4u",
                        "kind": "automation_rule",
                        "account_id": 10023,
                        "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                        "trigger_kind": "schedule",
                        "occurrence_key": "atrig_6aKp3wT9mQ2xVc8bR1nY7z:1780630800000",
                        "status": "succeeded",
                        "attempts": 1,
                        "started_at": 1780630800000,
                        "completed_at": 1780630923456,
                        "duration_ms": 123456,
                        "error_code": "",
                        "error_message": "",
                        "stats_json": {},
                        "result_json": {
                          "session_id": "sess_f8oDvqiG64uur6sBNsTc4u"
                        },
                        "created_at": 1780630800000,
                        "updated_at": 1780630923456
                      }
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationRunListRequest"
              },
              "example": {
                "rule_id": "arule_7NnLzY2Qp8xS4kUaV3mR6b",
                "limit": 20,
                "trigger_kind": "schedule"
              }
            }
          }
        }
      }
    },
    "/safari/automation/template/list": {
      "post": {
        "operationId": "automation-template-read-list",
        "summary": "List Automation templates",
        "description": "List preset Automation templates for the requested locale.",
        "tags": [
          "AI SRE/Automations"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **1,000 requests/minute**; **50 requests/second** per account |\n| Permissions | Valid `app_key`; results are filtered to the caller's visible scope |\n",
          "href": "/en/api-reference/ai-sre/automations/automation-template-read-list",
          "metadata": {
            "sidebarTitle": "List Automation templates"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AutomationTemplateListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "templates": [
                      {
                        "name": "Weekly Insights",
                        "description": "Analyze incidents, alerts, response activity, notification load, and related changes from the past week.",
                        "icon": "chart-no-axes-combined",
                        "enabled": false,
                        "prompt": "Generate a weekly insights report. Analyze incidents, alerts, response activity, notification load, and related changes from the past week. Focus on what happened this week, which signals deserve attention, and which improvement actions are most valuable. Do not modify any Flashduty business state.\n"
                      }
                    ]
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationTemplateListRequest"
              },
              "example": {
                "locale": "en-US"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/create": {
      "post": {
        "operationId": "mcp-write-server-create",
        "summary": "Create MCP server",
        "description": "Register a new MCP server (connector) on the account.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- `command`/`args`/`env` apply to `stdio`; `url`/`headers` apply to `sse`/`streamable-http`.\n- Server name must start with a letter and contain only letters, digits, `-`, or `_`, and is unique within the account (case-insensitive); violations return InvalidParameter.\n- `environment_kind` accepts only `byoc` (with `environment_id`) or empty for automatic selection — `cloud` cannot be bound directly to an MCP server.\n- `per_user_secret` auth mode requires `secret_schema` to be valid JSON with a non-empty `header_name`.\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-create",
          "metadata": {
            "sidebarTitle": "Create MCP server"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MCPServerItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1",
                    "account_id": 10023,
                    "team_id": 0,
                    "can_edit": true,
                    "environment_kind": "",
                    "environment_id": "",
                    "server_name": "prometheus",
                    "description": "Query Prometheus metrics and alerts.",
                    "transport": "streamable-http",
                    "url": "https://mcp.example.com/prometheus",
                    "status": "enabled",
                    "connect_timeout": 10,
                    "call_timeout": 60,
                    "tool_count": 2,
                    "tools": [
                      {
                        "name": "query",
                        "description": "Run a PromQL instant query."
                      },
                      {
                        "name": "query_range",
                        "description": "Run a PromQL range query."
                      }
                    ],
                    "auth_mode": "shared",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MCPServerCreateRequest"
              },
              "example": {
                "server_name": "prometheus",
                "description": "Query Prometheus metrics and alerts.",
                "transport": "streamable-http",
                "url": "https://mcp.example.com/prometheus",
                "status": "enabled"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/delete": {
      "post": {
        "operationId": "mcp-write-server-delete",
        "summary": "Delete MCP server",
        "description": "Delete an MCP server by ID.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-delete",
          "metadata": {
            "sidebarTitle": "Delete MCP server"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MCPServerDeleteRequest"
              },
              "example": {
                "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/disable": {
      "post": {
        "operationId": "mcp-write-server-disable",
        "summary": "Disable MCP server",
        "description": "Disable an enabled MCP server.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- Disabling an already-disabled server returns InvalidParameter instead of a silent no-op.\n- Requires edit permission on the server's current team: account-scope servers are owner/admin only; team-scope servers require the caller to belong to that team (or be owner/admin).\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-disable",
          "metadata": {
            "sidebarTitle": "Disable MCP server"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MCPServerStatusRequest"
              },
              "example": {
                "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/enable": {
      "post": {
        "operationId": "mcp-write-server-enable",
        "summary": "Enable MCP server",
        "description": "Enable a disabled MCP server.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- Enabling an already-enabled server returns InvalidParameter instead of a silent no-op.\n- Requires edit permission on the server's current team: account-scope servers are owner/admin only; team-scope servers require the caller to belong to that team (or be owner/admin).\n- Every call is recorded in the account audit log.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-write-server-enable",
          "metadata": {
            "sidebarTitle": "Enable MCP server"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MCPServerStatusRequest"
              },
              "example": {
                "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/get": {
      "post": {
        "operationId": "mcp-read-server-get",
        "summary": "Get MCP server detail",
        "description": "Get one MCP server and run a live probe of its tool list.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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 detail call live-probes tools; on failure `list_error` is set and the request still succeeds.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-read-server-get",
          "metadata": {
            "sidebarTitle": "Get MCP server detail"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MCPServerItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1",
                    "account_id": 10023,
                    "team_id": 0,
                    "can_edit": true,
                    "environment_kind": "",
                    "environment_id": "",
                    "server_name": "prometheus",
                    "description": "Query Prometheus metrics and alerts.",
                    "transport": "streamable-http",
                    "url": "https://mcp.example.com/prometheus",
                    "status": "enabled",
                    "connect_timeout": 10,
                    "call_timeout": 60,
                    "tool_count": 2,
                    "tools": [
                      {
                        "name": "query",
                        "description": "Run a PromQL instant query."
                      },
                      {
                        "name": "query_range",
                        "description": "Run a PromQL range query."
                      }
                    ],
                    "auth_mode": "shared",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000
                  }
                }
              }
            }
          },
          "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/MCPServerGetRequest"
              },
              "example": {
                "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1"
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/list": {
      "post": {
        "operationId": "mcp-read-server-list",
        "summary": "List MCP servers",
        "description": "List MCP servers visible to the caller across account and team scopes, with pagination.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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 live tool list is not included; fetch a single server to probe its tools.\n- `query` performs a case-insensitive substring search across name, description, AI-generated description, server ID, transport, URL, command, and source template name.\n",
          "href": "/en/api-reference/ai-sre/mcp-servers/mcp-read-server-list",
          "metadata": {
            "sidebarTitle": "List MCP servers"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MCPServerListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "total": 1,
                    "servers": [
                      {
                        "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1",
                        "account_id": 10023,
                        "team_id": 0,
                        "can_edit": true,
                        "environment_kind": "",
                        "environment_id": "",
                        "server_name": "prometheus",
                        "description": "Query Prometheus metrics and alerts.",
                        "transport": "streamable-http",
                        "url": "https://mcp.example.com/prometheus",
                        "status": "enabled",
                        "connect_timeout": 10,
                        "call_timeout": 60,
                        "tool_count": 2,
                        "tools": [
                          {
                            "name": "query",
                            "description": "Run a PromQL instant query."
                          },
                          {
                            "name": "query_range",
                            "description": "Run a PromQL range query."
                          }
                        ],
                        "auth_mode": "shared",
                        "created_by": 80011,
                        "created_at": 1716960000000,
                        "updated_at": 1717046400000
                      }
                    ]
                  }
                }
              }
            }
          },
          "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/MCPServerListRequest"
              },
              "example": {
                "p": 1,
                "limit": 20,
                "include_account": true
              }
            }
          }
        }
      }
    },
    "/safari/mcp/server/update": {
      "post": {
        "operationId": "mcp-write-server-update",
        "summary": "Update MCP server",
        "description": "Update an MCP server's configuration. Omit a field to leave it unchanged.",
        "tags": [
          "AI SRE/MCP servers"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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- `environment_kind`/`environment_id` are independent partial-update fields: omit both to leave the runner binding unchanged; set either to change it, subject to the same `byoc`-or-empty constraint as create.\n- Changing `team_id` requires reassignment permission on the destination team; if the runner binding is left unchanged, it 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"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MCPServerItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1",
                    "account_id": 10023,
                    "team_id": 0,
                    "can_edit": true,
                    "environment_kind": "",
                    "environment_id": "",
                    "server_name": "prometheus",
                    "description": "Query Prometheus metrics, alerts, and rules.",
                    "transport": "streamable-http",
                    "url": "https://mcp.example.com/prometheus",
                    "status": "enabled",
                    "connect_timeout": 10,
                    "call_timeout": 60,
                    "tool_count": 2,
                    "tools": [
                      {
                        "name": "query",
                        "description": "Run a PromQL instant query."
                      },
                      {
                        "name": "query_range",
                        "description": "Run a PromQL range query."
                      }
                    ],
                    "auth_mode": "shared",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MCPServerUpdateRequest"
              },
              "example": {
                "server_id": "mcp_4kP9wQ2nLceRtY7uVb3xA1",
                "description": "Query Prometheus metrics, alerts, and rules."
              }
            }
          }
        }
      }
    },
    "/safari/session/delete": {
      "post": {
        "operationId": "session-write-delete",
        "summary": "Delete session",
        "description": "Delete a session by ID.",
        "tags": [
          "AI SRE/Sessions"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionDeleteRequest"
              },
              "example": {
                "session_id": "sess_f8oDvqiG64uur6sBNsTc4u"
              }
            }
          }
        }
      }
    },
    "/safari/session/export": {
      "post": {
        "operationId": "session-read-export",
        "summary": "Export session transcript",
        "description": "Stream a session's full event transcript as newline-delimited JSON.",
        "tags": [
          "AI SRE/Sessions"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "x-mint": {
          "content": "## Restrictions\n\n| Aspect | Value |\n| ------ | ----- |\n| Rate limits | **20 requests/minute**; **1 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"
          }
        },
        "responses": {
          "200": {
            "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.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "Newline-delimited JSON stream. Parse line-by-line; do not buffer the whole body."
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionExportRequest"
              },
              "example": {
                "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                "include_subagents": false
              }
            }
          }
        }
      }
    },
    "/safari/session/get": {
      "post": {
        "operationId": "session-read-info",
        "summary": "Get session detail",
        "description": "Fetch one session plus a backward-paged window of its most recent events.",
        "tags": [
          "AI SRE/Sessions"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Get session detail"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SessionGetResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "session": {
                      "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                      "session_name": "Investigate cloud-assistant first heartbeat",
                      "app_name": "ai-sre",
                      "entry_kind": "web",
                      "person_id": "3790925372131",
                      "team_id": 0,
                      "is_mine": false,
                      "can_manage": true,
                      "status": "enabled",
                      "incognito": false,
                      "created_at": 1780367971228,
                      "updated_at": 1780367993457,
                      "token_usage": {
                        "input_tokens": 14948,
                        "cached_tokens": 11520,
                        "output_tokens": 888,
                        "reasoning_tokens": 351
                      },
                      "current_context_tokens": 14948,
                      "context_window": 0,
                      "archived_at": 0,
                      "pinned_at": 0,
                      "last_event_at": 1780367992649,
                      "is_running": false,
                      "has_unread": true,
                      "current_turn_started_at": 0,
                      "current_turn_active_ms": 0,
                      "current_turn_wait_ms": 0,
                      "current_turn_tokens": 0
                    },
                    "events": [
                      {
                        "event_id": "evt_3aZQ9p",
                        "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                        "author": "user",
                        "partial": false,
                        "turn_complete": false,
                        "status": "normal",
                        "created_at": 1780367971241
                      },
                      {
                        "event_id": "evt_7bWk2r",
                        "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                        "author": "ai-sre",
                        "content": {
                          "role": "model",
                          "parts": [
                            {
                              "text": "..."
                            }
                          ]
                        },
                        "partial": false,
                        "turn_complete": true,
                        "status": "normal",
                        "created_at": 1780367992649
                      }
                    ],
                    "has_more_older": false,
                    "suggest_init": false
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionGetRequest"
              },
              "example": {
                "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                "num_recent_events": 50
              }
            }
          }
        }
      }
    },
    "/safari/session/list": {
      "post": {
        "operationId": "session-read-list",
        "summary": "List sessions",
        "description": "List agent sessions visible to the caller, filtered by app, surface, archive status, and team.",
        "tags": [
          "AI SRE/Sessions"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "List sessions"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SessionListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "total": 988,
                    "sessions": [
                      {
                        "session_id": "sess_f8oDvqiG64uur6sBNsTc4u",
                        "session_name": "Investigate cloud-assistant first heartbeat",
                        "app_name": "ai-sre",
                        "entry_kind": "web",
                        "person_id": "3790925372131",
                        "team_id": 0,
                        "is_mine": false,
                        "can_manage": true,
                        "status": "enabled",
                        "incognito": false,
                        "created_at": 1780367971228,
                        "updated_at": 1780367993457,
                        "token_usage": {
                          "input_tokens": 14948,
                          "cached_tokens": 11520,
                          "output_tokens": 888,
                          "reasoning_tokens": 351
                        },
                        "current_context_tokens": 14948,
                        "context_window": 0,
                        "archived_at": 0,
                        "pinned_at": 0,
                        "last_event_at": 1780367992649,
                        "is_running": false,
                        "has_unread": true,
                        "current_turn_started_at": 0,
                        "current_turn_active_ms": 0,
                        "current_turn_wait_ms": 0,
                        "current_turn_tokens": 0
                      }
                    ],
                    "suggest_init": false
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionListRequest"
              },
              "example": {
                "app_name": "ai-sre",
                "limit": 2,
                "orderby": "updated_at",
                "scope": "all"
              }
            }
          }
        }
      }
    },
    "/safari/skill/delete": {
      "post": {
        "operationId": "skill-write-delete",
        "summary": "Delete skill",
        "description": "Delete a skill by ID.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Delete skill"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SkillDeleteRequest"
              },
              "example": {
                "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m"
              }
            }
          }
        }
      }
    },
    "/safari/skill/disable": {
      "post": {
        "operationId": "skill-write-disable",
        "summary": "Disable skill",
        "description": "Disable an enabled skill so the agent stops loading it.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Disable skill"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SkillStatusRequest"
              },
              "example": {
                "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m"
              }
            }
          }
        }
      }
    },
    "/safari/skill/enable": {
      "post": {
        "operationId": "skill-read-enable",
        "summary": "Enable skill",
        "description": "Enable a disabled skill so the agent can load it.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Enable skill"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "null",
                          "description": "Always null on success."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": null
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SkillStatusRequest"
              },
              "example": {
                "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m"
              }
            }
          }
        }
      }
    },
    "/safari/skill/get": {
      "post": {
        "operationId": "skill-read-get",
        "summary": "Get skill detail",
        "description": "Get one skill including its full SKILL.md content.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Get skill detail"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SkillItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m",
                    "account_id": 10023,
                    "team_id": 0,
                    "skill_name": "k8s-triage",
                    "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.",
                    "version": "1.2.0",
                    "tags": [
                      "kubernetes",
                      "triage"
                    ],
                    "author": "sre-team",
                    "tools": [
                      "bash",
                      "mcp:prometheus/query"
                    ],
                    "status": "enabled",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000,
                    "can_edit": true,
                    "update_available": false,
                    "is_modified": false,
                    "description_en": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.",
                    "content": "---\nname: k8s-triage\ndescription: ...\n---\n# Triage steps"
                  }
                }
              }
            }
          },
          "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/SkillGetRequest"
              },
              "example": {
                "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m"
              }
            }
          }
        }
      }
    },
    "/safari/skill/list": {
      "post": {
        "operationId": "skill-read-list",
        "summary": "List skills",
        "description": "List AI SRE skills visible to the caller across account and team scopes, with pagination.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "List skills"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SkillListResponse"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "total": 1,
                    "skills": [
                      {
                        "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m",
                        "account_id": 10023,
                        "team_id": 0,
                        "skill_name": "k8s-triage",
                        "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.",
                        "version": "1.2.0",
                        "tags": [
                          "kubernetes",
                          "triage"
                        ],
                        "author": "sre-team",
                        "tools": [
                          "bash",
                          "mcp:prometheus/query"
                        ],
                        "status": "enabled",
                        "created_by": 80011,
                        "created_at": 1716960000000,
                        "updated_at": 1717046400000,
                        "can_edit": true,
                        "update_available": false,
                        "is_modified": false
                      }
                    ]
                  }
                }
              }
            }
          },
          "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/SkillListRequest"
              },
              "example": {
                "p": 1,
                "limit": 20,
                "include_account": true
              }
            }
          }
        }
      }
    },
    "/safari/skill/update": {
      "post": {
        "operationId": "skill-write-update",
        "summary": "Update skill",
        "description": "Update a skill's descriptions or reassign its team scope.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Update skill"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SkillItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m",
                    "account_id": 10023,
                    "team_id": 0,
                    "skill_name": "k8s-triage",
                    "description": "Updated triage runbook.",
                    "version": "1.2.0",
                    "tags": [
                      "kubernetes",
                      "triage"
                    ],
                    "author": "sre-team",
                    "tools": [
                      "bash",
                      "mcp:prometheus/query"
                    ],
                    "status": "enabled",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000,
                    "can_edit": true,
                    "update_available": false,
                    "is_modified": false
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SkillUpdateRequest"
              },
              "example": {
                "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m",
                "description": "Updated triage runbook."
              }
            }
          }
        }
      }
    },
    "/safari/skill/upload": {
      "post": {
        "operationId": "skill-write-upload",
        "summary": "Upload skill",
        "description": "Upload a skill archive (.skill/.zip/.tar.gz/.tgz) to create or replace a skill.",
        "tags": [
          "AI SRE/Skills"
        ],
        "security": [
          {
            "AppKeyAuth": []
          }
        ],
        "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",
          "metadata": {
            "sidebarTitle": "Upload skill"
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ResponseEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SkillItem"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "data": {
                    "skill_id": "skill_8s7Hn2kLpQ3xYbVc4Wd2m",
                    "account_id": 10023,
                    "team_id": 0,
                    "skill_name": "k8s-triage",
                    "description": "Diagnose unhealthy Kubernetes workloads from cluster events and pod logs.",
                    "version": "1.2.0",
                    "tags": [
                      "kubernetes",
                      "triage"
                    ],
                    "author": "sre-team",
                    "tools": [
                      "bash",
                      "mcp:prometheus/query"
                    ],
                    "status": "enabled",
                    "created_by": 80011,
                    "created_at": 1716960000000,
                    "updated_at": 1717046400000,
                    "can_edit": true,
                    "update_available": false,
                    "is_modified": false,
                    "created": true
                  }
                }
              }
            }
          },
          "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"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/SkillUploadRequest"
              },
              "example": {
                "team_id": 0,
                "replace": false
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "AppKeyAuth": {
        "type": "apiKey",
        "in": "query",
        "name": "app_key",
        "description": "App key issued from the Flashduty console. Required on every public API call. Keep it secret — it grants the same access as the owning account."
      },
      "AutomationTriggerBearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token generated for one Automation HTTP POST trigger. This is not an app_key."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request — usually a missing or malformed parameter.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "missingParameter": {
                "summary": "Missing required parameter",
                "value": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "error": {
                    "code": "InvalidParameter",
                    "message": "The specified parameter skill_id is not valid."
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid app_key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "missingAppKey": {
                "value": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "error": {
                    "code": "Unauthorized",
                    "message": "You are unauthorized."
                  }
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The app_key is valid but lacks permission for this operation.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "accessDenied": {
                "value": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "error": {
                    "code": "AccessDenied",
                    "message": "Access Denied."
                  }
                }
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit hit. Either the global API limit or a per-account limit.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "rateLimited": {
                "value": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "error": {
                    "code": "RequestTooFrequently",
                    "message": "Request too frequently."
                  }
                }
              }
            }
          }
        }
      },
      "ServerError": {
        "description": "Unexpected server-side error. Include the request_id when reporting.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "internal": {
                "value": {
                  "request_id": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4",
                  "error": {
                    "code": "InternalError",
                    "message": "We encountered an internal error, and it has been reported. Please try again later."
                  }
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "A2AAgentCreateRequest": {
        "type": "object",
        "description": "Registration parameters for a new A2A agent.",
        "properties": {
          "agent_name": {
            "type": "string",
            "description": "Agent display name.",
            "maxLength": 128
          },
          "instructions": {
            "type": "string",
            "description": "Natural-language instructions for the remote agent. Required — a deprecated `description` field is still accepted for legacy clients and, if both are sent, must exactly match `instructions`.",
            "maxLength": 2000
          },
          "card_url": {
            "type": "string",
            "description": "URL of the remote agent card. Must be an absolute `http` or `https` URL with a non-empty host; reachability is enforced by the execution environment, not at creation time."
          },
          "auth_type": {
            "type": "string",
            "description": "Authentication type for reaching the remote agent: `none`, `api_key`, or `bearer`."
          },
          "auth_config": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Authentication config key-values, e.g. the API key or bearer token. Values for sensitive keys (`api_key`, `token`, `client_secret`) are masked back in responses."
          },
          "streaming": {
            "type": "boolean",
            "description": "Whether the remote agent supports streaming."
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope: 0 = account-wide; >0 = team. Creating at account scope requires the owner/admin role; creating into a team requires actual membership in that team.",
            "format": "int64"
          },
          "environment_kind": {
            "type": "string",
            "enum": [
              "",
              "byoc"
            ],
            "description": "Execution environment binding. Omit or send empty for automatic routing; `byoc` pins the agent to a specific runner given by `environment_id`. `cloud` is not accepted — configured A2A agents need a persistent runner, not a disposable cloud sandbox."
          },
          "environment_id": {
            "type": "string",
            "description": "BYOC runner ID. Required when `environment_kind=byoc`; the runner must belong to the account or a team the caller belongs to."
          },
          "auth_mode": {
            "type": "string",
            "description": "Authentication mode: `shared` (default) shares one credential across all users; `per_user_secret` requires `secret_schema.header_name`; `per_user_oauth` runs per-user OAuth."
          },
          "secret_schema": {
            "type": "string",
            "description": "JSON-encoded secret schema, e.g. `{\"header_name\":\"X-Api-Key\"}`; required when `auth_mode=per_user_secret`."
          },
          "oauth_metadata": {
            "type": "string",
            "description": "JSON-encoded OAuth metadata; populated by the OAuth discovery flow for `per_user_oauth` mode."
          },
          "allow_insecure_oauth_http": {
            "type": "boolean",
            "description": "Allow non-loopback HTTP OAuth discovery/metadata endpoints for this agent instead of requiring HTTPS. Defaults to false."
          },
          "allow_insecure_tls_skip_verify": {
            "type": "boolean",
            "description": "Skip TLS certificate verification when connecting to this agent's endpoint (self-signed/private certs). Defaults to false."
          }
        },
        "required": [
          "agent_name",
          "instructions",
          "card_url"
        ]
      },
      "A2AAgentCreateResponse": {
        "type": "object",
        "description": "Result of registering an A2A agent.",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "ID of the newly created agent."
          }
        },
        "required": [
          "agent_id"
        ]
      },
      "A2AAgentIDRequest": {
        "type": "object",
        "description": "A2A agent lookup by ID.",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "Target agent ID."
          }
        },
        "required": [
          "agent_id"
        ]
      },
      "A2AAgentItem": {
        "type": "object",
        "description": "A registered A2A (agent-to-agent) remote agent.",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "Unique A2A agent ID (prefix `a2a_`)."
          },
          "account_id": {
            "type": "integer",
            "description": "Owning account ID.",
            "format": "int64"
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope: 0 = account-wide; >0 = the owning team.",
            "format": "int64"
          },
          "can_edit": {
            "type": "boolean",
            "description": "Whether the caller may edit this agent."
          },
          "environment_kind": {
            "type": "string",
            "enum": [
              "",
              "byoc"
            ],
            "description": "Execution environment binding. Empty selects automatic routing; `byoc` pins the agent to a specific runner named by `environment_id`."
          },
          "environment_id": {
            "type": "string",
            "description": "BYOC runner ID. Set only when `environment_kind=byoc`; empty otherwise."
          },
          "agent_name": {
            "type": "string",
            "description": "Agent display name."
          },
          "instructions": {
            "type": "string",
            "description": "Natural-language instructions for the remote agent (formerly named `description`).",
            "maxLength": 2000
          },
          "card_url": {
            "type": "string",
            "description": "URL of the remote agent card."
          },
          "auth_type": {
            "type": "string",
            "description": "Authentication type for reaching the remote agent: `none`, `api_key`, or `bearer`."
          },
          "auth_config": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Authentication config; sensitive values (`api_key`, `token`, `client_secret`) are masked."
          },
          "streaming": {
            "type": "boolean",
            "description": "Whether the remote agent supports streaming responses."
          },
          "status": {
            "type": "string",
            "description": "Agent status.",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "agent_card_name": {
            "type": "string",
            "description": "Agent name resolved from the remote card."
          },
          "agent_card_skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Skills advertised by the remote card."
          },
          "card_resolve_timeout": {
            "type": "integer",
            "description": "Card-resolution timeout in seconds. Always 0 today — the API does not yet expose a way to set it."
          },
          "task_timeout": {
            "type": "integer",
            "description": "Single-task execution timeout in seconds. Always 0 today — the API does not yet expose a way to set it."
          },
          "auth_mode": {
            "type": "string",
            "description": "Authentication mode.",
            "enum": [
              "shared",
              "per_user_secret",
              "per_user_oauth"
            ]
          },
          "secret_schema": {
            "type": "string",
            "description": "JSON-encoded secret schema (per_user_secret mode)."
          },
          "oauth_metadata": {
            "type": "string",
            "description": "JSON-encoded OAuth metadata (per_user_oauth mode)."
          },
          "allow_insecure_oauth_http": {
            "type": "boolean",
            "description": "Allow non-loopback HTTP OAuth discovery/metadata endpoints for this agent instead of requiring HTTPS."
          },
          "allow_insecure_tls_skip_verify": {
            "type": "boolean",
            "description": "Skip TLS certificate verification when connecting to this agent's endpoint."
          },
          "created_by": {
            "type": "integer",
            "description": "Member ID that created the agent.",
            "format": "int64"
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Creation time. Unix timestamp in milliseconds."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Last update time. Unix timestamp in milliseconds."
          }
        },
        "required": [
          "agent_id",
          "account_id",
          "team_id",
          "can_edit",
          "environment_kind",
          "environment_id",
          "agent_name",
          "instructions",
          "card_url",
          "auth_type",
          "streaming",
          "status",
          "card_resolve_timeout",
          "task_timeout",
          "created_by",
          "created_at",
          "updated_at"
        ]
      },
      "A2AAgentListRequest": {
        "type": "object",
        "description": "Pagination, scope, and search filter for listing A2A agents.",
        "properties": {
          "offset": {
            "type": "integer",
            "description": "Row offset for pagination.",
            "default": 0
          },
          "limit": {
            "type": "integer",
            "description": "Page size.",
            "default": 20
          },
          "scope": {
            "type": "string",
            "enum": [
              "all",
              "account",
              "team"
            ],
            "default": "all",
            "description": "Visibility scope: `all` (account-scope plus the caller's visible teams), `account` (account-scope only), or `team` (team-scoped rows across the caller's visible teams)."
          },
          "query": {
            "type": "string",
            "description": "Case-insensitive substring search across agent name, instructions, card URL, agent ID, and the resolved card name.",
            "maxLength": 128
          },
          "team_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Filter to these team IDs; empty = the caller's visible set."
          },
          "include_account": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Include account-scoped (team_id=0) rows. Defaults to true."
          }
        }
      },
      "A2AAgentListResponse": {
        "type": "object",
        "description": "Paginated A2A agent list.",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/A2AAgentItem"
            },
            "description": "A2A agents on this page."
          },
          "total": {
            "type": "integer",
            "description": "Total number of matching agents.",
            "format": "int64"
          }
        },
        "required": [
          "items",
          "total"
        ]
      },
      "A2AAgentUpdateRequest": {
        "type": "object",
        "description": "Partial update of an A2A agent. A null/omitted field is left unchanged.",
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "Target agent ID."
          },
          "agent_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "New display name. Omit to leave unchanged.",
            "maxLength": 128
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "New instructions. Omit to leave unchanged. A deprecated `description` field is also accepted; if both are sent they must match.",
            "maxLength": 2000
          },
          "card_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "New card URL. Omit to leave unchanged."
          },
          "auth_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "New auth type. Omit to leave unchanged."
          },
          "auth_config": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Replace the auth config. Omit to leave unchanged. Sending back the masked value (or an empty string) for a sensitive key keeps the stored secret instead of overwriting it."
          },
          "streaming": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Toggle streaming support. Omit to leave unchanged."
          },
          "team_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Reassign team scope. Omit to leave unchanged. Reassigning requires rights on the destination team; if the team changes without also sending a new environment binding, the existing runner binding must remain selectable by the caller or the update is rejected.",
            "format": "int64"
          },
          "environment_kind": {
            "type": [
              "string",
              "null"
            ],
            "description": "New execution environment binding: empty for automatic, `byoc` for a specific runner. `cloud` is rejected. Omit to leave unchanged."
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "New BYOC runner ID. Required alongside `environment_kind=byoc`. Omit to leave unchanged."
          },
          "auth_mode": {
            "type": [
              "string",
              "null"
            ],
            "description": "New auth mode: shared, per_user_secret, or per_user_oauth. Changing it always rewrites secret_schema together with it."
          },
          "secret_schema": {
            "type": [
              "string",
              "null"
            ],
            "description": "New JSON secret schema."
          },
          "oauth_metadata": {
            "type": [
              "string",
              "null"
            ],
            "description": "New JSON OAuth metadata. If omitted while auth_mode changes, it is cleared to empty."
          },
          "allow_insecure_oauth_http": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Toggle non-loopback HTTP OAuth discovery for this agent. Omit to leave unchanged."
          },
          "allow_insecure_tls_skip_verify": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Toggle TLS certificate verification skipping for this agent. Omit to leave unchanged."
          }
        },
        "required": [
          "agent_id"
        ]
      },
      "AutomationRuleCreateRequest": {
        "type": "object",
        "description": "Create an Automation rule.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Rule name."
          },
          "team_id": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "description": "Scope team ID. 0 or omitted means a personal rule; >0 means a team in the account. Immutable after creation."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the rule is enabled after creation. Omitted API value is false; Chat/CLI create sends true by default unless the user asks for disabled."
          },
          "cron_expr": {
            "type": "string",
            "description": "Run cadence. Supports 4 fields (`hour day month weekday`, minute defaults to 0) and 5 fields (`minute hour day month weekday`). The minute must be one fixed integer; 6-field seconds are not supported. A cron that sets both day-of-month and day-of-week is rejected. The create API currently requires this field even for HTTP-POST-only rules; send a valid cron and set `schedule_trigger_enabled=false`.",
            "example": "15 9 * * *"
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone `cron_expr` is evaluated in, e.g. `Asia/Shanghai`. Must be a timezone name loadable by the server; an invalid value is rejected. Defaults to the caller's member timezone, then the account timezone, then UTC when omitted."
          },
          "schedule_trigger_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the schedule trigger is enabled. Defaults to true when omitted; HTTP-POST-only rules should send false."
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "description": "Task prompt sent to the AI SRE agent on each run."
          },
          "environment_kind": {
            "type": "string",
            "description": "Runtime environment kind. Omit or send an empty value for automatic selection.",
            "enum": [
              "",
              "cloud",
              "byoc"
            ]
          },
          "environment_id": {
            "type": "string",
            "description": "BYOC Runner ID. Used only when `environment_kind=byoc`."
          },
          "http_post_trigger_enabled": {
            "type": "boolean",
            "description": "Whether to create and enable an HTTP POST trigger. When enabled, the response includes a one-time token."
          },
          "oncall_incident_trigger_enabled": {
            "type": "boolean",
            "description": "Whether the On-call incident trigger is enabled."
          },
          "oncall_incident_channel_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "On-call integration IDs to watch. Creating or enabling this trigger requires at least one valid ID."
          },
          "oncall_incident_severities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "Critical",
                "Warning",
                "Info"
              ]
            },
            "description": "Incident severities to watch. Supported values are Critical, Warning, and Info; creating or enabling this trigger requires at least one value."
          }
        },
        "required": [
          "name",
          "cron_expr",
          "prompt"
        ]
      },
      "AutomationRuleIDRequest": {
        "type": "object",
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Rule ID."
          }
        },
        "required": [
          "rule_id"
        ]
      },
      "AutomationRuleItem": {
        "type": "object",
        "description": "Automation rule.",
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Rule ID."
          },
          "account_id": {
            "type": "integer",
            "format": "int64",
            "description": "Account ID."
          },
          "team_id": {
            "type": "integer",
            "format": "int64",
            "description": "Scope team ID; 0 means personal rule."
          },
          "owner_id": {
            "type": "integer",
            "format": "int64",
            "description": "Creator person ID."
          },
          "name": {
            "type": "string",
            "description": "Rule name."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the rule is enabled."
          },
          "run_scope": {
            "type": "string",
            "enum": [
              "person",
              "team"
            ],
            "description": "Hidden session run scope."
          },
          "cron_expr": {
            "type": "string",
            "description": "Normalized 5-field cron expression."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone `cron_expr` is evaluated in. Always populated for rules created after this field shipped; empty on legacy rows created before it, which still resolve to UTC when scheduled."
          },
          "prompt": {
            "type": "string",
            "description": "Task prompt."
          },
          "environment_kind": {
            "type": "string",
            "description": "Runtime environment kind. Omit or send an empty value for automatic selection.",
            "enum": [
              "",
              "cloud",
              "byoc"
            ]
          },
          "environment_id": {
            "type": "string",
            "description": "BYOC Runner ID."
          },
          "schedule_trigger_id": {
            "type": "string",
            "description": "Schedule trigger ID."
          },
          "schedule_trigger_enabled": {
            "type": "boolean",
            "description": "Whether the schedule trigger is enabled."
          },
          "http_post_trigger_id": {
            "type": "string",
            "description": "HTTP POST trigger ID."
          },
          "http_post_trigger_url": {
            "type": "string",
            "description": "HTTP POST trigger path."
          },
          "http_post_trigger_enabled": {
            "type": "boolean",
            "description": "Whether the HTTP POST trigger is enabled."
          },
          "oncall_incident_trigger_id": {
            "type": "string",
            "description": "On-call incident trigger ID."
          },
          "oncall_incident_trigger_enabled": {
            "type": "boolean",
            "description": "Whether the On-call incident trigger is enabled."
          },
          "oncall_incident_channel_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "On-call integration IDs to watch. Creating or enabling this trigger requires at least one valid ID."
          },
          "oncall_incident_severities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "Critical",
                "Warning",
                "Info"
              ]
            },
            "description": "Incident severities to watch. Supported values are Critical, Warning, and Info; creating or enabling this trigger requires at least one value."
          },
          "http_post_token": {
            "type": "string",
            "description": "HTTP POST trigger token. Returned only on create or token rotation; save it immediately."
          },
          "can_edit": {
            "type": "boolean",
            "description": "True when the caller can manage this rule: the personal rule owner; for team rules, an account admin or a member of the rule's team."
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Creation time, Unix milliseconds."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Last update time, Unix milliseconds."
          },
          "schedule_next_fire_at_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available."
          }
        },
        "required": [
          "rule_id",
          "account_id",
          "team_id",
          "owner_id",
          "name",
          "enabled",
          "run_scope",
          "cron_expr",
          "timezone",
          "prompt",
          "environment_kind",
          "environment_id",
          "schedule_trigger_enabled",
          "http_post_trigger_enabled",
          "can_edit",
          "created_at",
          "updated_at",
          "schedule_next_fire_at_ms",
          "oncall_incident_trigger_enabled"
        ]
      },
      "AutomationRuleListRequest": {
        "type": "object",
        "description": "List Automation rules visible to the caller. `all` includes the caller's personal rules plus accessible team rules; account admins do not see other users' personal rules in list results.",
        "properties": {
          "p": {
            "type": "integer",
            "default": 1,
            "description": "Page number, 1-based."
          },
          "limit": {
            "type": "integer",
            "default": 20,
            "maximum": 100,
            "description": "Page size."
          },
          "scope": {
            "type": "string",
            "enum": [
              "all",
              "personal",
              "team"
            ],
            "description": "Scope filter: `all` (own personal + accessible team rules), `personal`, or `team`; default `all`."
          },
          "team_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Filter to these team IDs; this narrows results and does not expand access."
          },
          "include_person": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Compatibility field; when scope is empty and this is false, behaves like team scope."
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Filter by enabled status."
          },
          "keyword": {
            "type": "string",
            "maxLength": 64,
            "description": "Filter by name keyword."
          }
        }
      },
      "AutomationRuleListResponse": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count."
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationRuleItem"
            }
          }
        },
        "required": [
          "total",
          "rules"
        ]
      },
      "AutomationRuleUpdateRequest": {
        "type": "object",
        "description": "Update an Automation rule. Omit or send null on a field to leave it unchanged.",
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Target rule ID."
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 255,
            "description": "New rule name."
          },
          "team_id": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0,
            "description": "Only the current value is accepted; personal/team scope is immutable after creation."
          },
          "enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the rule is enabled."
          },
          "cron_expr": {
            "type": [
              "string",
              "null"
            ],
            "description": "Run cadence. Supports 4 fields (`hour day month weekday`, minute defaults to 0) and 5 fields (`minute hour day month weekday`). The minute must be one fixed integer; 6-field seconds are not supported.",
            "example": "15 9 * * *"
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ],
            "description": "New IANA timezone for evaluating `cron_expr`. Omit or send null to leave the current timezone unchanged."
          },
          "schedule_trigger_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the schedule trigger is enabled."
          },
          "prompt": {
            "type": [
              "string",
              "null"
            ],
            "description": "New task prompt."
          },
          "environment_kind": {
            "type": [
              "string",
              "null"
            ],
            "description": "Runtime environment kind. Omit or send an empty value for automatic selection.",
            "enum": [
              "",
              "cloud",
              "byoc"
            ]
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "BYOC Runner ID."
          },
          "http_post_trigger_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the HTTP POST trigger is enabled. Sending true creates one when missing."
          },
          "oncall_incident_trigger_enabled": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Whether the On-call incident trigger is enabled."
          },
          "oncall_incident_channel_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "description": "On-call integration IDs to watch. Creating or enabling this trigger requires at least one valid ID."
          },
          "oncall_incident_severities": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "Critical",
                "Warning",
                "Info"
              ]
            },
            "description": "Incident severities to watch. Supported values are Critical, Warning, and Info; creating or enabling this trigger requires at least one value."
          },
          "rotate_http_post_trigger_token": {
            "type": "boolean",
            "description": "Whether to rotate the HTTP POST trigger token. The new token is returned only in this response."
          }
        },
        "required": [
          "rule_id"
        ]
      },
      "AutomationRunItem": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string",
            "description": "Run ID."
          },
          "kind": {
            "type": "string",
            "description": "Run kind."
          },
          "account_id": {
            "type": "integer",
            "format": "int64",
            "description": "Account ID."
          },
          "rule_id": {
            "type": "string",
            "description": "Rule ID."
          },
          "trigger_kind": {
            "type": "string",
            "enum": [
              "schedule",
              "debug",
              "manual",
              "http_post",
              "oncall_incident"
            ],
            "description": "Trigger kind."
          },
          "occurrence_key": {
            "type": "string",
            "description": "Idempotency key for this occurrence."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "retrying",
              "succeeded",
              "partial",
              "failed",
              "skipped",
              "abandoned"
            ],
            "description": "Run status."
          },
          "attempts": {
            "type": "integer",
            "description": "Attempt count."
          },
          "started_at": {
            "type": "integer",
            "format": "int64",
            "description": "Start time, Unix milliseconds."
          },
          "completed_at": {
            "type": "integer",
            "format": "int64",
            "description": "Completion time, Unix milliseconds. 0 means not completed."
          },
          "duration_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Duration in milliseconds."
          },
          "error_code": {
            "type": "string",
            "description": "Error code."
          },
          "error_message": {
            "type": "string",
            "description": "Error message."
          },
          "stats_json": {
            "description": "Run stats JSON."
          },
          "result_json": {
            "description": "Run result JSON."
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Creation time, Unix milliseconds."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Last update time, Unix milliseconds."
          }
        },
        "required": [
          "run_id",
          "kind",
          "account_id",
          "rule_id",
          "trigger_kind",
          "occurrence_key",
          "status",
          "attempts",
          "started_at",
          "completed_at",
          "duration_ms",
          "created_at",
          "updated_at"
        ]
      },
      "AutomationRunListRequest": {
        "type": "object",
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Target rule ID."
          },
          "p": {
            "type": "integer",
            "default": 1,
            "description": "Page number, 1-based."
          },
          "limit": {
            "type": "integer",
            "default": 20,
            "maximum": 100,
            "description": "Page size."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "retrying",
              "succeeded",
              "partial",
              "failed",
              "skipped",
              "abandoned"
            ],
            "description": "Run status filter."
          },
          "trigger_kind": {
            "type": "string",
            "enum": [
              "schedule",
              "debug",
              "manual",
              "http_post",
              "oncall_incident"
            ],
            "description": "Trigger kind filter."
          },
          "started_after_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Start-time lower bound, Unix milliseconds."
          },
          "started_before_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Start-time upper bound, Unix milliseconds."
          }
        },
        "required": [
          "rule_id"
        ]
      },
      "AutomationRunListResponse": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total count."
          },
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationRunItem"
            }
          }
        },
        "required": [
          "total",
          "runs"
        ]
      },
      "AutomationRunView": {
        "type": "object",
        "description": "Reference to the run started by a manual trigger.",
        "properties": {
          "run_id": {
            "type": "string",
            "description": "Run ID, always populated once a run is created."
          },
          "session_id": {
            "type": "string",
            "description": "AI SRE session ID for this run. Always populated in a 200 response, since the call only returns after the session has started."
          }
        },
        "required": [
          "run_id"
        ]
      },
      "AutomationTemplateItem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Template name."
          },
          "description": {
            "type": "string",
            "description": "Template description."
          },
          "icon": {
            "type": "string",
            "description": "Icon identifier."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the template is enabled."
          },
          "prompt": {
            "type": "string",
            "description": "Template prompt."
          }
        },
        "required": [
          "name",
          "description",
          "icon",
          "enabled",
          "prompt"
        ]
      },
      "AutomationTemplateListRequest": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "maxLength": 16,
            "description": "Template locale such as zh-CN or en-US. Omit to detect from the request locale."
          }
        }
      },
      "AutomationTemplateListResponse": {
        "type": "object",
        "properties": {
          "templates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutomationTemplateItem"
            }
          }
        },
        "required": [
          "templates"
        ]
      },
      "ContextResolvedItem": {
        "type": "object",
        "description": "Snapshot of the three-tier knowledge-pack resolution for this session.",
        "properties": {
          "account_pack_id": {
            "type": "string",
            "description": "Resolved account-scoped pack id."
          },
          "team_pack_id": {
            "type": "string",
            "description": "Resolved team-scoped pack id."
          },
          "incident_id": {
            "type": "string",
            "description": "Bound incident id, when war-room originated."
          },
          "resolved_at_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds when the packs were resolved."
          },
          "versions": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Per-pack resolved version map."
          }
        },
        "required": [
          "resolved_at_ms"
        ]
      },
      "DutyError": {
        "type": "object",
        "description": "Error payload inside the response envelope. Present only on non-2xx responses.",
        "properties": {
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message, localized by the caller's Accept-Language. May contain field names, IDs, or other context from the failing request."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "EnvironmentBinding": {
        "type": "object",
        "description": "The runner or cloud sandbox the session is bound to. Null until the first message.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "Environment kind bound to the session: `cloud` (managed sandbox) or `byoc` (self-hosted runner).",
            "enum": [
              "cloud",
              "byoc"
            ]
          },
          "id": {
            "type": "string",
            "description": "Environment identifier: a cloud sandbox ID for `cloud` bindings, a runner/environment ID for `byoc` bindings."
          },
          "name": {
            "type": "string",
            "description": "Human-readable environment name; empty for cloud bindings using the default allowlist."
          },
          "status": {
            "type": "string",
            "description": "Live binding health, namespaced by kind: BYOC uses online/pending/offline/deleted; cloud uses available/rebuilding/expired.",
            "enum": [
              "online",
              "pending",
              "offline",
              "deleted",
              "available",
              "rebuilding",
              "expired"
            ]
          }
        },
        "required": [
          "kind",
          "id"
        ]
      },
      "ErrorCode": {
        "type": "string",
        "description": "Flashduty error code enum. Every failed API response sets `error.code` to one of these values. The value is a stable wire string — not a localized message and not a numeric status. HTTP status is informational.",
        "enum": [
          "OK",
          "InvalidParameter",
          "BadRequest",
          "InvalidContentType",
          "ResourceNotFound",
          "NoLicense",
          "ReferenceExist",
          "Unauthorized",
          "BalanceNotEnough",
          "AccessDenied",
          "RouteNotFound",
          "MethodNotAllowed",
          "UndonedOrderExist",
          "RequestLocked",
          "EntityTooLarge",
          "RequestTooFrequently",
          "RequestVerifyRequired",
          "DangerousOperation",
          "InternalError",
          "ServiceUnavailable"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Response envelope for errors. `error` is required; `data` is absent.",
        "properties": {
          "request_id": {
            "type": "string",
            "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4"
          },
          "error": {
            "$ref": "#/components/schemas/DutyError"
          }
        },
        "required": [
          "request_id",
          "error"
        ]
      },
      "EventItem": {
        "type": "object",
        "description": "One persisted session event. content/actions/usage_metadata carry the raw ADK envelope; treat them as opaque structured payloads.",
        "properties": {
          "event_id": {
            "type": "string",
            "description": "Event identifier."
          },
          "session_id": {
            "type": "string",
            "description": "Owning session id."
          },
          "invocation_id": {
            "type": "string",
            "description": "ADK invocation id grouping a turn."
          },
          "author": {
            "type": "string",
            "description": "Event author (e.g. user, the agent name)."
          },
          "branch": {
            "type": "string",
            "description": "ADK branch path for nested agents."
          },
          "content": {
            "type": "object",
            "additionalProperties": true,
            "description": "ADK content envelope {role, parts:[...]}."
          },
          "actions": {
            "type": "object",
            "additionalProperties": true,
            "description": "ADK actions envelope (state deltas, transfers, escalation)."
          },
          "usage_metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Per-turn token usage metadata."
          },
          "partial": {
            "type": "boolean",
            "description": "True for a streaming partial chunk."
          },
          "turn_complete": {
            "type": "boolean",
            "description": "True on the terminal event of a turn."
          },
          "error_code": {
            "type": "string",
            "description": "Error code when the event represents a failure."
          },
          "error_message": {
            "type": "string",
            "description": "Human-readable error message, when present."
          },
          "status": {
            "type": "string",
            "description": "Event status.",
            "enum": [
              "normal",
              "compressed"
            ]
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds when the event was written."
          }
        },
        "required": [
          "event_id",
          "session_id",
          "partial",
          "turn_complete",
          "created_at"
        ]
      },
      "MCPServerCreateRequest": {
        "type": "object",
        "description": "Configuration for a new MCP server.",
        "properties": {
          "server_name": {
            "type": "string",
            "description": "MCP server name, unique within the account.",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "description": "Server description.",
            "minLength": 1,
            "maxLength": 1024
          },
          "transport": {
            "type": "string",
            "description": "Transport protocol.",
            "enum": [
              "stdio",
              "sse",
              "streamable-http"
            ]
          },
          "command": {
            "type": "string",
            "description": "Executable command (stdio transport)."
          },
          "args": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command arguments (stdio transport)."
          },
          "env": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Environment variables (stdio transport)."
          },
          "url": {
            "type": "string",
            "description": "Server URL (sse / streamable-http transport)."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "HTTP headers (sse / streamable-http)."
          },
          "connect_timeout": {
            "type": "integer",
            "description": "Connection timeout in seconds. 0 = default (10s)."
          },
          "call_timeout": {
            "type": "integer",
            "description": "Tool-call timeout in seconds. 0 = default (60s)."
          },
          "auth_mode": {
            "type": "string",
            "description": "Authentication mode: shared (default), per_user_secret, or per_user_oauth."
          },
          "secret_schema": {
            "type": "string",
            "description": "JSON secret schema; required when auth_mode=per_user_secret."
          },
          "oauth_metadata": {
            "type": "string",
            "description": "JSON OAuth metadata; reserved for per_user_oauth."
          },
          "status": {
            "type": "string",
            "description": "Initial status.",
            "enum": [
              "enabled",
              "disabled"
            ],
            "default": "enabled"
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope: 0 = account-wide; >0 = team.",
            "format": "int64"
          },
          "environment_kind": {
            "type": "string",
            "description": "Pin the server to a specific BYOC runner (`environment_id` required). Omit or send empty for automatic selection; `cloud` is not supported for MCP servers.",
            "enum": [
              "byoc"
            ]
          },
          "environment_id": {
            "type": "string",
            "description": "Runner ID; required when environment_kind is byoc."
          },
          "allow_insecure_oauth_http": {
            "type": "boolean",
            "description": "Allow this server's OAuth token exchange over plaintext HTTP. Testing use only; defaults to false."
          },
          "allow_insecure_tls_skip_verify": {
            "type": "boolean",
            "description": "Skip TLS certificate verification when connecting to this server. Testing use only; defaults to false."
          },
          "source_template_name": {
            "type": "string",
            "description": "Marketplace template name when created from a connector template."
          }
        },
        "required": [
          "server_name",
          "description",
          "transport"
        ]
      },
      "MCPServerDeleteRequest": {
        "type": "object",
        "description": "MCP server deletion by ID.",
        "properties": {
          "server_id": {
            "type": "string",
            "description": "Target MCP server ID."
          }
        },
        "required": [
          "server_id"
        ]
      },
      "MCPServerGetRequest": {
        "type": "object",
        "description": "MCP server lookup by ID.",
        "properties": {
          "server_id": {
            "type": "string",
            "description": "Target MCP server ID."
          }
        },
        "required": [
          "server_id"
        ]
      },
      "MCPServerItem": {
        "type": "object",
        "description": "An MCP server (connector) registered on the account.",
        "properties": {
          "server_id": {
            "type": "string",
            "description": "Unique MCP server ID (prefix `mcp_`)."
          },
          "account_id": {
            "type": "integer",
            "description": "Owning account ID.",
            "format": "int64"
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope: 0 = account-wide; >0 = the owning team.",
            "format": "int64"
          },
          "can_edit": {
            "type": "boolean",
            "description": "Whether the caller may edit this server."
          },
          "environment_kind": {
            "type": "string",
            "description": "Runtime environment kind: empty for automatic selection, or `byoc` when pinned to a specific runner. `cloud` cannot be bound to an MCP server.",
            "enum": [
              "",
              "byoc"
            ]
          },
          "environment_id": {
            "type": "string",
            "description": "Runner ID when environment_kind is byoc; empty otherwise."
          },
          "server_name": {
            "type": "string",
            "description": "MCP server name, unique within the account."
          },
          "description": {
            "type": "string",
            "description": "Server description."
          },
          "ai_description": {
            "type": "string",
            "description": "LLM-generated description, preferred over `description` when present."
          },
          "transport": {
            "type": "string",
            "description": "Transport protocol.",
            "enum": [
              "stdio",
              "sse",
              "streamable-http"
            ]
          },
          "command": {
            "type": "string",
            "description": "Executable command (stdio transport only)."
          },
          "args": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command arguments (stdio transport)."
          },
          "env": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Environment variables (stdio transport). Secret values are masked."
          },
          "url": {
            "type": "string",
            "description": "Server URL (sse / streamable-http transport)."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "HTTP headers (sse / streamable-http). Secret values are masked."
          },
          "proxy_url": {
            "type": "string",
            "description": "Outbound proxy URL used to reach the server."
          },
          "status": {
            "type": "string",
            "description": "Server status.",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "connect_timeout": {
            "type": "integer",
            "description": "Connection timeout in seconds (0 = server default, 10s)."
          },
          "call_timeout": {
            "type": "integer",
            "description": "Tool-call timeout in seconds (0 = server default, 60s)."
          },
          "allow_insecure_oauth_http": {
            "type": "boolean",
            "description": "Allow this server's OAuth token exchange over plaintext HTTP; testing use only."
          },
          "allow_insecure_tls_skip_verify": {
            "type": "boolean",
            "description": "Skip TLS certificate verification when connecting to this server; testing use only."
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MCPToolInfo"
            },
            "description": "Live tool list; populated by the get/test endpoints."
          },
          "tool_count": {
            "type": "integer",
            "description": "Number of tools in the live list."
          },
          "list_error": {
            "type": "string",
            "description": "Error message when the live tool list failed."
          },
          "auth_mode": {
            "type": "string",
            "description": "Authentication mode.",
            "enum": [
              "shared",
              "per_user_secret",
              "per_user_oauth"
            ]
          },
          "secret_schema": {
            "type": "string",
            "description": "JSON-encoded secret schema (per_user_secret mode)."
          },
          "oauth_metadata": {
            "type": "string",
            "description": "JSON-encoded OAuth metadata (per_user_oauth mode)."
          },
          "source_template_name": {
            "type": "string",
            "description": "Marketplace template this connector was installed from; empty for user-authored."
          },
          "created_by": {
            "type": "integer",
            "description": "Member ID that created the server.",
            "format": "int64"
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Creation time. Unix timestamp in milliseconds."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Last update time. Unix timestamp in milliseconds."
          }
        },
        "required": [
          "server_id",
          "account_id",
          "team_id",
          "can_edit",
          "environment_kind",
          "environment_id",
          "server_name",
          "description",
          "transport",
          "status",
          "connect_timeout",
          "call_timeout",
          "created_by",
          "created_at",
          "updated_at"
        ]
      },
      "MCPServerListRequest": {
        "type": "object",
        "description": "Pagination, scope, and search filters for listing MCP servers.",
        "properties": {
          "p": {
            "type": "integer",
            "description": "Page number, 1-based.",
            "default": 1
          },
          "limit": {
            "type": "integer",
            "description": "Page size.",
            "default": 20
          },
          "scope": {
            "type": "string",
            "description": "Restrict results to a scope: `account` for account-wide rows only, `team` for the caller's own visible team rows only, or omit (defaults to `all`) for both, subject to team_ids/include_account.",
            "enum": [
              "all",
              "account",
              "team"
            ]
          },
          "query": {
            "type": "string",
            "maxLength": 128,
            "description": "Case-insensitive substring search across name, description, AI-generated description, server ID, transport, URL, command, and source template name."
          },
          "team_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Filter to these team IDs; empty = the caller's visible set."
          },
          "include_account": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Include account-scoped (team_id=0) rows. Defaults to true."
          }
        }
      },
      "MCPServerListResponse": {
        "type": "object",
        "description": "Paginated MCP server list.",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of matching servers.",
            "format": "int64"
          },
          "servers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MCPServerItem"
            },
            "description": "MCP servers on this page."
          }
        },
        "required": [
          "total",
          "servers"
        ]
      },
      "MCPServerStatusRequest": {
        "type": "object",
        "description": "MCP server enable/disable by ID.",
        "properties": {
          "server_id": {
            "type": "string",
            "description": "Target MCP server ID."
          }
        },
        "required": [
          "server_id"
        ]
      },
      "MCPServerUpdateRequest": {
        "type": "object",
        "description": "Partial update of an MCP server. Omit a field to leave it unchanged.",
        "properties": {
          "server_id": {
            "type": "string",
            "description": "Target MCP server ID."
          },
          "server_name": {
            "type": "string",
            "description": "New name.",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "description": "New description.",
            "minLength": 1,
            "maxLength": 1024
          },
          "transport": {
            "type": "string",
            "description": "Transport protocol.",
            "enum": [
              "stdio",
              "sse",
              "streamable-http"
            ]
          },
          "command": {
            "type": "string",
            "description": "Executable command (stdio transport)."
          },
          "args": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command arguments (stdio transport)."
          },
          "env": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Environment variables (stdio transport)."
          },
          "url": {
            "type": "string",
            "description": "Server URL (sse / streamable-http transport)."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "HTTP headers (sse / streamable-http)."
          },
          "connect_timeout": {
            "type": "integer",
            "description": "Connection timeout in seconds. 0 = default (10s)."
          },
          "call_timeout": {
            "type": "integer",
            "description": "Tool-call timeout in seconds. 0 = default (60s)."
          },
          "auth_mode": {
            "type": "string",
            "description": "Authentication mode: shared (default), per_user_secret, or per_user_oauth."
          },
          "secret_schema": {
            "type": "string",
            "description": "JSON secret schema; required when auth_mode=per_user_secret."
          },
          "oauth_metadata": {
            "type": "string",
            "description": "JSON OAuth metadata; reserved for per_user_oauth."
          },
          "team_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Reassign team scope: 0 = account-wide; >0 = team. Omit to leave unchanged.",
            "format": "int64"
          },
          "environment_kind": {
            "type": [
              "string",
              "null"
            ],
            "description": "Reassign the runner binding: `byoc` (with environment_id) or empty string to reset to automatic selection. Omit (null) to leave the current binding unchanged."
          },
          "environment_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Runner ID paired with environment_kind=byoc. Omit (null) to leave the current binding unchanged."
          },
          "allow_insecure_oauth_http": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Allow OAuth token exchange over plaintext HTTP. Omit to leave unchanged."
          },
          "allow_insecure_tls_skip_verify": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Skip TLS certificate verification. Omit to leave unchanged."
          }
        },
        "required": [
          "server_id"
        ]
      },
      "MCPToolInfo": {
        "type": "object",
        "description": "Metadata for one tool exposed by an MCP server.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Tool name."
          },
          "description": {
            "type": "string",
            "description": "Tool description."
          },
          "input_schema": {
            "type": "object",
            "additionalProperties": true,
            "description": "JSON Schema describing the tool's input parameters."
          }
        },
        "required": [
          "name",
          "description"
        ]
      },
      "ManualRunRuleResult": {
        "type": "object",
        "description": "Result of manually running an Automation rule outside its schedule.",
        "properties": {
          "rule_id": {
            "type": "string",
            "description": "Rule ID that was run."
          },
          "trigger_kind": {
            "type": "string",
            "enum": [
              "manual"
            ],
            "description": "Always manual for this operation."
          },
          "preflight": {
            "$ref": "#/components/schemas/PreflightResult"
          },
          "run": {
            "$ref": "#/components/schemas/AutomationRunView"
          }
        },
        "required": [
          "rule_id",
          "trigger_kind",
          "preflight"
        ]
      },
      "PreflightResult": {
        "type": "object",
        "description": "Readiness checks computed before a manual run is allowed to start.",
        "properties": {
          "ok": {
            "type": "boolean",
            "description": "Whether all readiness checks passed. Always true in a response that reaches the caller — a failed preflight returns a 400/403 error instead of a payload with ok=false."
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Names of the readiness checks performed, in order. Current fixed set: rule_loaded, actor_authorized, app_allowed, runtime_scope_resolved, rule_config_valid."
          },
          "scope": {
            "type": "string",
            "enum": [
              "person",
              "team"
            ],
            "description": "Resolved run scope for this run; mirrors the rule's run_scope."
          },
          "owner_id": {
            "type": "integer",
            "format": "int64",
            "description": "Rule owner person ID."
          },
          "team_id": {
            "type": "integer",
            "format": "int64",
            "description": "Rule's scope team ID; 0 means a personal rule."
          },
          "app_name": {
            "type": "string",
            "description": "App the rule is scoped to. Currently always ai-sre; manual runs are only supported for that app."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Non-fatal warnings surfaced during preflight. Omitted or empty when there are none."
          }
        },
        "required": [
          "ok",
          "checks",
          "scope",
          "owner_id",
          "team_id",
          "app_name"
        ]
      },
      "ResponseEnvelope": {
        "type": "object",
        "description": "Standard response envelope used by every Flashduty public API. On success `data` contains the endpoint-specific payload and `error` is absent. On failure `error` is present and `data` is absent. `request_id` is always present and is also mirrored in the `Flashcat-Request-Id` response header.",
        "properties": {
          "request_id": {
            "type": "string",
            "description": "Unique ID for this request. Mirrored in the Flashcat-Request-Id header. Include it when reporting issues.",
            "example": "01HK8XQE3Z7JM2NTFQ5YJ8P9R4"
          },
          "error": {
            "$ref": "#/components/schemas/DutyError"
          },
          "data": {
            "description": "Endpoint-specific payload. See each operation's 200 response schema."
          }
        },
        "required": [
          "request_id"
        ]
      },
      "SessionDeleteRequest": {
        "type": "object",
        "description": "Session deletion by ID.",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Target session ID.",
            "minLength": 1
          }
        },
        "required": [
          "session_id"
        ]
      },
      "SessionExportRequest": {
        "type": "object",
        "description": "Export the full event transcript of one session as a streaming NDJSON body.",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Target session ID."
          },
          "include_subagents": {
            "type": "boolean",
            "description": "When true, each subagent_dispatch line is followed by the child session's full event stream, bracketed by its own session_meta. Defaults to false."
          }
        },
        "required": [
          "session_id"
        ]
      },
      "SessionGetRequest": {
        "type": "object",
        "description": "Fetch one session plus a backward-paged window of its most recent events.",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Target session ID.",
            "minLength": 1
          },
          "num_recent_events": {
            "type": "integer",
            "description": "Legacy page size: number of most-recent events to return. Superseded by `limit` when both are set; 0 uses the server default (100).",
            "minimum": 0,
            "maximum": 1000
          },
          "limit": {
            "type": "integer",
            "description": "Page size for events; takes precedence over `num_recent_events`. 0 uses the server default (100).",
            "minimum": 0,
            "maximum": 1000
          },
          "search_after_ctx": {
            "type": "string",
            "description": "Opaque keyset cursor from a previous response; pass it back to fetch the next older page.",
            "maxLength": 4096
          }
        },
        "required": [
          "session_id"
        ]
      },
      "SessionGetResponse": {
        "type": "object",
        "description": "A session plus a backward-paged window of its events.",
        "properties": {
          "session": {
            "$ref": "#/components/schemas/SessionItem"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventItem"
            },
            "description": "Recent events, ascending by (created_at, event_id)."
          },
          "has_more_older": {
            "type": "boolean",
            "description": "True when older events remain beyond this page."
          },
          "search_after_ctx": {
            "type": "string",
            "description": "Opaque keyset cursor; pass back as search_after_ctx to fetch the next older page. Omitted when has_more_older is false."
          },
          "suggest_init": {
            "type": "boolean",
            "description": "Account-wide onboarding flag: true when the account has zero knowledge packs in any scope; not specific to this session."
          }
        },
        "required": [
          "session",
          "events",
          "has_more_older",
          "suggest_init"
        ]
      },
      "SessionItem": {
        "type": "object",
        "description": "One agent session row.",
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Session identifier."
          },
          "parent_session_id": {
            "type": "string",
            "description": "Parent session id for subagent (child) sessions; empty otherwise."
          },
          "session_name": {
            "type": "string",
            "description": "Session title; may be empty for untitled sessions."
          },
          "app_name": {
            "type": "string",
            "description": "Agent app that owns the session."
          },
          "entry_kind": {
            "type": "string",
            "description": "Surface that created the session.",
            "enum": [
              "web",
              "im",
              "api",
              "automation",
              "subagent"
            ]
          },
          "person_id": {
            "type": "string",
            "description": "Creator person id."
          },
          "team_id": {
            "type": "integer",
            "format": "int64",
            "description": "Owning team id; 0 means no team is bound. Immutable after create."
          },
          "team_name": {
            "type": "string",
            "description": "Resolved team name; empty for unbound rows or deleted teams."
          },
          "is_mine": {
            "type": "boolean",
            "description": "True when the caller created this session."
          },
          "can_manage": {
            "type": "boolean",
            "description": "True when the caller may rename/archive/delete the session; personal sessions are creator-only, team sessions allow the creator, account admin, or team member."
          },
          "status": {
            "type": "string",
            "description": "Lifecycle status.",
            "enum": [
              "enabled",
              "deleted"
            ]
          },
          "incognito": {
            "type": "boolean",
            "description": "True for incognito (non-persisted-memory) sessions."
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds when the session was created."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds of the last session update."
          },
          "template_staging_round_id": {
            "type": "string",
            "description": "Current save→validate round id (template-assistant only); empty otherwise."
          },
          "state": {
            "type": "object",
            "additionalProperties": true,
            "description": "Raw session-state bag (session-scoped keys). Omitted when empty."
          },
          "bound_environment": {
            "$ref": "#/components/schemas/EnvironmentBinding"
          },
          "context_resolved": {
            "$ref": "#/components/schemas/ContextResolvedItem"
          },
          "token_usage": {
            "$ref": "#/components/schemas/SessionTokenUsage"
          },
          "current_context_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Size in tokens of the LLM context window as of the most recent turn. 0 means no turn has completed."
          },
          "context_window": {
            "type": "integer",
            "format": "int64",
            "description": "The bound model's max context size in tokens. 0 means unknown."
          },
          "archived_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds when archived; 0 means not archived."
          },
          "pinned_at": {
            "type": "integer",
            "format": "int64",
            "description": "Caller's per-user pin timestamp in milliseconds; 0 means not pinned."
          },
          "last_event_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds of the most recent assistant-side event."
          },
          "is_running": {
            "type": "boolean",
            "description": "True when an agent turn is currently in flight for this session."
          },
          "has_unread": {
            "type": "boolean",
            "description": "True when there is assistant output the caller has not yet viewed."
          },
          "current_turn_started_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix timestamp in milliseconds when the current or most recent round started; 0 if no round has started yet."
          },
          "current_turn_active_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Active working duration in milliseconds for the current or most recent round, excluding time spent waiting on ask_user; resets to 0 at the start of each new round."
          },
          "current_turn_wait_ms": {
            "type": "integer",
            "format": "int64",
            "description": "Accumulated ask_user human-wait duration in milliseconds for the current round; resets to 0 at the start of each new round."
          },
          "current_turn_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Total tokens (input+output+reasoning) for the in-flight round across the parent and its subagents; only computed by session/get while the session is running, always 0 in session/list responses and when idle."
          }
        },
        "required": [
          "session_id",
          "session_name",
          "app_name",
          "person_id",
          "team_id",
          "is_mine",
          "can_manage",
          "status",
          "incognito",
          "created_at",
          "updated_at",
          "current_context_tokens",
          "context_window",
          "archived_at",
          "pinned_at",
          "is_running",
          "has_unread",
          "current_turn_started_at",
          "current_turn_active_ms",
          "current_turn_wait_ms",
          "current_turn_tokens"
        ]
      },
      "SessionListRequest": {
        "type": "object",
        "description": "Filters for listing agent sessions. `all` visibility means the caller's own personal sessions plus accessible team sessions; account admins do not see other users' personal sessions.",
        "properties": {
          "app_name": {
            "type": "string",
            "description": "Agent app whose sessions to list.",
            "enum": [
              "ask-ai",
              "support",
              "support-website",
              "support-flashcat",
              "ai-sre",
              "template-assistant",
              "swe"
            ]
          },
          "p": {
            "type": "integer",
            "description": "Page number, 1-based.",
            "default": 1,
            "minimum": 1
          },
          "limit": {
            "type": "integer",
            "description": "Page size, 1–100.",
            "minimum": 1,
            "maximum": 100,
            "default": 20
          },
          "orderby": {
            "type": "string",
            "description": "Sort field.",
            "enum": [
              "created_at",
              "updated_at"
            ]
          },
          "asc": {
            "type": "boolean",
            "description": "Ascending order when true; applies only when `orderby` is set."
          },
          "include_subagent_sessions": {
            "type": "boolean",
            "description": "Include subagent-dispatched sessions in the list."
          },
          "keyword": {
            "type": "string",
            "description": "Filter by session-name keyword.",
            "maxLength": 64
          },
          "scope": {
            "type": "string",
            "description": "Visibility scope: `all` (own personal + accessible team sessions), `personal`, or `team`; default `all`.",
            "enum": [
              "all",
              "personal",
              "team"
            ]
          },
          "team_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Optional explicit team filter; intersects with `scope` and never expands access."
          },
          "entry_kinds": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "web",
                "im",
                "api",
                "automation"
              ]
            },
            "description": "Restrict to sessions produced by these surfaces; empty returns every kind."
          },
          "status": {
            "type": "string",
            "description": "Archive bucket: active (default) returns un-archived, archived returns archived, all returns both.",
            "enum": [
              "active",
              "archived",
              "all"
            ]
          }
        },
        "required": [
          "app_name"
        ]
      },
      "SessionListResponse": {
        "type": "object",
        "description": "A page of agent sessions.",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of sessions matching the filter (ignoring pagination)."
          },
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionItem"
            },
            "description": "The page of sessions."
          },
          "suggest_init": {
            "type": "boolean",
            "description": "Account-wide onboarding flag: true when the account has zero knowledge packs in any scope; not dependent on this call's filters."
          }
        },
        "required": [
          "total",
          "sessions",
          "suggest_init"
        ]
      },
      "SessionTokenUsage": {
        "type": "object",
        "description": "Cumulative session-level token rollup across all turns. The account-billing source of truth.",
        "properties": {
          "input_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Total prompt (input) tokens, including the cached portion."
          },
          "cached_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Portion of input_tokens served from the prompt cache."
          },
          "output_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Total generated (output) tokens."
          },
          "reasoning_tokens": {
            "type": "integer",
            "format": "int64",
            "description": "Total reasoning/thinking tokens."
          }
        },
        "required": [
          "input_tokens",
          "cached_tokens",
          "output_tokens",
          "reasoning_tokens"
        ]
      },
      "SkillDeleteRequest": {
        "type": "object",
        "description": "Skill deletion by ID.",
        "properties": {
          "skill_id": {
            "type": "string",
            "description": "Target skill ID."
          }
        },
        "required": [
          "skill_id"
        ]
      },
      "SkillGetRequest": {
        "type": "object",
        "description": "Skill lookup by ID.",
        "properties": {
          "skill_id": {
            "type": "string",
            "description": "Target skill ID."
          }
        },
        "required": [
          "skill_id"
        ]
      },
      "SkillItem": {
        "type": "object",
        "description": "An AI SRE skill — a packaged SKILL.md bundle the agent can load.",
        "properties": {
          "skill_id": {
            "type": "string",
            "description": "Unique skill ID (prefix `skill_`)."
          },
          "account_id": {
            "type": "integer",
            "description": "Owning account ID.",
            "format": "int64"
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope: 0 = account-wide; >0 = the owning team.",
            "format": "int64"
          },
          "skill_name": {
            "type": "string",
            "description": "Skill name, unique within the account."
          },
          "description": {
            "type": "string",
            "description": "Human-readable description from the SKILL.md frontmatter."
          },
          "description_en": {
            "type": "string",
            "description": "Optional English description. English-locale UI responses prefer this over `description`; the skill catalog also uses it as a stable selection signal when `description` is localized for display."
          },
          "content": {
            "type": "string",
            "description": "Full SKILL.md content. Omitted in list responses."
          },
          "version": {
            "type": "string",
            "description": "Skill version from the frontmatter."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags parsed from the frontmatter."
          },
          "author": {
            "type": "string",
            "description": "Skill author."
          },
          "license": {
            "type": "string",
            "description": "Skill license."
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Required tools (builtin or `mcp:server/tool`)."
          },
          "s3_key": {
            "type": "string",
            "description": "Object-storage key of the skill zip."
          },
          "checksum": {
            "type": "string",
            "description": "SHA-256 checksum of the skill zip."
          },
          "status": {
            "type": "string",
            "description": "Skill status. Deleted skills are excluded from every API response, so only these two values are ever returned.",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "created_by": {
            "type": "integer",
            "description": "Member ID that created the skill.",
            "format": "int64"
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Creation time. Unix timestamp in milliseconds."
          },
          "updated_at": {
            "type": "integer",
            "format": "int64",
            "description": "Last update time. Unix timestamp in milliseconds."
          },
          "can_edit": {
            "type": "boolean",
            "description": "Whether the caller may edit this skill."
          },
          "source_template_name": {
            "type": "string",
            "description": "Marketplace template this skill was installed from; empty for user-authored."
          },
          "source_template_version": {
            "type": "string",
            "description": "Template version at install time."
          },
          "update_available": {
            "type": "boolean",
            "description": "True when the marketplace has a newer template version."
          },
          "is_modified": {
            "type": "boolean",
            "description": "True when a marketplace-sourced skill was edited locally (auto-update skips it)."
          },
          "created": {
            "type": "boolean",
            "description": "Set only on install-from-session responses: true = fresh install, false = in-place update."
          }
        },
        "required": [
          "skill_id",
          "account_id",
          "team_id",
          "skill_name",
          "description",
          "status",
          "created_by",
          "created_at",
          "updated_at",
          "can_edit",
          "update_available",
          "is_modified"
        ]
      },
      "SkillListRequest": {
        "type": "object",
        "description": "Pagination, search, and team filter for listing skills.",
        "properties": {
          "p": {
            "type": "integer",
            "description": "Page number, 1-based.",
            "default": 1
          },
          "limit": {
            "type": "integer",
            "description": "Page size.",
            "default": 20
          },
          "scope": {
            "type": "string",
            "description": "Restrict results to `all` (default), `account`-only (team_id=0), or `team`-only (excludes account-scoped rows). Overrides `include_account` when set.",
            "enum": [
              "all",
              "account",
              "team"
            ]
          },
          "query": {
            "type": "string",
            "description": "Free-text search across skill name, description, English description, skill ID, marketplace source template name, and author.",
            "maxLength": 128
          },
          "team_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Filter to these team IDs; empty = the caller's visible set."
          },
          "include_account": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Include account-scoped (team_id=0) rows. Defaults to true. Ignored when `scope` is `account` or `team`."
          }
        }
      },
      "SkillListResponse": {
        "type": "object",
        "description": "Paginated skill list.",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of matching skills.",
            "format": "int64"
          },
          "skills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SkillItem"
            },
            "description": "Skills on this page."
          }
        },
        "required": [
          "total",
          "skills"
        ]
      },
      "SkillStatusRequest": {
        "type": "object",
        "description": "Skill enable/disable by ID.",
        "properties": {
          "skill_id": {
            "type": "string",
            "description": "Target skill ID."
          }
        },
        "required": [
          "skill_id"
        ]
      },
      "SkillUpdateRequest": {
        "type": "object",
        "description": "Editable skill metadata.",
        "properties": {
          "skill_id": {
            "type": "string",
            "description": "Target skill ID."
          },
          "description": {
            "type": "string",
            "description": "New description. Cannot contain `<` or `>`. Sending an empty string leaves the current value unchanged — there is no way to clear it via this field.",
            "maxLength": 1024
          },
          "description_en": {
            "type": [
              "string",
              "null"
            ],
            "description": "New English description. Cannot contain `<` or `>`. Omit to leave unchanged; send an empty string to explicitly clear it.",
            "maxLength": 1024
          },
          "team_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Reassign team scope: 0 = account-wide; >0 = team. Omit to leave unchanged.",
            "format": "int64"
          }
        },
        "required": [
          "skill_id"
        ]
      },
      "SkillUploadRequest": {
        "type": "object",
        "description": "Multipart form for uploading a skill archive.",
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Skill archive (.skill / .zip / .tar.gz / .tgz). Max 100MB; oversized files are rejected before the body is read."
          },
          "team_id": {
            "type": "integer",
            "description": "Team scope for the created/upserted skill: 0 = account-wide. Ignored when replacing a specific skill via `skill_id`.",
            "format": "int64"
          },
          "replace": {
            "type": "boolean",
            "description": "When true, overwrite an existing skill instead of failing on a name collision — matched by `skill_id` if provided, otherwise by skill name."
          },
          "skill_id": {
            "type": "string",
            "description": "Existing skill ID to target when replacing a specific skill (requires `replace=true`)."
          }
        },
        "required": [
          "file"
        ]
      }
    }
  }
}