Passer au contenu principal
Loading market data…
SoccerverseSoccerverse

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

GSP JSON-RPC

The Soccerverse GSP JSON-RPC interface: read methods and game-state envelope semantics, with request and response examples.

Purpose

The GSP (game-state processor) API exposes Soccerverse game-state data via JSON-RPC 2.0. That includes seasons, leagues, cups, squads, fixtures, tactics, transfers/auctions, manager history, votes, and share orderbooks.

Most apps should start with the Datacentre REST API, which has filters, paging and joined rows. For a whole page of data in one call, such as /v1/club/50 or /v1/player/1100, use the /v1 bundles from the overview. Use /v1/gsp only when a JSON-RPC method has no REST equivalent. It returns the raw game state: numeric ids, raw integer money values, Unix timestamps and a blockchain state envelope. Ids map to names through the datapack.

This page uses the public endpoints on play.soccerverse.com. If you run your own node, see Running your own node.

Base URL

Use this endpoint. It needs no API key and serves the methods most apps need:

POST https://play.soccerverse.com/v1/gsp

Write it exactly like that, with no trailing slash: /v1/gsp/ does not work.

Older docs and integrations used services.soccerverse.com/gsp/, which no longer exists: use /v1/gsp instead. Do not build on https://play.soccerverse.com/gsp either: it is an older, uncached endpoint that is being retired, with no stability promise.

