Streams API
Resolve all currently usable streams in one provider group. Source names are opaque, operator-defined values: always obtain them from a match response rather than inventing or hard-coding them.
Base URL: https://streamcenter.st
Stream structure
TypeScript
interface APIStream {
id: string;
streamNo: number;
language: string;
hd: boolean;
embedUrl: string;
webUrl?: string;
source: string;
}| Field | Type | Description |
|---|---|---|
id | string | Individual stored stream-row ID. |
streamNo | number | Stable stream number within its source. |
language | string | Human-readable English language name. |
hd | boolean | Whether the source is marked high definition. |
embedUrl | string | Current validated HTTPS embed URL. |
webUrl | string | Canonical StreamCenter Watch-page URL for the complete match. |
source | string | Provider/source requested in the route. |
Endpoint and flow
GET /api/stream/{source}/{matchId}
- Fetch a match selection.
- Choose one object from
match.sources. - Put its
sourceandidinto this route.
Shell
curl --fail-with-body --silent --show-error \
"https://streamcenter.st/api/stream/example-source/match-123"JavaScript
const matchesResponse = await fetch("https://streamcenter.st/api/matches/live");
if (!matchesResponse.ok) throw new Error("Could not load matches");
const matches = await matchesResponse.json();
if (!Array.isArray(matches) || matches.length === 0) {
throw new Error("No live match is available");
}
const match = matches[0];
const group = match.sources[0];
const streamsResponse = await fetch(
`https://streamcenter.st/api/stream/${encodeURIComponent(group.source)}/${encodeURIComponent(group.id)}`
);
if (!streamsResponse.ok) {
const requestId = streamsResponse.headers.get("X-Request-ID");
throw new Error(`Stream request failed (reference: ${requestId ?? "unknown"})`);
}
const streams = await streamsResponse.json();
if (!Array.isArray(streams)) throw new Error("Invalid stream response");
if (streams.length === 0) throw new Error("No stream survived validation");
for (const stream of streams) {
console.log(
stream.language,
stream.hd ? "HD" : "SD",
"Watch:",
stream.webUrl,
"Embed:",
stream.embedUrl
);
}Example response
JSON
[
{
"id": "stream-english",
"streamNo": 1,
"language": "English",
"hd": true,
"embedUrl": "https://player.example/english",
"webUrl": "https://streamcenter.st/watch/match-123",
"source": "example-source"
},
{
"id": "stream-spanish",
"streamNo": 2,
"language": "Spanish",
"hd": false,
"embedUrl": "https://player.example/spanish",
"webUrl": "https://streamcenter.st/watch/match-123",
"source": "example-source"
}
]Embed a selected stream
Navigate to webUrl for the complete StreamCenter Watch page. To embed only the selected third-party player, use a descriptive title, grant only the required capabilities, avoid leaking the parent-page referrer, and keep the API-returned embedUrl.
HTML
<iframe
src="https://player.example/english"
title="North City vs. South United — English stream"
allow="autoplay *; encrypted-media *; fullscreen *; picture-in-picture *"
referrerpolicy="no-referrer"
allowfullscreen
></iframe>Failures and partial groups
- An unavailable or unauthorized group returns
404. - If one member fails validation but another succeeds, the response contains only valid members.
- The limit is 60 requests per minute per client IP. A
429includesRetry-After. - Treat network errors as temporary and retain the request reference from
X-Request-IDwhen a response exists.
Need group IDs? Begin with the Matches API.