Přejít na hlavní obsah
Loading market data…
SoccerverseSoccerverse

These developer docs are available in English only. View in English

Datapack and Assets

The Soccerverse datapack: JSON structure, customization and share flow, asset URL rules, cache behaviour and the default-pack fetch.

The datapack is a static JSON file that maps Soccerverse's numeric IDs to names, colours and image files, so your app can show player, club, league, cup and stadium labels. It is off-chain and read-only: no API key, and no game state in it.

This page shows how to fetch and read the pack, how to build image URLs, and how to make and share your own pack.

Purpose

Game and chain APIs expose IDs. Most hosted responses on https://play.soccerverse.com give IDs, not club, player, league, cup or stadium names. The one exception is /v1/portfolio/discover, which includes club and player names from the default pack. A game node you run yourself (POST http://<node>:8600/) gives IDs only, see Running your own node. The datapack is how you label them:

  • player ID -> first name, surname, and a photo if the player has one;
  • club ID -> club name, primary RGB colour, and club shirt image;
  • country and division -> league name and league icon;
  • country or cup code -> cup icon (the pack has no real cup names, so give cups your own names);
  • stadium ID -> stadium name (the default pack has no stadium images).

The default pack lives at:

https://downloads.soccerverse.com/svpack/packv2/default.json

Player names are real. Most club names are real town or club names, and some are changed (for example Manchester Blue). Leagues, cups and stadiums have generic names such as ENG Division 1, ENG Cup and Manchester Blue Stadium, so real names such as "Premier League", "FA Cup" or "Old Trafford" never appear in it.

The older URL https://downloads.soccerverse.com/svpack/default.json still answers, but it is an out-of-date copy. Use the packv2 URL for anything new.

Example: name a club

GET https://play.soccerverse.com/v1/club/50 gives you IDs, not club, stadium or league names: clubId 50, details.stadium_id 555, details.country_id ENG and details.division 0. The pack turns them into names:

From the APILook it up in the packYou get
clubId 50ClubData, the row with id "50"Manchester Blue, colour 132,187,255
details.stadium_id 555StadiumData, the row with id "555"Manchester Blue Stadium
details.country_id ENG, details.division 0LeagueData, the row with c "ENG" and d "1" (division 0 + 1)ENG Division 1, icon div1.png

The league lookup adds 1 to the division, see Division numbers. The club shirt and the league icon are plain files, and both of these URLs work:

https://downloads.soccerverse.com/svpack/packv2/clubs/50_home_medium.webp
https://downloads.soccerverse.com/svpack/packv2/leagues/div1.png

Going the other way, from a name to an ID: there is no general name-to-ID lookup for clubs or players in the hosted APIs (/v1/search only finds user names). Search the pack yourself, or use the resolve_player_name, resolve_club_name, resolve_league_name, resolve_competition_name and resolve_stadium_name tools of the Soccerverse MCP server. The MCP counts divisions from 1, see Division numbers.

Access notes

ItemValue
ProtocolPlain HTTPS GET for one static JSON file and static image files.
AuthNo API key or login. Send your own User-Agent header, see Fetching the default pack.
Custom packsPlayers can switch the game to your own pack in Settings or with a share link, see Custom packs and sharing.
WritesNone. You host a custom pack yourself, outside Soccerverse. Choosing one only changes that player's own browser settings.

What the server sends for the pack and for the image files:

  • Access-Control-Allow-Origin: *, so any website can use them from a browser.
  • Cache-Control: public, max-age=86400 (24 hours).
  • ETag and Last-Modified. Conditional requests work: send If-None-Match or If-Modified-Since and you get 304 Not Modified while the file is unchanged. Use them to spot a new pack.
  • For the pack, Content-Type: application/json and a size of about 9 MB (about 3 MB compressed: send Accept-Encoding: gzip).

Top-level JSON structure

A datapack is a JSON object with a PackData wrapper. Always keep that wrapper.

This is the shape, with real rows from the default pack. name and desc are the pack's title and description, and the only metadata it has. (The default pack's desc says the clubs are fictional; that text is out of date.)

{
  "PackData": {
    "name": "Fictional clubs and leagues",
    "desc": "All players are real, but clubs, leagues, and cups are fictional.",
    "PlayerData": {
      "baseImageUrl": "https://downloads.soccerverse.com/svpack/packv2/player_webp/",
      "imageFlags": true,
      "P": [{ "id": "1100", "f": "Erling", "s": "Braut Haaland", "i": 1 }]
    },
    "ClubData": {
      "baseImageUrl": "#",
      "C": [{ "id": "50", "n": "Manchester Blue", "rgb": "132,187,255" }]
    },
    "LeagueData": {
      "baseImageUrl": "https://downloads.soccerverse.com/svpack/packv2/leagues/",
      "L": [{ "id": "88", "n": "ENG Division 1", "c": "ENG", "d": "1", "i": "div1.png" }]
    },
    "CupData": {
      "baseImageUrl": "https://downloads.soccerverse.com/svpack/packv2/cups/",
      "C": [{ "id": "ENG", "n": "ENG Cup", "i": "national_cup.png" }]
    },
    "StadiumData": {
      "baseImageUrl": "#",
      "S": [{ "id": "555", "n": "Manchester Blue Stadium" }]
    }
  }
}

