Skip to content

v1.0.0 — the schema describes what the producers actually send

Choose a tag to compare

@dsaiko dsaiko released this 13 Sep 20:01
· 2 commits to main since this release

First release under vMAJOR.MINOR.PATCH, superseding the one-off v2025.01 tag
from January 2025.

The wire has not changed. The schema was wrong about it, and this release
corrects that: roughly 65 attributes the producers already send are now declared,
the two messages that had no schema file have one, and the three REST schemas
that did not compile do now.

Versioning from here

The major tracks the contract generation, not this repository's history:

  • MAJOR — v1.x.y describes wire v1, the one behind the /v1/ REST paths and
    the feed/v1 / rest/v1 SDK packages. A v2.0.0 would only ever accompany a
    /v2/, so a major bump is something clients are told about rather than
    something they discover.
  • MINOR — additive: a new optional attribute, a new message or endpoint.
    Nothing that was valid before stops being valid.
  • PATCH — a correction that does not change what the producer sends.

v2025.01 is left in place and not continued.

Action required if you regenerate bindings

Consumers that parse the feed are unaffected — no producer changed, and every new
attribute is use="optional". But if you run xjc or xsd.exe over these files,
this release is breaking and the output will differ:

  • targetNamespace="http://schemas.oddin.gg/v1" is gone from the 18 REST schemas
    that declared it. It was fiction: responses carry no xmlns, netcoresdk never
    mentioned the string, and javasdk's generated @XmlRootElements have no
    namespace. No real payload validated against those files.
  • The named types sportEventStatusBase and periodScoreBase no longer exist —
    sportEventStatus and periodScore are each one flat type now.
  • Three type corrections, each following what the producer sends: per-period
    sub-scores are xs:int (were xs:decimal), scores are xs:double (were
    xs:decimal — Go's float formatting can emit exponent notation, which
    xs:decimal rejects), and period_score/@number is required on the REST side.

match_summary.xsd has not compiled since before v2025.01, and schedule.xsd
and tournament_schedule.xsd stopped compiling in #15 — so for those three,
"regenerating" was not possible in the first place.

Newly declared attributes

All use="optional"; all already being sent.

Element Added
<scoreboard>, both wires cricket runs / wickets / overs / balls / coin toss, home_batting, away_batting, inning, home_games, away_games, elapsed_time, plus time and game_time on the REST copy
<period_score>, both wires the same cricket set, plus home_games / away_games for set-based classic sports
<sport_event_status>, feed winner_id
<sport_event> (inherited by <fixture>) type, scheduled_end, start_time_tbd
team, teamCompetitor, teamExtended country, country_code, virtual
<tv_channel> start_time

<scoreboard> now matches the producer's own model exactly, 35 for 35 — no gaps
and no attributes the producer cannot send.

New schema files

  • schema/feed/bet_stop.xsd — the producer emits bet_stop and all three SDKs
    model it; it had no schema file at all.
  • schema/rest/error.xsd — the <response> envelope every REST endpoint returns
    on a non-2xx status.

Other fixes

  • sport/@id was typed od:match:N; sports are od:sport:N.
  • fixture_change/@sport_event_id rejected the od:tournament:N URNs the
    endpoint returns.
  • player_profile was missing generated_at.
  • An empty <players/> or <sport_events/> wrapper was invalid, though the
    producer emits both.
  • A void reason could declare only one <param>.

Conformance gate

make check (JDK only) compiles every schema and validates 41 captured payloads
covering all 9 AMQP messages and all 18 REST endpoints. It fails on a schema that
does not compile, a payload that does not validate, a payload carrying an
attribute the schema does not declare
, or a message type with no payload. CI
runs it on every pull request and every tag.

<scoreboard> and <period_score> now live once, in schema/common/, referenced
by both wires — one place to add the next attribute. <sport_event_status> stays
two types on purpose; NOTES.md
explains why, and carries a verdict on every attribute that exists in an SDK but
on no wire.

Included since v2025.01

  • #15 — sport_format in extra_info, moved to sportEvent so match_summary
    gets it too
  • #16 — groups on a REST market description (player props)
  • #18 — everything above

Full changelog: v2025.01...v1.0.0