Home · JSON Schemas

JSON Schemas

Draft 2020-12. These files are the machine-normative field definitions. Each $id is this same URL on GitHub Pages.

OpenBook change envelope

One envelope for every message: one object, one action. `changes` is a JSON Merge Patch against the object's schema (absent = unchanged, null = removed). JSON Patch (RFC 6902) is not an alternate (Q91). Mirrors the topic openbook/v1/<publisher>/<object>/<action>/<sport>/<id>.

change.schema.json · required: openbookVersion, sequence, datePublished, publisher, object, action, sport, changes

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/change.schema.json",
  "title": "OpenBook change envelope",
  "description": "One envelope for every message: one object, one action. `changes` is a JSON Merge Patch against the object's schema (absent = unchanged, null = removed). JSON Patch (RFC 6902) is not an alternate (Q91). Mirrors the topic openbook/v1/<publisher>/<object>/<action>/<sport>/<id>.",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "datePublished",
    "publisher",
    "object",
    "action",
    "sport",
    "changes"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "datePublished": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "publisher": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "object": {
      "$ref": "common.schema.json#/$defs/objectType"
    },
    "action": {
      "$ref": "common.schema.json#/$defs/action"
    },
    "sport": {
      "type": "string",
      "pattern": "^[a-z0-9-]+$"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The topic's <id>: the fixture id for fixture-scoped objects, else the object's own id."
    },
    "msgType": {
      "$ref": "common.schema.json#/$defs/msgType"
    },
    "reason": {
      "type": "string"
    },
    "references": {
      "type": "array",
      "items": {
        "$ref": "common.schema.json#/$defs/sequence"
      }
    },
    "conflated": {
      "type": "boolean",
      "description": "true when this message skipped intermediate ticks (Q47). Sequence still increases."
    },
    "changes": {
      "type": "object"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "action": {
            "const": "change"
          }
        },
        "required": [
          "action"
        ]
      },
      "then": {
        "properties": {
          "object": {
            "const": "odds"
          }
        }
      }
    }
  ],
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook common definitions

Field names are camelCase and follow schema.org where a property exists (startDate, dateModified, alternateName, sameAs, identifier, superEvent). Every document MAY carry JSON-LD @context / @type.

