The APIVex Live Sports API provides Sofascore-based public data for teams, fixtures, live scores, standings, and player statistics. This guide starts with a team name and retrieves its upcoming matches, giving you the IDs needed for a fixture dashboard.
The key step is selecting the correct entity. Searching for “Arsenal” returned the men’s team, the women’s team, players, and other results. A name match alone is not enough to choose a team reliably.
Search for a team and inspect its identity
APIVex supplies this third-party API at https://api.apivex.com/sofascore. Get your key from the dashboard and send it in x-apivex-key from your server.
curl --get 'https://api.apivex.com/sofascore/api/search' \
--header "x-apivex-key: $APIVEX_API_KEY" \
--data-urlencode 'query=Arsenal' \
--data-urlencode 'sport=football'Results live in data.results. Each result has a type and an entity; the entity’s id is the identifier to use on detail routes. Inspect the sport, country, and other identity fields before saving the selection.
For example, the returned Arsenal men’s football team had entity ID 42, sport slug football, gender M, and country name England. The women’s team appeared separately. Store the selected ID instead of repeatedly searching by name on every dashboard refresh.
Retrieve upcoming fixtures with Node.js
The team-events route embeds team_id in the path. Set when=next for upcoming matches or when=last for past matches. Its page parameter is zero-based.
Save this example as fixtures.mjs, set APIVEX_API_KEY, and run node fixtures.mjs using Node.js 20 or newer. The selection conditions deliberately identify the Arsenal men’s team rather than accepting the first search result.
const key = process.env.APIVEX_API_KEY;
if (!key) throw new Error('Set APIVEX_API_KEY first');
const base = 'https://api.apivex.com/sofascore';
// Demonstration pacing; use the request rate allowed by your plan.
const pause = () => new Promise(resolve => setTimeout(resolve, 2500));
async function get(path, params) {
const url = new URL(base + path);
url.search = new URLSearchParams(params).toString();
const response = await fetch(url, {
headers: {'x-apivex-key': key},
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const body = await response.json();
if (body.status !== true) throw new Error(body.message || 'API request failed');
return body.data;
}
const search = await get('/api/search', {query: 'Arsenal', sport: 'football'});
const match = search.results.find(r => r.type === 'team' && r.entity.name === 'Arsenal'
&& r.entity.gender === 'M' && r.entity.country?.name === 'England'
&& r.entity.sport?.slug === 'football');
if (!match) throw new Error('Requested team was not found');
await pause();
const fixtures = await get('/api/teams/' + match.entity.id + '/events', {when: 'next', page: 0});
console.table(fixtures.events.map(e => ({
eventId: e.id, home: e.homeTeam?.name, away: e.awayTeam?.name,
kickoff: e.startTimestamp == null ? null : new Date(e.startTimestamp * 1000).toISOString(),
status: e.status?.description
})));
console.log({hasNextPage: fixtures.hasNextPage});Each returned event has its own id. The fixture response also includes hasNextPage, which tells you whether to request another page. Keep the team and event IDs in separate fields: a team ID does not identify a match.
Turn a fixture into a match page
Use an event ID from the fixture response with /api/events/{event_id} for teams, score, status, kickoff, tournament, and venue. Related routes add match information when available:
| Match information | Route suffix after /api/events/{event_id} |
|---|---|
| Goals, cards, and other incidents | /incidents |
| Team lineups | /lineups |
| Match statistics | /statistics |
| Head-to-head information | /h2h |
For an overview of currently running games, /api/events/live accepts a sport parameter. An empty live-events list can simply mean no games are in play for that sport.
Coverage can differ between events. Make lineups and statistics optional sections rather than requirements for rendering the match page.
Missing scores are not a goalless draw
The upcoming-fixture response contained empty homeScore and awayScore objects for matches that had not started. Converting those missing scores to 0–0 would make the interface misleading.
Use the event status to decide whether to show a kickoff time, a current score, or a final score. The example converts startTimestamp from Unix seconds into a JavaScript date by multiplying by 1,000. Format that date in the viewer’s timezone when building the UI.
Store the retrieval time with your cache. Poll active fixtures according to your plan and product requirements, and refresh historical or scheduled fixtures separately. Do not present the last successful response as a new live update if the current request fails.
What about league tables and player statistics?
Tournament, season, team, player, and event identifiers represent different objects. A standings or season-statistics workflow should first resolve its competition and season using the relevant documentation, rather than reusing the IDs from this team tutorial.
Open the Live Sports API documentation to test a team search and inspect the event routes for your dashboard. The API overview summarizes the broader sports-data coverage.



