Skip to content
Developer docsREST · JSON and PNG · /v1

Overview

Build on UK and Irish racing data.

A versioned REST API under /v1 for UK and Ireland only, through the combined region=uk feed. Racecards, results, runner connections, racecourses and odds return JSON; silks return PNG images.

Download the customer API guide (PDF)

Authentication

Create keys in Dashboard, API keys. The secret is shown once; store it server-side in an environment variable such as RACINGAPI_KEY. Send it with every request using either header:

Authorization: Bearer $RACINGAPI_KEY
  • Never place keys in URLs, query strings or browser code.
  • Revoke a leaked key immediately from the dashboard and create a new one.
  • These public docs never ask for or store your key. Real calls belong in your server or the signed-in playground.

Subscriptions and API access

Signing up and creating a key do not grant feed access. Choose a monthly plan in Billing and complete Stripe Checkout with a card. Eligible new customers receive one seven-day trial, followed by automatic monthly renewal unless cancelled. API access begins only after server verification of your subscription. Suspended accounts, expired trials and overdue or cancelled subscriptions cannot access the feeds. Explicit administrator-approved access remains valid until its expiry. In Stripe test mode, use test cards only; no real payments are taken.

Rate limits

Limits apply per customer account across all of its keys. Monthly quotas reset on the UTC calendar month.

Enterprise is £99.99 per month with unlimited monthly requests and live support. Its 5-requests-per-second rate limit still applies. No VAT is added. Monthly quotas reset on the first day of each calendar month in UTC, not the subscription anniversary; changing plans does not reset usage. Account and usage JSON represent an unlimited monthly allowance with quota: -1; the monthly limit and remaining response headers contain unlimited.

  • Successful responses include X-RateLimit-Limit, X-RateLimit-Monthly-Limit and X-RateLimit-Monthly-Remaining.
  • There is no per-second remaining or reset header.
  • HTTP 429 includes Retry-After in seconds. Per-second and monthly exhaustion both use quota_exceeded; the code alone cannot distinguish them, so track X-RateLimit-Monthly-Remaining.
  • Authorised calls count against quota even when the resource or source is unavailable.

Filters and pagination

ParameterBehaviour
regionOnly uk is accepted (also the default). This combined feed includes UK and Ireland. Other regional codes return HTTP 422.
dateYYYY-MM-DD. Omit for the current feed. Historical requests use the same combined UK and Ireland feed; completeness is not guaranteed.
tomorrowtrue selects tomorrow's combined UK and Ireland feed. Cannot be combined with date.
pageList page, starting at 1.
limitItems per page, 1 to 100, default 50.

meta.total is the unpaginated count of matches. Keep requesting while page * limit < meta.total, respecting your per-second limit between pages.

Errors and retries

Errors return JSON with error, code and requestId. Quote the request ID when contacting support.

{
  "error": "Request quota exceeded",
  "code": "quota_exceeded",
  "requestId": "req_example_not_live"
}

Illustrative body. Exact codes per endpoint are in the API reference.

StatusMeaningRetry?
400Malformed requestNo, fix the request
401Missing, invalid or revoked keyNo
403No active approval or suspended accountNo, contact support
404Not found in the selected regional daily feedNo
405Only GET and HEAD are acceptedNo
422Unsupported region, invalid date or other invalid filtersNo
429Per-second limit or monthly quota exceededYes, after Retry-After
500 / 503Internal error, inactive endpoint or source unavailableOnly transient failures; use bounded backoff

Coverage

Region availability is read live from the platform. UK historical samples reach back to 2016, but a continuous, complete archive has not been verified.

Full detail on the Coverage page.

Field semantics

  • JSON responses contain meta and data. List endpoints return an array; ID endpoints return one object. Empty schedules return an empty array.
  • meta.retrievedAt is the gateway retrieval time. Source data may be cached for up to 30 seconds; this is not a freshness guarantee.
  • Times, weights and price strings preserve the source values. No timezone, weight-unit or odds-format conversion is applied.
  • Missing source strings stay empty strings; absent collections stay empty arrays.
  • IDs are resolved within the selected daily feed. Use the same date or tomorrow filter for subsequent race, horse, connection, odds and silk lookups.
  • Jockey and trainer endpoints return daily bookings in that feed (horseId, horseName, raceId, name, connections). They are not runner records or career statistics.
  • Horse form statistics are horse-specific, not comprehensive career histories.
  • Upstream failures return a classified 503 rather than invented empty data.

Silks

GET /v1/silks/{horseId}?raceId=RACE_ID&region=uk returns binary image/png, not JSON. Take both IDs from a racecard for the same region and date, and pass the same date or tomorrow=true. A missing source image or undeclared runner returns 404 with no substitute; an inactive image feed returns 503. Error statuses return the standard JSON error body.

Compatibility and changes

  • The major version is in the path. Treat the /v1 contract at /api/openapi.json as the source of truth.
  • Tolerate unknown fields and new enum values; do not rely on property order.
  • Pin client generation to a downloaded contract and diff it before regenerating.
  • Notable changes are announced on the changelog.

No implied guarantees

Example values across these docs are illustrative. Coverage depth, freshness and availability are described as observed, not as service-level commitments.