Skip to main content
This guide walks you through the complete flow from a public ID (e.g., Transfermarkt or Wyscout ID) to a working API response. By the end you will have authenticated, resolved a player ID, and retrieved a full valuation for that player at a specific club.

Prerequisites

Before you start, make sure you have:
  • A SquadAssist account with an API key
  • A SquadAssist player ID, Transfermarkt player ID, or Wyscout player ID for the player you want to evaluate (at least one is needed, otherwise see
  • The SquadAssist club ID for the club perspective you want to use in the ROI analysis. This is typically your own club.
  • curl available in your terminal (all examples below use curl)
Player IDs and club IDs are drawn from the SquadAssist database. Use POST /query_player and POST /query_club to resolve external IDs (Transfermarkt, Wyscout) to SquadAssist IDs before calling valuation endpoints.

Step-by-step

1

Look up a player

Use POST /query_player to resolve a player’s external IDs and confirm they exist in the SquadAssist database. You can supply any combination of squadassist_id, transfermarkt_id, or wyscout_id.
curl -X POST https://api.squadassist.ai/v1/query_player \
  -H "x-api-key: YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transfermarkt_id": 123456
  }'
The response gives you the player’s SquadAssist ID and profile fields:
{
  "squadassist_id": "P01JJ...",
  "transfermarkt_id": 123456,
  "wyscout_id": 789012,
  "name": "Jan De Smedt",
  "first_name": "Jan",
  "last_name": "De Smedt",
  "alias": null,
  "nationality": "BEL",
  "birth_date": "1998-03-15",
  "height": 182,
  "preferred_foot": "right"
}
Note the squadassist_id from this response—you will need it for valuation calls.
2

Get the ROI analysis

POST /roi_analysis calculates a full value creation estimation (sportive impact and future transfer value) for a player at a specific club. The player_id and club_id fields are required; wage and expected transfer value are optional inputs that affect the financial return calculation.
curl -X POST https://api.squadassist.ai/v1/get_roi_analysis \
  -H "x-api-key: YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "player_id": "P01JJ...",
    "club_id": "C01JJBVJAPKG8CM7ZA5JF5G84R8",
    "annual_wage": 1500000,
    "expected_transfer_value": 8000000,
    "currency_code": "EUR"
  }'
FieldRequiredDescription
player_idYesSquadAssist player ID
club_idYesSquadAssist club ID for the valuation context
annual_wageNoPlayer’s annual gross wage, in currency_code
expected_transfer_valueNoYour estimated acquisition cost, in currency_code
currency_codeNoISO 4217 code for input amounts (defaults to EUR)
The response contains the full valuation breakdown. All monetary values are returned in the currency you specified via currency_code.
{
  "currency": "EUR",
  "total_value": 12400000,
  "on_field_value": 6200000,
  "marketing_value": 950000,
  "future_transfer_value": 7800000,
  "roi": 1.55,
  "simulation_years": 3,
  "player_id": "P01JJ...",
  "club_id": "C01JJBVJAPKG8CM7ZA5JF5G84R8"
}

End-to-end python code

import time
import requests

BASE_URL = "https://api.squadassist.ai/v1"
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}
IDS_TO_process = [982081, 733410, 981398, 565431, 409490, 1053160, 919173, 847279, 745178, 1086381, 183383, 950874, 1233680, 1120020, 1208836, 993333, 679050, 1451916, 583913, 668587, 923838, 1176433, 579089, 1105918, 1021007, 1467501, 110822, 1474022, 1464975, 1451913, 477460] #Adjust appropriately 

def post_with_retry(endpoint, payload, max_retries=3):
url = f"{BASE_URL}/{endpoint}"
for attempt in range(max_retries):
    resp = requests.post(url, headers=HEADERS, json=payload)
    if resp.status_code == 429:
        wait = resp.json().get("retry_after_seconds", 10)
        print(f"Rate limited. Waiting {wait}s...")
        time.sleep(wait)
        continue
    if resp.status_code == 403:
        #Some players are available but not yet ready for ROI analysis. We will translate that error here so it's easier to access in the try except below 
        if resp.json().get("error") == "This player_is not available for analysis":
            raise AttributeError("Player can't be analysed yet")
    resp.raise_for_status()
    return resp.json()
raise Exception("Rate limit retries exhausted")

for id in IDS_TO_process:
# Step 1 — Resolve player via Transfermarkt ID
player = post_with_retry("query_player", {"transfermarkt_id": id}) #Adjust to other ID type if needed
print("Player:", player["name"], "| ID:", player["squadassist_id"])

# Step 2 — Get ROI analysis
try: 
    roi = post_with_retry("get_roi_analysis", {
        "player_id": player["squadassist_id"],
        "club_id": "C01JJBVJAPKG8CM7ZA5JF5G84R8",
        "annual_wage": 1500000,
        "expected_transfer_value": 8000000,
        "currency_code": "EUR",
    })
    print("ROI Analysis for", player["name"])
    print("Total value:", roi["total_value_created"])
    print("ROI:", roi["return_on_investment"])
except AttributeError as e:
    print(f"Skipping {player['name']} as he can't be analysed yet: {e}")
except Exception as e:
    print(f"Error processing {player['name']}: {e}")

What’s next

  • POST /get_future_transfer_value — project the resale value of a player in 3 years
  • GET /expected_transfer_value — get the current expected transfer fee for a player
  • GET /player_info — retrieve detailed position, role, and club affiliation data for a player