common.schema.json · required:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/common.schema.json",
  "title": "OpenBook common definitions",
  "description": "Field names are camelCase and follow schema.org where a property exists (startDate, dateModified, alternateName, sameAs, identifier, superEvent). Every document MAY carry JSON-LD @context / @type.",
  "$defs": {
    "openbookVersion": {
      "type": "string",
      "maxLength": 64,
      "examples": [
        "0.3.0-draft"
      ]
    },
    "sequence": {
      "type": "integer",
      "minimum": 0,
      "description": "Monotonic per feed, issued by the publisher's server. The `since` cursor."
    },
    "dateTime": {
      "type": "string",
      "format": "date-time",
      "description": "RFC 3339 (ISO 8601 with an explicit offset)."
    },
    "decimalString": {
      "type": "string",
      "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$",
      "maxLength": 40,
      "description": "Exact decimal as a string, not a JSON number (Q39)."
    },
    "decimalOdds": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^(?:1\\.(?:0*[1-9][0-9]*)|[2-9][0-9]*(?:\\.[0-9]+)?|[1-9][0-9]+(?:\\.[0-9]+)?)$",
      "maxLength": 40,
      "description": "Decimal odds as a decimal string. MUST be strictly greater than 1. null = tombstone (Merge Patch removed). Never a sentinel (not \"0\"). American and fractional forms are presentation only."
    },
    "money": {
      "type": "object",
      "required": [
        "amount"
      ],
      "additionalProperties": false,
      "patternProperties": {
        "^x_": {}
      },
      "properties": {
        "amount": {
          "$ref": "#/$defs/decimalString"
        }
      },
      "description": "A monetary value in the feed's baseCurrency (Q44). Incremental messages do not repeat currency. Odds are not money."
    },
    "iso4217": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "description": "ISO 4217 alpha code (GBP, EUR, USD)."
    },
    "sharedId": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]*(:[a-z0-9-]+)+$",
      "maxLength": 128,
      "description": "Short form of a shared id (sport:soccer). Formal form: urn:openbook:sport:soccer."
    },
    "ownId": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "description": "The publisher's own id, unique within the publisher."
    },
    "territory": {
      "type": "string",
      "pattern": "^[A-Z]{2}(-[A-Z0-9]{1,3})?$",
      "description": "CLDR territory code: ISO 3166-1 alpha-2 (GB) or ISO 3166-2 subdivision (GB-ENG, US-PR)."
    },
    "sameAs": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^https://www\\.wikidata\\.org/entity/Q[0-9]+$",
      "maxLength": 128,
      "description": "schema.org sameAs \u2192 the Wikidata entity URL. The shared entity id: required when one exists, null otherwise."
    },
    "identifier": {
      "type": "array",
      "maxItems": 100,
      "description": "schema.org identifier as PropertyValue list \u2014 external cross-reference ids.",
      "items": {
        "type": "object",
        "required": [
          "propertyID",
          "value"
        ],
        "additionalProperties": false,
        "properties": {
          "propertyID": {
            "type": "string",
            "maxLength": 128,
            "examples": [
              "sportradar",
              "opta"
            ]
          },
          "value": {
            "type": "string",
            "maxLength": 256
          }
        }
      }
    },
    "alternateName": {
      "type": "array",
      "maxItems": 100,
      "items": {
        "type": "string",
        "maxLength": 256
      },
      "description": "schema.org alternateName \u2014 aliases and other spellings."
    },
    "localizedNames": {
      "type": "object",
      "propertyNames": {
        "pattern": "^[a-z]{2}$"
      },
      "additionalProperties": {
        "type": "string",
        "maxLength": 256
      },
      "description": "Per-language names keyed by ISO 639-1."
    },
    "nameLatin": {
      "type": "string",
      "description": "Latin-script form. Method: ISO 9 (Cyrillic) or ISO 843 (Greek)."
    },
    "iso6391": {
      "type": "string",
      "pattern": "^[a-z]{2}$",
      "description": "ISO 639-1 language code (Q68)."
    },
    "timeZone": {
      "type": "string",
      "minLength": 1,
      "description": "IANA time-zone database name (Europe/London). Display only; timestamps stay RFC 3339 with offset (Q9, Q64)."
    },
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90,
      "description": "WGS 84 latitude (Q70)."
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180,
      "description": "WGS 84 longitude (Q70)."
    },
    "place": {
      "type": "object",
      "additionalProperties": false,
      "description": "schema.org Place (Q62). City + territory; no street or postal (Q69). No capacity (Q71).",
      "properties": {
        "name": {
          "type": "string"
        },
        "shortName": {
          "type": "string"
        },
        "registeredName": {
          "type": "string"
        },
        "alternateName": {
          "$ref": "#/$defs/alternateName"
        },
        "names": {
          "$ref": "#/$defs/localizedNames"
        },
        "nameLatin": {
          "$ref": "#/$defs/nameLatin"
        },
        "addressLocality": {
          "type": "string"
        },
        "territory": {
          "$ref": "#/$defs/territory"
        },
        "timeZone": {
          "$ref": "#/$defs/timeZone"
        },
        "latitude": {
          "$ref": "#/$defs/latitude"
        },
        "longitude": {
          "$ref": "#/$defs/longitude"
        },
        "sameAs": {
          "$ref": "#/$defs/sameAs"
        },
        "identifier": {
          "$ref": "#/$defs/identifier"
        }
      },
      "patternProperties": {
        "^x_": {}
      }
    },
    "surface": {
      "enum": [
        "grass",
        "clay",
        "hard",
        "turf",
        "ice",
        "indoor",
        "other"
      ],
      "description": "This fixture's playing surface (Q84)."
    },
    "gender": {
      "enum": [
        "men",
        "women",
        "mixed",
        "open",
        "other"
      ],
      "description": "Competition gender on the league, not the person (Q72). Vocab, not ISO 5218."
    },
    "ageGroup": {
      "type": "string",
      "minLength": 1,
      "description": "League age grade (open, U21, U19, …). Growable vocab (Q73)."
    },
    "hand": {
      "enum": [
        "left",
        "right",
        "both"
      ],
      "description": "Throwing/shooting or batting side (Q88). No ISO."
    },
    "side": {
      "enum": [
        "home",
        "away",
        "draw",
        "over",
        "under",
        "yes",
        "no",
        "participant",
        "other",
        "odd",
        "even",
        "none",
        "home-or-draw",
        "away-or-draw",
        "home-or-away"
      ],
      "description": "Q105 extra tokens: odd, even, none, home-or-draw, away-or-draw, home-or-away. none is a listed selection (Q116). other is leftover."
    },
    "homeAwayDraw": {
      "enum": [
        "home",
        "away",
        "draw"
      ],
      "description": "HT/FT halfTime and fullTime only (Q109)."
    },
    "propOutcomePairing": {
      "description": "Row rules Q110, Q112, Q114, Q119–Q121, Q126–Q131. Listed CS both totals; HT/FT both halves; plus-band is participant + atLeast, not line; yes/no player has player and not leftover other or outcome line; no mix of boards.",
      "allOf": [
        {
          "if": {
            "required": [
              "halfTime"
            ]
          },
          "then": {
            "required": [
              "fullTime"
            ]
          }
        },
        {
          "if": {
            "required": [
              "fullTime"
            ]
          },
          "then": {
            "required": [
              "halfTime"
            ]
          }
        },
        {
          "if": {
            "required": [
              "homeTotal"
            ]
          },
          "then": {
            "required": [
              "awayTotal"
            ]
          }
        },
        {
          "if": {
            "required": [
              "awayTotal"
            ]
          },
          "then": {
            "required": [
              "homeTotal"
            ]
          }
        },
        {
          "if": {
            "required": [
              "atLeast"
            ]
          },
          "then": {
            "required": [
              "participant"
            ]
          }
        },
        {
          "if": {
            "required": [
              "atLeast"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "line"
                  ]
                },
                {
                  "required": [
                    "homeTotal"
                  ]
                },
                {
                  "required": [
                    "halfTime"
                  ]
                },
                {
                  "required": [
                    "player"
                  ]
                }
              ]
            }
          }
        },
        {
          "if": {
            "required": [
              "homeTotal"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "halfTime"
                  ]
                },
                {
                  "required": [
                    "player"
                  ]
                },
                {
                  "required": [
                    "atLeast"
                  ]
                }
              ]
            }
          }
        },
        {
          "if": {
            "required": [
              "halfTime"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "homeTotal"
                  ]
                },
                {
                  "required": [
                    "player"
                  ]
                },
                {
                  "required": [
                    "atLeast"
                  ]
                }
              ]
            }
          }
        },
        {
          "if": {
            "required": [
              "player"
            ]
          },
          "then": {
            "not": {
              "anyOf": [
                {
                  "required": [
                    "homeTotal"
                  ]
                },
                {
                  "required": [
                    "halfTime"
                  ]
                },
                {
                  "required": [
                    "atLeast"
                  ]
                }
              ]
            }
          }
        },
        {
          "if": {
            "required": [
              "player"
            ]
          },
          "then": {
            "properties": {
              "side": {
                "not": {
                  "const": "other"
                }
              }
            }
          }
        },
        {
          "if": {
            "required": [
              "player"
            ],
            "properties": {
              "side": {
                "enum": [
                  "yes",
                  "no"
                ]
              }
            }
          },
          "then": {
            "not": {
              "required": [
                "line"
              ]
            }
          }
        }
      ]
    },
    "marketOutcome": {
      "type": "object",
      "required": [
        "side"
      ],
      "additionalProperties": false,
      "patternProperties": {
        "^x_": {}
      },
      "properties": {
        "side": {
          "$ref": "#/$defs/side"
        },
        "participant": {
          "$ref": "#/$defs/ownId",
          "description": "Required when side = participant. Listed winning margin always has this plus outcome line (Q113) or atLeast (Q120)."
        },
        "odds": {
          "$ref": "#/$defs/decimalOdds"
        },
        "line": {
          "$ref": "#/$defs/decimalString"
        },
        "active": {
          "type": "boolean"
        },
        "homeTotal": {
          "type": "number",
          "description": "Listed correct-score home amount (Q105). JSON number like scores[].total. Pair with awayTotal (Q112)."
        },
        "awayTotal": {
          "type": "number",
          "description": "Listed correct-score away amount (Q105). Pair with homeTotal (Q112)."
        },
        "halfTime": {
          "$ref": "#/$defs/homeAwayDraw"
        },
        "fullTime": {
          "$ref": "#/$defs/homeAwayDraw"
        },
        "player": {
          "$ref": "#/$defs/ownId",
          "description": "Player over/under and yes/no player rows: OpenBook player id only (Q108, Q115, Q126, Q127)."
        },
        "atLeast": {
          "type": "number",
          "description": "Listed winning-margin plus-band floor (Q119). JSON number like homeTotal. 3 means 3 or more. Pair with participant (Q120). Not outcome line (Q121)."
        }
      },
      "allOf": [
        {
          "$ref": "#/$defs/propOutcomePairing"
        }
      ]
    },
    "gradeOutcome": {
      "type": "object",
      "required": [
        "side",
        "result"
      ],
      "additionalProperties": false,
      "properties": {
        "side": {
          "$ref": "#/$defs/side"
        },
        "participant": {
          "$ref": "#/$defs/ownId"
        },
        "line": {
          "$ref": "#/$defs/decimalString"
        },
        "result": {
          "$ref": "#/$defs/gradeResult"
        },
        "homeTotal": {
          "type": "number"
        },
        "awayTotal": {
          "type": "number"
        },
        "halfTime": {
          "$ref": "#/$defs/homeAwayDraw"
        },
        "fullTime": {
          "$ref": "#/$defs/homeAwayDraw"
        },
        "player": {
          "$ref": "#/$defs/ownId"
        },
        "atLeast": {
          "type": "number",
          "description": "Listed winning-margin plus-band floor (Q119). JSON number like homeTotal. 3 means 3 or more. Pair with participant (Q120). Not outcome line (Q121)."
        }
      },
      "allOf": [
        {
          "$ref": "#/$defs/propOutcomePairing"
        }
      ]
    },

    "provenance": {
      "enum": [
        "official",
        "licensed",
        "observed"
      ]
    },
    "role": {
      "enum": [
        "home",
        "away",
        "neutral"
      ],
      "description": "A fact set by the publisher; never inferred from presentation order."
    },
    "deprecation": {
      "type": "object",
      "required": [
        "name",
        "reason",
        "replacement",
        "sunset"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "reason": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512
        },
        "replacement": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "sunset": {
          "type": "string",
          "format": "date",
          "description": "Inclusive last date the name may appear on the live wire; removal only at MAJOR (Q36)."
        }
      }
    },
    "jsonld": {
      "properties": {
        "@context": {},
        "@type": {
          "type": "string"
        }
      }
    },
    "enums": {
      "description": "Every closed vocabulary in OpenBook lives here, once. Schemas $ref these; docs/vocabularies are generated from them."
    },
    "objectType": {
      "enum": [
        "fixture",
        "odds",
        "market",
        "score",
        "grade",
        "league",
        "season",
        "stage",
        "participant",
        "player",
        "lineup",
        "publisher",
        "stall",
        "toss",
        "series"
      ]
    },
    "action": {
      "enum": [
        "snapshot",
        "create",
        "update",
        "delete",
        "change",
        "snapshotComplete",
        "heartbeat"
      ],
      "description": "`change` is used only by `odds`. `snapshotComplete` and `heartbeat` are control actions on the same stream (Q46)."
    },
    "msgType": {
      "enum": [
        "alert",
        "update",
        "cancel"
      ],
      "description": "CAP 1.2 msgType, on market/update."
    },
    "eventStatus": {
      "enum": [
        "scheduled",
        "delayed",
        "live",
        "paused",
        "suspended",
        "postponed",
        "ended",
        "cancelled"
      ],
      "description": "Fixture lifecycle (Q25). `ended` happens once."
    },
    "marketStatus": {
      "enum": [
        "open",
        "suspended",
        "closed",
        "void"
      ],
      "description": "Can you bet it (Q43). Off the board is status, not a sentinel price. Last odds MAY remain when not open."
    },
    "competitionType": {
      "enum": [
        "league",
        "cup",
        "tournament",
        "series",
        "exhibition"
      ]
    },
    "participantType": {
      "enum": [
        "team",
        "individual"
      ]
    },
    "sourceType": {
      "enum": [
        "sportsbook",
        "exchange",
        "model"
      ]
    },
    "feedKind": {
      "enum": [
        "snapshot",
        "stream",
        "docs",
        "mcp",
        "plugin"
      ],
      "description": "What a discovery feed entry is (Q56). snapshot/stream/docs are the OpenBook feed; mcp and plugin point at another standard's manifest, not an OpenBook document."
    },
    "stageType": {
      "enum": [
        "phase",
        "group",
        "round",
        "matchday",
        "leg",
        "seriesGame"
      ]
    },
    "marketShape": {
      "enum": [
        "binary",
        "n-way",
        "over-under",
        "handicap",
        "exact-value",
        "correct-score",
        "yes-no"
      ]
    },
    "marketCategory": {
      "enum": [
        "main-line",
        "score-prop",
        "game-prop",
        "player-prop",
        "outright",
        "parlay-special",
        "same-game-parlay"
      ]
    },
    "segmentStatus": {
      "enum": [
        "pending",
        "live",
        "paused",
        "down"
      ],
      "description": "Per-segment status (Q30). `down` = final, happens once, terminal."
    },
    "statusReason": {
      "enum": [
        "weather",
        "crowd",
        "injury",
        "retirement",
        "walkover",
        "forfeit",
        "technical",
        "scheduling",
        "correction",
        "other"
      ]
    },
    "scoreUnit": {
      "enum": [
        "goals",
        "points",
        "runs",
        "hits",
        "errors",
        "sets",
        "games",
        "frames",
        "strokes",
        "laps",
        "position",
        "time",
        "corners",
        "yellowCards",
        "redCards",
        "wickets",
        "overs",
        "rounds",
        "knockdowns",
        "aces",
        "faults",
        "other"
      ],
      "description": "What a score line counts (Q26). The sport/league declares its primaryUnit."
    },
    "gradeResult": {
      "enum": [
        "win",
        "lose",
        "void",
        "half-win",
        "half-lose"
      ]
    }
  }
}

