{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "LegaBot Football Data API",
    "version": "1.4.1",
    "summary": "Versioned B2B football data, fair prices and optional media manifests.",
    "description": "The production contract for fixture discovery, revealed match state, fair decimal prices, suspensions, results, settlements, corrections and recovery. Optional Media is separately entitled and returns CDN manifests only. The service supplies data and does not provide wagering, wallet, customer-account or payment functions.",
    "contact": { "name": "LegaBot Data partner operations", "url": "https://data.lega.bot/owner/" },
    "x-contract-id": "legabot-data-api.v1",
    "x-feed-schema-version": "legabot-football-feed.v1.1",
    "x-certification-schema-version": "legabot-delivery-certification.v2",
    "x-media-schema-version": "legabot-optional-media.v1",
    "x-compatibility-policy": "Within API v1, new optional fields and enum values may be added. Required fields are not removed or retyped. Consumers must ignore unknown fields and persist the last successfully applied global Sequence."
  },
  "servers": [{ "url": "https://data.lega.bot", "description": "Production" }],
  "tags": [
    { "name": "Service", "description": "Health, capabilities and contract versions." },
    { "name": "Core Data", "description": "Required fixture, event, price, result and recovery contract." },
    { "name": "Operations", "description": "Authenticated delivery telemetry." },
    { "name": "Partner Delivery", "description": "Streaming, certification and owner-managed partner delivery." },
    { "name": "Optional Media", "description": "Independent add-on; never required for Core Data." }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "operationId": "getHealth", "tags": ["Service"], "summary": "Read public service health", "security": [],
        "responses": { "200": { "description": "Service health", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Health" } } } }, "405": { "$ref": "#/components/responses/MethodNotAllowed" } }
      },
      "head": { "operationId": "headHealth", "tags": ["Service"], "summary": "Probe service readiness", "security": [], "responses": { "200": { "description": "Service route is reachable" } } }
    },
    "/api/v1/meta": {
      "get": {
        "operationId": "getCapabilities", "tags": ["Service"], "summary": "Read capabilities and active versions", "security": [{ "CoreDataAuth": [] }],
        "responses": { "200": { "description": "Service capabilities", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Capabilities" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "503": { "$ref": "#/components/responses/ServiceNotConfigured" } }
      }
    },
    "/api/v1/catalogue": {
      "get": {
        "operationId": "getMarketCatalogue", "tags": ["Core Data"], "summary": "Read the 31-market catalogue", "description": "Stable supplier market order, selections, lifecycle rules and settlement outcomes.", "security": [{ "CoreDataAuth": [] }],
        "responses": { "200": { "description": "Market catalogue", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketCatalogue" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "503": { "$ref": "#/components/responses/ServiceNotConfigured" } }
      }
    },
    "/api/v1/feed/fixtures": {
      "get": {
        "operationId": "listFixtures", "tags": ["Core Data"], "summary": "Discover fixtures", "description": "FixtureId is stable for the complete match lifecycle.", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/StatusFilter" }],
        "responses": { "200": { "description": "Fixture list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FixtureList" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "502": { "$ref": "#/components/responses/UpstreamUnavailable" }, "503": { "$ref": "#/components/responses/ServiceNotConfigured" } }
      }
    },
    "/api/v1/feed/snapshot": {
      "get": {
        "operationId": "getFeedSnapshot", "tags": ["Core Data"], "summary": "Read and journal current fixture state", "description": "Initialize from this replace message. Persist X-Feed-Sequence only after applying the message durably.", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }],
        "responses": { "200": { "description": "Journaled snapshot", "headers": { "X-Feed-Sequence": { "$ref": "#/components/headers/FeedSequence" }, "ETag": { "$ref": "#/components/headers/StateEtag" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedMessage" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/SequenceConflict" }, "422": { "$ref": "#/components/responses/IntegrityFailure" }, "502": { "$ref": "#/components/responses/FeedUnavailable" }, "503": { "$ref": "#/components/responses/JournalUnavailable" } }
      }
    },
    "/api/v1/feed/deltas": {
      "get": {
        "operationId": "getFeedDeltas", "tags": ["Core Data"], "summary": "Read ordered changes after a cursor", "description": "Apply messages in ascending global Sequence order. Continue while Meta.hasMore is true using Meta.nextSequence.", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }, { "$ref": "#/components/parameters/AfterSequenceRequired" }, { "$ref": "#/components/parameters/Limit" }],
        "responses": { "200": { "description": "Ordered delta batch", "headers": { "X-Feed-Sequence": { "$ref": "#/components/headers/FeedSequence" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedBatch" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "409": { "$ref": "#/components/responses/SequenceConflict" }, "502": { "$ref": "#/components/responses/FeedUnavailable" }, "503": { "$ref": "#/components/responses/JournalUnavailable" } }
      }
    },
    "/api/v1/feed/replay": {
      "get": {
        "operationId": "replayFeedJournal", "tags": ["Core Data"], "summary": "Replay the immutable delivery journal", "description": "Recovery endpoint. CorrectionOfSequence links a correction to the message it replaces.", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }, { "$ref": "#/components/parameters/AfterSequence" }, { "$ref": "#/components/parameters/ThroughSequence" }, { "$ref": "#/components/parameters/Limit" }],
        "responses": { "200": { "description": "Ordered replay batch", "headers": { "X-Feed-Sequence": { "$ref": "#/components/headers/FeedSequence" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedBatch" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "502": { "$ref": "#/components/responses/FeedUnavailable" }, "503": { "$ref": "#/components/responses/JournalUnavailable" } }
      }
    },
    "/api/v1/feed/stream": {
      "get": {
        "operationId": "streamFeedDeltas", "tags": ["Partner Delivery"], "summary": "Consume a bounded Server-Sent Events batch", "description": "Reconnect using Last-Event-ID or afterSequence. Each data event contains one complete journaled FeedMessage; the final cursor event states whether more history is available.", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }, { "$ref": "#/components/parameters/AfterSequence" }, { "$ref": "#/components/parameters/LastEventId" }, { "$ref": "#/components/parameters/StreamLimit" }],
        "responses": { "200": { "description": "Bounded text/event-stream response", "headers": { "X-Feed-Sequence": { "$ref": "#/components/headers/FeedSequence" } }, "content": { "text/event-stream": { "schema": { "type": "string" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/JournalUnavailable" } }
      }
    },
    "/api/v1/certification/report": {
      "get": {
        "operationId": "getMatchCertification", "tags": ["Partner Delivery"], "summary": "Read the latest end-to-end delivery certification", "security": [{ "CoreDataAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }],
        "responses": { "200": { "description": "Prematch-to-settlement certification report", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CertificationResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "429": { "$ref": "#/components/responses/RateLimited" } }
      }
    },
    "/api/v1/owner/partners": {
      "get": {
        "operationId": "listPartners", "tags": ["Partner Delivery"], "summary": "List partner accounts and non-secret key metadata", "security": [{ "OwnerAuth": [] }],
        "responses": { "200": { "description": "Partner accounts and keys", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      },
      "post": {
        "operationId": "createPartner", "tags": ["Partner Delivery"], "summary": "Create a partner and one-time API key", "description": "The plaintext key is returned exactly once. Only its SHA-256 hash is retained.", "security": [{ "OwnerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreatePartnerRequest" } } } },
        "responses": { "201": { "description": "Partner created; store the returned key immediately", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      },
      "patch": {
        "operationId": "updatePartner", "tags": ["Partner Delivery"], "summary": "Edit partner access, rotate a key or change account status", "security": [{ "OwnerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdatePartnerRequest" } } } },
        "responses": { "200": { "description": "Partner updated", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" } }
      }
    },
    "/api/v1/owner/webhooks": {
      "get": { "operationId": "listWebhooks", "tags": ["Partner Delivery"], "summary": "List registered webhook endpoints and optional Sandbox receipts", "security": [{ "OwnerAuth": [] }], "parameters": [{ "in": "query", "name": "includeReceipts", "schema": { "type": "boolean", "default": false } }], "responses": { "200": { "description": "Webhook endpoint metadata and verified Sandbox receipts" }, "401": { "$ref": "#/components/responses/Unauthorized" } } },
      "post": { "operationId": "createWebhook", "tags": ["Partner Delivery"], "summary": "Register an HTTPS webhook or managed Sandbox receiver", "description": "Set action to create_sandbox_receiver for a first-party signed delivery loop. The signing secret is returned once.", "security": [{ "OwnerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequest" } } } }, "responses": { "201": { "description": "Webhook created; store the signing secret immediately" }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" } } },
      "patch": { "operationId": "updateWebhook", "tags": ["Partner Delivery"], "summary": "Activate, pause, revoke or send a signed test event", "security": [{ "OwnerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookRequest" } } } }, "responses": { "200": { "description": "Webhook updated or test delivered" }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" } } }
    },
    "/api/v1/owner/usage": {
      "get": {
        "operationId": "getPartnerUsageAnalytics", "tags": ["Operations"], "summary": "Read detailed consumption analytics for one partner", "description": "Owner-only request volume, endpoint, fixture, latency, error, rate-limit and response-byte telemetry. Raw credentials and IP addresses are never returned.", "security": [{ "OwnerAuth": [] }],
        "parameters": [{ "in": "query", "name": "partnerId", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "in": "query", "name": "range", "required": false, "schema": { "enum": ["24h", "7d", "30d"], "default": "24h" } }],
        "responses": { "200": { "description": "Partner usage analytics", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PartnerUsageAnalytics" } } } }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "404": { "$ref": "#/components/responses/NotFound" }, "503": { "$ref": "#/components/responses/ServiceNotConfigured" } }
      }
    },
    "/api/v1/sandbox/webhook-receiver": {
      "post": {
        "operationId": "receiveManagedSandboxWebhook", "tags": ["Partner Delivery"], "summary": "Receive and verify a managed Sandbox test delivery", "description": "Internal first-party Sandbox receiver. Requires X-LegaBot-Signature-Version: v1. The unguessable token is issued only through Owner operations.", "security": [],
        "parameters": [{ "in": "query", "name": "token", "required": true, "schema": { "type": "string", "minLength": 32, "maxLength": 100 } }],
        "responses": { "204": { "description": "Signature verified and receipt stored" }, "401": { "description": "Signature or timestamp rejected" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/api/v1/monitor/status": {
      "get": {
        "operationId": "getDeliveryStatus", "tags": ["Operations"], "summary": "Read publisher, alert, webhook, usage and certification telemetry", "security": [{ "CoreDataAuth": [] }],
        "responses": { "200": { "description": "Current delivery readiness", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliveryStatus" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "429": { "$ref": "#/components/responses/RateLimited" }, "503": { "$ref": "#/components/responses/ServiceNotConfigured" } }
      }
    },
    "/api/v1/monitor/activity": {
      "post": {
        "operationId": "recordPartnerPortalActivity", "tags": ["Operations"], "summary": "Record an authenticated portal export or integration action", "description": "Used by the Partner Portal to distinguish JSON, CSV and copied integration requests in partner usage analytics.", "security": [{ "CoreDataAuth": [] }],
        "parameters": [{ "in": "query", "name": "activity", "required": true, "schema": { "enum": ["download", "copy_request"] } }, { "in": "query", "name": "format", "required": true, "schema": { "enum": ["json", "csv", "curl"] } }, { "in": "query", "name": "product", "required": true, "schema": { "enum": ["snapshot", "replay", "core-data", "media", "deltas", "stream", "certification"] } }, { "$ref": "#/components/parameters/MatchId" }],
        "responses": { "204": { "description": "Activity accepted" }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "429": { "$ref": "#/components/responses/RateLimited" } }
      }
    },
    "/api/v1/media/package": {
      "get": {
        "operationId": "getOptionalMediaPackage", "tags": ["Optional Media"], "summary": "Read a CDN media manifest", "description": "Separate entitlement. Returns URLs and metadata only; Core Data remains independent.", "security": [{ "MediaAuth": [] }], "parameters": [{ "$ref": "#/components/parameters/MatchId" }, { "$ref": "#/components/parameters/IfNoneMatch" }],
        "responses": { "200": { "description": "Optional Media package", "headers": { "ETag": { "$ref": "#/components/headers/StateEtag" }, "X-Media-Cursor": { "$ref": "#/components/headers/MediaCursor" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MediaPackage" } } } }, "304": { "description": "Manifest unchanged" }, "400": { "$ref": "#/components/responses/InvalidRequest" }, "403": { "$ref": "#/components/responses/MediaForbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "502": { "$ref": "#/components/responses/MediaUnavailable" }, "503": { "$ref": "#/components/responses/MediaNotConfigured" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "CoreDataAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "LegaBot partner API key", "description": "Use the Authorization header; never a URL, log or source file." },
      "MediaAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "LegaBot media-entitled API key", "description": "Independent Optional Media entitlement." },
      "OwnerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "LegaBot owner API key", "description": "Privileged operator key. Never distribute to partners." }
    },
    "parameters": {
      "MatchId": { "in": "query", "name": "matchId", "required": true, "description": "Stable FixtureId from discovery.", "schema": { "type": "string", "format": "uuid" }, "example": "8275e9f0-a0a7-4a79-a6d2-9e87463aff56" },
      "StatusFilter": { "in": "query", "name": "status", "required": false, "description": "Comma-separated statuses.", "schema": { "type": "string", "default": "scheduled,live", "pattern": "^(scheduled|live|final)(,(scheduled|live|final))*$" }, "example": "scheduled,live,final" },
      "AfterSequenceRequired": { "in": "query", "name": "afterSequence", "required": true, "description": "Last global sequence durably applied.", "schema": { "type": "integer", "format": "int64", "minimum": 0 }, "example": 1842 },
      "AfterSequence": { "in": "query", "name": "afterSequence", "required": false, "description": "Exclusive global cursor.", "schema": { "type": "integer", "format": "int64", "minimum": 0, "default": 0 } },
      "ThroughSequence": { "in": "query", "name": "throughSequence", "required": false, "description": "Optional inclusive audit boundary, greater than afterSequence.", "schema": { "type": "integer", "format": "int64", "minimum": 1 } },
      "Limit": { "in": "query", "name": "limit", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 500, "default": 100 } },
      "StreamLimit": { "in": "query", "name": "limit", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 100 } },
      "LastEventId": { "in": "header", "name": "Last-Event-ID", "required": false, "description": "Last global Sequence durably applied by the SSE consumer.", "schema": { "type": "integer", "format": "int64", "minimum": 0 } },
      "IfNoneMatch": { "in": "header", "name": "If-None-Match", "required": false, "description": "ETag returned by the previous media request.", "schema": { "type": "string" } }
    },
    "headers": {
      "FeedSequence": { "description": "Latest global delivery sequence represented.", "schema": { "type": "integer", "format": "int64", "minimum": 0 } },
      "MediaCursor": { "description": "Highest revealed media event sequence.", "schema": { "type": "integer", "minimum": 0 } },
      "StateEtag": { "description": "Quoted state fingerprint.", "schema": { "type": "string" } }
    },
    "responses": {
      "InvalidRequest": { "description": "Missing or invalid parameter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing or invalid Core Data API key", "headers": { "WWW-Authenticate": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "MediaForbidden": { "description": "Key lacks Optional Media entitlement", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Forbidden": { "description": "Key lacks the required scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited": { "description": "Partner request limit exceeded", "headers": { "Retry-After": { "schema": { "type": "integer", "minimum": 1 } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "NotFound": { "description": "Fixture not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "SequenceConflict": { "description": "Source sequence regression rejected", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "IntegrityFailure": { "description": "Revealed state cannot be safely priced or settled", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "FeedUnavailable": { "description": "Protected feed unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "UpstreamUnavailable": { "description": "Official league source unavailable", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "MediaUnavailable": { "description": "Media manifest unavailable; Core Data unaffected", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "JournalUnavailable": { "description": "Append-only journal not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "ServiceNotConfigured": { "description": "Core authentication not configured", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "MediaNotConfigured": { "description": "Optional Media not configured; Core Data remains active", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "MethodNotAllowed": { "description": "HTTP method not supported", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    },
    "schemas": {
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string" }, "matchStatus": { "type": "string" } }, "additionalProperties": true },
      "Health": {
        "type": "object", "required": ["service", "status", "apiVersion", "wageringEnabled", "oddsPublished", "priceType", "feedStatus", "optionalMediaStatus", "assetsStoredByDataService", "timestamp"],
        "properties": { "service": { "const": "data.lega.bot" }, "status": { "enum": ["ok", "degraded"] }, "environment": { "type": "string" }, "apiVersion": { "const": "v1" }, "wageringEnabled": { "const": false }, "oddsPublished": { "const": true }, "priceType": { "const": "fair" }, "commercialMarginApplied": { "const": false }, "feedStatus": { "type": "string" }, "journalStatus": { "type": "string" }, "publisherStatus": { "type": "string" }, "resultDeliveryStatus": { "type": "string" }, "optionalMediaStatus": { "type": "string" }, "assetsStoredByDataService": { "const": false }, "timestamp": { "type": "string", "format": "date-time" } }, "additionalProperties": true
      },
      "Capabilities": {
        "type": "object", "required": ["service", "apiVersion", "delivery", "resources", "marketCatalogue", "wageringEnabled", "oddsPublished", "publishedPriceType", "products", "documentation"],
        "properties": { "service": { "const": "data.lega.bot" }, "apiVersion": { "const": "v1" }, "audience": { "const": "licensed-b2b-partners" }, "delivery": { "type": "object", "additionalProperties": true }, "resources": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "marketCatalogue": { "type": "object", "additionalProperties": true }, "wageringEnabled": { "const": false }, "oddsPublished": { "const": true }, "publishedPriceType": { "const": "fair_decimal" }, "commercialMarginApplied": { "const": false }, "products": { "type": "object", "additionalProperties": true }, "documentation": { "type": "object", "additionalProperties": true } }, "additionalProperties": true
      },
      "BaseHeader": {
        "type": "object", "required": ["SchemaVersion", "Type", "GeneratedAt"],
        "properties": { "SchemaVersion": { "type": "string" }, "Type": { "type": "string" }, "MessageGuid": { "type": "string", "format": "uuid" }, "Sequence": { "type": ["integer", "null"], "format": "int64" }, "SourceSequence": { "type": ["integer", "null"], "format": "int64" }, "PreviousSequence": { "type": ["integer", "null"], "format": "int64" }, "CorrectionOfSequence": { "type": ["integer", "null"], "format": "int64" }, "AfterSequence": { "type": "integer", "format": "int64", "minimum": 0 }, "ThroughSequence": { "type": ["integer", "null"], "format": "int64" }, "ServerTimestamp": { "type": "integer", "format": "int64" }, "GeneratedAt": { "type": "string", "format": "date-time" }, "StateFingerprint": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "MediaCursor": { "type": "integer", "minimum": 0 } }, "additionalProperties": true
      },
      "CoreMeta": {
        "type": "object", "required": ["service", "oddsPublished", "wageringEnabled"],
        "properties": { "service": { "const": "data.lega.bot" }, "marketCatalogueVersion": { "type": "string" }, "pricePublicationVersion": { "type": "string" }, "oddsPublished": { "const": true }, "wageringEnabled": { "const": false }, "journaled": { "type": "boolean" }, "hasMore": { "type": "boolean" }, "nextSequence": { "type": "integer", "format": "int64", "minimum": 0 } }, "additionalProperties": true
      },
      "FixtureStatus": { "enum": ["scheduled", "live", "final", "postponed", "cancelled"] },
      "Score": { "type": "object", "required": ["Home", "Away"], "properties": { "Home": { "type": "integer", "minimum": 0 }, "Away": { "type": "integer", "minimum": 0 } }, "additionalProperties": false },
      "FixtureList": {
        "type": "object", "required": ["Header", "Body", "Meta"],
        "properties": { "Header": { "$ref": "#/components/schemas/BaseHeader" }, "Body": { "type": "object", "required": ["Fixtures"], "properties": { "Fixtures": { "type": "array", "items": { "$ref": "#/components/schemas/FixtureSummary" } } }, "additionalProperties": true }, "Meta": { "$ref": "#/components/schemas/CoreMeta" } }, "additionalProperties": true
      },
      "FixtureSummary": {
        "type": "object", "required": ["FixtureId", "SeasonId", "RoundNumber", "RoundName", "HomeTeamId", "AwayTeamId", "StartDate", "Status", "Phase", "Score", "SnapshotUrl"],
        "properties": { "FixtureId": { "type": "string", "format": "uuid" }, "SeasonId": { "type": "string" }, "RoundNumber": { "type": ["integer", "null"] }, "RoundName": { "type": ["string", "null"] }, "HomeTeamId": { "type": "string" }, "AwayTeamId": { "type": "string" }, "StartDate": { "type": "string", "format": "date-time" }, "Status": { "$ref": "#/components/schemas/FixtureStatus" }, "Phase": { "type": ["string", "null"] }, "Score": { "oneOf": [{ "$ref": "#/components/schemas/Score" }, { "type": "null" }] }, "SnapshotUrl": { "type": "string", "pattern": "^/api/v1/feed/snapshot\\?matchId=" } }, "additionalProperties": true
      },
      "FeedHeader": {
        "allOf": [{ "$ref": "#/components/schemas/BaseHeader" }, { "type": "object", "required": ["SchemaVersion", "Type", "MessageGuid", "Sequence", "SourceSequence", "GeneratedAt", "StateFingerprint"], "properties": { "SchemaVersion": { "const": "legabot-football-feed.v1.1" }, "Type": { "enum": ["snapshot", "price", "suspension", "result", "correction"] } } }]
      },
      "FeedMessage": {
        "type": "object", "required": ["Header", "Body", "Meta"],
        "properties": { "Header": { "$ref": "#/components/schemas/FeedHeader" }, "Body": { "type": "object", "required": ["Operation", "Events"], "properties": { "Operation": { "enum": ["replace", "upsert", "suspend", "settle", "correct", "no_change"] }, "Events": { "type": "array", "items": { "$ref": "#/components/schemas/Event" }, "maxItems": 1 } }, "additionalProperties": true }, "Meta": { "$ref": "#/components/schemas/CoreMeta" } }, "additionalProperties": true
      },
      "FeedBatch": {
        "type": "object", "required": ["Header", "Body", "Meta"],
        "properties": { "Header": { "allOf": [{ "$ref": "#/components/schemas/BaseHeader" }, { "type": "object", "required": ["AfterSequence"], "properties": { "Type": { "enum": ["delta-batch", "replay-batch"] } } }] }, "Body": { "type": "object", "required": ["Operation", "Messages"], "properties": { "Operation": { "enum": ["replay", "no_change"] }, "Messages": { "type": "array", "items": { "$ref": "#/components/schemas/FeedMessage" } } }, "additionalProperties": true }, "Meta": { "$ref": "#/components/schemas/CoreMeta" } }, "additionalProperties": true
      },
      "Event": {
        "type": "object", "required": ["Sequence", "FixtureId", "Fixture", "Livescore", "PricePublication", "Suspensions", "Markets"],
        "properties": { "Sequence": { "type": "integer", "format": "int64", "minimum": 0 }, "FixtureId": { "type": "string", "format": "uuid" }, "Fixture": { "$ref": "#/components/schemas/Fixture" }, "Livescore": { "$ref": "#/components/schemas/Livescore" }, "PricePublication": { "$ref": "#/components/schemas/PricePublication" }, "Suspensions": { "type": "array", "items": { "$ref": "#/components/schemas/Suspension" } }, "Markets": { "type": "array", "items": { "$ref": "#/components/schemas/Market" } }, "Results": { "type": ["object", "null"], "additionalProperties": true }, "Settlements": { "type": "array", "items": { "$ref": "#/components/schemas/Settlement" } } }, "additionalProperties": true
      },
      "NamedEntity": { "type": "object", "required": ["Id", "Name"], "properties": { "Id": { "type": "string" }, "Name": { "type": "string" } }, "additionalProperties": true },
      "Participant": { "type": "object", "required": ["Id", "Name", "Position"], "properties": { "Id": { "type": "string" }, "Name": { "type": "string" }, "Position": { "enum": ["1", "2"] } }, "additionalProperties": true },
      "Fixture": {
        "type": "object", "required": ["Sport", "League", "Season", "Round", "StartDate", "Status", "Phase", "Participants", "FixtureName"],
        "properties": { "Sport": { "$ref": "#/components/schemas/NamedEntity" }, "League": { "$ref": "#/components/schemas/NamedEntity" }, "Season": { "$ref": "#/components/schemas/NamedEntity" }, "Round": { "type": "object", "required": ["Number", "Name"], "properties": { "Number": { "type": ["integer", "null"] }, "Name": { "type": ["string", "null"] } }, "additionalProperties": true }, "StartDate": { "type": "string", "format": "date-time" }, "Status": { "$ref": "#/components/schemas/FixtureStatus" }, "Phase": { "type": ["string", "null"] }, "Participants": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "$ref": "#/components/schemas/Participant" } }, "FixtureName": { "type": "string" } }, "additionalProperties": true
      },
      "Livescore": { "type": "object", "required": ["Scoreboard", "Incidents"], "properties": { "Scoreboard": { "$ref": "#/components/schemas/Scoreboard" }, "Incidents": { "type": "array", "items": { "$ref": "#/components/schemas/Incident" } } }, "additionalProperties": true },
      "Scoreboard": { "type": "object", "required": ["Status", "CurrentPeriod", "TimeSeconds", "Score"], "properties": { "Status": { "$ref": "#/components/schemas/FixtureStatus" }, "CurrentPeriod": { "type": ["string", "null"] }, "TimeSeconds": { "type": "integer", "minimum": 0 }, "Score": { "oneOf": [{ "$ref": "#/components/schemas/Score" }, { "type": "null" }] } }, "additionalProperties": true },
      "Incident": {
        "type": "object", "required": ["Sequence", "Period", "EventType", "Minute", "Second", "TeamId", "PlayerId", "PlayerName", "RelatedPlayerId", "RevealedAt"],
        "properties": { "Sequence": { "type": "integer", "minimum": 0 }, "Period": { "enum": ["first_half", "second_half"] }, "EventType": { "type": "string", "description": "Revealed incident; substitution is intentionally excluded." }, "Minute": { "type": "integer", "minimum": 0 }, "Second": { "type": "integer", "minimum": 0, "maximum": 59 }, "TeamId": { "type": ["string", "null"] }, "PlayerId": { "type": ["string", "null"] }, "PlayerName": { "type": ["string", "null"] }, "RelatedPlayerId": { "type": ["string", "null"] }, "RevealedAt": { "type": ["string", "null"], "format": "date-time" } }, "additionalProperties": true
      },
      "PricePublication": {
        "type": "object", "required": ["Status", "PriceType", "PublicationVersion", "CommercialMarginApplied", "Model", "PlayerMarketsMayBeUnavailable", "SubstitutionDataIncluded"],
        "properties": { "Status": { "type": "string" }, "PriceType": { "const": "fair_decimal" }, "PublicationVersion": { "type": "string" }, "CommercialMarginApplied": { "const": false }, "Model": { "type": "object", "additionalProperties": true }, "PlayerMarketsMayBeUnavailable": { "const": true }, "SubstitutionDataIncluded": { "const": false } }, "additionalProperties": true
      },
      "Suspension": { "type": "object", "required": ["Resource", "Reason"], "properties": { "Resource": { "type": "string" }, "Reason": { "type": "string" } }, "additionalProperties": true },
      "MarketBaseline": { "type": "object", "required": ["TargetGoalOrdinal", "QuoteAfterEventSequence"], "properties": { "TargetGoalOrdinal": { "type": "integer", "minimum": 1 }, "QuoteAfterEventSequence": { "type": "integer", "minimum": 0 } }, "additionalProperties": true },
      "Market": {
        "type": "object", "required": ["Id", "InstanceId", "Key", "Name", "Period", "Line", "Baseline", "Status", "LastUpdate", "Providers"],
        "properties": { "Id": { "type": ["integer", "null"] }, "InstanceId": { "type": "string" }, "Key": { "type": "string" }, "Name": { "type": "string" }, "Period": { "type": "string" }, "Line": { "type": ["number", "string", "null"] }, "Baseline": { "oneOf": [{ "$ref": "#/components/schemas/MarketBaseline" }, { "type": "null" }] }, "Status": { "enum": ["open", "suspended", "closed"] }, "LastUpdate": { "type": "string", "format": "date-time" }, "Providers": { "type": "array", "items": { "$ref": "#/components/schemas/Provider" } } }, "additionalProperties": true
      },
      "Provider": { "type": "object", "required": ["Id", "Name", "ModelRole", "CommercialMarginApplied", "Bets"], "properties": { "Id": { "const": "legabot-fair-prices" }, "Name": { "type": "string" }, "ModelRole": { "const": "champion" }, "CommercialMarginApplied": { "const": false }, "Bets": { "type": "array", "items": { "$ref": "#/components/schemas/Selection" } } }, "additionalProperties": true },
      "Selection": {
        "type": "object", "required": ["Id", "Key", "Name", "Line", "BaseLine", "Status", "Probability", "Price", "PriceType", "LastUpdate"],
        "properties": { "Id": { "type": "string" }, "Key": { "type": "string" }, "Name": { "type": "string" }, "Line": { "type": ["number", "string", "null"] }, "BaseLine": { "type": ["number", "string", "null"] }, "Status": { "type": "string" }, "Probability": { "type": "number", "minimum": 0, "maximum": 1 }, "Price": { "type": ["number", "null"], "minimum": 1, "maximum": 1000 }, "PriceType": { "const": "fair_decimal" }, "LastUpdate": { "type": "string", "format": "date-time" }, "UnavailableReason": { "type": "string" }, "PlayerId": { "type": "string" }, "TeamId": { "type": "string" }, "Position": { "type": "string" }, "SettlementOutcomeProbabilities": { "type": "object", "additionalProperties": { "type": "number", "minimum": 0, "maximum": 1 } } }, "additionalProperties": true
      },
      "Settlement": { "type": "object", "required": ["InstanceId", "Key", "Status", "Bets"], "properties": { "Id": { "type": ["integer", "null"] }, "InstanceId": { "type": "string" }, "Key": { "type": "string" }, "Name": { "type": "string" }, "Period": { "type": "string" }, "Line": { "type": ["number", "string", "null"] }, "Baseline": { "oneOf": [{ "$ref": "#/components/schemas/MarketBaseline" }, { "type": "null" }] }, "Status": { "enum": ["settled", "void"] }, "Reason": { "type": "string" }, "Bets": { "type": "array", "items": { "$ref": "#/components/schemas/SettlementSelection" } } }, "additionalProperties": true },
      "SettlementSelection": { "type": "object", "required": ["Id", "Key", "Name", "Outcome", "SupplierSettlementId"], "properties": { "Id": { "type": "string" }, "Key": { "type": "string" }, "Name": { "type": "string" }, "PlayerId": { "type": ["string", "null"] }, "TeamId": { "type": ["string", "null"] }, "Outcome": { "enum": ["win", "loss", "push", "half_win", "half_loss", "void"] }, "SupplierSettlementId": { "type": ["integer", "null"] }, "Reason": { "type": "string" } }, "additionalProperties": true },
      "MarketCatalogue": {
        "type": "object", "required": ["version", "count", "settlementOutcomes", "supplierSettlementMap", "markets", "oddsPublished", "publishedPriceType", "commercialMarginApplied"],
        "properties": { "version": { "type": "string" }, "count": { "const": 31 }, "settlementOutcomes": { "type": "array", "items": { "enum": ["win", "loss", "push", "half_win", "half_loss", "void"] }, "uniqueItems": true }, "supplierSettlementMap": { "type": "object", "additionalProperties": { "type": "string" } }, "markets": { "type": "array", "minItems": 31, "maxItems": 31, "items": { "$ref": "#/components/schemas/MarketDefinition" } }, "oddsPublished": { "const": true }, "publishedPriceType": { "const": "fair_decimal" }, "commercialMarginApplied": { "const": false } }, "additionalProperties": true
      },
      "MarketDefinition": {
        "type": "object", "required": ["key", "supplier", "sport", "family", "period", "availability", "line", "selections", "settlement", "dataRequirements", "lifecycle"],
        "properties": { "key": { "type": "string" }, "supplier": { "type": "object", "required": ["id", "name"], "properties": { "id": { "type": "integer" }, "name": { "type": "string" } }, "additionalProperties": true }, "sport": { "const": "football" }, "family": { "type": "string" }, "period": { "type": "string" }, "availability": { "type": "array", "items": { "enum": ["prematch", "inplay"] }, "uniqueItems": true }, "line": { "type": "object", "additionalProperties": true }, "selections": { "type": "object", "additionalProperties": true }, "settlement": { "type": "object", "additionalProperties": true }, "dataRequirements": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }, "lifecycle": { "type": "object", "additionalProperties": true }, "notes": { "type": "string" } }, "additionalProperties": true
      },
      "DeliveryStatus": { "type": "object", "properties": { "service": { "const": "data.lega.bot" }, "status": { "enum": ["healthy", "degraded", "critical"] }, "coreData": { "type": "object", "additionalProperties": true }, "publisher": { "type": "object", "additionalProperties": true }, "delivery": { "type": "object", "additionalProperties": true } }, "additionalProperties": true },
      "CertificationResponse": { "type": "object", "required": ["service", "wageringEnabled", "report"], "properties": { "service": { "const": "data.lega.bot" }, "wageringEnabled": { "const": false }, "report": { "$ref": "#/components/schemas/CertificationReport" } }, "additionalProperties": false },
      "CertificationReport": { "type": "object", "required": ["matchId", "schemaVersion", "status", "checks", "metrics", "certifiedAt"], "properties": { "matchId": { "type": "string", "format": "uuid" }, "schemaVersion": { "const": "legabot-delivery-certification.v2" }, "feedSchemaVersion": { "type": "string" }, "phase": { "enum": ["scheduled", "live", "final"] }, "status": { "enum": ["passed", "failed", "incomplete"] }, "checks": { "type": "array", "items": { "type": "object", "required": ["id", "passed"], "properties": { "id": { "type": "string" }, "passed": { "type": "boolean" } }, "additionalProperties": true } }, "metrics": { "type": "object", "additionalProperties": true }, "certifiedAt": { "type": "string", "format": "date-time" } }, "additionalProperties": true },
      "PartnerUsageAnalytics": { "type": "object", "required": ["service", "analytics"], "properties": { "service": { "const": "data.lega.bot" }, "analytics": { "type": "object", "required": ["generatedAt", "range", "partner", "summary", "endpoints", "matches", "timeline", "outcomes", "formats"], "properties": { "generatedAt": { "type": "string", "format": "date-time" }, "range": { "enum": ["24h", "7d", "30d"] }, "partner": { "type": "object", "additionalProperties": true }, "summary": { "type": "object", "additionalProperties": true }, "endpoints": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "matches": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "timeline": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "outcomes": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "formats": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "additionalProperties": false } }, "additionalProperties": false },
      "CreatePartnerRequest": { "type": "object", "required": ["code", "displayName", "environment", "scopes"], "properties": { "code": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$" }, "displayName": { "type": "string", "minLength": 2, "maxLength": 100 }, "environment": { "enum": ["sandbox", "production"] }, "scopes": { "type": "array", "items": { "enum": ["core:read", "media:read", "stream:read", "webhook:manage", "certification:read"] }, "uniqueItems": true }, "rateLimitPerMinute": { "type": "integer", "minimum": 1, "maximum": 10000, "default": 120 }, "metadata": { "type": "object", "additionalProperties": true } }, "additionalProperties": false },
      "UpdatePartnerRequest": { "oneOf": [{ "type": "object", "required": ["action", "partnerId", "displayName", "scopes", "rateLimitPerMinute"], "properties": { "action": { "const": "update_settings" }, "partnerId": { "type": "string", "format": "uuid" }, "displayName": { "type": "string", "minLength": 2, "maxLength": 100 }, "scopes": { "type": "array", "minItems": 1, "items": { "enum": ["core:read", "media:read", "stream:read", "webhook:manage", "certification:read"] }, "uniqueItems": true }, "rateLimitPerMinute": { "type": "integer", "minimum": 1, "maximum": 10000 } }, "additionalProperties": false }, { "type": "object", "required": ["action", "partnerId"], "properties": { "action": { "const": "rotate_key" }, "partnerId": { "type": "string", "format": "uuid" } }, "additionalProperties": false }, { "type": "object", "required": ["action", "partnerId", "status"], "properties": { "action": { "const": "set_status" }, "partnerId": { "type": "string", "format": "uuid" }, "status": { "enum": ["active", "suspended", "revoked"] } }, "additionalProperties": false }] },
      "CreateWebhookRequest": { "type": "object", "required": ["partnerId", "displayName"], "properties": { "action": { "enum": ["create_sandbox_receiver"] }, "partnerId": { "type": "string", "format": "uuid" }, "displayName": { "type": "string", "minLength": 2, "maxLength": 100 }, "url": { "type": "string", "format": "uri" }, "eventTypes": { "type": "array", "items": { "enum": ["*", "snapshot", "price", "suspension", "result", "correction"] }, "uniqueItems": true } }, "additionalProperties": false },
      "UpdateWebhookRequest": { "type": "object", "required": ["action", "endpointId"], "properties": { "action": { "enum": ["set_status", "send_test", "redrive_dead"] }, "endpointId": { "type": "string", "format": "uuid" }, "status": { "enum": ["active", "paused", "revoked"] } }, "additionalProperties": false },
      "MediaAsset": {
        "type": "object", "required": ["AssetId", "Type", "Format", "Url", "Delivery", "ExpiresAt"],
        "properties": { "AssetId": { "type": "string" }, "SourceContentId": { "type": "string" }, "Type": { "enum": ["team_crest", "player_photo", "match_image", "match_video"] }, "Format": { "type": "string" }, "Title": { "type": ["string", "null"] }, "Url": { "type": "string", "format": "uri" }, "Delivery": { "enum": ["lega.bot-cdn", "signed-cdn"] }, "ExpiresAt": { "type": ["string", "null"], "format": "date-time" }, "RevealedAt": { "type": ["string", "null"], "format": "date-time" }, "Event": { "type": ["object", "null"], "additionalProperties": true } }, "additionalProperties": true
      },
      "MediaTeam": { "type": "object", "required": ["TeamId", "Name", "Crest"], "properties": { "TeamId": { "type": "string" }, "Name": { "type": "string" }, "Crest": { "$ref": "#/components/schemas/MediaAsset" } }, "additionalProperties": true },
      "MediaPlayer": { "type": "object", "required": ["PlayerId", "TeamId", "Name", "Position", "SquadNumber", "Role", "Photo"], "properties": { "PlayerId": { "type": "string" }, "TeamId": { "type": "string" }, "Name": { "type": "string" }, "Position": { "type": "string" }, "SquadNumber": { "type": ["integer", "null"] }, "Role": { "type": "string" }, "Photo": { "oneOf": [{ "$ref": "#/components/schemas/MediaAsset" }, { "type": "null" }] } }, "additionalProperties": true },
      "MediaFixture": { "type": "object", "required": ["FixtureId", "Status", "Phase", "StartDate", "HomeTeamId", "AwayTeamId"], "properties": { "FixtureId": { "type": "string", "format": "uuid" }, "Status": { "$ref": "#/components/schemas/FixtureStatus" }, "Phase": { "type": ["string", "null"] }, "StartDate": { "type": "string", "format": "date-time" }, "HomeTeamId": { "type": "string" }, "AwayTeamId": { "type": "string" } }, "additionalProperties": true },
      "MediaPackage": {
        "type": "object", "required": ["Header", "Body", "Meta"],
        "properties": {
          "Header": { "allOf": [{ "$ref": "#/components/schemas/BaseHeader" }, { "type": "object", "required": ["SchemaVersion", "Type", "GeneratedAt", "StateFingerprint", "MediaCursor"], "properties": { "SchemaVersion": { "const": "legabot-optional-media.v1" }, "Type": { "const": "media-package-snapshot" } } }] },
          "Body": { "type": "object", "required": ["Product", "Fixture", "Teams", "Players", "MatchMedia", "Completeness", "Rights"], "properties": { "Product": { "type": "object", "required": ["Code", "RequiredForCoreData", "EntitlementRequired"], "properties": { "Code": { "const": "optional-media" }, "RequiredForCoreData": { "const": false }, "EntitlementRequired": { "const": true } }, "additionalProperties": true }, "Fixture": { "$ref": "#/components/schemas/MediaFixture" }, "Teams": { "type": "array", "items": { "$ref": "#/components/schemas/MediaTeam" } }, "Players": { "type": "array", "items": { "$ref": "#/components/schemas/MediaPlayer" } }, "MatchMedia": { "type": "array", "items": { "$ref": "#/components/schemas/MediaAsset" } }, "Completeness": { "type": "object", "additionalProperties": { "type": "integer", "minimum": 0 } }, "Rights": { "type": "object", "additionalProperties": true } }, "additionalProperties": true },
          "Meta": { "type": "object", "required": ["service", "sourceOfTruth", "manifestSource", "assetsStoredByDataService", "coreDataIndependent", "wageringEnabled"], "properties": { "service": { "const": "data.lega.bot" }, "sourceOfTruth": { "const": "lega.bot" }, "manifestSource": { "type": "string", "format": "uri" }, "assetsStoredByDataService": { "const": false }, "coreDataIndependent": { "const": true }, "wageringEnabled": { "const": false } }, "additionalProperties": true }
        }, "additionalProperties": true
      }
    }
  }
}
