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.

POSThttps://gql.teamkick.app

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>.

Base request
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.

200 Success

Responses are standard GraphQL: your data under data, problems under errors.

Request samples
cURLJavaScript
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

GQLgetLeagueBySlug(slug: String!)

The league's identity: name, colors, emblem, member teams and sponsors.

Arguments

slugStringREQUIRED
League slug from your public page URL.

Returns

name / slug / emblemString
League identity. See Images for emblem URLs.
primaryColor / secondaryColorString
The league's theme colors (hex), when set.
members[LeagueMember]
Teams in the league with role, status, isPlaying and the team object.
sponsors[LeagueSponsor]
name, logo, url, isPrimary.
Request sample
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 }
  }
}
Response sample
200
{
  "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

GQLgetLeagueStandingsBySlug(slug: String!)

The league table, ordered. Wins are 3 points, draws 1.

Returns

teamTeam
id, teamname, emblem.
played / won / drawn / lostInt
Completed league matches only.
goalsFor / goalsAgainst / goalDifferenceInt
pointsInt
Table points (3 / 1 / 0).
Request sample
query ($slug: String!) {
  getLeagueStandingsBySlug(slug: $slug) {
    team { id teamname emblem }
    played won drawn lost
    goalsFor goalsAgainst goalDifference points
  }
}
Response sample
200
{
  "data": {
    "getLeagueStandingsBySlug": [
      { "team": { "teamname": "W-Team Clan" },
        "played": 4, "won": 3, "drawn": 0, "lost": 1,
        "goalDifference": 5, "points": 9 }
    ]
  }
}

Fixtures & results

GQLgetLeagueMatchesBySlug(slug: String!)

All matches in the league — upcoming, live and completed.

Returns

statusString
pending, accepted, in_progress or completed.
starttimeDateTime
Kick-off (set when the match starts; scheduled time before that).
goals1 / goals2Int
Final score. Only written when the match completes — derive live scores from events (see live data).
team1 / team2Team
Home / away sides.
Request sample
query ($slug: String!) {
  getLeagueMatchesBySlug(slug: $slug) {
    id status starttime goals1 goals2
    team1 { id teamname emblem }
    team2 { id teamname emblem }
  }
}

Player statistics

GQLgetLeaguePlayerStatsBySlug(slug: String!)

Per-player league totals. Covers everyone who appeared in a completed league match (lineups or events).

Returns

playerPlayer
id, name, surname, nickname, avatar, gk (goalkeeper flag).
played / goals / assistsInt
onTarget / offTarget / saves / concededInt
tkPointsInt
TeamKick performance points across the league.
motmInt
Man-of-the-match awards (top points in a match).
Request sample
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

GQLgetLeagueMatchBySlug(slug: String!, matchId: ID!)

One match with its full event timeline — everything our match page renders.

Arguments

slugStringREQUIRED
matchIdIDREQUIRED
From getLeagueMatchesBySlug or the match page URL.

Returns

pausedAt / pausedSecondsDateTime / Int
Clock state. Live minute = (pausedAt ?? now) − starttime − pausedSeconds.
possession1 / possession2Int
Possession in seconds per side (when the organizer tracks it).
events[Event]
Newest first: event (see event types), minute, player, team.
Request sample
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 }
    }
  }
}
Response sample
200
{
  "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

GQLgetLeaguePlayerMatchHistoryBySlug(slug: String!, playerId: ID!, limit: Int)

A player's recent league appearances — what powers the form graphs on our player pages.

Arguments

playerIdIDREQUIRED
From getLeaguePlayerStatsBySlug.
limitInt
Most recent N matches (default 10).
Request sample
query ($slug: String!, $playerId: ID!) {
  getLeaguePlayerMatchHistoryBySlug(
    slug: $slug, playerId: $playerId, limit: 10
  ) {
    matchId matchDate
  }
}

Team profile & roster

GQLteams(username: String!)

A team's public profile with its full player roster and all-time stats.

Arguments

usernameStringREQUIRED
From members.team.username on the league profile.
Request sample
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

WShttps://mb.teamkick.app/live

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

joined_matchJoin acknowledgement — { matchId }.
event_createdA match event was recorded. Payload right →
event_deleted{ eventId, matchId, teamId, eventType } — remove it from your view.
possession_tick{ possession1, possession2, activeTeamId } — seconds per side; activeTeamId is who has the ball right now (nullable).
match_pause_toggled{ pausedAt, pausedSeconds } — half time and other clock stops.
match_started / match_endedKick-off and final whistle.
Request sample
JavaScript
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
});
event_created payload
{
  "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

GEThttps://teamkick.app/leagues/<slug>/matches/<matchId>/live.json

Can't hold a socket? The same live state is available as plain JSON. Poll every 10–15 seconds at most.

200 Success
404 Not a league match
Response sample
200
{
  "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:

GOAL / ASSISTA goal and the pass that set it up.
ON_TARGET / OFF_TARGETShots at goal / wide.
SAVED / CONCEDEDGoalkeeper events — credited to the keeper's team.
DRIBBLE / STEAL / TURNOVERBall progression and possession changes.
YELLOW_CARD / RED_CARD / TWO_MINDiscipline.

Images

Image fields (emblem, avatar, logo) are bare filenames. Prefix them with the image CDN and the right folder:

CDN paths
# 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:

cacheCache responses for at least a minute — league data outside live matches changes rarely.
scopeOnly the operations documented here are public; everything else needs an authenticated TeamKick session.
creditA visible "Powered by TeamKick" credit is appreciated.

Tracked with TeamKick — the ultimate pickup football tracker.