OpenBook discovery document

One URL lists a publisher's feeds and additional surfaces (Q49, Q56). GBFS-shaped field names, not a GBFS data wrapper (Q90). Not a list of other publishers (Q94). The publisher object stays identity, not the catalog.

discovery.schema.json · required: lastUpdated, ttl, feeds

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/discovery.schema.json",
  "title": "OpenBook discovery document",
  "description": "One URL lists a publisher's feeds and additional surfaces (Q49, Q56). GBFS-shaped field names, not a GBFS data wrapper (Q90). Not a list of other publishers (Q94). The publisher object stays identity, not the catalog.",
  "type": "object",
  "required": [
    "lastUpdated",
    "ttl",
    "feeds"
  ],
  "properties": {
    "lastUpdated": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "ttl": {
      "type": "integer",
      "minimum": 0,
      "description": "Cache lifetime in seconds (Q48)."
    },
    "feeds": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": [
          "name",
          "url"
        ],
        "additionalProperties": false,
        "patternProperties": {
          "^x_": {}
        },
        "properties": {
          "name": {
            "type": "string",
            "description": "Human label for this entry (snapshot, stream, docs, or a plugin name)."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "For snapshot/stream/docs: the OpenBook surface. For mcp/plugin: that surface's own manifest URL, not an OpenBook document (Q56)."
          },
          "kind": {
            "$ref": "common.schema.json#/$defs/feedKind"
          },
          "id": {
            "$ref": "common.schema.json#/$defs/ownId",
            "description": "Publisher-own id when listing more than one mcp or plugin entry."
          },
          "schemaUrl": {
            "type": "string",
            "format": "uri",
            "description": "URI of the schema that governs the document at url. Required in practice for mcp and plugin; omitted for snapshot/stream (those are OpenBook)."
          }
        }
      }
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook fixture

One match — the base object (schema.org SportsEvent). Publisher-own id plus the standard facts that let consumers match it across publishers. Every participant carries a role (home / away / neutral) AND an order.

fixture.schema.json · required: openbookVersion, id, sequence, dateModified, sport, league, startDate, participants

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/fixture.schema.json",
  "title": "OpenBook fixture",
  "description": "One match \u2014 the base object (schema.org SportsEvent). Publisher-own id plus the standard facts that let consumers match it across publishers. Every participant carries a role (home / away / neutral) AND an order.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "sport",
    "league",
    "startDate",
    "participants"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string",
      "examples": [
        "SportsEvent"
      ]
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "name": {
      "type": "string"
    },
    "sport": {
      "type": "object",
      "required": [
        "id",
        "name"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "$ref": "common.schema.json#/$defs/sharedId"
        },
        "name": {
          "type": "string"
        }
      }
    },
    "league": {
      "type": "object",
      "required": [
        "id",
        "name",
        "territory",
        "competitionType"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "$ref": "common.schema.json#/$defs/ownId"
        },
        "name": {
          "type": "string"
        },
        "territory": {
          "$ref": "common.schema.json#/$defs/territory"
        },
        "competitionType": {
          "$ref": "common.schema.json#/$defs/competitionType"
        },
        "shortName": {
          "type": "string"
        },
        "registeredName": {
          "type": "string"
        },
        "gender": {
          "$ref": "common.schema.json#/$defs/gender"
        },
        "ageGroup": {
          "$ref": "common.schema.json#/$defs/ageGroup"
        },
        "sameAs": {
          "$ref": "common.schema.json#/$defs/sameAs"
        }
      }
    },
    "season": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.schema.json#/$defs/ownId"
        },
        "name": {
          "type": "string"
        }
      }
    },
    "stage": {
      "type": "object",
      "description": "The leaf stage; walk `parent` on the stage object for the chain.",
      "properties": {
        "id": {
          "$ref": "common.schema.json#/$defs/ownId"
        },
        "name": {
          "type": "string"
        },
        "stageType": {
          "$ref": "common.schema.json#/$defs/stageType"
        }
      }
    },
    "startDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "cutoffDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "eventStatus": {
      "$ref": "common.schema.json#/$defs/eventStatus"
    },
    "superEvent": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "schema.org superEvent. Not a second fixture for live (Q101); pregame and live are one fixture."
    },
    "participants": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "territory",
          "role",
          "order"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "$ref": "common.schema.json#/$defs/ownId"
          },
          "name": {
            "type": "string"
          },
          "territory": {
            "$ref": "common.schema.json#/$defs/territory"
          },
          "role": {
            "$ref": "common.schema.json#/$defs/role"
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Listing order \u2014 always present, even for two-sided events."
          },
          "sameAs": {
            "$ref": "common.schema.json#/$defs/sameAs"
          },
          "seed": {
            "type": "integer",
            "minimum": 1,
            "description": "This draw's seed on the fixture participant row (Q85)."
          }
        }
      }
    },
    "location": {
      "$ref": "common.schema.json#/$defs/place"
    },
    "surface": {
      "$ref": "common.schema.json#/$defs/surface"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook grade

The book's judgement: one market x one source, graded from a segment that is down. `basedOn` is the score `sequence` (the down, or a later correction) it graded from. A grade is never edited: a corrected grade is grade/delete + a new grade/create with `supersedes`.

grade.schema.json · required: openbookVersion, sequence, dateModified, gradeId, fixture, segment, source, marketType, basis, basedOn, outcomes

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/grade.schema.json",
  "title": "OpenBook grade",
  "description": "The book's judgement: one market x one source, graded from a segment that is down. `basedOn` is the score `sequence` (the down, or a later correction) it graded from. A grade is never edited: a corrected grade is grade/delete + a new grade/create with `supersedes`.",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "dateModified",
    "gradeId",
    "fixture",
    "segment",
    "source",
    "marketType",
    "basis",
    "basedOn",
    "outcomes"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "gradeId": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "supersedes": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "segment": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "source": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "marketType": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "line": {
      "$ref": "common.schema.json#/$defs/decimalString"
    },
    "basis": {
      "$ref": "common.schema.json#/$defs/scoreUnit",
      "description": "The unit this market graded on (goals, corners, cards...)."
    },
    "basedOn": {
      "$ref": "common.schema.json#/$defs/sequence",
      "description": "The score message sequence the grade was computed from."
    },
    "dateGraded": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "outcomes": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "common.schema.json#/$defs/gradeOutcome"
      }
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook league

