Skip to content
datasportsAPI

DeliveryWidgets

Documentation

/

Type to filter the docs by title or path.

Delivery · Widgets

Live sport on any page, without a backend

Widgets put live scores, a match centre or a league table into a web page with plain HTML. They run in your visitor's browser, talk to the API with a key that is safe to publish, and carry no logo of ours, so they look like part of your site.

  • Free: not included
  • Starter: not included
  • Pro: included
  • Business: included
dsa_pub_ keys3 types · 3 sizes
01

Two tags and a key

Create a widget key, tell it which sites may use it, paste the snippet. There is nothing to deploy on your side.

  1. 01

    Create a widget key

    In the dashboard's Widgets tab. It starts with dsa_pub_.

  2. 02

    List your sites

    The origins allowed to use the key: exact ones, or a wildcard for every subdomain.

  3. 03

    Paste the snippet

    One element per widget, one script tag per page. The dashboard previews every option with sample data first.

02

A key that is meant to be seen

A dsa_pub_ key sits in your page source on purpose. Three locks make that safe.

Only from your sites

The browser's Origin header must match an entry on the key's list, either exactly (https://www.example.com) or by subdomain wildcard (https://*.example.com). Requests without an Origin are refused too: widget keys are for browsers.

Only what widgets read

Live scores; a fixture with its events, lineups and statistics; league seasons and standings. Nothing else in the API answers to it.

Only while your plan allows

Widgets come with Pro and Business. If the account moves to a plan without them, the key stops working.

03

The embed

Put an element wherever a widget should appear, then load the script once, with your key on it.

your-page.html
<!-- 1. Place one element per widget at the spot it should render -->
<div data-dsa-widget="livescore" data-sport="football" data-league="17"></div>
<div data-dsa-widget="standings" data-league="17" data-theme="dark"></div>

<!-- 2. The script, once per page, with your widget key -->
<script src="https://datasportsapi.com/embed/v1.js" data-key="dsa_pub_…" async></script>

The script scans the page for elements with data-dsa-widget, fetches their data with the key from data-key and renders each one in place. Load it with async so it never holds up your page.

The script is served from https://datasportsapi.com and reads its data from api.datasportsapi.com. If your site sends a strict Content Security Policy, allow both.

04

Three widget types

The value of data-dsa-widget picks the type; the other attributes say what it should show.

data-dsa-widgetShowsAttributesDefault refresh
livescoreThe matches of one sport that are in play right now, grouped by competition.
  • data-sport requiredA sport slug, such as football or tennis.
  • data-league optionalOur league id, to show a single competition.
30 s
matchOne match: the score, its status and a timeline of goals, cards and substitutions.
  • data-fixture requiredOur fixture id.
30 s
standingsA season's main league table.
  • data-league requiredOur league id.
  • data-season optionalA season id. Without it, the newest season.
600 s

Roughly how each type looks

Sample data
data-dsa-widget="livescore" data-sport="football"
Football · live

England · Premier League

  • 63'ArsenalChelsea11

Spain · LaLiga

  • 37'Real MadridAthletic Club20

Türkiye · Süper Lig

  • 12'GalatasarayFenerbahçe00
data-dsa-widget="match" data-fixture="480112"

Premier League

Arsenal1–1Chelsea

63' · 2nd half

  • 22'GoalARS
  • 41'Yellow cardCHE
  • 55'GoalCHE
  • 60'SubstitutionARS
data-dsa-widget="standings" data-league="17" data-size="small"
Premier League
Sample standings, small size
#TeamPPts
1Arsenal1126
2Chelsea1123
3Liverpool1122
4Aston Villa1119
5Brighton1118
05

Options

Every type accepts the same four optional attributes.

AttributeValuesEffect
data-sizesmall | medium | largeHow much room the widget takes. medium is the default. See the ruler below.
data-themelight | dark | autoauto follows the visitor's own light or dark setting.
data-accent#hexYour brand colour for highlights, e.g. #e4002b.
data-refreshseconds, 15 or moreHow often the widget reloads its data. Defaults: 30 for livescore and match, 600 for standings.
data-size against a 1,200 px page
  • small≤ 340 px

    A sidebar. Compact rows; tables keep only P and Pts.

  • medium≤ 640 px

    A content column. The default.

  • largefull width

    The whole container, with larger type.

06

Theme and styling

Widgets render inside their own shadow root. Your stylesheet cannot break them, and cannot restyle them either.

data-theme="light"

Light surfaces and dark text, for light pages.

data-theme="dark"

Dark surfaces and light text, for dark pages.

data-theme="auto"

Follows the light or dark setting of the visitor's own device.

Add data-accent with a hex colour to bring in your brand. Between the theme, the accent and the three sizes, most sites can match their own look without writing any CSS; the dashboard's Widgets tab lets you try every combination on sample data before you embed.

07

What a widget costs

Each time a widget refreshes, that is one request against your quota, from every browser that has it open.

The arithmetic is simple and it adds up quickly: keep one livescore widget, refreshing every 30 seconds, on screen in 100 browsers for an hour and you have made 100 × 120 = 12,000 requests. Try your own numbers:

Your page

Count each widget on each open page: two widgets in 50 tabs is 100. Refresh values below 15 are treated as 15.

Requests it costs

Per day
12,000
Per 30 days
360,000
  • Pro36.0% of 1,000,000 / month
  • Business3.6% of 10,000,000 / month

Widget refreshes share the quota with every other call your account makes.

  • Slow down what moves slowly

    Standings change after matches, not every 30 seconds. The 600-second default is there for a reason.

  • Show live only where it is live

    A match widget on an article from last week does not need to refresh. Remove it, or raise data-refresh.

  • Mind the per-minute rate

    Many visitors arriving at once all refresh in the same minute, which counts against your rate as well as your quota.

Quotas and rates per plan: Plans, quota & rate limits.

08

Troubleshooting

The widget stays empty and the console shows a 403
403origin_not_allowed means the page's origin is not on the key's list. Origins are exact: https://example.com and https://www.example.com are two different entries, and so are http and https. Add the missing one, or use a wildcard for subdomains.
403 endpoint_not_in_plan
Either the account's plan does not include widgets (they need Pro or Business), or the key was used for something widgets never read. A publishable key cannot reach the rest of the API.
It worked, then stopped mid-month
The quota is spent: every widget refresh is a request. Look for 429quota_exceeded, then raise data-refresh or remove widgets that nobody needs to see live.
My CSS does not change it
By design. The widget renders inside its own shadow root, so page styles cannot leak in. Use data-theme and data-accent instead.