Field table

SectionRow keyMain fieldsNotes
PlayerDataPid, f, s, optional if (first name) and s (surname) can be null: about 2,000 rows have both null. i is 1 when the player has a photo and is missing otherwise, see Image URLs. The section also has "imageFlags": true.
ClubDataCid, n, rgbrgb is a decimal triplet string such as 132,187,255. baseImageUrl is # in the default pack, which means "use the shirts folder", see Image URLs.
LeagueDataLid, n, c, d, iLook a league up by c (country) plus d (division). d is 1-based, see Division numbers. id is only a row number in the pack, not the game's league_id, which changes every season (the top English division has league_id 1665 in season 4 but pack id "88"). i is an icon in the leagues folder.
CupDataCid, n, iid is a country code such as ENG or a region code (EUR, AFR, AME, ASI, WOR). n is only a placeholder such as ENG Cup, not a real cup name, so use i (an icon in the cups folder) and give cups your own names.
StadiumDataSid, nNo i: the default pack has no stadium images, and its baseImageUrl is #.

id and d are strings in the JSON, while the player i is a number.

Division numbers

Pack divisions (d) are 1-based: "1" is the top division. The Datacentre REST API, the /v1 API and GSP are 0-based (0 is the top division) in every division or level field and every division filter, apart from the two exceptions below. So add 1 before you look up the pack row: d = division + 1.

The two exceptions already count from 1, so use them as they are:

  • the {division} in the /v1/league/{country_id}/{division} URL, and the division it echoes at the top of its response. /v1/league/ENG/1 is the top division, and /v1/league/ENG/0 is rejected with 422. The other division fields in that response, such as league.division and table[].division, are 0-based, so add 1 to those.
  • the division in /datacentre/dumps/league_tables?country_ids=..., where the top flight is division: 1.

The Soccerverse MCP tools count from 1 too, like the pack. Use their division values as they are and do not add 1. Many of them also return a ready-made league_name.

Fetching the default pack

This fetch is read-only and needs no key or login. The script downloads the pack, prints the row count and image folder of each section, then looks up player 1100 and club 50.

python3 - <<'PY'
import json, urllib.request
url='https://downloads.soccerverse.com/svpack/packv2/default.json'
# Use your own app name here: Python's default User-Agent is blocked (see below).
req=urllib.request.Request(url, headers={'User-Agent':'my-app/1.0'})
with urllib.request.urlopen(req, timeout=30) as r:
    status=r.status
    content_type=r.headers.get('content-type')
    data=r.read()
print('status', status)
print('content_type', content_type)
print('bytes', len(data))
obj=json.loads(data)
pack=obj['PackData']
for section, arrkey in [('PlayerData','P'),('ClubData','C'),('LeagueData','L'),('CupData','C'),('StadiumData','S')]:
    rows=pack.get(section,{}).get(arrkey,[])
    print(section, len(rows), 'baseImageUrl=', pack.get(section,{}).get('baseImageUrl'))

def find(section, arrkey, key, val):
    for row in pack.get(section,{}).get(arrkey,[]):
        if str(row.get(key))==str(val): return row
print('player_1100', find('PlayerData','P','id',1100))
print('club_50', find('ClubData','C','id',50))
PY

Two things to know before you script it:

  • Send your own User-Agent. The host rejects Python's stock urllib agent (Python-urllib/3.x) with HTTP 403 and the body error code: 1010. curl, python-requests, Node and Go work as they are, and no key or bypass header is needed.
  • Go easy on it. No rate limit is published. Download the pack once and cache it. If you get HTTP 429, wait a second and try again.

How the game looks things up

The game's website (https://play.soccerverse.com) loads the pack like this, and you can copy the same rules in your own client:

  1. It takes the active pack URL: the player's custom pack if they chose one, otherwise the default.
  2. It downloads the JSON and lets the browser reuse a saved copy.
  3. It reads PackData and builds in-memory lookup tables for players, clubs, leagues, cups and stadiums.

The lookup rules:

You haveThe game shows
A player IDf, a space, then s. A null part is replaced: the first name by Player, the surname by the ID, so a row with both null shows as Player 47399. An ID that is not in the pack at all shows Player #<id> and a placeholder image. Always null-check f and s, because a plain f + " " + s fails on those rows.
A club IDThe club name, colour and shirt image. An ID that is not in the pack shows Club #<id> and a placeholder image.
A country and a 0-based divisionThe league name and icon. It adds 1 to the division first, see Division numbers. If the pack has no such league it shows <CC> Division <n>, for example ENG Division 1.
A cup codeThe pack's cup names are only placeholders (ENG Cup), so the game does not use them. It names each cup itself from the competition type and country (for example World Club Cup or English Cup), and takes only the icon i from the pack.
A stadium IDThe stadium name, or Stadium #<id>. There is no image unless a custom pack sets a real StadiumData.baseImageUrl.
Two club IDs for a matchThe home club in its home kit. The away club uses its away kit when the two club colours are too similar, otherwise its home kit.