Any recurring competition — the Premier League, the FA Cup, the NBA Cup, the F1 World Championship — typed by competitionType. Publisher-own id; sameAs (Wikidata) as the shared entity id.

league.schema.json · required: openbookVersion, id, sequence, dateModified, name, sport, territory, competitionType, sameAs

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/league.schema.json",
  "title": "OpenBook league",
  "description": "Any recurring competition \u2014 the Premier League, the FA Cup, the NBA Cup, the F1 World Championship \u2014 typed by competitionType. Publisher-own id; sameAs (Wikidata) as the shared entity id.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "name",
    "sport",
    "territory",
    "competitionType",
    "sameAs"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "name": {
      "type": "string"
    },
    "shortName": {
      "type": "string"
    },
    "registeredName": {
      "type": "string"
    },
    "alternateName": {
      "$ref": "common.schema.json#/$defs/alternateName"
    },
    "names": {
      "$ref": "common.schema.json#/$defs/localizedNames"
    },
    "nameLatin": {
      "$ref": "common.schema.json#/$defs/nameLatin"
    },
    "gender": {
      "$ref": "common.schema.json#/$defs/gender"
    },
    "ageGroup": {
      "$ref": "common.schema.json#/$defs/ageGroup"
    },
    "sport": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "territory": {
      "$ref": "common.schema.json#/$defs/territory"
    },
    "competitionType": {
      "$ref": "common.schema.json#/$defs/competitionType"
    },
    "organizer": {
      "type": "object",
      "additionalProperties": false,
      "description": "schema.org organizer \u2014 the NBA, UEFA, the FIA.",
      "properties": {
        "id": {
          "$ref": "common.schema.json#/$defs/ownId"
        },
        "name": {
          "type": "string"
        },
        "sameAs": {
          "$ref": "common.schema.json#/$defs/sameAs"
        }
      }
    },
    "ruleset": {
      "type": "object",
      "properties": {
        "clockBased": {
          "type": "boolean"
        },
        "clockAscending": {
          "type": "boolean"
        },
        "scoreBased": {
          "type": "boolean"
        },
        "segmentBased": {
          "type": "boolean"
        },
        "hasHalftime": {
          "type": "boolean"
        },
        "allowTies": {
          "type": "boolean"
        },
        "segments": {
          "type": "array",
          "items": {
            "$ref": "common.schema.json#/$defs/sharedId"
          }
        },
        "primaryUnit": {
          "$ref": "common.schema.json#/$defs/scoreUnit"
        }
      }
    },
    "limit": {
      "$ref": "common.schema.json#/$defs/money",
      "description": "Default stake/liability cap for this league (Q45). Overrides sport; overridden by market."
    },
    "sameAs": {
      "$ref": "common.schema.json#/$defs/sameAs"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook lineup

Starting players for one fixture (Q80). Roster player ids only. Not on the catalog fixture. No formation, substitutions, or predicted lineup (Q82).

lineup.schema.json · required: openbookVersion, sequence, dateModified, fixture, player

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/lineup.schema.json",
  "title": "OpenBook lineup",
  "description": "Starting players for one fixture (Q80). Roster player ids only. Not on the catalog fixture. No formation, substitutions, or predicted lineup (Q82).",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "dateModified",
    "fixture",
    "player"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "player": {
      "type": "array",
      "items": {
        "$ref": "common.schema.json#/$defs/ownId"
      },
      "description": "Roster player ids that started (Q80)."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook market

A fixture's market as priced by ONE source — the document form used by market/snapshot and market/update. Identity: (source, fixture, marketType, segment, line, basis). Price moves arrive as odds/change.

market.schema.json · required: openbookVersion, sequence, dateModified, fixture, marketType, source, provenance, status, limit, outcomes

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/market.schema.json",
  "title": "OpenBook market",
  "description": "A fixture's market as priced by ONE source \u2014 the document form used by market/snapshot and market/update. Identity: (source, fixture, marketType, segment, line, basis). Price moves arrive as odds/change.",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "dateModified",
    "fixture",
    "marketType",
    "source",
    "provenance",
    "status",
    "limit",
    "outcomes"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "marketType": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "segment": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "line": {
      "$ref": "common.schema.json#/$defs/decimalString"
    },
    "basis": {
      "$ref": "common.schema.json#/$defs/scoreUnit",
      "description": "What this market counts (Q98). Same list as score/grade. If omitted, sport/league primaryUnit. Not a new market type."
    },
    "source": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "provenance": {
      "$ref": "common.schema.json#/$defs/provenance"
    },
    "status": {
      "$ref": "common.schema.json#/$defs/marketStatus"
    },
    "isMain": {
      "type": "boolean",
      "description": "The main line among alternates."
    },
    "limit": {
      "$ref": "common.schema.json#/$defs/money",
      "description": "Max stake/liability in the feed's baseCurrency (Q45). Required on the market document; omitted on a patch unless it changed."
    },
    "outcomes": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "common.schema.json#/$defs/marketOutcome"
      }
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook reference_market_type

A canonical market type — what can be bet. The controlled market vocabulary is the core contribution of OpenBook.

market_type.schema.json · required: openbookVersion, id, name, genre, shape, category

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/market_type.schema.json",
  "title": "OpenBook reference_market_type",
  "description": "A canonical market type \u2014 what can be bet. The controlled market vocabulary is the core contribution of OpenBook.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "name",
    "genre",
    "shape",
    "category"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^market:[a-z0-9-]+$",
      "examples": [
        "market:moneyline",
        "market:total",
        "market:spread",
        "market:player-points"
      ]
    },
    "name": {
      "type": "string",
      "examples": [
        "Moneyline",
        "Total",
        "Player Points"
      ]
    },
    "genre": {
      "type": "string",
      "description": "Grouping label, e.g. 'match', 'player', 'team'."
    },
    "shape": {
      "$ref": "common.schema.json#/$defs/marketShape"
    },
    "category": {
      "$ref": "common.schema.json#/$defs/marketCategory"
    },
    "sides": {
      "type": "array",
      "items": {
        "$ref": "common.schema.json#/$defs/side"
      }
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "isPlayerProp": {
      "type": "boolean",
      "default": false
    },
    "isTeamProp": {
      "type": "boolean",
      "default": false
    },
    "isGameProp": {
      "type": "boolean",
      "default": false
    },
    "@context": {},
    "@type": {
      "type": "string"
    }
  },
  "patternProperties": {
    "^x_": {}
  }
}

OpenBook odds/change payload

The `changes` payload of an odds/change message: only the markets/outcomes whose prices moved (Merge Patch). Each market names its source and provenance. Identity: (source, fixture, marketType, segment, line, basis).

