{
  "openapi": "3.1.0",
  "info": {
    "title": "Vigilia API",
    "version": "1.0.0",
    "summary": "Read your apps and incidents, and mark incidents fixed — the same things the Vigilia dashboard does.",
    "description": "Vigilia watches your live app, explains every problem in plain language and writes a fix prompt for your AI builder. This API gives your own scripts and AI agents the same view.\n\n**Authentication.** Create a personal access token in the dashboard under Settings → API tokens, and send it as `Authorization: Bearer vgs_…`. A token acts as you across every app you own, so keep it secret. Read-only tokens can call every `GET`; changing an incident needs a read & write token.\n\n**The fix loop.** List your open incidents (worst first), read one — its `fixPrompt` is written for your builder and its `evidence` carries the technical detail — fix it, then `POST …/resolve`. Resolving opens a fix watch: if the error stays away through real traffic for 24 hours, Vigilia confirms the fix (`fix.watch` becomes `verified`).\n\n**Rate limits.** Per token, per minute: Free 60, Pro 300, Team 600. Free accounts also have 2,000 requests a day across all their tokens (API and MCP together), reset at midnight UTC. Over either limit you get `429` with a `Retry-After` header; the daily one has the code `daily_limit`.\n\n**Conventions.** Timestamps are epoch milliseconds. Errors are always `{ \"error\": { \"code\", \"message\" } }`. Something that exists but belongs to another account is reported as `404`, never `403`.",
    "contact": {
      "name": "Vigilia support",
      "email": "support@getvigilia.com",
      "url": "https://getvigilia.com"
    }
  },
  "servers": [
    {
      "url": "https://app.getvigilia.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Who the token belongs to."
    },
    {
      "name": "Apps",
      "description": "The apps Vigilia watches for you."
    },
    {
      "name": "Incidents",
      "description": "Diagnosed problems, in plain language, with a fix prompt."
    },
    {
      "name": "Errors",
      "description": "Every error group Vigilia recorded, diagnosed or not."
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "The account and plan behind this token",
        "operationId": "getMe",
        "responses": {
          "200": {
            "description": "The token's owner, plan and limits.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/apps": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "List your apps",
        "operationId": "listApps",
        "responses": {
          "200": {
            "description": "Every app you own, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apps"
                  ],
                  "properties": {
                    "apps": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/App"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "openIncidents": {
                                "type": "integer"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/apps/{appId}": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "An app's health right now",
        "description": "Uptime, open incidents by severity, today's events and this month's AI diagnosis budget.",
        "operationId": "getApp",
        "parameters": [
          {
            "$ref": "#/components/parameters/AppId"
          }
        ],
        "responses": {
          "200": {
            "description": "The app and its health.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "app"
                  ],
                  "properties": {
                    "app": {
                      "$ref": "#/components/schemas/AppHealth"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/apps/{appId}/errors": {
      "get": {
        "tags": [
          "Errors"
        ],
        "summary": "An app's error groups, most recently seen first",
        "description": "Every distinct error Vigilia recorded for the app — including ones it filtered as noise, or held back for budget — not only the diagnosed ones.",
        "operationId": "listErrors",
        "parameters": [
          {
            "$ref": "#/components/parameters/AppId"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "resolved",
                "ignored",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Error groups.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "errors",
                    "hasMore"
                  ],
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ErrorGroup"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/apps/{appId}/check-install": {
      "post": {
        "tags": [
          "Apps"
        ],
        "summary": "Check the snippet is installed and allowed to run",
        "description": "Fetches the app's pages and verifies that vigilia.js is present and that the site's Content-Security-Policy lets it load and report. Any token can run it.",
        "operationId": "checkInstall",
        "parameters": [
          {
            "$ref": "#/components/parameters/AppId"
          }
        ],
        "responses": {
          "200": {
            "description": "The verdict, per address the app runs on.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "installCheck"
                  ],
                  "properties": {
                    "installCheck": {
                      "type": "object",
                      "properties": {
                        "checkedAt": {
                          "type": "integer"
                        },
                        "ok": {
                          "type": "boolean",
                          "description": "At least one address serves a working snippet."
                        },
                        "origins": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/incidents": {
      "get": {
        "tags": [
          "Incidents"
        ],
        "summary": "List incidents — open ones worst first",
        "description": "Open incidents come back by severity, then most recent: the order to fix them in.",
        "operationId": "listIncidents",
        "parameters": [
          {
            "name": "appId",
            "in": "query",
            "description": "Only this app's incidents.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "resolved",
                "ignored",
                "all"
              ],
              "default": "open"
            }
          },
          {
            "name": "severity",
            "in": "query",
            "description": "Comma-separated, e.g. `critical,high`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Incidents.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "incidents",
                    "hasMore"
                  ],
                  "properties": {
                    "incidents": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Incident"
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/incidents/{incidentId}": {
      "get": {
        "tags": [
          "Incidents"
        ],
        "summary": "One incident, with its fix prompt and the evidence behind it",
        "operationId": "getIncident",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncidentId"
          }
        ],
        "responses": {
          "200": {
            "description": "The incident.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "incident"
                  ],
                  "properties": {
                    "incident": {
                      "$ref": "#/components/schemas/IncidentDetail"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/incidents/{incidentId}/resolve": {
      "post": {
        "tags": [
          "Incidents"
        ],
        "summary": "Mark an incident fixed — and start verifying it",
        "description": "Resolving a diagnosed error opens a fix watch: if the error stays away through real traffic for 24 hours, `fix.watch` becomes `verified` and the owner gets a \"your fix worked\" email. If it comes back, the incident reopens flagged as a regression.",
        "operationId": "resolveIncident",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncidentId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IncidentChanged"
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/incidents/{incidentId}/ignore": {
      "post": {
        "tags": [
          "Incidents"
        ],
        "summary": "Ignore an incident",
        "description": "Ignored errors don't reopen and aren't verified.",
        "operationId": "ignoreIncident",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncidentId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IncidentChanged"
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/incidents/{incidentId}/reopen": {
      "post": {
        "tags": [
          "Incidents"
        ],
        "summary": "Reopen an incident",
        "operationId": "reopenIncident",
        "parameters": [
          {
            "$ref": "#/components/parameters/IncidentId"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/IncidentChanged"
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/apps/{appId}/deploys": {
      "post": {
        "tags": [
          "Apps"
        ],
        "summary": "Tell Vigilia a new version went live",
        "description": "Call it from CI or a deploy hook. Vigilia also notices deploys on its own from the page's build; a marker adds your label (a version or commit) and exact timing. Errors that begin within a day of a deploy say so on their incident (`afterDeploy`). The same label posted twice within ten minutes is treated as one deploy. Needs a read & write token.",
        "operationId": "markDeploy",
        "parameters": [
          {
            "$ref": "#/components/parameters/AppId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 80,
                    "description": "e.g. \"v1.4.2\" or a commit SHA"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deploy": {
                      "type": "object",
                      "properties": {
                        "at": {
                          "type": "integer"
                        },
                        "label": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/InsufficientScope"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A personal access token (`vgs_…`) from Settings → API tokens."
      }
    },
    "parameters": {
      "AppId": {
        "name": "appId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "IncidentId": {
        "name": "incidentId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthenticated": {
        "description": "No token, or not a valid one.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InsufficientScope": {
        "description": "The token is read-only.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such thing on your account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InvalidRequest": {
        "description": "A parameter has a value that isn't allowed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests for this token (`rate_limited`), or a Free account's daily requests are used up (`daily_limit`) — wait `Retry-After` seconds.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "IncidentChanged": {
        "description": "The incident after the change.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "incident"
              ],
              "properties": {
                "incident": {
                  "$ref": "#/components/schemas/Incident"
                },
                "message": {
                  "type": "string",
                  "description": "Present when a fix watch started."
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "unauthenticated",
                  "insufficient_scope",
                  "not_found",
                  "invalid_request",
                  "rate_limited",
                  "internal"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Me": {
        "type": "object",
        "properties": {
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "plan": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "enum": [
                  "free",
                  "pro",
                  "team"
                ]
              },
              "name": {
                "type": "string"
              },
              "maxApps": {
                "type": "integer"
              },
              "diagnosesPerMonth": {
                "type": "integer"
              }
            }
          },
          "token": {
            "type": "object",
            "properties": {
              "scope": {
                "type": "string",
                "enum": [
                  "read",
                  "write"
                ]
              },
              "requestsPerMinute": {
                "type": "integer"
              }
            }
          }
        }
      },
      "App": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "builder": {
            "type": "string",
            "enum": [
              "lovable",
              "bolt",
              "v0",
              "cursor",
              "claude-code",
              "replit",
              "other"
            ]
          },
          "createdAt": {
            "type": "integer"
          },
          "installed": {
            "type": "boolean",
            "description": "Vigilia has received at least one event."
          },
          "withinPlan": {
            "type": "boolean",
            "description": "False for an app beyond the plan's app limit: it records, but isn't diagnosed."
          },
          "uptime": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "up",
                  "down",
                  "unknown"
                ]
              },
              "lastCheckedAt": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "dashboardUrl": {
            "type": "string"
          }
        }
      },
      "AppHealth": {
        "allOf": [
          {
            "$ref": "#/components/schemas/App"
          },
          {
            "type": "object",
            "properties": {
              "uptime": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "lastCheckedAt": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "lastDownAt": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "uptimePercentLastHour": {
                    "type": [
                      "number",
                      "null"
                    ]
                  }
                }
              },
              "openIncidents": {
                "type": "object",
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "critical": {
                    "type": "integer"
                  },
                  "high": {
                    "type": "integer"
                  },
                  "medium": {
                    "type": "integer"
                  },
                  "low": {
                    "type": "integer"
                  }
                }
              },
              "events": {
                "type": "object",
                "properties": {
                  "today": {
                    "type": "integer"
                  },
                  "total": {
                    "type": "integer"
                  },
                  "lastEventAt": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  }
                }
              },
              "aiDiagnoses": {
                "type": "object",
                "description": "This month's budget of AI diagnoses for the app. On Free it's the allowance; on paid plans, a fair-use ceiling.",
                "properties": {
                  "used": {
                    "type": "integer"
                  },
                  "limit": {
                    "type": "integer"
                  },
                  "remaining": {
                    "type": "integer"
                  },
                  "resetsAt": {
                    "type": "integer"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "allowance",
                      "fair-use"
                    ]
                  }
                }
              }
            }
          }
        ]
      },
      "Incident": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "appId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "error",
              "downtime",
              "health"
            ],
            "description": "error: errors from real visitors, diagnosed. downtime: the uptime checker. health: a recurring check of the app itself (secret keys in its public code, its certificate)."
          },
          "check": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "secrets",
              "certificate",
              "domain",
              "speed",
              null
            ],
            "description": "Health incidents: which check raised it. `speed`: the app answers several times slower than its usual."
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Health incidents: the specifics, e.g. each exposed key, masked, and where it was found. Empty otherwise."
          },
          "endpoint": {
            "type": [
              "object",
              "null"
            ],
            "description": "Downtime incidents about one of the app's extra check URLs (a page such as checkout, or an API), rather than the whole app. Null otherwise.",
            "properties": {
              "url": {
                "type": "string"
              },
              "label": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The owner's name for it, e.g. Checkout."
              }
            },
            "required": [
              "url",
              "label"
            ]
          },
          "sentry": {
            "type": [
              "object",
              "null"
            ],
            "description": "The Sentry issue this incident explains, when it came through the Sentry bridge (Team). Null otherwise.",
            "properties": {
              "url": {
                "type": "string"
              }
            },
            "required": [
              "url"
            ]
          },
          "issue": {
            "type": [
              "object",
              "null"
            ],
            "description": "The issue opened for this incident in GitHub Issues, Linear or Jira (Team plan), by hand or automatically. Null when there is none.",
            "properties": {
              "tracker": {
                "type": "string",
                "enum": [
                  "github",
                  "linear",
                  "jira"
                ]
              },
              "url": {
                "type": "string"
              },
              "key": {
                "type": "string",
                "description": "#123, ENG-45, SHOP-7"
              }
            },
            "required": [
              "tracker",
              "url",
              "key"
            ]
          },
          "related": {
            "type": [
              "object",
              "null"
            ],
            "description": "The same problem seen from the other side: for a request that failed with a 5xx in visitors' browsers, the server error behind it (side: server); for a server error, the failed request visitors saw (side: browser). Null when there is none.",
            "properties": {
              "side": {
                "type": "string",
                "enum": [
                  "server",
                  "browser"
                ]
              },
              "incidentId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "title": {
                "type": "string"
              },
              "count": {
                "type": "integer"
              }
            },
            "required": [
              "side",
              "incidentId",
              "title",
              "count"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "high",
              "medium",
              "low"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "resolved",
              "ignored"
            ]
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "description": "What broke, in plain language."
          },
          "userImpact": {
            "type": "string",
            "description": "Who is affected and how."
          },
          "occurrences": {
            "type": [
              "integer",
              "null"
            ]
          },
          "sessions": {
            "type": [
              "integer",
              "null"
            ]
          },
          "isRegression": {
            "type": "boolean",
            "description": "It was marked fixed and came back."
          },
          "createdAt": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "integer"
          },
          "resolvedAt": {
            "type": [
              "integer",
              "null"
            ]
          },
          "fix": {
            "type": "object",
            "properties": {
              "watch": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "watching",
                  "verified",
                  "unverified",
                  null
                ]
              },
              "verifiedAt": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "dashboardUrl": {
            "type": "string"
          },
          "afterDeploy": {
            "type": [
              "object",
              "null"
            ],
            "description": "The deploy this problem first appeared after, within a day. Timing, not blame.",
            "properties": {
              "at": {
                "type": "integer"
              },
              "label": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "providerOutage": {
            "type": [
              "object",
              "null"
            ],
            "description": "A platform the app depends on (Supabase, Vercel, OpenAI…) was reporting its own incident when this began, from its public status page. There may be nothing to fix in the app. `resolvedAt` is set once the provider marks it resolved; if the problem continues after that, the cause is likely the app's.",
            "properties": {
              "provider": {
                "type": "string",
                "examples": [
                  "Supabase"
                ]
              },
              "incident": {
                "type": "string",
                "description": "The provider's own title for its incident."
              },
              "level": {
                "type": "string",
                "enum": [
                  "outage",
                  "degraded"
                ]
              },
              "url": {
                "type": "string",
                "description": "The provider's status page for this incident."
              },
              "startedAt": {
                "type": "integer"
              },
              "resolvedAt": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        }
      },
      "IncidentDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Incident"
          },
          {
            "type": "object",
            "properties": {
              "builder": {
                "type": "string"
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "fixPrompt": {
                "type": "string",
                "description": "A paste-ready prompt for the app's builder, or for any coding agent."
              },
              "evidence": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "normalizedMessage": {
                    "type": "string"
                  },
                  "page": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Where the visitor was — not necessarily where the fault is."
                  },
                  "pagePattern": {
                    "type": "string"
                  },
                  "source": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Script, or for a failed request the endpoint that failed."
                  },
                  "line": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "column": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "httpStatus": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "stack": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "sourceStack": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string"
                    },
                    "description": "The top frames in the app's original code, resolved through its published source maps (e.g. `at src/pages/Checkout.tsx:42:7` with a few lines of source). Null when the app publishes no source maps."
                  },
                  "breadcrumbs": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "at": {
                          "type": "integer"
                        },
                        "type": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "userAgent": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "environment": {
                    "type": "string",
                    "enum": [
                      "production",
                      "development"
                    ]
                  },
                  "count": {
                    "type": "integer"
                  },
                  "sessions": {
                    "type": "integer"
                  },
                  "firstSeenAt": {
                    "type": "integer"
                  },
                  "lastSeenAt": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        ]
      },
      "ErrorGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "appId": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "error",
              "unhandledrejection",
              "console_error",
              "failed_fetch"
            ]
          },
          "title": {
            "type": "string"
          },
          "pagePattern": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "resolved",
              "ignored"
            ]
          },
          "diagnosis": {
            "type": "string",
            "enum": [
              "pending",
              "diagnosing",
              "done",
              "failed",
              "skipped",
              "filtered"
            ]
          },
          "skipReason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "budget",
              "fair-use",
              "app-limit",
              null
            ]
          },
          "filterReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "count": {
            "type": "integer"
          },
          "sessions": {
            "type": "integer"
          },
          "firstSeenAt": {
            "type": "integer"
          },
          "lastSeenAt": {
            "type": "integer"
          },
          "regressed": {
            "type": "boolean"
          },
          "environment": {
            "type": "string"
          },
          "incidentId": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    }
  }
}
