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
{
"@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
{
"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
{
"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
{
"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
{
"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
{
"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
{
"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
{
"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
{
"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
{
"openbookVersion": "0.3.0-draft",
"id": "TOSS-1",
"sequence": 104120,
"dateModified": "2026-09-01T09:00:00Z",
"fixture": "EVT-88213",
"participant": "T-3"
}