odds_change.schema.json · required: markets

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/odds_change.schema.json",
  "title": "OpenBook odds/change payload",
  "description": "The `changes` payload of an odds/change message: only the markets/outcomes whose prices moved (Merge Patch). Each market names its source and provenance. Identity: (source, fixture, marketType, segment, line, basis).",
  "type": "object",
  "required": [
    "markets"
  ],
  "properties": {
    "markets": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": [
          "marketType",
          "source",
          "provenance",
          "outcomes"
        ],
        "properties": {
          "segment": {
            "$ref": "common.schema.json#/$defs/sharedId"
          },
          "line": {
            "$ref": "common.schema.json#/$defs/decimalString",
            "description": "Handicap / total value for the market, when applicable."
          },
          "basis": {
            "$ref": "common.schema.json#/$defs/scoreUnit",
            "description": "What this market counts (Q98). If omitted, sport/league primaryUnit."
          },
          "status": {
            "$ref": "common.schema.json#/$defs/marketStatus"
          },
          "limit": {
            "$ref": "common.schema.json#/$defs/money",
            "description": "Present on a tick only when the limit changed (Merge Patch)."
          },
          "source": {
            "$ref": "common.schema.json#/$defs/ownId",
            "description": "Whose odds these are \u2014 a source declared in the publisher record."
          },
          "provenance": {
            "$ref": "common.schema.json#/$defs/provenance"
          },
          "outcomes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "common.schema.json#/$defs/marketOutcome"
            }
          },
          "marketType": {
            "$ref": "common.schema.json#/$defs/sharedId"
          }
        },
        "patternProperties": {
          "^x_": {}
        },
        "additionalProperties": false
      }
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook participant

A competitor — a team OR an individual (schema.org SportsTeam / Person). Belongs to a SPORT, never to a league. Publisher-own id; sameAs (Wikidata) as the shared entity id. Names: Q11 / Q57.

participant.schema.json · required: openbookVersion, id, sequence, dateModified, name, territory, participantType, sport, sameAs

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/participant.schema.json",
  "title": "OpenBook participant",
  "description": "A competitor — a team OR an individual (schema.org SportsTeam / Person). Belongs to a SPORT, never to a league. Publisher-own id; sameAs (Wikidata) as the shared entity id. Names: Q11 / Q57.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "name",
    "territory",
    "participantType",
    "sport",
    "sameAs"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string",
      "examples": [
        "SportsTeam",
        "Person"
      ]
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "participantType": {
      "$ref": "common.schema.json#/$defs/participantType"
    },
    "sport": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "territory": {
      "$ref": "common.schema.json#/$defs/territory"
    },
    "name": {
      "type": "string",
      "description": "Required popular/board name, UTF-8, diacritics kept."
    },
    "shortName": {
      "type": "string",
      "description": "Board / ticker form: 'Man City', 'K. De Bruyne'."
    },
    "abbreviation": {
      "type": "string",
      "description": "Teams only (Q11): 'MCI'."
    },
    "location": {
      "type": "string",
      "description": "Teams only. NFL-style market city; empty/omit when the board name has no city (Arsenal)."
    },
    "nickname": {
      "type": "string",
      "description": "Teams only. NFL-style nickname (Giants); omit when unused."
    },
    "registeredName": {
      "type": "string",
      "description": "Teams only. Registry / FIFA international long name — not ISO."
    },
    "alternateName": {
      "$ref": "common.schema.json#/$defs/alternateName"
    },
    "names": {
      "$ref": "common.schema.json#/$defs/localizedNames"
    },
    "nameLatin": {
      "$ref": "common.schema.json#/$defs/nameLatin"
    },
    "familyName": {
      "type": "string",
      "description": "Individuals only (vCard N / X.520 / schema.org)."
    },
    "givenName": {
      "type": "string",
      "description": "Individuals only (vCard N / X.520 / schema.org)."
    },
    "sameAs": {
      "$ref": "common.schema.json#/$defs/sameAs"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "participantType": {
            "const": "individual"
          }
        },
        "required": [
          "participantType"
        ]
      },
      "then": {
        "properties": {
          "abbreviation": false,
          "location": false,
          "nickname": false,
          "registeredName": false
        }
      }
    },
    {
      "if": {
        "properties": {
          "participantType": {
            "const": "team"
          }
        },
        "required": [
          "participantType"
        ]
      },
      "then": {
        "properties": {
          "givenName": false,
          "familyName": false
        }
      }
    }
  ],
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook player (roster membership)

A person's membership of a team's roster — for lineups and player props. The person and the team are both participants. Not a competitor object; individuals who compete are participants.

player.schema.json · required: openbookVersion, id, sequence, dateModified, participant, team

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/player.schema.json",
  "title": "OpenBook player (roster membership)",
  "description": "A person's membership of a team's roster \u2014 for lineups and player props. The person and the team are both participants. Not a competitor object; individuals who compete are participants.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "participant",
    "team"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "participant": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The person (a participant with participantType individual)."
    },
    "team": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The team (a participant with participantType team)."
    },
    "position": {
      "type": "string"
    },
    "number": {
      "type": "integer",
      "minimum": 0
    },
    "throws": {
      "$ref": "common.schema.json#/$defs/hand",
      "description": "Throwing or shooting hand (Q88)."
    },
    "bats": {
      "$ref": "common.schema.json#/$defs/hand",
      "description": "Batting side (Q88). both = switch."
    },
    "startDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "endDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "active": {
      "type": "boolean",
      "default": true
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook publisher

The feed's own record — who transmits, and which sources (whose odds) the feed carries. Analogous to GTFS agency.txt.

publisher.schema.json · required: openbookVersion, id, sequence, dateModified, name, baseCurrency, sources

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/publisher.schema.json",
  "title": "OpenBook publisher",
  "description": "The feed's own record \u2014 who transmits, and which sources (whose odds) the feed carries. Analogous to GTFS agency.txt.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "name",
    "baseCurrency",
    "sources"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]*$",
      "description": "Publisher id: lowercase, dash-separated; also the <publisher-id> level of stream names."
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "name": {
      "type": "string"
    },
    "registeredName": {
      "type": "string",
      "description": "Optional registry / legal name (Q60). ISO 17442 is the LEI id, not this string."
    },
    "inLanguage": {
      "$ref": "common.schema.json#/$defs/iso6391",
      "description": "Feed language (Q68). A bare name is in this language."
    },
    "baseCurrency": {
      "$ref": "common.schema.json#/$defs/iso4217",
      "description": "This feed's accounting currency. Money `{amount}` is in this code. Another currency is another subscription (Q44)."
    },
    "url": {
      "type": "string",
      "format": "uri"
    },
    "sources": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": [
          "id",
          "name",
          "sourceType"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "$ref": "common.schema.json#/$defs/ownId"
          },
          "name": {
            "type": "string"
          },
          "territory": {
            "$ref": "common.schema.json#/$defs/territory"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "sourceType": {
            "$ref": "common.schema.json#/$defs/sourceType"
          },
          "sameAs": {
            "$ref": "common.schema.json#/$defs/sameAs"
          }
        }
      }
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "email": {
      "type": "string"
    },
    "heartbeatMs": {
      "type": "integer",
      "minimum": 1,
      "description": "Maximum silence on the push stream in milliseconds (Q46). Quiet longer than this, the consumer SHOULD treat the feed as down."
    },
    "ttl": {
      "type": "integer",
      "minimum": 0,
      "description": "Cache lifetime in seconds (GBFS ttl, Q48). Optional on the publisher record; required on the discovery document."
    },
    "@context": {},
    "@type": {
      "type": "string",
      "examples": [
        "Organization"
      ]
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook region

A territory. id = CLDR territory code (ISO 3166-1 alpha-2, or ISO 3166-2 for sub-national teams); names from CLDR; sport-body codes as crosswalks.

region.schema.json · required: openbookVersion, id, sequence, dateModified, name

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/region.schema.json",
  "title": "OpenBook region",
  "description": "A territory. id = CLDR territory code (ISO 3166-1 alpha-2, or ISO 3166-2 for sub-national teams); names from CLDR; sport-body codes as crosswalks.",
  "type": "object",
  "required": ["openbookVersion", "id", "sequence", "dateModified", "name"],
  "properties": {
    "@context": {}, "@type": { "type": "string", "examples": ["Country", "AdministrativeArea"] },
    "openbookVersion": { "$ref": "common.schema.json#/$defs/openbookVersion" },
    "id": { "$ref": "common.schema.json#/$defs/territory", "examples": ["GB", "GB-ENG", "US-PR", "XK"] },
    "sequence": { "$ref": "common.schema.json#/$defs/sequence" },
    "dateModified": { "$ref": "common.schema.json#/$defs/dateTime" },
    "name": { "type": "string" },
    "names": { "$ref": "common.schema.json#/$defs/localizedNames" },
    "parent": { "$ref": "common.schema.json#/$defs/territory" },
    "iocCode": { "type": ["string", "null"], "pattern": "^[A-Z]{3}$" },
    "fifaCode": { "type": ["string", "null"], "pattern": "^[A-Z]{3}$" },
    "sameAs": { "$ref": "common.schema.json#/$defs/sameAs" },
    "identifier": { "$ref": "common.schema.json#/$defs/identifier" }
  },
  "patternProperties": { "^x_": {} },
  "additionalProperties": false
}

