Skip to main content
Prerequisites: Complete the Quickstart guide to set up authentication and subscriptions. The snippets assume jwt is the guest JWT from /auth/guest/start and apiToken is the value returned by /api/token/activate.
API Endpoints: Use https://txline.txodds.com/api/ for mainnet or https://txline-dev.txodds.com/api/ for devnet
Program setup: Use generated types that match your selected network, and use Program Addresses, Program Reference (Mainnet), or Program Reference (Devnet) for program IDs and PDA derivation.

Overview

This guide demonstrates how to validate scores data against on-chain Merkle roots using cryptographic proofs. You’ll learn how to fetch validation data and perform single-stat, two-stat, and V2 multi-stat validations. The public /api/scores/stat-validation endpoint supports both validation shapes: Use the same network for the API request, IDL/types, program ID, and on-chain root PDA.
The repository now includes runnable devnet examples for both paths in examples/devnet/scripts. See Runnable Devnet Examples for setup and script mapping.

Validation Checklist

Before calling validateStat, confirm:
  • The proof came from the same API host as your activated subscription.
  • The program ID matches the network used for the proof.
  • daily_scores_roots is derived from the same timestamp you pass into validateStat.
  • The epoch day is encoded as u16 little-endian.
  • Every proof hash is decoded to exactly 32 bytes.
  • The fixture ID and sequence number refer to the score update you intend to validate.
  • For V2, each strategy index refers to the same position in the requested statKeys array.

Setup

Fetching Scores Data

Retrieve a snapshot of scores for a specific fixture:
Search for recent score updates:

Choosing the Score Sequence

The seq parameter is not a placeholder. Use the sequence value from a real score record observed through one of the scores data endpoints:
  • /api/scores/snapshot/{fixtureId}
  • /api/scores/updates/{epochDay}/{hourOfDay}/{interval}
  • /api/scores/historical/{fixtureId}
  • /api/scores/stream
Do not call /api/scores/stat-validation with seq=0. Score sequences start at 1 for a fixture and increment as new score records are produced. Depending on your client and response mapper, the payload field may appear as Seq or seq; use that observed value when requesting the validation proof.

Phase and Status Semantics

Pick the score record whose game phase matches the condition you want to prove. For example, “final score of the first half” should use the record for the completed first-half phase or halftime/rest state, not an arbitrary in-running first-half update. If you validate an in-running first-half record, the predicate means the condition was true at that observed moment. That is different from proving the final first-half result. Check the sport-specific phase tables, such as Soccer Feed, and use the score record’s statusId, StatusId, gameState, or equivalent phase field when deciding whether a record is suitable for settlement. For final match outcome settlement on the current devnet and mainnet releases, use a scores record with action=game_finalised. These finalisation records set statusId and period to 100, so the same final-outcome validation path covers regulation-time wins, extra-time wins, penalty wins, and abandoned matches.

Single-Stat Validation

Validate a single statistic against on-chain Merkle roots:

Two-Stat Validation

Validate a comparison between two stats (e.g., score difference). This example builds on the single-stat validation above:

V2 Multi-Stat Validation

Use statKeys when you need the current V2 payload and strategy model. The requested key order is important: the response arrays statsToProve and statProofs are mapped by position, and strategy fields such as index, indexA, indexB, and statIndex refer to those same 0..N positions. Every stat in payload.stats must be covered exactly once by the strategy, or the program returns IncompleteStatCoverage.
For complete runnable versions, use:

Common Validation Errors

See Troubleshooting for the full activation, streaming, and validation checklist.

Real-Time Scores Streaming

Subscribe to real-time scores updates:

Validation Use Cases

On-chain validation enables trustless verification of:
  • Trading Settlement - Prove score outcomes for bet settlement
  • Conditional Logic - Execute smart contract logic based on verified game stats
  • Dispute Resolution - Provide cryptographic proof of game data
  • Automated Markets - Settle prediction markets with on-chain verification
  • Score Differentials - Validate margins and score differences for complex betting scenarios