{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Incident Platform Public API",
    "version": "0.1.0",
    "description": "Canonical wire contract for SDK-to-ingest communication in the incident platform."
  },
  "servers": [
    {
      "url": "http://localhost:3001",
      "description": "Local Bun ingest service"
    },
    {
      "url": "https://dashboard.example.com",
      "description": "Placeholder dashboard origin for authenticated observation routes; use the deployed dashboard URL"
    }
  ],
  "tags": [
    {
      "name": "ingest",
      "description": "Endpoints used by SDKs to submit incident events."
    },
    {
      "name": "observation",
      "description": "Metadata-only operator reads through the dashboard mobile bridge."
    },
    {
      "name": "project-onboarding",
      "description": "Authenticated operator project setup and explicit capture-key read."
    }
  ],
  "components": {
    "securitySchemes": {
      "projectKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Project key used by SDKs to authenticate batch requests."
      },
      "operatorBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authenticated Dancer operator token. Project app keys cannot read analytics."
      }
    },
    "schemas": {
      "TimestampValue": {
        "description": "Event timestamps may be emitted as ISO-8601 strings or Unix epoch milliseconds.",
        "oneOf": [
          {
            "type": "string",
            "format": "date-time"
          },
          {
            "type": "integer",
            "format": "int64"
          },
          {
            "type": "number"
          }
        ]
      },
      "UnknownMap": {
        "type": "object",
        "additionalProperties": true
      },
      "PlatformRuntime": {
        "type": "object",
        "description": "Shared runtime bucket that identifies how the event was collected.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "Platform identifier such as ios, android, web, or node."
          },
          "environment": {
            "type": "string",
            "description": "Collector environment such as expo-react-native, browser, or node."
          },
          "collector": {
            "type": "string",
            "description": "Collector implementation such as native-module, browser-sdk, or server-middleware."
          }
        },
        "additionalProperties": false
      },
      "PlatformContext": {
        "type": "object",
        "description": "Canonical normalized context bucket shared across SDKs.",
        "properties": {
          "runtime": {
            "$ref": "#/components/schemas/PlatformRuntime"
          },
          "app": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "device": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "os": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "expo": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "browser": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "request": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "server": {
            "$ref": "#/components/schemas/UnknownMap"
          }
        },
        "additionalProperties": false
      },
      "Breadcrumb": {
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "category": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "level": {
            "type": "string",
            "enum": [
              "debug",
              "info",
              "warning",
              "error"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/UnknownMap"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "IncidentError": {
        "type": "object",
        "required": [
          "name",
          "message"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "stack": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "IncidentContext": {
        "type": "object",
        "description": "Freeform event context. Shared normalized metadata must live under platformContext.",
        "properties": {
          "clientErrorId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
            "description": "Opaque UUIDv4 shared by direct exception capture and compatibility transports for one reported error. Distinct from eventId and server requestId."
          },
          "serverRequestId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
            "description": "Optional reported server operation ID for exact retained-log correlation. It does not authenticate the operation or grant log access."
          },
          "platformContext": {
            "$ref": "#/components/schemas/PlatformContext"
          }
        },
        "additionalProperties": true
      },
      "ExceptionEvent": {
        "type": "object",
        "required": [
          "eventId",
          "timestamp",
          "error"
        ],
        "properties": {
          "eventId": {
            "type": "string"
          },
          "timestamp": {
            "$ref": "#/components/schemas/TimestampValue"
          },
          "type": {
            "type": "string",
            "enum": [
              "exception"
            ]
          },
          "level": {
            "type": "string",
            "enum": [
              "debug",
              "info",
              "warning",
              "error",
              "fatal"
            ],
            "default": "error"
          },
          "release": {
            "type": "string"
          },
          "dist": {
            "type": "string"
          },
          "environment": {
            "type": "string",
            "description": "Application environment such as development, staging, preview, or production."
          },
          "error": {
            "$ref": "#/components/schemas/IncidentError"
          },
          "breadcrumbs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Breadcrumb"
            }
          },
          "context": {
            "$ref": "#/components/schemas/IncidentContext"
          }
        },
        "additionalProperties": false
      },
      "MessageEvent": {
        "type": "object",
        "required": [
          "eventId",
          "timestamp",
          "message"
        ],
        "properties": {
          "eventId": {
            "type": "string"
          },
          "timestamp": {
            "$ref": "#/components/schemas/TimestampValue"
          },
          "type": {
            "type": "string",
            "enum": [
              "message"
            ]
          },
          "level": {
            "type": "string",
            "enum": [
              "debug",
              "info",
              "warning",
              "error",
              "fatal"
            ],
            "default": "info"
          },
          "release": {
            "type": "string"
          },
          "dist": {
            "type": "string"
          },
          "environment": {
            "type": "string",
            "description": "Application environment such as development, staging, preview, or production."
          },
          "message": {
            "type": "string"
          },
          "breadcrumbs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Breadcrumb"
            }
          },
          "context": {
            "$ref": "#/components/schemas/IncidentContext"
          }
        },
        "additionalProperties": false
      },
      "ProductEventPropertyValue": {
        "description": "Privacy-bounded scalar product-event property value.",
        "oneOf": [
          {
            "type": "string",
            "maxLength": 128
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ]
      },
      "ProductEventProperties": {
        "type": "object",
        "description": "At most 8 flat scalar properties. Keys containing email, token, password, authorization, message, prompt, or content are forbidden by SDK and ingest validation.",
        "maxProperties": 8,
        "propertyNames": {
          "type": "string",
          "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
        },
        "additionalProperties": {
          "$ref": "#/components/schemas/ProductEventPropertyValue"
        }
      },
      "SignalRuntimeV1": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "kind": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "collector": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          }
        },
        "additionalProperties": false
      },
      "SignalContextFilter": {
        "type": "object",
        "description": "Exact-match AND filters over forward-only context coverage. Historical events without context do not match. No arbitrary tags, URLs or user identifiers.",
        "minProperties": 1,
        "properties": {
          "environment": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "release": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "dist": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "runtime": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SignalRuntimeV1"
              }
            ],
            "minProperties": 1
          }
        },
        "additionalProperties": false
      },
      "SignalContextV1": {
        "type": "object",
        "description": "Immutable capture-time application context. release and dist are distinct release and distribution identities, never inferred from an app version. Do not include identity or secrets.",
        "required": [
          "schemaVersion"
        ],
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "environment": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "release": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "dist": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "runtime": {
            "$ref": "#/components/schemas/SignalRuntimeV1"
          }
        },
        "additionalProperties": false
      },
      "ProductEvent": {
        "type": "object",
        "description": "A privacy-bounded product event. It does not imply an identified user or session.",
        "required": [
          "eventId",
          "timestamp",
          "type",
          "name"
        ],
        "properties": {
          "eventId": {
            "type": "string"
          },
          "timestamp": {
            "$ref": "#/components/schemas/TimestampValue"
          },
          "type": {
            "type": "string",
            "enum": [
              "product"
            ]
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "properties": {
            "$ref": "#/components/schemas/ProductEventProperties"
          },
          "context": {
            "$ref": "#/components/schemas/SignalContextV1"
          }
        },
        "additionalProperties": false
      },
      "ProductEventBatchRequest": {
        "type": "object",
        "required": [
          "events"
        ],
        "properties": {
          "events": {
            "type": "array",
            "minItems": 1,
            "maxItems": 25,
            "items": {
              "$ref": "#/components/schemas/ProductEvent"
            }
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsCountQuery": {
        "type": "object",
        "required": [
          "projectId",
          "kind",
          "event",
          "from",
          "to"
        ],
        "properties": {
          "context": {
            "$ref": "#/components/schemas/SignalContextFilter"
          },
          "projectId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "count"
            ]
          },
          "comparePreviousPeriod": {
            "type": "boolean",
            "description": "Compare with the equal-duration window immediately preceding from. Both windows are half-open UTC intervals, individually at most 30 days. When true, from and to must use whole-second precision."
          },
          "event": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsSeriesQuery": {
        "type": "object",
        "required": [
          "projectId",
          "kind",
          "event",
          "from",
          "to",
          "bucket"
        ],
        "properties": {
          "context": {
            "$ref": "#/components/schemas/SignalContextFilter"
          },
          "projectId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "series"
            ]
          },
          "event": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "bucket": {
            "type": "string",
            "enum": [
              "1h",
              "1d"
            ]
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsBreakdownQuery": {
        "type": "object",
        "required": [
          "projectId",
          "kind",
          "event",
          "from",
          "to",
          "property"
        ],
        "properties": {
          "context": {
            "$ref": "#/components/schemas/SignalContextFilter"
          },
          "projectId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "breakdown"
            ]
          },
          "event": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "property": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "default": 20
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsEventsQuery": {
        "type": "object",
        "description": "Observed names over a positive received-time window at most 30 days, with whole-second bounds. Search is a case-insensitive literal substring applied before the limit. No complete catalog is claimed.",
        "required": [
          "projectId",
          "kind",
          "from",
          "to"
        ],
        "properties": {
          "projectId": {
            "type": "string",
            "pattern": "^[a-z0-9]{1,64}$"
          },
          "kind": {
            "type": "string",
            "enum": [
              "events"
            ]
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "search": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_.:-]{1,64}$"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 50
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsQueryRequest": {
        "description": "A tenant-scoped aggregate query. from must precede to and the window cannot exceed 30 days.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ProductAnalyticsCountQuery"
          },
          {
            "$ref": "#/components/schemas/ProductAnalyticsSeriesQuery"
          },
          {
            "$ref": "#/components/schemas/ProductAnalyticsBreakdownQuery"
          },
          {
            "$ref": "#/components/schemas/ProductAnalyticsEventsQuery"
          }
        ]
      },
      "ProductAnalyticsAggregateRow": {
        "type": "object",
        "description": "Aggregate row. count is a sampling-weighted estimate, not an exact ledger count.",
        "properties": {
          "count": {
            "type": "number"
          },
          "name": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_.:-]{0,63}$",
            "description": "Observed event name, present for events queries."
          },
          "bucket": {
            "type": "number",
            "description": "Unix timestamp in seconds for a series bucket."
          },
          "propertyType": {
            "type": "string",
            "enum": [
              "string",
              "number",
              "boolean",
              "null"
            ]
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "count"
        ],
        "additionalProperties": false
      },
      "ProductAnalyticsCountWindow": {
        "type": "object",
        "required": [
          "from",
          "to",
          "count"
        ],
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "count": {
            "type": "number",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsCountComparison": {
        "type": "object",
        "description": "Present only for count queries with comparePreviousPeriod=true. Counts and deltas inherit the response quality caveats. Neither period's failure yields partial success.",
        "required": [
          "current",
          "previous",
          "absoluteDelta",
          "percentDelta"
        ],
        "properties": {
          "current": {
            "$ref": "#/components/schemas/ProductAnalyticsCountWindow"
          },
          "previous": {
            "$ref": "#/components/schemas/ProductAnalyticsCountWindow"
          },
          "absoluteDelta": {
            "type": "number",
            "description": "Current count minus previous count."
          },
          "percentDelta": {
            "type": [
              "number",
              "null"
            ],
            "description": "100 times absoluteDelta divided by previous count, or null when previous count is zero."
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsQuality": {
        "type": "object",
        "required": [
          "kind",
          "timeBasis",
          "delivery",
          "deduplicated"
        ],
        "properties": {
          "contextCoverage": {
            "type": "string",
            "enum": [
              "forward_only"
            ],
            "description": "Present for context-filtered queries. Only events captured with context can match; historical context is not backfilled."
          },
          "observedOnly": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "Present for discovery. Sampling can omit rare names even when truncated is false."
          },
          "retentionMonths": {
            "type": "integer",
            "enum": [
              3
            ],
            "description": "Current provider retention; present for discovery."
          },
          "kind": {
            "type": "string",
            "enum": [
              "sampled_estimate"
            ]
          },
          "timeBasis": {
            "type": "string",
            "enum": [
              "received"
            ]
          },
          "delivery": {
            "type": "string",
            "enum": [
              "best_effort"
            ]
          },
          "deduplicated": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        },
        "additionalProperties": false
      },
      "ProductAnalyticsQueryResponse": {
        "type": "object",
        "description": "Bounded aggregate analytics. Results are sampled estimates over received best-effort events; this is not an exact event ledger.",
        "required": [
          "data",
          "query",
          "quality"
        ],
        "properties": {
          "data": {
            "type": "array",
            "maxItems": 744,
            "items": {
              "$ref": "#/components/schemas/ProductAnalyticsAggregateRow"
            }
          },
          "query": {
            "$ref": "#/components/schemas/ProductAnalyticsQueryRequest"
          },
          "scope": {
            "type": "object",
            "description": "Required for events discovery; echoes the authorized project.",
            "required": [
              "kind",
              "projectId"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "project"
                ]
              },
              "projectId": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Effective discovery cap."
          },
          "truncated": {
            "type": "boolean",
            "description": "Discovery found more groups than the cap; false does not guarantee completeness under sampling."
          },
          "comparison": {
            "$ref": "#/components/schemas/ProductAnalyticsCountComparison"
          },
          "quality": {
            "$ref": "#/components/schemas/ProductAnalyticsQuality"
          }
        },
        "additionalProperties": false
      },
      "ProductEventBatchResponse": {
        "type": "object",
        "required": [
          "accepted",
          "eventIds",
          "delivery",
          "deduplicated"
        ],
        "properties": {
          "accepted": {
            "type": "integer",
            "minimum": 0
          },
          "eventIds": {
            "type": "array",
            "maxItems": 25,
            "items": {
              "type": "string"
            }
          },
          "delivery": {
            "type": "string",
            "enum": [
              "best_effort"
            ]
          },
          "deduplicated": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        },
        "additionalProperties": false
      },
      "IncidentBatchEvent": {
        "description": "Single event accepted by the public ingest API.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ExceptionEvent"
          },
          {
            "$ref": "#/components/schemas/MessageEvent"
          }
        ]
      },
      "SdkInfo": {
        "type": "object",
        "required": [
          "name",
          "version"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "IngestBatchRequest": {
        "type": "object",
        "required": [
          "events"
        ],
        "properties": {
          "projectKey": {
            "type": "string",
            "description": "Optional body fallback for environments where the Authorization header is inconvenient. Header auth remains the preferred path."
          },
          "sentAt": {
            "type": "string",
            "format": "date-time"
          },
          "sdk": {
            "$ref": "#/components/schemas/SdkInfo"
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/IncidentBatchEvent"
            }
          }
        },
        "additionalProperties": false,
        "examples": [
          {
            "sdk": {
              "name": "@incident/sdk",
              "version": "0.1.0"
            },
            "events": [
              {
                "eventId": "evt_example_1",
                "timestamp": "2026-03-06T18:41:53.016Z",
                "level": "error",
                "error": {
                  "name": "Error",
                  "message": "dev-expo smoke button"
                },
                "breadcrumbs": [
                  {
                    "category": "ui.action",
                    "level": "info",
                    "message": "Pressed Expo smoke-test button",
                    "data": {
                      "screen": "home",
                      "source": "incident-platform-dev-expo"
                    },
                    "timestamp": "2026-03-06T18:41:53.015Z"
                  }
                ],
                "context": {
                  "source": "incident-platform-dev-expo",
                  "surface": "home-screen",
                  "trigger": "button",
                  "platformContext": {
                    "runtime": {
                      "kind": "ios",
                      "environment": "expo-react-native",
                      "collector": "native-module"
                    },
                    "app": {
                      "bundleId": "com.incident.devexpo",
                      "version": "1.0.0",
                      "buildNumber": "1"
                    },
                    "device": {
                      "manufacturer": "Apple",
                      "model": "iPhone",
                      "isDevice": false
                    },
                    "os": {
                      "name": "iOS",
                      "version": "18.6"
                    }
                  }
                }
              }
            ]
          }
        ]
      },
      "IngestBatchResponse": {
        "type": "object",
        "required": [
          "accepted",
          "rejected",
          "eventIds"
        ],
        "properties": {
          "accepted": {
            "type": "integer",
            "minimum": 0
          },
          "rejected": {
            "type": "integer",
            "minimum": 0
          },
          "eventIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "SourceMapUploadRequest": {
        "type": "object",
        "required": [
          "release",
          "platform",
          "sourceMap"
        ],
        "properties": {
          "projectKey": {
            "type": "string",
            "description": "Optional body fallback for environments where the Authorization header is inconvenient. Header auth remains the preferred path."
          },
          "release": {
            "type": "string"
          },
          "dist": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "ios",
              "android"
            ]
          },
          "sourceMap": {
            "type": "string",
            "description": "Stringified source map JSON."
          }
        },
        "additionalProperties": false
      },
      "SourceMapUploadResponse": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "LogLevel": {
        "type": "string",
        "enum": [
          "debug",
          "info",
          "warn",
          "error"
        ]
      },
      "LogCorrelation": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "sessionId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "requestId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "traceId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "incidentId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "runId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          }
        },
        "required": []
      },
      "StructuredLog": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "logId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "timestamp": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "level": {
            "$ref": "#/components/schemas/LogLevel"
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "Diagnostic text only. Never interpolate user content or credentials; detected email and credential patterns are rejected."
          },
          "attributes": {
            "type": "object",
            "maxProperties": 16,
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string",
                  "maxLength": 128
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Flat scalar diagnostics. Sensitive keys and credential/email-like values are rejected."
          },
          "correlation": {
            "$ref": "#/components/schemas/LogCorrelation"
          }
        },
        "required": [
          "logId",
          "timestamp",
          "level",
          "message"
        ]
      },
      "LogBatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "logs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 25,
            "items": {
              "$ref": "#/components/schemas/StructuredLog"
            }
          }
        },
        "required": [
          "schemaVersion",
          "logs"
        ]
      },
      "LogBatchResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "accepted": {
            "type": "integer"
          },
          "logIds": {
            "type": "array",
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
              "maxLength": 128
            }
          },
          "deduplicated": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "schemaVersion",
          "accepted",
          "logIds",
          "deduplicated"
        ]
      },
      "LogQueryRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "projectId": {
            "type": "string",
            "maxLength": 64
          },
          "from": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "to": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "level": {
            "$ref": "#/components/schemas/LogLevel"
          },
          "correlation": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "field": {
                "type": "string",
                "enum": [
                  "sessionId",
                  "requestId",
                  "traceId",
                  "incidentId",
                  "runId"
                ]
              },
              "value": {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
                "maxLength": 128
              }
            },
            "required": [
              "field",
              "value"
            ]
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Defaults to 50 when omitted."
          },
          "cursor": {
            "type": "string",
            "maxLength": 4096
          }
        },
        "required": [
          "schemaVersion",
          "projectId",
          "from",
          "to"
        ]
      },
      "StoredLog": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "logId": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$",
            "maxLength": 128
          },
          "timestamp": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "level": {
            "$ref": "#/components/schemas/LogLevel"
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512,
            "description": "Diagnostic text only. Never interpolate user content or credentials; detected email and credential patterns are rejected."
          },
          "attributes": {
            "type": "object",
            "maxProperties": 16,
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string",
                  "maxLength": 128
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Flat scalar diagnostics. Sensitive keys and credential/email-like values are rejected."
          },
          "correlation": {
            "$ref": "#/components/schemas/LogCorrelation"
          },
          "receivedAt": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "logId",
          "timestamp",
          "level",
          "message",
          "receivedAt"
        ]
      },
      "LogQueryResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "const": 1
          },
          "projectId": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StoredLog"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "schemaVersion",
          "projectId",
          "items",
          "nextCursor"
        ]
      },
      "ObservationScope": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "organizationId",
          "projectId"
        ],
        "properties": {
          "organizationId": {
            "type": "string"
          },
          "projectId": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ObservationTimeBounds": {
        "type": "object",
        "description": "Effective half-open [from,to) epoch-millisecond window, default seven days, maximum 90 days.",
        "additionalProperties": false,
        "required": [
          "from",
          "to"
        ],
        "properties": {
          "from": {
            "type": "integer"
          },
          "to": {
            "type": "integer"
          }
        }
      },
      "ObservationProject": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "projectId",
          "name"
        ],
        "properties": {
          "projectId": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ObservationWorkflowStatus": {
        "type": "string",
        "enum": [
          "open",
          "investigation_queued",
          "investigating",
          "proposal_ready",
          "needs_more_data",
          "execution_queued",
          "executing",
          "verify_queued",
          "verifying",
          "human_review_required",
          "merge_waiting_on_requirements",
          "merge_ready",
          "merge_queued",
          "resolved",
          "ignored"
        ]
      },
      "ObservationError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "errorId",
          "projectId",
          "workflowStatus",
          "count",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "errorId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "workflowStatus": {
            "$ref": "#/components/schemas/ObservationWorkflowStatus"
          },
          "count": {
            "type": "integer"
          },
          "firstSeen": {
            "type": "integer"
          },
          "lastSeen": {
            "type": "integer"
          }
        }
      },
      "ObservationCorrelation": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "requestId",
          "source"
        ],
        "properties": {
          "requestId": {
            "type": "string",
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
            "description": "Opaque server operation ID copied from one strictly validated dedicated Sentry tag. Not an authorization credential or proof of causality."
          },
          "source": {
            "type": "string",
            "enum": [
              "sentry_tag"
            ]
          }
        }
      },
      "ObservationOccurrence": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "occurrenceId",
          "errorId",
          "timestamp",
          "receivedAt",
          "exceptionName",
          "topFrames"
        ],
        "properties": {
          "occurrenceId": {
            "type": "string"
          },
          "errorId": {
            "type": "string"
          },
          "timestamp": {
            "type": "integer"
          },
          "receivedAt": {
            "type": [
              "integer",
              "null"
            ]
          },
          "exceptionName": {
            "type": [
              "string",
              "null"
            ]
          },
          "topFrames": {
            "type": "array",
            "maxItems": 5,
            "items": {
              "type": "string"
            }
          },
          "correlation": {
            "$ref": "#/components/schemas/ObservationCorrelation"
          }
        }
      },
      "ObservationRun": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "runId",
          "errorId",
          "projectId",
          "type",
          "status",
          "queuedAt",
          "startedAt",
          "finishedAt"
        ],
        "properties": {
          "runId": {
            "type": "string"
          },
          "errorId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "queuedAt": {
            "type": "integer"
          },
          "startedAt": {
            "type": [
              "integer",
              "null"
            ]
          },
          "finishedAt": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "ObservationActivity": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "activityId",
          "runId",
          "sequence",
          "timestamp",
          "kind"
        ],
        "properties": {
          "activityId": {
            "type": "string"
          },
          "runId": {
            "type": "string"
          },
          "sequence": {
            "type": "integer"
          },
          "timestamp": {
            "type": "integer"
          },
          "kind": {
            "type": "string"
          }
        }
      },
      "ObservationProjectsData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "items",
          "nextCursor"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationProject"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ObservationErrorsData": {
        "type": "object",
        "description": "Server-filtered candidate page; items may be empty while nextCursor is non-null.",
        "additionalProperties": false,
        "required": [
          "scope",
          "effectiveTimeBounds",
          "items",
          "nextCursor"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "effectiveTimeBounds": {
            "$ref": "#/components/schemas/ObservationTimeBounds"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationError"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ObservationOccurrencesData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "effectiveTimeBounds",
          "items",
          "nextCursor"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "effectiveTimeBounds": {
            "$ref": "#/components/schemas/ObservationTimeBounds"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationOccurrence"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ObservationErrorData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "item"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "item": {
            "$ref": "#/components/schemas/ObservationError"
          }
        }
      },
      "ObservationRunsData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "items",
          "nextCursor",
          "source"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationRun"
            }
          },
          "nextCursor": {
            "type": "null"
          },
          "source": {
            "$ref": "#/components/schemas/ObservationSourceCoverage"
          }
        }
      },
      "ObservationRunData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "item"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "item": {
            "$ref": "#/components/schemas/ObservationRun"
          }
        }
      },
      "ObservationRunActivityData": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "items",
          "nextCursor",
          "source"
        ],
        "properties": {
          "scope": {
            "$ref": "#/components/schemas/ObservationScope"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationActivity"
            }
          },
          "nextCursor": {
            "type": "null"
          },
          "source": {
            "$ref": "#/components/schemas/ObservationSourceCoverage"
          }
        }
      },
      "ObservationSourceCoverage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "limit",
          "truncated"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "truncated": {
            "type": "boolean"
          }
        }
      },
      "ObservationEnvelope": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "organizationId",
          "data"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "organizationId": {
            "type": "string"
          },
          "data": {
            "type": "object"
          }
        }
      },
      "ObservationProjectsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationProjectsData"
              }
            }
          }
        ]
      },
      "ObservationErrorsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationErrorsData"
              }
            }
          }
        ]
      },
      "ObservationErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationErrorData"
              }
            }
          }
        ]
      },
      "ObservationOccurrencesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationOccurrencesData"
              }
            }
          }
        ]
      },
      "ObservationRunsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationRunsData"
              }
            }
          }
        ]
      },
      "ObservationRunResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationRunData"
              }
            }
          }
        ]
      },
      "ObservationRunActivityResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ObservationEnvelope"
          },
          {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ObservationRunActivityData"
              }
            }
          }
        ]
      }
    }
  },
  "paths": {
    "/api/mobile/v1/projects/ensure": {
      "post": {
        "operationId": "ensureOperatorProject",
        "summary": "Create or return an organization project by stable slug",
        "tags": [
          "project-onboarding"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "name",
                  "slug"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "slug": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9-]{1,62}$"
                  },
                  "adoptProjectId": {
                    "type": "string"
                  },
                  "expectedOrganizationId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Project ID and organization; never includes the capture key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "ok",
                    "status",
                    "outcome",
                    "nameDiffers",
                    "project",
                    "organization"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "status": {
                      "type": "string",
                      "const": "ok"
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "created",
                        "existing",
                        "adopted"
                      ]
                    },
                    "nameDiffers": {
                      "type": "boolean"
                    },
                    "project": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "slug"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "slug": {
                          "type": "string"
                        }
                      }
                    },
                    "organization": {
                      "type": "object",
                      "required": [
                        "id",
                        "name"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Wrong organization or explicit project adoption required"
          }
        }
      }
    },
    "/api/mobile/v1/projects/{projectId}/capture-key": {
      "get": {
        "operationId": "readOperatorProjectCaptureKey",
        "summary": "Read one same-organization project capture key",
        "tags": [
          "project-onboarding"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Explicit capture-key read; private no-store response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "ok",
                    "projectId",
                    "projectKey"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "projectId": {
                      "type": "string"
                    },
                    "projectKey": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Project is missing or belongs to another organization"
          }
        }
      }
    },
    "/api/mobile/v1/observations/projects": {
      "get": {
        "operationId": "listObservationProjects",
        "summary": "List authorized projects",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of authorized projects",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationProjectsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/projects/{projectId}/errors": {
      "get": {
        "operationId": "listObservationErrors",
        "summary": "List project errors",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ObservationWorkflowStatus"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of errors by lastSeen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationErrorsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/errors/{errorId}": {
      "get": {
        "operationId": "getObservationError",
        "summary": "Get an error",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "errorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Canonical error metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/errors/{errorId}/occurrences": {
      "get": {
        "operationId": "listObservationOccurrences",
        "summary": "List error occurrences",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "errorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of safe occurrence diagnostics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationOccurrencesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/errors/{errorId}/runs": {
      "get": {
        "operationId": "listObservationRuns",
        "summary": "List recent error runs",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "errorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Latest 50 runs, possibly truncated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationRunsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/runs/{runId}": {
      "get": {
        "operationId": "getObservationRun",
        "summary": "Get a run",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationRunResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/mobile/v1/observations/runs/{runId}/activity": {
      "get": {
        "operationId": "listObservationRunActivity",
        "summary": "List recent run activity",
        "tags": [
          "observation"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Latest 200 activity rows, possibly truncated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationRunActivityResponse"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "ingest"
        ],
        "operationId": "getHealth",
        "summary": "Return ingest service health.",
        "security": [],
        "responses": {
          "200": {
            "description": "The ingest service is reachable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v0/batch": {
      "post": {
        "tags": [
          "ingest"
        ],
        "operationId": "postBatch",
        "summary": "Submit a batch of incident events.",
        "description": "Public ingest endpoint used by SDKs to submit exception and message events.",
        "security": [
          {
            "projectKeyBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestBatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch accepted and processed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Batch payload is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Project key is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "The service failed while persisting the batch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v0/events": {
      "post": {
        "tags": [
          "ingest"
        ],
        "operationId": "postProductEvents",
        "summary": "Submit a batch of product events.",
        "description": "Product-only ingest endpoint. Product events do not create incident issues or dispatch coding agents.",
        "security": [
          {
            "projectKeyBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductEventBatchRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Product event batch accepted for best-effort delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductEventBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid project key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v0/events/query": {
      "post": {
        "tags": [
          "ingest"
        ],
        "operationId": "queryProductEvents",
        "summary": "Query bounded product-event aggregates.",
        "description": "Operator-authenticated aggregate queries over at most 30 days. Results are sampled estimates, not exact counts or an event ledger.",
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductAnalyticsQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bounded aggregate result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductAnalyticsQueryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid or out-of-bounds query.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or unauthorized operator token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v0/source-maps": {
      "post": {
        "tags": [
          "ingest"
        ],
        "operationId": "postSourceMap",
        "summary": "Upload a React Native source map artifact.",
        "description": "Public ingest endpoint used by Expo and React Native build tooling to upload source maps for later stack symbolication.",
        "security": [
          {
            "projectKeyBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SourceMapUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Source map uploaded and ready for symbolication.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SourceMapUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Source map payload is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Project key is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v0/logs": {
      "post": {
        "operationId": "ingestLogs",
        "summary": "ingestLogs",
        "tags": [
          "ingest"
        ],
        "security": [
          {
            "projectKeyBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LogBatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid bounded input"
          },
          "401": {
            "description": "Unauthorized"
          },
          "503": {
            "description": "Unavailable"
          }
        }
      }
    },
    "/v0/logs/query": {
      "post": {
        "operationId": "queryLogs",
        "summary": "queryLogs",
        "tags": [
          "ingest"
        ],
        "security": [
          {
            "operatorBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LogQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogQueryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid bounded input"
          },
          "401": {
            "description": "Unauthorized"
          },
          "503": {
            "description": "Unavailable"
          }
        }
      }
    }
  }
}