In league and stadium names, write ~ for a space and a backtick for an apostrophe. This does not apply to player or club names.

Image URLs

The pack gives you a folder (baseImageUrl) for each kind of image, and its rows give the file names. The default pack keeps everything under https://downloads.soccerverse.com/svpack/packv2/. All of these URLs work today:

https://downloads.soccerverse.com/svpack/packv2/player_webp/1100.webp
https://downloads.soccerverse.com/svpack/packv2/clubs/50_home_medium.webp
https://downloads.soccerverse.com/svpack/packv2/leagues/div1.png
https://downloads.soccerverse.com/svpack/packv2/cups/national_cup.png
ImageHow to build the URL
Player photo${PlayerData.baseImageUrl}${playerId}.webp. The game uses .webp when the base URL contains webp, otherwise .png. Only some players have a photo, see below.
Club shirt${shirtBase}${clubId}_${kit}_${size}.webp, where kit is home or away and size is small, medium or large. All six files exist for a club. shirtBase is explained below.
League icon${LeagueData.baseImageUrl}${i}, where i is div1.png to div5.png, or divgeneric.png.
Cup icon${CupData.baseImageUrl}${i}, where i is national_cup.png for national cups, or EUR.png, AFR.png, AME.png, ASI.png or WOR.png for continental and world cups.
Stadium imageNone in the default pack. If a custom pack sets a real StadiumData.baseImageUrl, the game requests ${baseImageUrl}${stadiumId}.jpg.

Check i before you request a player photo. Only players with "i": 1 have one, which is about 4 in 10 players. For every other player the URL returns 404, so use your own placeholder instead of requesting it.

Club shirts and the # base. In the default pack ClubData.baseImageUrl is #. It does not mean "append the club ID to #". It means the shirts live in https://downloads.soccerverse.com/svpack/packv2/clubs/, which is your shirtBase. A custom pack can set a real base URL instead. The club image is then ${base}${clubId} plus .webp if the base contains webp, otherwise .png.

Custom packs and sharing

The game can use a pack other than the default. A custom pack replaces the default and nothing is merged, so start from a full copy of the default pack and keep every section. A missing section shows placeholders (Player #<id>, Club #<id>, <CC> Division <n>, Stadium #<id>). A custom pack also only changes what that person's browser shows: the parts of pages that Soccerverse's servers render still use the default pack.

To make and share one:

  1. Download the default pack (see Fetching the default pack) and change the values you want. Keep the PackData wrapper.
  2. Check that the file still parses as JSON and that the fields keep the shapes above.
  3. Host it at an HTTPS URL that allows browser requests from other websites (Access-Control-Allow-Origin: *).
  4. Give people a share link: https://play.soccerverse.com/?pack= followed by your pack's URL, URL-encoded. It works on any game page. For example:
https://play.soccerverse.com/?pack=https%3A%2F%2Fexample.com%2Fmy-pack.json

When someone opens the link, the game checks that the address is a valid URL and asks Add Custom Datapack?. The prompt shows the pack URL and warns that a malicious datapack could show incorrect or misleading player and club information, so people should only add packs from sources they trust. Yes, Add It makes it the active pack and reloads the page. No, Cancel removes ?pack= from the address and changes nothing.

Test your share link before you send it. If the download fails (for example, the host does not send Access-Control-Allow-Origin: *), the player sees "Failed to add datapack. Please try again." The broken URL is already saved as their active pack and ?pack= stays in the address, so pages cannot load names and images until the player chooses Default in Settings -> Datapack Source.

Players can also add a pack by hand: Settings -> Datapack Source -> + Add Custom URL. There is no file upload, because the game always loads a pack from a URL. It keeps up to 3 custom packs, newest first, and drops the oldest when a fourth is added. The + Add Custom URL button is hidden while 3 are saved, so remove one first. A share link still works then.

Cache and refresh behaviour

The game keeps the pack in the browser's own cache. After you change your pack, click Settings -> Refresh Datapack: it downloads the pack again and reloads the page. Clear Cache does not force a new download.

If you fetch the pack yourself, keep the ETag from your last download and send it back in If-None-Match. A 304 means nothing changed, so you can skip the download. The pack has no version field, only name and desc. For your own packs, put a version in the URL or compare a file hash.

Running your own node

A game node you run yourself never reads the datapack. Fetch the pack from downloads.soccerverse.com like any other client.

Naši partneři