OpenBook score

The live state of a fixture (score/update): event status, per-segment status (a segment goes `down` ONCE, terminally), clock, and score lines per participant x unit with per-segment breakdown. A correction to a down segment is an erratum (`correction: true`), never a second down.

score.schema.json · required: openbookVersion, sequence, dateModified, fixture, eventStatus, segments, scores

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/score.schema.json",
  "title": "OpenBook score",
  "description": "The live state of a fixture (score/update): event status, per-segment status (a segment goes `down` ONCE, terminally), clock, and score lines per participant x unit with per-segment breakdown. A correction to a down segment is an erratum (`correction: true`), never a second down.",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "dateModified",
    "fixture",
    "eventStatus",
    "segments",
    "scores"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "eventStatus": {
      "$ref": "common.schema.json#/$defs/eventStatus"
    },
    "statusReason": {
      "$ref": "common.schema.json#/$defs/statusReason"
    },
    "correction": {
      "type": "boolean",
      "default": false,
      "description": "True when this update corrects the scores of an already-down segment (Q31). Status and downAt do not change."
    },
    "segments": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "segment",
          "status"
        ],
        "additionalProperties": false,
        "properties": {
          "segment": {
            "$ref": "common.schema.json#/$defs/sharedId"
          },
          "status": {
            "$ref": "common.schema.json#/$defs/segmentStatus"
          },
          "downAt": {
            "$ref": "common.schema.json#/$defs/dateTime"
          },
          "order": {
            "type": "integer",
            "minimum": 1
          }
        }
      }
    },
    "currentSegment": {
      "$ref": "common.schema.json#/$defs/sharedId"
    },
    "clock": {
      "type": "object",
      "additionalProperties": false,
      "description": "Integer seconds within the current segment plus the broadcast string.",
      "properties": {
        "elapsed": {
          "type": "integer",
          "minimum": 0
        },
        "remaining": {
          "type": "integer",
          "minimum": 0
        },
        "running": {
          "type": "boolean"
        },
        "display": {
          "type": "string",
          "examples": [
            "67:00",
            "Q3 07:12",
            "45:00+2"
          ]
        }
      }
    },
    "scores": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "participant",
          "unit",
          "total"
        ],
        "additionalProperties": false,
        "properties": {
          "participant": {
            "$ref": "common.schema.json#/$defs/ownId"
          },
          "unit": {
            "$ref": "common.schema.json#/$defs/scoreUnit"
          },
          "total": {
            "type": "number"
          },
          "bySegment": {
            "type": "object",
            "description": "segment id -> value in that segment",
            "additionalProperties": {
              "type": "number"
            }
          },
          "display": {
            "type": "string",
            "description": "For units like tennis points: '30', 'AD'."
          }
        }
      }
    },
    "server": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "Racket sports: the serving participant."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook season

One edition of a league: 2025-26, F1 2026. Publisher-own id.

season.schema.json · required: openbookVersion, id, sequence, dateModified, league, name

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/season.schema.json",
  "title": "OpenBook season",
  "description": "One edition of a league: 2025-26, F1 2026. Publisher-own id.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "league",
    "name"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "league": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "name": {
      "type": "string",
      "description": "Display label (2025/26, F1 2026). Machine bounds are startDate / endDate (Q60)."
    },
    "alternateName": {
      "$ref": "common.schema.json#/$defs/alternateName"
    },
    "startDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "endDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "sameAs": {
      "$ref": "common.schema.json#/$defs/sameAs"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook series (live lead)

Live playoff series lead (Q86 leftovers, Q139–Q140). Not this game's score. Not competitionType series. Round stays on stage (seriesGame). Win counts wait.

series.schema.json · required: openbookVersion, sequence, dateModified, fixture, stage

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/series.schema.json",
  "title": "OpenBook series (live lead)",
  "description": "Live playoff series lead (Q86 leftovers, Q139–Q140). Not this game's score. Not competitionType series. Round stays on stage (seriesGame). Win counts wait.",
  "type": "object",
  "required": [
    "openbookVersion",
    "sequence",
    "dateModified",
    "fixture",
    "stage"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "This game in the series."
    },
    "stage": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The printed round (seriesGame)."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook sport

A sport — shared vocabulary owned by the standard. Disciplines hang beneath (athletics:110m-hurdles).

sport.schema.json · required: openbookVersion, id, name

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/sport.schema.json",
  "title": "OpenBook sport",
  "description": "A sport \u2014 shared vocabulary owned by the standard. Disciplines hang beneath (athletics:110m-hurdles).",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "name"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/sharedId",
      "examples": [
        "sport:soccer",
        "sport:athletics"
      ]
    },
    "name": {
      "type": "string"
    },
    "abbreviation": {
      "type": "string"
    },
    "active": {
      "type": "boolean",
      "default": true
    },
    "alternateName": {
      "$ref": "common.schema.json#/$defs/alternateName"
    },
    "names": {
      "$ref": "common.schema.json#/$defs/localizedNames"
    },
    "sameAs": {
      "$ref": "common.schema.json#/$defs/sameAs"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    },
    "primaryUnit": {
      "$ref": "common.schema.json#/$defs/scoreUnit"
    },
    "limit": {
      "$ref": "common.schema.json#/$defs/money",
      "description": "Default stake/liability cap for this sport (Q45). Overridden by a more specific league or market limit."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook stage

A named slice of a season. Recursive: a stage MAY have a parent stage. Regular Season (phase) · Group A (group) · Round 14 (round) · Matchday 7 · Leg 2 · Game 3 (seriesGame).

stage.schema.json · required: openbookVersion, id, sequence, dateModified, season, name, stageType

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/stage.schema.json",
  "title": "OpenBook stage",
  "description": "A named slice of a season. Recursive: a stage MAY have a parent stage. Regular Season (phase) \u00b7 Group A (group) \u00b7 Round 14 (round) \u00b7 Matchday 7 \u00b7 Leg 2 \u00b7 Game 3 (seriesGame).",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "season",
    "name",
    "stageType"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "season": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "name": {
      "type": "string"
    },
    "alternateName": {
      "$ref": "common.schema.json#/$defs/alternateName"
    },
    "parent": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The containing stage, if any."
    },
    "stageType": {
      "$ref": "common.schema.json#/$defs/stageType"
    },
    "order": {
      "type": "integer",
      "minimum": 1
    },
    "startDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "endDate": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "identifier": {
      "$ref": "common.schema.json#/$defs/identifier"
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook stall

Racing stall/draw for one runner in one race (Q86 leftovers, Q141–Q144). Not on the generic fixture or participant row. Gate is order (1-based, Q111). Not a new live object.

stall.schema.json · required: openbookVersion, id, sequence, dateModified, fixture, participant, order

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/stall.schema.json",
  "title": "OpenBook stall",
  "description": "Racing stall/draw for one runner in one race (Q86 leftovers, Q141–Q144). Not on the generic fixture or participant row. Gate is order (1-based, Q111). Not a new live object.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "fixture",
    "participant",
    "order"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The race."
    },
    "participant": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The runner."
    },
    "order": {
      "type": "integer",
      "minimum": 1,
      "description": "The gate (1-based)."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

OpenBook toss

Cricket toss: who won the coin (Q86 leftovers, Q142–Q144). Not on the generic fixture. Not score. Not a new live object. participant is who won. Elected bat/bowl not in this pick.

toss.schema.json · required: openbookVersion, id, sequence, dateModified, fixture, participant

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openbook-data-standards.github.io/openbook/schema/toss.schema.json",
  "title": "OpenBook toss",
  "description": "Cricket toss: who won the coin (Q86 leftovers, Q142–Q144). Not on the generic fixture. Not score. Not a new live object. participant is who won. Elected bat/bowl not in this pick.",
  "type": "object",
  "required": [
    "openbookVersion",
    "id",
    "sequence",
    "dateModified",
    "fixture",
    "participant"
  ],
  "properties": {
    "@context": {},
    "@type": {
      "type": "string"
    },
    "openbookVersion": {
      "$ref": "common.schema.json#/$defs/openbookVersion"
    },
    "id": {
      "$ref": "common.schema.json#/$defs/ownId"
    },
    "sequence": {
      "$ref": "common.schema.json#/$defs/sequence"
    },
    "dateModified": {
      "$ref": "common.schema.json#/$defs/dateTime"
    },
    "fixture": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "The match."
    },
    "participant": {
      "$ref": "common.schema.json#/$defs/ownId",
      "description": "Who won the toss."
    }
  },
  "patternProperties": {
    "^x_": {}
  },
  "additionalProperties": false
}

