For the complete documentation index, see llms.txt. This page is also available as Markdown.

How to Manage Query Complexity in the Motorsport API

βœ… Included in All Plans

Query complexity management applies to all plans.

Plans differ only in leagues and API call limits.

Compare plans β†’

This guide explains how query complexity works in the Motorsport API, how to read the complexity score on each endpoint, and how to restructure requests that exceed the threshold.

When to use this

Read this guide when you:

  • Receive a 422 error with a complexity-related message

  • Want to understand why a particular include combination is rejected

  • Are planning a heavy live-race request and want to avoid hitting the threshold

  • Need to decide between one large request versus several smaller ones

What query complexity Is

Every include you add to a request has a complexity score. The API sums these scores and rejects the request if the total exceeds the endpoint's threshold, returning a 422 status.

This is separate from your plan's rate limit (hourly call count). A complexity error means a single request is too expensive to process - it has nothing to do with how many requests you've made.

The complexity score for each include is listed on the individual endpoint documentation page, alongside the "Include depth" and "Include options" sections.

Reading the complexity score

On each endpoint's documentation page, the include options section shows the allowed includes. The complexity score for each appears either inline or via the linked type reference. The GET Laps by Fixture ID endpoint, for example, lists fixture, participant, and details as its includes - each has a score that contributes to the total.

Before building a complex request, check:

  1. The endpoint's maximum include depth

  2. The complexity score of each include you intend to use

  3. Whether your combination stays below the threshold

Common motorsport include combinations

These are practical combinations tested against typical use cases, ordered from lightest to heaviest:

Live session - minimal (low complexity)

Just the fixture state. Very light. Suitable for a session status indicator that only needs to know if a race is live or finished.

Live session - race order (moderate complexity)

Adds driver positions, lap times, gaps, and tyre data via the results include. Good balance for a leaderboard display.

Live session - full timing (heavier)

Adds the latest lap for each driver on top of the race order. Use this when you need lap-by-lap timing in your live display. Poll at a sensible interval (15+ seconds).

Live session - maximum enrichment (heaviest)

Full live picture: positions, latest lap, latest pit stop, and current stint. This is the heaviest practical combination for a live race display. If this approaches or exceeds the threshold, split into two requests - one for results and a separate one for latestLaps;latestPitstops.

Standings with driver details (moderate)

Driver name, image, and the most recent race weekend context. Standard for a championship table display.

Fixture with lineup and driver details (moderate)

Driver names and headshots for each car in the session. One level of nesting.

Fixture with lineup and nationality (heavier)

Two nested includes on the same base entity. Adds nationality flag data per driver. Only do this once at session start and cache the result - driver nationalities do not change during a race.

Reducing Complexity

If a request returns a 422 complexity error, try these strategies in order:

Remove includes one at a time to find which one tips you over. Start with the deepest or heaviest include.

Use field selection to reduce payload without removing the include entirely. include=lineups.driver:display_name,image_path requests only two fields from the driver entity instead of the full profile:

Split into two requests for enrichment data you only need once. Fetch lineup driver details at session start and cache them. During the live race, only poll for results and latestLaps - you already have the driver names.

Cache stable data aggressively. Driver names, team logos, venue details, and country flags do not change during a race. Fetch them once and store locally. Your live poll only needs the data that actually changes: positions, lap times, pit stops.

Use the dedicated endpoints for granular data instead of piling includes on the livescores endpoint. Rather than include=laps on a livescores call, use GET Laps by Fixture ID separately after you have the fixture ID.

Practical caching strategy for a live race

This keeps live polls light while still having rich driver data available for display.

Common errors

Status
Message
Fix

422

Query too complex

Remove includes or split into multiple requests

400

Parameter not allowed

The include is not supported on this endpoint

429

Rate limit exceeded

Reduce polling frequency; you have hit the hourly call limit

See also

Reference

Related tutorials

FAQ

Is query complexity the same as rate limiting? No. Rate limiting counts how many requests you make per hour against your plan's limit. Query complexity is per-request - it measures how expensive a single request is to process. A complexity error means the request itself is too heavy, regardless of how many other calls you have made.

Does query complexity apply to all endpoints? Yes, but the threshold and scores vary by endpoint. A lighter endpoint like GET Driver by ID has a higher tolerance for includes than a heavier one like GET All Livescores.

If I split a heavy request into two lighter requests, does that hurt my rate limit? It counts as two requests instead of one against your hourly limit. For most plans this is negligible - the trade-off is nearly always worth it to avoid complexity errors during a live race.

Does caching the response locally help with query complexity? Caching does not change whether a single request exceeds the complexity threshold - it either does or it doesn't. But caching stable data means you can use lighter includes on your polling requests, which reduces the chance of hitting the threshold in the first place.

Last updated

Was this helpful?