How It Works


Sports API Hub acts as a data bridge between external sports APIs and your WordPress frontend. This page explains the architecture, data flow, and design decisions that shape how the plugin works.

Sports API Hub dashboard with four admin menus

🚀 Hub Architecture

The plugin follows a hub-and-spoke model: one central connector pulls data from external APIs and distributes it through WordPress.

LayerWhat It DoesDetails
🌐 External Sports APISource of all sports dataAllSportsAPI2 (multi-sport), BasketAPI1 (basketball), BaseballAPI (baseball)
🔌 API AdapterConnects to API, normalizes dataAuthentication headers, rate limit handling, automatic retries, response mapping
🗃️ Custom DB TablesStores all sports data19 tables — entities, per-game stats, aggregate stats cache, logs. Queryable fields as real columns, display-only data as JSON
📄 WordPress PostsWordPress integration layer6 thin CPTs with only sport_id + api_id meta. Provides permalinks, search, sitemaps
🎨 Frontend PagesWhat visitors seeGame, Team, Player, Season pages + 13 shortcodes + live scores. Layout Builder or template-based

Data Flow: From API to Frontend

1. API Request

When you trigger an import or the background sync runs, the plugin sends HTTP requests to the external API. All requests are server-side — your visitors’ browsers never contact the API directly.

2. Data Normalization

API responses are JSON objects with nested structures. The adapter extracts relevant fields and maps them to the plugin’s table schema. For example, an API “uniqueTournament” becomes a row in the leagues table.

3. Database Upsert

Data is inserted or updated using “upsert” operations — if the record already exists (matched by sport ID + API ID), it is updated; if not, it is created. This makes re-imports safe: running the same import twice does not create duplicate data.

4. Post Creation

After upserting a database record, the plugin creates a corresponding WordPress post if one does not already exist. These posts are minimal — just a title and two meta fields. Posts provide permalinks, WordPress search integration, and XML sitemap entries. The actual data is always read from the custom tables.

5. Cache Invalidation

After data changes, the plugin invalidates relevant caches (object cache groups, page cache) so that frontend pages show fresh data.

6. Template Rendering

When a visitor loads a game, team, or player page, the template system resolves the entity from the URL, fetches data from custom tables, prepares display-ready data (team names, logos, display order), and renders the appropriate template or Layout Builder layout.

Read-Only Philosophy

The plugin is designed around the principle that the API is the source of truth:

  • Most data is fetched, not entered manually
  • Re-importing a season updates existing records with the latest API data
  • Manual edits to entity names are preserved through a translation system
  • The plugin does not write data back to the API — it is a one-way data consumer

You can enrich data through the plugin (custom logos, translated names, Layout Builder pages, AI-generated content), but the core statistics, scores, and rosters come from the API.

Six Entity Types

The plugin manages six types of data entities:

EntityWhat It RepresentsFrontend Page
GamesIndividual matches with scores, stats, timelineYes
TeamsTeam profiles with roster, colors, venueYes
PlayersPlayer profiles with position, stats, photoYes
SeasonsYear-specific competitions (e.g., NBA 2025/26)Yes
VenuesStadiums and arenasAdmin only
ManagersCoaches and managersAdmin only

Additionally, Categories (countries/regions) and Leagues are stored in their own tables but do not have frontend pages — they serve as organizational containers for seasons.

Multi-Sport in a Single Installation

All sports share the same entity tables with a sport_id column that separates them:

  • Separate permalink bases/basketball/, /baseball/, etc.
  • Separate statistics tables — each sport has its own optimized stat schema
  • Separate admin filters — lists can be filtered by sport
  • Separate Layout Builder layouts — different page designs per sport

See Sports for a detailed capability matrix.

⚙️ Admin Menu Structure

The plugin adds four root menus to your WordPress admin sidebar:

MenuContains
Sports API HubDashboard, Support, Account
Hub DataGames, Teams, Players, Venues, Managers, Seasons
API & ImportImport, API Config, Custom Logos
Settings & ToolsSettings, Translations, Shortcodes, Entity Links, Layout Builder, AI Writer

Dual Data Sources: API + Database

Statistics blocks on team and season pages can pull data from two sources:

  • API aggregates — pre-computed stats fetched directly from the sports API (season totals, leaderboards, advanced metrics like PER or WAR). Loaded on demand with stale-while-revalidate caching.
  • Database — stats calculated from per-game data stored during import. Always available once games are imported.

In the Layout Builder, stats blocks offer a Data Source setting with four modes:

ModeBehavior
APIAlways use API aggregates
DBAlways compute from imported game data
API firstTry API, fall back to DB if unavailable
DB firstUse DB if game data exists, otherwise try API

This hybrid approach means you always have stats to show — even when the API doesn’t provide aggregate endpoints for a particular sport or league. Basketball defaults to DB-first (rich per-game data), while sports with limited DB coverage can rely on API aggregates.

Caching

The plugin uses WordPress object cache (Redis/Memcached) for data caching. Cached data is grouped by entity type and automatically invalidated when imports, live updates, or syncs change the underlying data.

For sites behind a page cache, the plugin can flush page caches when data changes. See Caching for configuration details.

📚 Related