League API
Everything on your public TeamKick league pages — standings, fixtures, results, player stats, even live match events — is available as a free, read-only API. Use it to power your league's own website or widgets.
Authorizations
None. Every operation on this page is public — no API key, no token. CORS is open,
so you can call the endpoint straight from a browser. The endpoint answers
POST only; a JSON body with query and variables.
Finding your slug
Your league slug is in your public page URL: teamkick.app/leagues/<slug>.
POST https://gql.teamkick.app
Content-Type: application/json
{
"query": "…",
"variables": { "slug": "your-league-slug" }
}Quick start
Fetch your league table with one request — no signup required.
Responses are standard GraphQL: your data under data, problems under errors.
curl -s https://gql.teamkick.app \
-H 'Content-Type: application/json' \
-d '{
"query": "query($slug: String!) { getLeagueStandingsBySlug(slug: $slug) { team { teamname } played points } }",
"variables": { "slug": "your-league-slug" }
}'const res = await fetch('https://gql.teamkick.app', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables: { slug: 'your-league-slug' } })
});
const { data } = await res.json();League profile & teams
The league's identity: name, colors, emblem, member teams and sponsors.
Arguments
Returns
query ($slug: String!) {
getLeagueBySlug(slug: $slug) {
name slug emblem primaryColor secondaryColor
owner { teamname username emblem }
members {
role status isPlaying
team { id teamname username emblem }
}
sponsors { name logo url isPrimary }
}
}{
"data": {
"getLeagueBySlug": {
"name": "Sunday Night League",
"slug": "sunday-night-league",
"primaryColor": "#B62121",
"members": [
{ "role": "MEMBER", "status": "ACTIVE", "isPlaying": true,
"team": { "id": "cmfe…", "teamname": "Park FC" } }
]
}
}
}Standings
The league table, ordered. Wins are 3 points, draws 1.
Returns
query ($slug: String!) {
getLeagueStandingsBySlug(slug: $slug) {
team { id teamname emblem }
played won drawn lost
goalsFor goalsAgainst goalDifference points
}
}{
"data": {
"getLeagueStandingsBySlug": [
{ "team": { "teamname": "W-Team Clan" },
"played": 4, "won": 3, "drawn": 0, "lost": 1,
"goalDifference": 5, "points": 9 }
]
}
}Fixtures & results
All matches in the league — upcoming, live and completed.
Returns
query ($slug: String!) {
getLeagueMatchesBySlug(slug: $slug) {
id status starttime goals1 goals2
team1 { id teamname emblem }
team2 { id teamname emblem }
}
}Player statistics
Per-player league totals. Covers everyone who appeared in a completed league match (lineups or events).
Returns
query ($slug: String!) {
getLeaguePlayerStatsBySlug(slug: $slug) {
player { id name surname nickname avatar gk }
team { id teamname }
played goals assists onTarget offTarget
saves conceded tkPoints motm
}
}Match with timeline
One match with its full event timeline — everything our match page renders.
Arguments
Returns
query ($slug: String!, $matchId: ID!) {
getLeagueMatchBySlug(slug: $slug, matchId: $matchId) {
id status starttime pausedAt pausedSeconds
goals1 goals2 possession1 possession2
team1 { id teamname emblem }
team2 { id teamname emblem }
events {
id event minute
player { name surname nickname avatar }
team { id teamname }
}
}
}{
"data": {
"getLeagueMatchBySlug": {
"status": "in_progress",
"possession1": 380, "possession2": 265,
"events": [
{ "event": "GOAL", "minute": 33,
"player": { "nickname": "Tosa" },
"team": { "teamname": "W-Team Clan" } }
]
}
}
}Player match history
A player's recent league appearances — what powers the form graphs on our player pages.
Arguments
query ($slug: String!, $playerId: ID!) {
getLeaguePlayerMatchHistoryBySlug(
slug: $slug, playerId: $playerId, limit: 10
) {
matchId matchDate
}
}Team profile & roster
A team's public profile with its full player roster and all-time stats.
Arguments
query ($username: String!) {
teams(username: $username) {
elements {
teamname username emblem
players {
id name surname nickname gk avatar retired
played goals assists saves points
}
}
}
}Live match stream
While a league match is in progress you can stream its events in real time over socket.io — the same feed that powers the animated pitch on our match pages. Rooms are read-only; only league matches can be joined.
Server events
import { io } from 'socket.io-client';
const socket = io('https://mb.teamkick.app/live');
socket.on('connect', () =>
socket.emit('join_match', { matchId }));
socket.on('event_created', (e) => {
// render it
});{
"eventId": "cmrj…",
"matchId": "cmrg…",
"teamId": "cmfe…",
"teamName": "Park FC",
"playerId": "cmfe…",
"playerName": "Teofil",
"playerAvatar": "abc123.png",
"event": "GOAL",
"minute": 24,
"timestamp": "2026-07-13T14:26:19.691Z"
}Live polling
Can't hold a socket? The same live state is available as plain JSON. Poll every 10–15 seconds at most.
{
"status": "in_progress",
"starttime": "2026-07-13T12:29:14.953Z",
"pausedAt": null,
"pausedSeconds": 0,
"possession1": 380,
"possession2": 265,
"team1Id": "cmfe…",
"events": [
{ "id": "cmrg…", "event": "GOAL", "minute": 33,
"teamId": "cmra…", "playerName": "Tosa",
"playerAvatar": "" }
]
}Event types
The event field on match events is one of:
Images
Image fields (emblem, avatar, logo) are bare
filenames. Prefix them with the image CDN and the right folder:
# leagues, teams, players, sponsors https://images.teamkick.app/leagues/<emblem> https://images.teamkick.app/teams/<emblem> https://images.teamkick.app/players/<avatar> https://images.teamkick.app/sponsors/<logo>
Fair use
The API is free for league and team websites. In return:
Tracked with TeamKick — the ultimate pickup football tracker.