Datacentre REST API
The Soccerverse Datacentre REST API: read endpoints for clubs, players, users, market, fixtures, transfers, news and leaderboards, with request examples.
Base URL and access
- Public base URL:
https://services.soccerverse.com/api - Live OpenAPI source:
GET /openapi.json - All documented routes are
GET. - Some protected/test environments require a Cloudflare bypass header. Use the placeholder only; never commit or print the value:
-H "x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET"
Common response and money notes
- Paged endpoints generally return
{ page, per_page, total, total_pages, items }. - Some data endpoints return raw arrays; dump endpoints often return
{ meta, data }or a file download. - Money/SVC values from REST/MySQL are raw scaled integers unless the endpoint explicitly says otherwise. Divide raw money fields by
10000to present SVC. Example:1234567raw =123.4567 SVC. Do not divide fields that are already documented as USD, USDC, percentages, counts, ratings, ages, timestamps, or prices from a dump that explicitly says it is converted. - Array filters are accepted as query parameters by FastAPI; examples here use one value, e.g.
club_id=50,player_id=1100,names=snailbrain.
Quick start
# Health check
curl -sS \
-H "x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET" \
"https://services.soccerverse.com/api/healthz" | jq .
# Club lookup using the sample club_id
curl -sS \
-H "x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET" \
"https://services.soccerverse.com/api/clubs?club_id=50&per_page=5" | jq .items[0]
# Player lookup using the sample player_id
curl -sS \
-H "x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET" \
"https://services.soccerverse.com/api/players?player_id=1100&per_page=5" | jq .items[0]
# User lookup using the sample username
curl -sS \
-H "x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET" \
"https://services.soccerverse.com/api/users/detailed?names=snailbrain&per_page=5" | jq .items[0]
System
Operational health of the public Datacentre app.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /healthz | Health Check | None |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/healthz' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/healthz", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Do not document or expose
/metrics; it is intentionally excluded from the public app.
Clubs
Club market, detailed club records, job postings and weekly club balance sheets.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /clubs | Retrieve influence market data for clubs | page integer default 1per_page PerPageOptions default 20sort_by ClubsSortBysort_order string default ascclub_id array[integer]country_id stringowned stringmanager_locked integerbalance_min integerbalance_max integer |
| GET | /clubs/detailed | Retrieve detailed data for clubs | page integer default 1per_page PerPageOptions default 20sort_by ClubsSortBysort_order string default ascclub_id array[integer]country_id stringowned stringmanager_locked integeravailable integerleague_id integerdivision integerhas_job_posting integerbalance_min integerbalance_max integerdivision_start_min integerdivision_start_max integerfans_start_min integerfans_start_max integerfans_current_min integerfans_current_max integerstadium_size_start_min integerstadium_size_start_max integerstadium_size_current_min integerstadium_size_current_max integerstadium_id_min integerstadium_id_max integervalue_min integervalue_max integerrating_start_min integerrating_start_max integerdefault_formation_min integerdefault_formation_max integerpenalty_taker_min integerpenalty_taker_max integertransfers_in_min integertransfers_in_max integertransfers_out_min integertransfers_out_max integer |
| GET | /clubs/{club_id}/job | Retrieve job posting details for a specific club | club_id (required) integer |
| GET | /club_balance_sheet/weeks | Get club balance sheet entries by game week | club_id (required) integerseason_id (required) integer |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/clubs?club_id=50&per_page=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/clubs?club_id=50&per_page=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields. /clubs/{club_id}/jobreturns404when the club has no public job posting; that is a valid no-job result, not proof the route is broken.
Players
Player search/detail, historical transfers/loans/morale and combined player history.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /players | Retrieve list of soccer players | page integer default 1per_page PerPageOptions default 20sort_by PlayersSortBysort_order string default ascage_min integerage_max integerage integerplayer_id array[integer]wages_min integerwages_max integerrating_min integerrating_max integervalue_min integervalue_max integercountry_id stringowned stringpositions stringclub_id integerallow_transfer integerallow_renew integer |
| GET | /players/detailed | Retrieve detailed soccer player data | page integer default 1per_page PerPageOptions default 20sort_by PlayersSortBysort_order string default ascage_min integerage_max integerage integerplayer_id array[integer]wages_min integerwages_max integercontract_min integercontract_max integerrating_min integerrating_max integerrating_gk_min integerrating_gk_max integerrating_tackling_min integerrating_tackling_max integerrating_passing_min integerrating_passing_max integerrating_shooting_min integerrating_shooting_max integerrating_aggression_min integerrating_aggression_max integerrating_stamina_min integerrating_stamina_max integervalue_min integervalue_max integerdesired_contract_min integerdesired_contract_max integercountry_id stringowned stringpositions stringclub_id integerinclude_loaned boolean default Falseallow_transfer integerallow_renew integerfitness integerretired integermorale integerinjured integerinjury_id integerposition integermulti_position integerability_gk integerability_tackling integerability_passing integerability_shooting integerbanned integercup_tied integeryellow_cards integerred_cards integeragent_name stringloan_offered stringloan_offer_accepted stringloaned_to_club string |
| GET | /player/history/{player_id} | Retrieve player history | player_id (required) integer |
| GET | /players/morale_history/{player_id} | Get morale change history for a player | player_id (required) integerlimit integer default 10 |
| GET | /player/transfer_history | Retrieve transfer history | season_id integerclub_id integerplayer_id integer |
| GET | /players/loan_history | Retrieve loan history | season_id integerclub_id integer |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/players?player_id=1100&per_page=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/players?player_id=1100&per_page=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields.
Users/profile
User lookup, profile/trading details, achievements and balance-sheet/earnings views.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /users | Get user list and basic data | page integer default 1per_page PerPageOptions default 20sort_by UsersSortBysort_order string default ascname_prefix stringnames array[string] |
| GET | /users/detailed | Get detailed user and trading data | page integer default 1per_page PerPageOptions default 20sort_by UsersDetailedSortBysort_order string default ascname_prefix stringnames array[string]buy_volume_min integerbuy_volume_max integersell_volume_min integersell_volume_max integertotal_volume_min integertotal_volume_max integer |
| GET | /achievements | Get user achievements status | username (required) string |
| GET | /user_activity | Get user activity stats | name string |
| GET | /user_balance_sheet | Get user balance sheet entries | page integer default 1per_page PerPageOptionsExtended default 50name (required) stringfrom_time integerto_time integer |
| GET | /user_balance_sheet/earnings | Get aggregated SVC earnings | name (required) string |
| GET | /user_balance_sheet/weeks | Get weekly aggregated user balance sheets | page integer default 1per_page integer default 10name (required) string |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/users/detailed?names=snailbrain&per_page=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/users/detailed?names=snailbrain&per_page=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields.
Reference/leagues/countries
Reference country/league data and current league-table snapshots.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /countries | Retrieve data for countries | sort_by CountriesSortBysort_order string default desccountry_id string |
| GET | /leagues | Retrieve data for leagues (with 5-min cache) | page integer default 1per_page PerPageOptions default 20sort_by LeaguesSortBysort_order string default asccountry_id stringdivision integerleague_id integerseason_id integer |
| GET | /league_tables | Get league table standings | league_id integercountry_id stringdivision integerseason_id integer |
| GET | /dumps/leagues | All national leagues for the current season | None |
| GET | /dumps/league_tables | League tables for all divisions, optionally filtered to Division 1 by country | country_ids array[string] |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/countries?country_id=ENG' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/countries?country_id=ENG", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- League IDs are season-specific; prefer
country_id + division + season_idwhen linking historical data.
Market/trading
Market overview, account/share balances, recent trades, leader/rich lists and trading graphs.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /market | Obtain overall market metrics | None |
| GET | /ticker | Get ticker data | None |
| GET | /rich_list | Retrieve the richest users | page integer default 1per_page PerPageOptions default 20name stringsort_by RichListSortBy default total_networthsort_order string default desc |
| GET | /best_managers | Get best managers data | page integer default 1per_page PerPageOptions default 20sort_by BestManagersSortBy default rank_a_rankingsort_order string default ascname string |
| GET | /share/transactions | Retrieve share transactions for a user | name (required) string |
| GET | /share_balance_by_user_club | Get share balance for a specific user and club | name (required) stringclub_id (required) integer |
| GET | /share_balances | Retrieve influence balances | page integer default 1per_page PerPageOptions default 20sort_by ShareBalancesSortBysort_order string default ascclub_id integerplayer_id integername stringshare_type stringcountries boolean default Falseleagues boolean default Falsecountry_id stringleague_id integerhas_manager booleanhas_agent booleanmanager_last_active_unix_min integermanager_last_active_unix_max integeragent_last_active_unix_min integeragent_last_active_unix_max integer |
| GET | /share_balances/detailed | Retrieve detailed influence balances with position and earnings | page integer default 1per_page integer default 20name (required) stringshare_type stringhas_manager booleanhas_agent booleanmanager_last_active_unix_min integermanager_last_active_unix_max integeragent_last_active_unix_min integeragent_last_active_unix_max integer |
| GET | /share_trade_history | Retrieve share trade history | page integer default 1per_page integer default 50name stringclub_id integerplayer_id integersort_by stringsort_order string default desc |
| GET | /share_trade_history/all | Get last 20 trades | None |
| GET | /trading_graph | Retrieve aggregated trading data | club_id integerplayer_id integertime_range (required) TimeRangeEnum |
| GET | /trading_graph/all | Retrieve daily and monthly payouts data | None |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/market' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/market", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields.
Datacentre dumps/snapshots
Pre-calculated bulk snapshots for earnings, pack deals and order books. These can be larger than normal paged API responses.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /dumps/club_earnings | Pre-calculated club earnings for buyers | None |
| GET | /dumps/club_earnings_light | Simplified club earnings (club_id → SVC per influence per season) | None |
| GET | /dumps/club_packs | Club pack deals | None |
| GET | /dumps/club_seller_opportunities | Pre-calculated club seller opportunities | None |
| GET | /dumps/player_earnings | Player earnings and ROI analysis | threshold (required) integercountry stringdivision integermin_rating integermax_rating integerposition stringmin_age integermax_age integermin_buyable integermin_match_time numbermax_match_time numbersort string default paybackorder string default ascpage integer default 1limit integer default 100 |
| GET | /dumps/share_orders | All share orders (clubs + players combined) | None |
| GET | /dumps/share_orders/clubs | Club share orders (optionally filtered by ID) | ids array[integer] |
| GET | /dumps/share_orders/players | Player share orders (optionally filtered by ID) | ids array[integer] |
| GET | /dumps/share_orders/json | Download share_orders as JSON | None |
| GET | /dumps/share_orders/csv | Download share_orders as CSV | None |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/dumps/player_earnings?threshold=10&limit=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/dumps/player_earnings?threshold=10&limit=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields. - Dump endpoints can be large; prefer filtered endpoints (
ids,threshold,limit) where available. /dumps/share_orders/csvreturns CSV and/dumps/share_orders/jsonreturns a downloadable JSON file rather than the normal paged wrapper.
Shop datacentre
Pack-sale data for clubs in the shop/datacentre flow.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /shop/clubs | Retrieve pack-sale data for clubs | page integer default 1per_page integer default 20tiers array[integer]country_ids array[string]club_ids array[integer]pricePerPack_min integerpricePerPack_max integersort_by ShopClubsSortBysort_order string default asc |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/shop/clubs?club_ids=50&per_page=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/shop/clubs?club_ids=50&per_page=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Use
per_page/filters where available to keep responses small and cache-friendly.
Transfers
Recent completed transfers and transfer-count summaries.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /transfers/basic | Get latest completed transfers | None |
| GET | /transfers/counts | Get transfer counts for a club in a season | club_id (required) integerseason_id (required) integer |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/transfers/basic' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/transfers/basic", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields.
Fixtures/commentary
Fixture commentary, match events, player stats and tactics snapshots.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /commentary/match_commentary/{fixture_id} | Get match commentary for a fixture | fixture_id (required) integer |
| GET | /commentary/match_events/{fixture_id} | Get match events for a fixture | fixture_id (required) integer |
| GET | /fixture_history/players/{fixture_id} | Get fixture player data for a fixture | fixture_id (required) integer |
| GET | /fixture_history/tactics/{fixture_id} | Get fixture tactics data for a fixture | fixture_id (required) integer |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/commentary/match_commentary/1' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/commentary/match_commentary/1", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Use a real
fixture_id; examples here use fixture1as a stable reference value.
Messages/news
Blockchain/game messages/news filtered by season, country, competition or club.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /messages | Get messages from the blockchain | season_id (required) integercountry_id stringcomp_id integerclub_id integerlimit integer |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/messages?season_id=1&club_id=50&limit=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/messages?season_id=1&club_id=50&limit=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
season_idis required; addlimitto avoid very large responses.
Leaderboards
Earnings and referral leaderboards.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /leaderboards/earnings | Get top 10 earners leaderboard | days integer default 30 |
| GET | /leaderboards/referrals/all | Get top 20 referrers for all time | None |
| GET | /leaderboards/referrals/time-range | Get top 50 referrers within a specific time range | None |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/leaderboards/earnings?days=30' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/leaderboards/earnings?days=30", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Check whether money-like fields are raw scaled integers and divide by
10000only for raw SVC/money fields.
Votes/proposals
Active and historical proposal/vote views plus graph data.
| Method | Path | Purpose | Main query/path parameters |
|---|---|---|---|
| GET | /proposals/active | Get currently active proposals | page integer default 1per_page integer default 100proposal_type stringshare_type stringstage_filter stringclub_id integerplayer_id integername string |
| GET | /proposals/graph | Get daily proposal completion counts for graphing | days_back integer default 30 |
| GET | /proposals/historical | Get proposals that ended in the last N days with daily statistics | days_back integer default 7proposal_type stringshare_type stringclub_id integerplayer_id integername string |
Example curl:
curl -sS \
-H 'x-cf-bypass-secret: $CLOUDFLARE_BYPASS_SECRET' \
'https://services.soccerverse.com/api/proposals/active?club_id=50&per_page=5' | jq .
Example Python:
import os
import requests
headers = {}
if os.getenv("CLOUDFLARE_BYPASS_SECRET"):
headers["x-cf-bypass-secret"] = os.environ["CLOUDFLARE_BYPASS_SECRET"]
response = requests.get("https://services.soccerverse.com/api/proposals/active?club_id=50&per_page=5", headers=headers, timeout=30)
response.raise_for_status()
print(response.json())
Pitfalls:
- Active proposal lists may legitimately be empty for a specific club/player.