← Back to docs

Embeddable Widgets

Two lines of HTML. Real Web Components, not an iframe.

Six widgets ship in widgets/loader.js: three free, key-metered widgets and three predictive widgets built on our own models. Every widget is a Shadow-DOM custom element, so it renders crawlable HTML and can't clash with your page's CSS. See them live at kickoffapi.com/widgets or build an embed interactively at the Widget Builder.

The embed — two lines

<script src="https://cdn.kickoffapi.com/widgets/loader.js" data-key="YOUR_KEY"></script>

<kickoff-standings league="lg_8K3mZ0pQ" season="2025"></kickoff-standings>

The <script> tag goes once per page and carries your key in data-key. Add as many widget elements as you like after it. A widget can also carry its own data-key attribute to override the page-level one.

The key requirement — read this before you embed

The embed key sits in your page's HTML, in plain view of every visitor. It must be a widget-scoped key restricted to your site's own origin — never a full-privilege account key. A full key pasted into public HTML can be lifted by anyone who views source and used to spend your entire quota from wherever they like. An origin-restricted widget key is worthless off your own site: a request carrying it from any other origin is refused.

Mint a widget-scoped key from the panel's Widgets page (My API KeysWidgets). Minting requires at least one allowed origin — a widget key cannot be created without one, because the origin restriction is what makes a stolen key harmless. Full account keys continue to work everywhere they always have; only use one in a widget embed if you accept that anyone who views your page source can use it.

Widgets — free

ElementRequired attributesOptional attributes
<kickoff-standings> Free league, season label, theme, demo
<kickoff-livescores> Free league date (default: today), season, label, theme, demo
<kickoff-fixtures> Free team or league (at least one) count (default: 6), season, label, theme, demo

Note: the Widget Builder's field for kickoff-livescores is labelled "League id (optional)" — that is a builder UI copy bug. The loader itself refuses to render without league; this table matches the loader, which is the source of truth for what a widget actually needs.

Widgets — paid

From our own Dixon-Coles + xG models. Requires a plan with predictive access.

ElementRequired attributesOptional attributes
<kickoff-prediction> fixture label, theme, demo
<kickoff-seasonsim> league, season label, theme, demo
<kickoff-ratings> league, season label, theme, demo

A widget missing a required attribute renders "Couldn't load data (missing required attributes)" instead of calling the API.

On a locked plan

If your key can't reach predictive data, a paid widget does not render an error. It shows an upsell card — "Predictions are a paid feature" with a link to pricing — in place of the widget's normal content. This is what the API returns as 403 with code: "predictive_locked"; the loader recognises that specific response and swaps in the upsell card rather than failing.

Attributes common to every widget

AttributeMeaning
theme="light|dark"Defaults to light. Sets the widget's built-in color scheme.
label="…"Overrides the widget's header text — useful for localizing it.
demo="true"Renders sample data with no API call and no key required. Use it for previews, docs, or a page that hasn't been given a key yet. Leave the attribute off for live data — demo="false", demo="0" and demo="off" also mean live.
data-key="…"Overrides the page-level key from the loader's <script> tag for this one element.

Theming

Every widget is a real Web Component with Shadow DOM, so it can't be styled by accident from your page's own CSS — theming happens through theme="light|dark" and four CSS custom properties:

PropertyControlsDefault (dark)Default (light)
--ko-accentHighlight color — top-4 rank, live dot, primary bar segment#FF3D2E#FF3D2E
--ko-bgCard background#0f1729#ffffff
--ko-fontCard font familySystem font stack (-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)
--ko-radiusCard corner radius16px

Set them on the widget element itself:

kickoff-standings {
  --ko-accent: #7c3aed;
  --ko-font: "Inter", sans-serif;
  --ko-radius: 4px;
}

Quota

Widget calls meter against your account's normal quota — a widget request is not a separate, unlimited allowance. If your embeds are heavily trafficked, watch your usage the same way you would for direct API calls; per-key usage already breaks out what each key (including a widget key) has spent.