Examples (raw files)

The sequence-order walkthrough is the examples page. These are the same files, listed for implementers.

discovery.example.json

examples/discovery.example.json

{
  "lastUpdated": "2026-09-19T12:00:00Z",
  "ttl": 60,
  "feeds": [
    {
      "name": "snapshot",
      "kind": "snapshot",
      "url": "https://example.invalid/acme-feeds/snapshot"
    },
    {
      "name": "stream",
      "kind": "stream",
      "url": "https://example.invalid/acme-feeds/stream"
    },
    {
      "name": "docs",
      "kind": "docs",
      "url": "https://example.invalid/acme-feeds/docs"
    },
    {
      "name": "OpenBook MCP",
      "kind": "mcp",
      "id": "openbook-mcp",
      "schemaUrl": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
      "url": "https://example.invalid/.well-known/mcp.json"
    },
    {
      "name": "settlement plugin",
      "kind": "plugin",
      "id": "settlement",
      "schemaUrl": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
      "url": "https://example.invalid/plugins/settlement/plugin.json"
    }
  ]
}

fixture.example.json

examples/fixture.example.json

{
  "@context": "https://schema.org",
  "@type": "SportsEvent",
  "openbookVersion": "0.3.0-draft",
  "id": "EVT-88213",
  "sequence": 104870,
  "dateModified": "2026-09-12T18:02:11Z",
  "name": "Arsenal v Manchester City",
  "sport": {
    "id": "sport:soccer",
    "name": "Soccer"
  },
  "league": {
    "id": "LG-17",
    "name": "Premier League",
    "territory": "GB-ENG",
    "competitionType": "league",
    "gender": "men",
    "ageGroup": "open",
    "sameAs": "https://www.wikidata.org/entity/Q9448"
  },
  "season": {
    "id": "S-2025",
    "name": "2025-26"
  },
  "stage": {
    "id": "ST-REG",
    "name": "Regular Season",
    "stageType": "phase"
  },
  "startDate": "2026-09-19T14:00:00Z",
  "cutoffDate": "2026-09-19T14:00:00Z",
  "eventStatus": "scheduled",
  "participants": [
    {
      "id": "T-3",
      "name": "Arsenal",
      "territory": "GB-ENG",
      "role": "home",
      "order": 1,
      "sameAs": "https://www.wikidata.org/entity/Q9617"
    },
    {
      "id": "T-11",
      "name": "Manchester City",
      "territory": "GB-ENG",
      "role": "away",
      "order": 2,
      "sameAs": "https://www.wikidata.org/entity/Q50602"
    }
  ],
  "location": {
    "name": "Emirates Stadium",
    "addressLocality": "London",
    "territory": "GB-ENG",
    "timeZone": "Europe/London",
    "latitude": 51.555,
    "longitude": -0.108,
    "sameAs": "https://www.wikidata.org/entity/Q19478"
  },
  "surface": "grass",
  "identifier": [
    {
      "propertyID": "sportradar",
      "value": "sr:match:8412480"
    }
  ]
}

fixture_update.example.json

examples/fixture_update.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104902,
  "datePublished": "2026-09-19T13:05:00Z",
  "publisher": "acme-feeds",
  "object": "fixture",
  "action": "update",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "startDate": "2026-09-19T14:15:00Z",
    "x_reason": "kick-off delayed 15 minutes"
  }
}

grade.example.json

examples/grade.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 106001,
  "datePublished": "2026-09-19T14:48:02Z",
  "publisher": "acme-feeds",
  "object": "grade",
  "action": "create",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "gradeId": "GRD-77120",
    "fixture": "EVT-88213",
    "segment": "segment:soccer:1st-half",
    "source": "acme-book",
    "marketType": "market:total",
    "line": "1.5",
    "basis": "goals",
    "basedOn": 105388,
    "dateGraded": "2026-09-19T14:48:02Z",
    "outcomes": [
      {
        "side": "over",
        "result": "win"
      },
      {
        "side": "under",
        "result": "lose"
      }
    ]
  }
}

grade_htft.example.json

examples/grade_htft.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 106002,
  "datePublished": "2026-09-19T15:50:00Z",
  "publisher": "acme-feeds",
  "object": "grade",
  "action": "create",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "gradeId": "GRD-77121",
    "fixture": "EVT-88213",
    "segment": "segment:soccer:full-time",
    "source": "acme-book",
    "marketType": "market:half-time-full-time",
    "basis": "goals",
    "basedOn": 105410,
    "dateGraded": "2026-09-19T15:50:00Z",
    "outcomes": [
      {
        "side": "draw",
        "halfTime": "home",
        "fullTime": "draw",
        "result": "win"
      }
    ]
  }
}

heartbeat.example.json

examples/heartbeat.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104901,
  "datePublished": "2026-09-19T14:37:25Z",
  "publisher": "acme-feeds",
  "object": "publisher",
  "action": "heartbeat",
  "sport": "unknown",
  "changes": {}
}

lineup.example.json

examples/lineup.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 105500,
  "datePublished": "2026-09-19T14:00:00Z",
  "publisher": "acme-feeds",
  "object": "lineup",
  "action": "update",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "fixture": "EVT-88213",
    "player": [
      "PL-1",
      "PL-2",
      "PL-3",
      "PL-4",
      "PL-5",
      "PL-6",
      "PL-7",
      "PL-8",
      "PL-9",
      "PL-10",
      "PL-11",
      "PL-12",
      "PL-13",
      "PL-14",
      "PL-15",
      "PL-16",
      "PL-17",
      "PL-18",
      "PL-19",
      "PL-20",
      "PL-21",
      "PL-22"
    ]
  }
}

market.example.json

examples/market.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104880,
  "dateModified": "2026-09-19T14:05:00Z",
  "fixture": "EVT-88213",
  "marketType": "market:spread",
  "segment": "segment:soccer:full-time",
  "line": "-0.5",
  "source": "bigbook",
  "provenance": "observed",
  "status": "open",
  "limit": {
    "amount": "500"
  },
  "outcomes": [
    {
      "side": "home",
      "odds": "1.91",
      "line": "-0.5",
      "active": true
    },
    {
      "side": "away",
      "odds": "1.95",
      "line": "0.5",
      "active": true
    }
  ]
}

market_update.example.json

examples/market_update.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 105330,
  "datePublished": "2026-09-19T14:41:03Z",
  "publisher": "acme-feeds",
  "object": "market",
  "action": "update",
  "sport": "soccer",
  "id": "EVT-88213",
  "msgType": "update",
  "reason": "goal",
  "references": [
    104871
  ],
  "changes": {
    "marketType": "market:spread",
    "segment": "segment:soccer:full-time",
    "line": "-0.5",
    "source": "bigbook",
    "status": "open"
  }
}

odds_change.example.json

