API evaluation / testing

How to pick an odds API: a developer's test checklist

Choose an odds API with a repeatable acceptance test. A feature list can tell you which calls exist; a trial should establish whether the returned prices, coverage and usage rules fit the application you plan to ship.

Define the sample before opening a trial

Write down the required sport keys, books, market families, periods and plan features. Include scheduled fixtures, in-play fixtures and completed fixtures from your target archive range. Pick a normal window and a busy window. Keep the request URLs, parameters, response headers, HTTP status, body and client receive time for every sample.

Set acceptance criteria before seeing the results. A screen, an execution model and a historical study can need different price ages, field completeness and history granularity. Mark each requirement as observed, documented or unresolved.

Test timestamp semantics and in-play staleness

Price freshness stamp semantics

How to test: Request a quiet market repeatedly and retain its quote and timestamp together. Then observe a price change. Ask whether the stamp means last price change, last confirmation by the book, API receipt or response creation. Check which object it applies to: book, market or outcome. Test null stamps, timezone handling and any alternate date format. Compare the observed behavior with the documented definition.

A timestamp can advance while the price stays the same if it records a confirmation. A response creation time cannot establish when the book confirmed that price. Your client needs the distinction.

In-play staleness

How to test: Observe the same market before kickoff, during play, through a suspension and after settlement. Record quote ages using a synchronized client clock, and note whether a suspended or unavailable price disappears or gains an explicit state. Check how your application handles a missing quote and whether it accidentally keeps displaying the previous value as actionable.

Choose your application's age threshold in advance. Measure how often the sampled quotes meet it, with unknown timestamps reported separately. Keep this result scoped to the fixtures and window you tested.

Test absent fields and fixture identity

Absent versus zero

How to test: Collect responses with missing sizes, unavailable books, incomplete market sides and outcomes that have no price. Distinguish an absent property from null, a numeric zero and an empty collection. In your parser, test field presence explicitly and preserve unknown values through storage and display.

A zero handicap is a valid line. An absent size is unknown capacity. Coercing both to a falsy default loses information. Also check whether a missing fair probability or fee field means unavailable data, an unsupported calculation or an explicitly free transaction.

Event id stability

How to test: Save fixture ids over the trial, including schedule changes, home and away presentation differences and name variations across books. Follow the same fixture into history. Check that rematches remain distinct, that a correction does not strand your saved references, and that a postponed fixture follows a documented identity policy.

Use ids in the test join. A join by normalized team name and date can hide the identity problem you are trying to detect.

Measure usable coverage and history

Book count versus listed fixtures per book

How to test: Build a matrix of required books against sampled fixtures and market keys. Count listed fixtures, priced market sides, period markets and props for each book separately. Record missing books explicitly. Repeat during your application's normal operating hours and during play if required.

A catalogue total says how many books the API can name. Your matrix says which books supplied the contracts you need in the tested window. Keep those measures separate.

History depth

How to test: Query completed fixtures near the earliest documented archive date, within your intended study period and near the present. Check each required book and market. Determine whether the response contains openers and closers, timed snapshots or every recorded change. Test an unavailable date and save the error or missing-data marker.

Record the plan used. Plan access and recorded depth are separate constraints: access to an archive does not establish that every book and market has a full series throughout it.

The close definition

How to test: For a completed fixture, compare the closing endpoint with its final pre-start observations. Ask whether the cutoff uses scheduled or actual start, whether in-play observations can enter it, and whether each book closes independently. Check the outcome, line, period and book together. A closing total at a different point is a different contract.

Keep the definition beside the data in a backtest. A result that depends on the close needs a consistent cutoff policy.

Test the usage contract and busy periods

The billing unit

How to test: Save usage counters around requests that vary the books, markets, fixtures and history parameters. Compare the counter deltas with the documented request, credit or data-point formula. Check pagination, empty responses and rejected requests. Use the measured unit cost to estimate the actual request pattern your application will send.

Rate limits

How to test: Within the trial's permitted limits, measure sustained requests and an allowed burst. Record any limit headers, 429 bodies and retry instructions. Confirm whether the limit is shared across keys, an account or a connection. Test your retry queue with backoff so that a limit response does not generate a larger burst.

Keep speed limits separate from monthly allowance exhaustion. They can share an HTTP status while requiring different recovery behavior.

5xx during peak traffic

How to test: Use normal permitted traffic across a busy slate. Record request duration, HTTP status, endpoint and response body, including timeouts. Report the count and proportion of 5xx responses and whether bounded retries recovered. Check whether the response provides an error code or retry guidance.

Keep rate-limit responses out of the server-error count and retain connection failures separately. A quiet trial cannot establish peak behavior; repeat the same request set in the busy window.

Keep a test record you can rerun

For each item, record the acceptance criterion, request, observation window, observed result and any unresolved question. Attach the sampled responses. Re-run the same checks after a plan change or a material schema change.

The comparison pages collect documented feature and billing information. Use the first detailed comparison, second detailed comparison and third detailed comparison as inputs to your trial. Validate the parts your application depends on with your own request set.

Questions

How should I choose an odds API?

Start with the fixtures, markets, books and settlement data your application needs. Run the same sample against each candidate and record observed behavior, documented limits and unresolved questions. Choose against your acceptance criteria.

Does a large book count establish useful coverage?

No. Count the fixtures and markets each required book actually lists during your sample window. A catalogue entry alone does not establish coverage for a particular fixture or period.

What should a trial leave behind?

A reproducible request set, response timestamps, field-presence checks, a usage calculation and an incident log. Keep the plan, test dates and any unanswered contract questions attached to the result.

Test the response your application needs.

Read the API contract, build a request set and keep the responses with your acceptance criteria. The documentation covers fields, history and usage rules.

More from the blog