Ratings API
Live market-evidence ratings for your racecards, with supporting context and two ready-to-use click-through layouts.
Quick start
The API serves the latest saved Market Form rating for each available runner. Ratings use a 0–100 scale: 50 is neutral. Higher scores reflect stronger positive market evidence; lower scores reflect weaker or more negative evidence.
Base URL
https://dc-network.co.uk/wp-json/market-form-ratings/v1/
Test today’s ratings in your browser
Replace YOUR_KEY with your Ratings API key, then paste the full URL into your browser.
https://dc-network.co.uk/wp-json/market-form-ratings/v1/ratings?api_key=YOUR_KEY
The ratings response contains a runners array. Use its race_id and horse_id values to request a particular race or runner.
Data integration
Fetch JSON on your server and use the rating, timestamps and evidence fields in your own interface.
Market Form display
Request view=widget and use the supplied badge component with either the site panel or three-box panel.
Authentication
Every endpoint requires a valid Ratings API key. These keys are separate from Market Context API keys.
| Method | How to supply the key | Use |
|---|---|---|
| Request header | X-Market-Form-Ratings-Key: YOUR_KEY | Server integrations |
| Query parameter | ?api_key=YOUR_KEY | Direct browser testing |
If both are supplied, the header takes precedence. Keep production keys on your backend and deliver authorised data to your website or app through your own server.
curl -H 'X-Market-Form-Ratings-Key: YOUR_KEY' \
'https://dc-network.co.uk/wp-json/market-form-ratings/v1/ratings'
For the API owner: create or revoke a partner key
In WordPress, open Settings → Market Form Ratings API. Enter the partner name, create a key and copy it when displayed. The plaintext key is shown once. Use Revoke to remove that key’s access. Existing keys continue to work when this plugin is updated.
Endpoints
All four endpoints use GET and return JSON.
| Path | Returns | Required selection |
|---|---|---|
/ratings | Available saved ratings for a day, including live and completed races | None; defaults to today’s site date |
/race | All available saved runners in one race | race_id |
/horse | One runner, its rating and supporting context | horse_id or horse_name; add race details if ambiguous |
/results | Saved ratings for races whose scheduled off has passed, with results where available | None; use race_date for a previous day |
Request a race
https://dc-network.co.uk/wp-json/market-form-ratings/v1/race?race_id=YOUR_RACE_ID&api_key=YOUR_KEY
Request one horse
https://dc-network.co.uk/wp-json/market-form-ratings/v1/horse?horse_id=YOUR_HORSE_ID&race_id=YOUR_RACE_ID&api_key=YOUR_KEY
Request historical results
https://dc-network.co.uk/wp-json/market-form-ratings/v1/results?race_date=2026-10-03&api_key=YOUR_KEY
Parameters
| Parameter | Format | Behaviour |
|---|---|---|
race_date | YYYY-MM-DD | Defaults to the WordPress site’s current date. Historical data requires saved records for that date. |
race_id | String | Use the exact ID returned by this API. |
horse_id | String | Use the exact ID returned by this API. |
horse_name | URL-encoded string | Matches the saved name, ignoring case and repeated whitespace. Country suffixes and punctuation must match. |
course | URL-encoded string | Matches the saved course, ignoring case and repeated whitespace. |
race_time | HH:MM | 24-hour scheduled time in the site’s timezone. |
view | data or widget | Omit for the normal data response. Widget view adds the two panel HTML fields. |
odds_url | URL-encoded HTTPS URL | Optional Compare odds destination in the three-box panel; used with widget view. |
api_key | Ratings API key | Authentication for URL testing; a supplied authentication header takes precedence. |
Example name lookup: /horse?horse_name=Country%20Mile&course=Uttoxeter&race_time=12%3A51&race_date=2026-10-04&api_key=YOUR_KEY.
External racecard IDs are not automatically interchangeable with Market Form IDs. Maintain an ID mapping, or resolve an unambiguous runner using its saved name, date, course and time.
Understanding the response
The horse endpoint returns a single runner object. The other endpoints return a runners array. Both include the API version, race date, served time, count and rating definition.
Example horse response — selected fields
Selected fields from a saved response are shown below. The full response includes additional price, evidence and status fields.
{
"api_version": "1.1.0",
"race_date": "2026-10-04",
"freeze_boundary": "scheduled_off",
"suggested_poll_seconds": 60,
"count": 1,
"runner": {
"race_id": "rac_32299720427",
"horse_id": "hrs_38417561",
"horse_name": "Country Mile",
"course": "Uttoxeter",
"rating": 50,
"rating_band": "Neutral",
"assessment": "neutral",
"status": "frozen",
"scheduled_off": "2026-10-04T12:51:00+01:00",
"calculated_at": "2026-10-04T12:49:03+01:00",
"engine_version": "3.4.8",
"average_price_decimal": 1.28,
"market_direction": "quiet",
"nr_adjusted": false,
"nr_adjustment_pending": false,
"trainer_effect": null,
"is_top_rated": true,
"joint_top_rated": true,
"result": {
"status": "pending",
"finishing_position": "",
"is_win": null,
"is_top_two": null,
"sp_decimal": null
}
}
}Runner fields
| Field | Meaning |
|---|---|
race_date, race_id, horse_id | Stable selection identifiers within the saved source. |
horse_name, trainer_name, course | Display names supplied by the saved rating record. |
rating | Integer from 0 to 100; null for withdrawn, void or unavailable runners. A genuinely neutral scored runner can be 50. |
rating_band, assessment | Detailed rating band and broad positive / neutral / negative assessment. |
status | Live, stale, frozen, withdrawn, void or unavailable. |
scheduled_off, calculated_at | ISO 8601 timestamps including their timezone offset. Calculated time identifies the source snapshot. |
age_seconds, is_fresh | Age of the rating calculation. Freshness is true/false for live snapshots and null for frozen snapshots. |
engine_version | Version of the calculation engine that produced this snapshot; separate from API version. |
average_price_decimal, opening_average_price_decimal | Latest snapshot and opening average decimal market prices. These are market averages, not necessarily available bookmaker offers. |
price_source | average_fixed_odds_market. |
market_direction | Support, weakness or quiet. Null when the directional signal is withheld or the runner is inactive. Direction is distinct from the overall rating. |
nr_adjusted, nr_adjustment_pending | Whether non-runner adjustment applies and whether it remains incomplete. Pending adjustment can produce a neutral engine rating. |
headline, explanation | Saved engine evidence with HTML removed. Explanation text may contain technical terms such as pp. |
trainer_effect | Eligible trainer comparison object, or null when a comparable signal is not available. |
is_top_rated, joint_top_rated | Highest saved active rating in the race, and whether it is shared. Calculated before filtering to a single horse. |
result | Result object for completed, withdrawn or void runners; otherwise null. |
presentation | Added by view=widget for active runners. Contains version, site_html and three_box_html. |
Rating bands
| Rating | Band | Assessment |
|---|---|---|
| 80–100 | Strong Positive | Positive |
| 65–79 | Positive | Positive |
| 45–64 | Neutral | Neutral |
| 30–44 | Negative | Negative |
| 0–29 | Strong Negative | Negative |
Trainer effect
When eligible, the object contains baseline_win_rate, matching_win_rate, change_percentage_points, matching_runs, matching_stage and market_direction. Rates are percentages: a value of 21.9 means 21.9%.
The current adapter requires at least five matching support runs or 20 matching drift runs. Use the supplied checkpoint label: supported and drifting comparisons can use different checkpoints. When the value is null, leave the trainer comparison blank.
Results
The result object contains status, finishing_position, is_win, is_top_two and sp_decimal. Settlement comes from the existing results process; today’s frozen ratings may remain pending until that process settles them on a later day.
Live updates and freezing
Ratings are available throughout the day as soon as the engine saves them. The API reads those saved calculations; a request does not recalculate a rating.
| Status | How to display it |
|---|---|
live | Show the rating and calculation time. Continue polling for new saved output. |
stale | The live calculation is more than 15 minutes old. Identify it as an older saved rating. |
frozen | Retain the final available pre-off rating. Its timestamp remains the original calculation time. |
withdrawn / void | Rating is null. Exclude the runner from top-rated selections. |
unavailable | Display an unavailable state or dash; do not substitute a neutral 50. |
The supplied engine schedules background refreshes every five minutes, processing races in batches. Actual freshness depends on source data and successful background execution. The API suggests polling every 60 seconds; polling does not guarantee that a new calculation exists every minute.
Ratings freeze at the scheduled off, rather than an actual-off feed. The API enforces that boundary even if the freeze job is delayed. served_at is the response time; calculated_at is the rating’s age reference.
Day queries support up to 3,000 stored runner records. If the response exceeds that scope, request one race at a time. Responses use private, no-store caching.
The MF badge and two click-through layouts
The supplied component displays the circular MF + rating badge. Clicking it opens the selected layout using evidence from the same saved rating.
Site layout
layout="site"
The detailed panel extracted from the supplied site plugin: rating, evidence confidence, market explanation and evidence components.
Three-box layout
layout="three-box"
The supplied graphic design: score ring, Market / Trainer / Horse boxes and an optional Compare odds button.
The widget isolates its styles using Shadow DOM. Websites can embed it directly; native apps can use the same component inside a supported web view. The component follows the supplied Inter/system font stack.
1. Request panel content
https://dc-network.co.uk/wp-json/market-form-ratings/v1/horse?horse_id=YOUR_HORSE_ID&race_id=YOUR_RACE_ID&api_key=YOUR_KEY&view=widget
The response adds runner.presentation.site_html and runner.presentation.three_box_html. Request this on your backend and return the authorised response to your frontend.
2. Load the component and choose a layout
<script src="https://dc-network.co.uk/wp-content/plugins/market-form-ratings-api/assets/widget.js" defer></script>
<market-form-rating id="mf-horse" layout="three-box"></market-form-rating>
This asset URL assumes the standard plugin folder shown above. Adjust it if the installation folder differs.
3. Assign the returned runner
// response is the JSON supplied by your authorised backend.
await customElements.whenDefined('market-form-rating');
document.getElementById('mf-horse').runner = response.runner;
For a whole race, fetch the race response once and assign each runner to its matching badge. Repeat the request on your backend to update the badge and click-through evidence together.
Optional automatic polling through your backend
<market-form-rating
layout="site"
data-endpoint="/your-backend/market-form/horse"
data-poll-seconds="60">
</market-form-rating>
Your backend endpoint must return the Ratings API response with widget content and enforce your access rules. The component polls that endpoint every 60 seconds; the interval can be lengthened. If it returns a runners array, add data-horse-id and optionally data-race-id to identify the runner.
API keys stay on the backend. The embedded widget rejects frontend endpoint URLs containing api_key. Direct API URL testing remains available separately.
Compare odds destination
To include the button in the three-box panel, pass a URL-encoded odds_url pointing to the relevant destination on your platform. Without a destination, the button is omitted.
Preview both layouts in WordPress
This Ratings API demo is available to administrators.
Place the shortcode on a test page and view it while logged in as an administrator. Use layout="site" or layout="three-box" for one layout. Optional attributes include race_id, race_date and odds_url.
The component packages the supplied rendering separately from the original site plugin. Later changes to the original site’s panel require a corresponding component update. The graphic trainer comparison uses the API’s eligibility rules, so a small drift sample displayed by an older experiment may be blank here.
Errors and unavailable data
Unsuccessful requests return a WordPress-style JSON error with code, message and data.status.
| HTTP status | Meaning | Next step |
|---|---|---|
| 400 | Missing required selection, invalid parameter or query too large | Check the date and identifiers; narrow a large request to one race. |
| 401 | No API key supplied | Supply the Ratings API header or api_key query parameter. |
| 403 | Invalid or revoked Ratings API key | Use an active Ratings API key. |
| 404 | No matching saved rating, or an incorrect route | Check the error code. mfra_not_available means no matching data; rest_no_route means the path is incorrect or unregistered. |
| 409 | More than one runner matches the horse request | Add race_id, or course and race_time. |
| 503 | The saved ratings source is unavailable or could not be read | Retain a clearly marked older snapshot if appropriate and retry later. |
{
"code": "mfra_not_available",
"message": "No saved ratings match this request. No replacement rating has been generated.",
"data": { "status": 404 }
}
This Ratings API demo is available to administrators.