examples/odds_change.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104871,
  "datePublished": "2026-09-19T14:37:12Z",
  "publisher": "acme-feeds",
  "object": "odds",
  "action": "change",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "markets": [
      {
        "marketType": "market:moneyline",
        "segment": "segment:soccer:full-time",
        "status": "open",
        "source": "pinnacle",
        "provenance": "licensed",
        "outcomes": [
          {
            "side": "home",
            "odds": "2.1"
          },
          {
            "side": "away",
            "odds": "3.25"
          }
        ]
      },
      {
        "marketType": "market:total",
        "segment": "segment:soccer:full-time",
        "line": "2.5",
        "basis": "corners",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "over",
            "odds": "1.95"
          }
        ]
      },
      {
        "marketType": "market:spread",
        "segment": "segment:soccer:full-time",
        "status": "suspended",
        "source": "bigbook",
        "provenance": "observed",
        "outcomes": [
          {
            "side": "home",
            "line": "-0.5",
            "active": false
          },
          {
            "side": "away",
            "line": "0.5",
            "active": false
          }
        ]
      },
      {
        "marketType": "market:correct-score",
        "segment": "segment:soccer:full-time",
        "basis": "corners",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "home",
            "homeTotal": 1,
            "awayTotal": 0,
            "odds": "8.5"
          },
          {
            "side": "other",
            "odds": "1.12"
          }
        ]
      },
      {
        "marketType": "market:half-time-full-time",
        "segment": "segment:soccer:full-time",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "draw",
            "halfTime": "home",
            "fullTime": "draw",
            "odds": "15.0"
          }
        ]
      },
      {
        "marketType": "market:player-points",
        "segment": "segment:soccer:full-time",
        "line": "1.5",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "over",
            "player": "PL-9",
            "odds": "1.85"
          },
          {
            "side": "under",
            "player": "PL-9",
            "odds": "1.95"
          }
        ]
      },
      {
        "marketType": "market:double-chance",
        "segment": "segment:soccer:full-time",
        "source": "pinnacle",
        "provenance": "licensed",
        "outcomes": [
          {
            "side": "home-or-draw",
            "odds": "1.25"
          }
        ]
      },
      {
        "marketType": "market:winning-margin",
        "segment": "segment:soccer:full-time",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "participant",
            "participant": "T-3",
            "line": "1",
            "odds": "4.50"
          },
          {
            "side": "participant",
            "participant": "T-11",
            "atLeast": 3,
            "odds": "6.00"
          },
          {
            "side": "other",
            "odds": "1.40"
          }
        ]
      },
      {
        "marketType": "market:player-anytime-scorer",
        "segment": "segment:soccer:full-time",
        "source": "acme-book",
        "provenance": "official",
        "outcomes": [
          {
            "side": "yes",
            "player": "PL-9",
            "odds": "3.40"
          },
          {
            "side": "yes",
            "player": "PL-11",
            "odds": "4.20"
          }
        ]
      }
    ]
  }
}

odds_change_conflated.example.json

examples/odds_change_conflated.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104872,
  "datePublished": "2026-09-19T14:37:13Z",
  "publisher": "acme-feeds",
  "object": "odds",
  "action": "change",
  "sport": "soccer",
  "id": "EVT-88213",
  "conflated": true,
  "changes": {
    "markets": [
      {
        "marketType": "market:moneyline",
        "segment": "segment:soccer:full-time",
        "status": "open",
        "source": "pinnacle",
        "provenance": "licensed",
        "outcomes": [
          {
            "side": "home",
            "odds": "2.05"
          }
        ]
      }
    ]
  }
}

participant.example.json

examples/participant.example.json

{
  "@context": "https://schema.org",
  "@type": "Person",
  "openbookVersion": "0.3.0-draft",
  "id": "P-77",
  "sequence": 104000,
  "dateModified": "2026-09-01T09:00:00Z",
  "participantType": "individual",
  "sport": "sport:tennis",
  "territory": "ES",
  "name": "Carlos Alcaraz",
  "shortName": "C. Alcaraz",
  "familyName": "Alcaraz",
  "givenName": "Carlos",
  "alternateName": [
    "Carlos Alcaraz Garfia"
  ],
  "sameAs": "https://www.wikidata.org/entity/Q63155283"
}

player.example.json

examples/player.example.json

{
  "openbookVersion": "0.3.0-draft",
  "id": "PL-27",
  "sequence": 104100,
  "dateModified": "2026-09-01T09:00:00Z",
  "participant": "P-27",
  "team": "T-NYY",
  "position": "SS",
  "number": 2,
  "throws": "right",
  "bats": "both"
}

publisher.example.json

examples/publisher.example.json

{
  "openbookVersion": "0.3.0-draft",
  "id": "acme-feeds",
  "sequence": 1,
  "dateModified": "2026-09-19T12:00:00Z",
  "name": "Acme Feeds",
  "inLanguage": "en",
  "baseCurrency": "GBP",
  "heartbeatMs": 5000,
  "ttl": 60,
  "url": "https://example.invalid/acme-feeds",
  "sources": [
    {
      "id": "acme-book",
      "name": "Acme Book",
      "sourceType": "sportsbook"
    },
    {
      "id": "pinnacle",
      "name": "Pinnacle",
      "sourceType": "sportsbook"
    },
    {
      "id": "bigbook",
      "name": "Big Book",
      "sourceType": "sportsbook"
    }
  ]
}

score.example.json

examples/score.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 105410,
  "datePublished": "2026-09-19T15:32:08Z",
  "publisher": "acme-feeds",
  "object": "score",
  "action": "update",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "eventStatus": "live",
    "currentSegment": "segment:soccer:2nd-half",
    "segments": [
      {
        "segment": "segment:soccer:1st-half",
        "status": "down",
        "downAt": "2026-09-19T14:47:30Z",
        "order": 1
      },
      {
        "segment": "segment:soccer:2nd-half",
        "status": "live",
        "order": 2
      }
    ],
    "clock": {
      "elapsed": 1320,
      "running": true,
      "display": "67:00"
    },
    "scores": [
      {
        "participant": "T-3",
        "unit": "goals",
        "total": 2,
        "bySegment": {
          "segment:soccer:1st-half": 1,
          "segment:soccer:2nd-half": 1
        }
      },
      {
        "participant": "T-11",
        "unit": "goals",
        "total": 1,
        "bySegment": {
          "segment:soccer:1st-half": 1,
          "segment:soccer:2nd-half": 0
        }
      },
      {
        "participant": "T-3",
        "unit": "corners",
        "total": 5,
        "bySegment": {
          "segment:soccer:1st-half": 3,
          "segment:soccer:2nd-half": 2
        }
      },
      {
        "participant": "T-11",
        "unit": "corners",
        "total": 3,
        "bySegment": {
          "segment:soccer:1st-half": 1,
          "segment:soccer:2nd-half": 2
        }
      }
    ]
  }
}

series.example.json

examples/series.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 105510,
  "datePublished": "2026-09-19T14:00:00Z",
  "publisher": "acme-feeds",
  "object": "series",
  "action": "update",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {
    "fixture": "EVT-88213",
    "stage": "ST-QF"
  }
}

snapshot_complete.example.json

examples/snapshot_complete.example.json

{
  "openbookVersion": "0.3.0-draft",
  "sequence": 104900,
  "datePublished": "2026-09-19T14:37:20Z",
  "publisher": "acme-feeds",
  "object": "fixture",
  "action": "snapshotComplete",
  "sport": "soccer",
  "id": "EVT-88213",
  "changes": {}
}

stage.example.json

examples/stage.example.json

{
  "openbookVersion": "0.3.0-draft",
  "id": "ST-QF",
  "sequence": 104010,
  "dateModified": "2026-09-01T09:00:00Z",
  "season": "S-UCL-2025",
  "name": "Quarter-final",
  "stageType": "round",
  "parent": "ST-KO",
  "order": 3
}

stall.example.json

examples/stall.example.json

{
  "openbookVersion": "0.3.0-draft",
  "id": "STL-4",
  "sequence": 104110,
  "dateModified": "2026-09-01T09:00:00Z",
  "fixture": "EVT-88213",
  "participant": "T-3",
  "order": 4
}

toss.example.json

examples/toss.example.json

{
  "openbookVersion": "0.3.0-draft",
  "id": "TOSS-1",
  "sequence": 104120,
  "dateModified": "2026-09-01T09:00:00Z",
  "fixture": "EVT-88213",
  "participant": "T-3"
}