Protocol

  • Transport: HTTPS POST with a JSON body. GET returns 405.
  • Content type: application/json
  • JSON-RPC version: 2.0
  • No authentication and no API key.
  • Send a User-Agent header that names your app, for example my-app/1.0. Requests that use the default Python urllib agent are rejected with HTTP 403. Browsers set their own and are not affected.
  • params must be a JSON object, or left out. An array gives error -32602.
  • Browsers can call /v1/gsp directly: it accepts requests from any origin.
  • Batches: to send several calls at once, POST a JSON array of calls. /v1/gsp accepts up to 100 calls and 256 KiB per request. Replies come back in request order, but still match them by id.
  • Limit, per client IP address: 20 requests per second (bursts of 40), shared with all /v1/* and /datacentre/* calls. A batch counts as one request. Past the limit the server answers HTTP 429, which is not a JSON-RPC error. Slow down and retry.

Request shape:

{
  "jsonrpc": "2.0",
  "method": "get_seasons",
  "id": 1
}

Request with params:

{
  "jsonrpc": "2.0",
  "method": "get_squad",
  "params": { "club_id": 50 },
  "id": 2
}

Response shape:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "blockhash": "...",
    "chain": "polygon",
    "data": [ ... ],
    "gameid": "sv",
    "height": 94635948,
    "state": "up-to-date",
    "version": "44fb30c65872fb59f5ca51d2d1540cd80c47b816"
  }
}

Most useful payloads are in result.data. A few methods still return object payloads in result.data rather than lists. Always check the JSON-RPC error member before reading result.

State envelope fields

The get_* methods return a wrapper around the game data.

FieldMeaning
result.dataThe actual method payload. Usually a list; sometimes an object, or null when there is nothing to return.
result.heightBlock height of the state behind this response. Treat it as the consistency marker for cache/debugging, not a fixture/gameweek number. It can be behind the chain head: see How fresh is the data.
result.blockhashBlock hash for the indexed state behind the response.
result.chainChain name. Returns polygon.
result.gameidGame id. Returns sv.
result.stateup-to-date in normal operation. Anything else means the data may be behind. When a node has no state yet, height and blockhash can be missing.
result.versionCommit of the GSP build that answered. Not always present: /v1/gsp leaves it out of some answers, so do not rely on it.

Callers should display or degrade carefully when result.state is not up-to-date.

Pitfall: the Soccerverse MCP tools return only the payload. When you call GSP directly you get the full envelope and read result.data yourself.

How fresh is the data

/v1/gsp answers from a cache, so result.height is the height of the copy you received and can be behind the chain head. Live club, squad, market and orderbook reads are usually within a few seconds. Seasons, leagues, associations and game parameters can be up to about an hour old. Two calls in a row can also be answered by different servers, so height can differ a little between them.

  • Current head: call getnullstate. It returns the head height and the node's state, and is never cached.
  • Just sent a transaction? Add the header X-GSP-Min-Height: <height> to a /v1/gsp call and it will not answer from a cached copy older than that height. If the server has not reached that height yet, you get its current state, so check height. A value that is not a number gets HTTP 400.
  • Waiting for something to change: poll getnullstate for a new height. Server-side apps can use the events stream instead.

Example: list seasons

curl -sS https://play.soccerverse.com/v1/gsp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"get_seasons","id":1}'

Response, trimmed to the row for season 4. The real list has one row per season:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "blockhash": "4221174b0bd316751a332686d777d390db2763f06eb681d4c356a6110acc743b",
    "chain": "polygon",
    "data": [
      {
        "end": 1798848000,
        "finished": false,
        "name": 0,
        "number": 4,
        "season_id": 4,
        "start": 1783123200
      }
    ],
    "gameid": "sv",
    "height": 94634097,
    "state": "up-to-date"
  }
}

To find the current season, read seasonId from GET https://play.soccerverse.com/v1/bootstrap.

Python example: unwrapping result.data

import json
import urllib.request

url = "https://play.soccerverse.com/v1/gsp"
payload = {
    "jsonrpc": "2.0",
    "method": "get_squad",
    "params": {"club_id": 50},
    "id": 1,
}
request = urllib.request.Request(
    url,
    data=json.dumps(payload).encode("utf-8"),
    headers={"Content-Type": "application/json", "User-Agent": "my-app/1.0"},
    method="POST",
)

with urllib.request.urlopen(request, timeout=20) as response:
    body = json.loads(response.read().decode("utf-8"))

if "error" in body:
    raise RuntimeError(body["error"])

envelope = body["result"]
players = envelope["data"]
print(envelope["height"], envelope["state"], len(players))

get_squad for club_id=50 returns a list of players. First-player keys include player_id, club_id, country_id, position, rating, rating_gk, rating_tackling, rating_passing, rating_shooting, rating_stamina, rating_aggression, fitness, morale, wages, value, loaned_to_club, injured, banned, and card counters.

Method catalogue

Every method below only reads game state. The Params column is a working sample of the params object. It uses the sample ids from the overview (club 50, player 1100, user snailbrain) and season 4 where a value is needed. The one exception is get_game_world_history, which only has rows for a finished season, so its sample uses season 3.

The On /v1/gsp column says whether the hosted endpoint serves the method. Raw only methods are not served there. They belong to the raw GSP interface that a node you run exposes (see Running your own node).

On the hosted service, look for the same data in the Datacentre REST API instead. For example, GET https://play.soccerverse.com/datacentre/league_tables?league_id=1665 replaces get_league_table.

Methods

Tactics
JSON-RPC methodOn /v1/gspParamsReturns
get_club_tacticsYes{"club_id":50}Returns {commitment: <hash>} if the club has committed tactics (the contents stay hidden), otherwise an object with tactic_actions, team_sheet and validation. null if the club does not exist.
Helper/Metadata
JSON-RPC methodOn /v1/gspParamsReturns
getnullstateYes{}Returns the envelope without data (blockhash, chain, gameid, height, state, version): the chain head, and whether the node is up to date. Never cached.
get_extfileRaw only{"hash":"0000000000000000000000000000000000000000000000000000000000000000"}Returns external-file availability metadata for a content hash; object with keys: exists, hash.
get_paramsYes{"name":""}Returns game parameter values, optionally by name; object with parameter keys such as agent-min-bps, ban-length-yellowred, coins-to-club-multiplier-bps, dilution-max-bps, and more.
Clubs/Squads
JSON-RPC methodOn /v1/gspParamsReturns
get_club_idsRaw only{}Lists all club ids; returns a list of {"club_id": ...} objects.
get_squadYes{"club_id":50}Returns players owned/loaned by a club; returns a list.
get_club_scheduleYes{"club_id":50,"season_id":4}Returns club fixtures for a season; returns a list.
get_clubYes{"club_id":50}Returns club state by club id; object with keys: away_colour, balance, club_id, country_id, default_formation, fans_current, fans_start, form, home_colour, manager_locked, and more.
get_club_extendedYes{"club_id":50}Returns club state plus squad transfer/loan counters; object with keys: away_colour, balance, club_id, country_id, default_formation, fans_current, fans_start, form, home_colour, loans, and more.
get_stadiums_clubRaw only{"stadium_id":555}Returns club(s) for a stadium id; returns a list.
get_managers_clubYes{"manager_name":"snailbrain"}Returns club managed by a manager name; object with keys: away_colour, balance, club_id, country_id, default_formation, fans_current, fans_start, form, home_colour, manager_locked, and more.
get_all_clubsRaw only{}Returns all club rows; returns a list.
get_club_balance_sheetRaw only{"club_id":50,"season_id":4}Returns balance-sheet rows for a club and season; returns a list.
get_clubs_leagueRaw only{"club_id":50}Returns league ids associated with a club; returns a list of {"league_id": ...} objects.
get_clubs_next_fixtureRaw only{"club_id":50}Returns next fixture object for a club; object with keys: attendance, away_club, away_goals, away_manager, comp_type, country_id, date, fixture_id, home_club, home_goals, and more.
get_clubs_last_fixtureRaw only{"club_id":50}Returns last fixture object for a club; object with keys: attendance, away_club, away_goals, away_manager, away_pen_score, comp_type, country_id, date, fixture_id, home_club, and more.
get_all_stadium_data_idsRaw only{}Lists all stadium ids; returns a list of {"stadium_id": ...} objects.
get_clubs_transfer_auctionsYes{"club_id":50}Returns outgoing transfer auctions for a club; returns a list.
get_clubs_transfer_bidsYes{"club_id":50}Returns transfer auctions with bids from a club; returns a list.
get_clubs_player_loan_offersYes{"club_id":50}Returns loan offers for a club; returns a list.
get_comp_history_by_clubYes{"club_id":50}Returns competition-history rows for a club; returns a list.
get_manager_history_by_clubYes{"club_id":50}Returns manager-tenure history for a club; returns a list.
get_all_managersRaw only{}Returns all manager names/rows; returns a list.
Players
JSON-RPC methodOn /v1/gspParamsReturns
get_player_payoutsRaw only{"player_id":1100}Returns derived payout values for a player; returns a list.
get_playersYes{"player_ids":[1100]}Returns player records for up to 100 ids per call; returns a list. Ids with no player record are left out. More than 100 ids in one call is refused.
get_agents_playersYes{"agent_name":"snailbrain"}Returns players represented by an agent name; returns a list.
get_comp_player_dataYes{"player_id":1100}Returns league/cup stat rows for one player; object with keys: cups, leagues.
get_league_top_playersYes{"league_id":1665}Returns player leaderboard/stat rows for a league; returns a list.
get_player_loan_offerRaw only{"player_id":1100}Returns a loan offer for a player.

To search players by rating, age, country or position, or to list free agents, use the Datacentre REST API instead: GET https://play.soccerverse.com/datacentre/players/detailed, with filters such as rating_min, rating_max, age_min, age_max, country_id, positions and free_agents=true.

Users/Shares/Market
JSON-RPC methodOn /v1/gspParamsReturns
get_user_wagesRaw only{"id":1100,"season_id":4,"wage_type":"agent"}Returns derived agent or manager wage estimate for a player/club; returns a list.
get_best_managersRaw only{}Returns every manager-tenure history row (all managers, all clubs), highest points first; returns a list. About 7 MB. For a ranked list of managers use /datacentre/best_managers; for one manager, get_manager_history_by_manager.
get_manager_history_by_managerYes{"name":"snailbrain"}Returns manager-tenure history for a manager; returns a list.
get_user_accountYes{"name":"snailbrain"}Returns one user account row; object with keys: balance, last_active, name.
get_users_last_activeRaw only{"names":["snailbrain"]}Returns last-active info for user names; returns a list.
get_vaultsYes{"controller":"snailbrain","ids":[1,2,3]}Returns vault rows by controller and ids; returns a list.
get_vaults_by_founderRaw only{"founder":"snailbrain"}Returns vault rows by founder; returns a list.
get_user_share_balancesYes{"name":"snailbrain"}Returns share balances for a user; returns a list.
get_share_ownersRaw only{"share":{"club":50}}Returns owners for a share; returns a list.
get_user_share_ordersYes{"name":"snailbrain"}Returns active share orders for a user; returns a list.
get_share_orderbookYes{"share":{"club":50}}Returns current orderbook for a share; object with keys: ask, bid, share.
get_share_overviewYes{"type":"club","id":50,"since":0}Returns share overview data by type/id/since; returns a list.
get_share_dilutionsYes{"user":"snailbrain","type":"","id":0}Returns share-dilution events; returns a list. All three params are required: pass an empty string for user or type, or 0 for id, to skip that filter.
Competitions/Fixtures
JSON-RPC methodOn /v1/gspParamsReturns
get_all_turnsYes{"comp_id":1665}Returns turns/gameweeks for a competition id; returns a list.
get_fixtureYes{"fixture_id":363277}Returns fixture details/stats for a fixture id; returns a list.
get_league_tableRaw only{"league_id":1665}Returns table rows for a league id; returns a list.
get_turn_fixturesYes{"turn_id":45362}Returns fixtures in a turn; returns a list.
get_associationsYes{"association_type":"national"}Returns association config rows by type; returns a list.
get_associationRaw only{"country_id":"ENG"}Returns association config rows by country id; returns a list.
get_association_qualifiersRaw only{"association_id":255}Returns qualifier country/count rows for an association; returns a list.
get_leaguesYes{"season_id":4}Returns leagues for a season; returns a list.
get_leagues_by_countryRaw only{"country_id":"ENG","season_id":4}Returns leagues for country and season; returns a list.
get_leagueYes{"league_id":1665}Returns league details; returns a list.
get_cupsYes{"season_id":4}Returns cups for a season; returns a list.
get_cups_by_countryRaw only{"country_id":"ENG","season_id":4}Returns cups for country and season; returns a list.
get_cupRaw only{"cup_id":1675}Returns cup details; returns a list.
get_seasonsYes{}Returns available seasons; returns a list.
get_seasonRaw only{"season_id":4}Returns one season row; returns a list.
get_comp_history_by_managerRaw only{"name":"snailbrain"}Returns competition-history rows for a manager; returns a list.
Other
JSON-RPC methodOn /v1/gspParamsReturns
get_match_subsRaw only{"fixture_id":363277}Returns substitutions for a fixture; returns a list.
get_game_world_historyRaw only{"season_id":3}Returns game-world history rows for a finished season; returns a list.
Votes/Proposals
JSON-RPC methodOn /v1/gspParamsReturns
get_all_votesYes{}Returns all proposal/vote rows; returns a list.
get_votes_for_shareholderRaw only{"name":"snailbrain"}Returns votes relevant to a shareholder name; returns a list.
get_share_proposalsYes{"share":{"club":50}}Returns proposals for a share; returns a list.
Transfers/Loans
JSON-RPC methodOn /v1/gspParamsReturns
get_top_transfer_auctionsYes{"num":3}Returns top active transfer auctions; returns a list.
get_transfer_auction_detailsYes{"player_id":1100}Returns an active auction detail and bids for a player; object with keys: agent_name, bids, club_id, concerns, contract, country_id, dob, free_with_no_bids, high_bid, injured, and more. null if the player has no active auction. To see a real one, take a player_id from get_top_transfer_auctions.

Worked examples

Send these to https://play.soccerverse.com/v1/gsp.

get_comp_player_data example

Returns cup/league stat arrays for player 1100.

{
  "jsonrpc": "2.0",
  "method": "get_comp_player_data",
  "id": 1,
  "params": {
    "player_id": 1100
  }
}

Sample result.data shape, with each list trimmed to one row:

{
  "cups": [
    {
      "Active": 1,
      "apearances": 1,
      "assists": 1,
      "ave_rating": 7.0,
      "clean_sheets": 0,
      "club_id": 50,
      "comp_id": 1675,
      "comp_type": 1,
      "country_id": "ENG",
      "goals": 0,
      "key_passes": 0,
      "key_tackles": 0,
      "minutes_played": 59,
      "mom": 0,
      "player_id": 1100,
      "red_cards": 0,
      "saves": 0,
      "season_id": 4,
      "shots": 0,
      "sub_apearances": 0,
      "yellow_cards": 0,
      "yellowred_cards": 0
    }
  ],
  "leagues": [
    {
      "Active": 1,
      "apearances": 17,
      "assists": 0,
      "ave_rating": 6.764705882352941,
      "clean_sheets": 0,
      "club_id": 50,
      "comp_id": 1665,
      "comp_type": 0,
      "country_id": "ENG",
      "goals": 6,
      "key_passes": 0,
      "key_tackles": 0,
      "minutes_played": 1088,
      "mom": 0,
      "player_id": 1100,
      "red_cards": 0,
      "saves": 0,
      "season_id": 4,
      "shots": 0,
      "sub_apearances": 1,
      "yellow_cards": 2,
      "yellowred_cards": 0
    }
  ]
}

get_share_orderbook example

Returns an orderbook object with singular bid and ask arrays, plus the share it belongs to.

{
  "jsonrpc": "2.0",
  "method": "get_share_orderbook",
  "id": 2,
  "params": {
    "share": {
      "club": 50
    }
  }
}

Sample result.data shape, with the lists trimmed:

{
  "ask": [
    {
      "mint": false,
      "name": "Theramoe",
      "num": 82,
      "price": 390000
    }
  ],
  "bid": [
    {
      "mint": false,
      "name": "Johnelo",
      "num": 958,
      "price": 157600
    },
    {
      "mint": false,
      "name": "OrtechoOscar",
      "num": 1,
      "price": 33400
    },
    {
      "mint": false,
      "name": "Cthulhu",
      "num": 1000,
      "price": 11000
    }
  ],
  "share": {
    "club": 50
  }
}

Error handling

A JSON-RPC error comes back with HTTP 200 and an error member instead of result. A method /v1/gsp does not serve looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "method not allowed: get_league_table"
  }
}

Other failures you can meet on /v1/gsp:

HTTPWhat you getWhat it means
200Error -32601 with a message ending in unsafe methods not enabled: ...The public service switches this call off, for example get_players with over 100 ids.
200Error -32602, params must be an objectYou sent params as an array.
200Error -32602, INVALID_PARAMS: Invalid method parameters ...A required param is missing, misspelled or has the wrong type.
400{"detail":"invalid JSON"} or {"detail":"empty batch"}The body is not valid JSON, or it is an empty array.
400{"detail":"invalid X-GSP-Min-Height"}The X-GSP-Min-Height header is not a number.
403error code: 1010Your User-Agent is blocked. Send one that names your app.
405{"detail":"Method Not Allowed"}You used GET. Use POST.
413{"detail":"batch too large (max 100)"} or {"detail":"request body too large"}Send fewer calls per request, or a smaller body.
429Not JSON-RPCYou are over the rate limit. See Protocol.

Callers should:

  1. Check the HTTP status. If it is not 200, the body may not be JSON-RPC.
  2. Parse JSON.
  3. If top-level error exists, handle it and do not read result.
  4. If result.state is not up-to-date, warn or avoid making strong current-state claims.
  5. Read result.data for the payload.

Notes

  • GSP returns ids, not names. Expect ids such as club_id, player_id, league_id, stadium_id; look names up in the datapack.
  • Unix timestamps in payloads are seconds, not milliseconds.
  • date appears on fixtures and turns; do not assume a generic timestamp field.
  • Empty arrays are valid for no active bids, auctions, orders, manager history, share dilutions, or qualifiers. null is valid when a single record does not exist, for example an unknown club id (get_club, get_club_tactics), a user who manages no club (get_managers_club), a player with no auction (get_transfer_auction_details) or no loan offer (get_player_loan_offer).
  • Unknown ids are not errors. get_user_account for an unknown user name returns an object with zero balances and last_active: null, not null. Missing or wrongly named params are errors (-32602). The HTTP status stays 200 either way.
  • A few Raw only methods return a lot of data: get_best_managers (about 7 MB), get_all_clubs (about 2 MB), get_game_world_history (about 0.5 MB) and get_all_managers (about 170 KB). Avoid calling them repeatedly. For clubs, the Datacentre REST API returns paged rows: GET https://play.soccerverse.com/datacentre/clubs/detailed.
  • Stat rows keep the game's own spellings, such as apearances and sub_apearances. Use them exactly as returned.
  • Money values (balances, wages, values, prices) are whole numbers in units of 1/10,000 SVC: divide by 10000 to get SVC. In the orderbook example, a price of 390000 is 39 SVC. See Money and value scaling in the overview. Only some MCP tools return formatted SVC strings.
  • Share params are objects such as {"club": 50} or {"player": 1100}. MCP schemas may expose friendlier strings like club_50, but GSP expects the object form.

Running your own node

Everything above is the public service on play.soccerverse.com, apart from the Raw only methods. If you run your own node, you talk to the game server (the GSP) directly, with nothing in front of it.

  • JSON-RPC: the GSP Docker image serves it on port 8600 (POST http://localhost:8600/, plain HTTP, JSON-RPC 2.0), by default only from inside its own container. To reach it from outside, start the node with --nogame_rpc_listen_locally. Every method in the catalogue exists there, and the curl and Python examples above work if you swap in your node's URL. The get_* methods take named params (an object): a positional array gives INVALID_PARAMS. A method the node does not have gives error -32601 (METHOD_NOT_FOUND).
  • Status: the image also serves GET http://localhost:8700/state and GET http://localhost:8700/healthz. /state returns the head height and the node's state, like getnullstate. /healthz returns the text ok, or HTTP 500 while the node is not up to date.
  • New blocks: waitforchange (not on /v1/gsp) is a long poll: pass the last block hash you know as a positional array, ["<blockhash>"], and it returns the newest block hash. See Realtime events for the loop.
  • Nothing in front: there is no /v1, /datacentre, /events or /graph, and no allowlist, cache, rate limit or batch limit. Those belong to the public service. A node runs 50 worker threads by default, so throttle your own callers.
  • Switched off by default: get_freebench, get_all_users, get_player_ids, get_players with more than 100 ids, compressjobpost (a helper that compresses the text of a club job posting) and the admin calls stop, checkdb, hashcurrentstate and settargetblock only work if you start the node with --unsafe_rpc. Use that flag only on a private node that nobody else can reach. The public service keeps them off. From GSP v1.4.2 a node keeps them off by default too; older versions had them on.
  • Browsers: the RPC port answers calls from any website (Access-Control-Allow-Origin: *), so expose it only to networks you trust.

Nos Partenaires