{
  "openapi": "3.1.0",
  "info": {
    "title": "Xbox Competitive Cloud - Public Developer Plane",
    "version": "0.1.0",
    "description": "Public surface for the Xbox-as-the-rail-of-esports MVP. Covers the Step 5 observer pipeline, the Step 6 trust plane endpoints, and the Step 8 developer-platform services (keys, sandbox, bridge)."
  },
  "servers": [
    { "url": "http://127.0.0.1:7800", "description": "dev-platform (this MVP)" },
    { "url": "http://127.0.0.1:7700", "description": "observer-api gateway (Step 5)" },
    { "url": "http://127.0.0.1:7710", "description": "anti-cheat-trust verifier (Step 6)" }
  ],
  "paths": {
    "/api/keys": {
      "post": {
        "summary": "Issue an API key",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssueKeyRequest" } } } },
        "responses": { "201": { "description": "Created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IssueKeyResponse" } } } } }
      }
    },
    "/api/keys/{id}": {
      "get": { "summary": "Inspect a key (no secret returned)", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "OK" }, "404": { "description": "Not found" } } }
    },
    "/api/keys/{id}/revoke": {
      "post": { "summary": "Revoke", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Revoked" } } }
    },
    "/api/sandbox/tournaments": {
      "post": {
        "summary": "Spin up a synthetic tournament against the observer gateway",
        "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SandboxRequest" } } } },
        "responses": { "201": { "description": "Created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SandboxResponse" } } } } }
      }
    },
    "/api/sandbox/tournaments/{id}": {
      "get": { "summary": "Status", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "OK" } } }
    },
    "/api/bridge/subscriptions": {
      "post": {
        "summary": "Create a bridge that fans observer events out to broadcast tooling webhooks",
        "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BridgeRequest" } } } },
        "responses": { "201": { "description": "Created" } }
      }
    },
    "/api/bridge/subscriptions/{id}": {
      "get": { "summary": "Status", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "OK" } } },
      "delete": { "summary": "Stop", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Stopped" } } }
    }
  },
  "components": {
    "schemas": {
      "IssueKeyRequest":  { "type": "object", "required": ["org","contactEmail"], "properties": { "org": { "type": "string" }, "contactEmail": { "type": "string", "format": "email" }, "scopes": { "type": "array", "items": { "type": "string", "enum": ["observer:ingest","observer:spectate","sandbox","bridge"] } } } },
      "IssueKeyResponse": { "type": "object", "properties": { "id": { "type": "string" }, "secret": { "type": "string", "description": "Returned exactly once. Store it." }, "scopes": { "type": "array", "items": { "type": "string" } }, "issuedAt": { "type": "integer" } } },
      "SandboxRequest":   { "type": "object", "properties": { "titleId": { "type": "string", "default": "halo-infinite" }, "events": { "type": "integer", "minimum": 1, "maximum": 200, "default": 30 }, "speedMs": { "type": "integer", "minimum": 5, "maximum": 5000, "default": 25 } } },
      "SandboxResponse":  { "type": "object", "properties": { "matchId": { "type": "string" }, "overlayUrl": { "type": "string", "format": "uri" }, "spectateWsUrl": { "type": "string", "format": "uri" }, "replayUrl": { "type": "string", "format": "uri" }, "expectedEvents": { "type": "integer" } } },
      "BridgeRequest":    { "type": "object", "required": ["matchId","webhookUrl"], "properties": { "matchId": { "type": "string" }, "webhookUrl": { "type": "string", "format": "uri", "description": "We POST every event envelope here. Use it for OBS, vMix, Streamlabs, Streamer.bot, or your own service." }, "eventTypes": { "type": "array", "items": { "type": "string" }, "description": "Optional whitelist; omit to receive all." } } }
    }
  }
}
