How to Get Football Data with Java - Complete API Tutorial
Step-by-step Java tutorial for fetching football fixtures, match stats and odds via API using HttpClient and Jackson. Working code examples you can copy.
Java powers a lot of backend services, Android data layers, and Spring Boot APIs. TheStatsAPI is a plain REST JSON API, so you can use the built-in java.net.http.HttpClient (Java 11+) and Jackson for parsing - no SDK required.
This tutorial shows how to fetch football data with Java: competitions, fixtures, pagination, match stats, and odds.
Prerequisites
You need:
- Java 11+ (for
java.net.http.HttpClient) - Jackson for JSON parsing
- A TheStatsAPI API key
Add Jackson with Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
Set your API key as an environment variable:
export THESTATSAPI_KEY="your_api_key"
If you do not have a key yet, sign up at thestatsapi.com for a 7-day free trial.
Create a Small API Client
Create FootballApi.java. It returns a parsed Jackson JsonNode so every example can read fields directly.
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
public class FootballApi {
private static final String BASE_URL = "https://api.thestatsapi.com/api";
private static final String API_KEY = System.getenv("THESTATSAPI_KEY");
private static final HttpClient CLIENT = HttpClient.newHttpClient();
private static final ObjectMapper MAPPER = new ObjectMapper();
public static JsonNode get(String endpoint, Map<String, String> params) throws Exception {
String query = params.entrySet().stream()
.map(e -> URLEncoder.encode(e.getKey(), StandardCharsets.UTF_8)
+ "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
String url = BASE_URL + endpoint + (query.isEmpty() ? "" : "?" + query);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer " + API_KEY)
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException("API request failed: HTTP " + response.statusCode());
}
return MAPPER.readTree(response.body());
}
public static JsonNode get(String endpoint) throws Exception {
return get(endpoint, Map.of());
}
}
URLEncoder keeps query parameters safe. Every example below reuses FootballApi.get().
Fetch Competitions
import com.fasterxml.jackson.databind.JsonNode;
import java.util.Map;
public class Competitions {
public static void main(String[] args) throws Exception {
JsonNode result = FootballApi.get("/football/competitions",
Map.of("search", "Premier League"));
for (JsonNode competition : result.get("data")) {
System.out.println(competition.get("id").asText() + " "
+ competition.get("name").asText() + " "
+ competition.get("country").asText());
}
}
}
Typical output:
comp_3039 Premier League England
Save the competition ID for match and season queries.
Get Fixtures for a League
import com.fasterxml.jackson.databind.JsonNode;
import java.util.Map;
JsonNode result = FootballApi.get("/football/matches", Map.of(
"competition_id", "comp_3039",
"per_page", "10"
));
for (JsonNode match : result.get("data")) {
String home = match.get("home_team").get("name").asText();
String away = match.get("away_team").get("name").asText();
String status = match.get("status").asText();
String date = match.get("utc_date").asText();
System.out.printf("%s - %s vs %s (%s)%n", date, home, away, status);
}
Add date_from, date_to, season_id, team_id, and status to filter. See the fixtures API.
Handle Pagination
List endpoints return a meta block with total_pages.
import com.fasterxml.jackson.databind.JsonNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public static List<JsonNode> getAll(String endpoint, Map<String, String> baseParams) throws Exception {
List<JsonNode> rows = new ArrayList<>();
int page = 1;
while (true) {
Map<String, String> params = new HashMap<>(baseParams);
params.put("page", String.valueOf(page));
JsonNode result = FootballApi.get(endpoint, params);
result.get("data").forEach(rows::add);
int totalPages = result.path("meta").path("total_pages").asInt(1);
if (page >= totalPages) break;
page++;
}
return rows;
}
Run backfills like this in a scheduled job and cache the rows in your database.
Get Match Stats
import com.fasterxml.jackson.databind.JsonNode;
JsonNode data = FootballApi.get("/football/matches/mt_010249745/stats").get("data");
JsonNode overview = data.get("overview");
JsonNode xg = overview.get("expected_goals").get("all");
JsonNode shots = overview.get("total_shots").get("all");
System.out.println("Shots: " + shots.get("home").asText() + " - " + shots.get("away").asText());
System.out.println("xG: " + xg.get("home").asDouble() + " - " + xg.get("away").asDouble());
See the match stats API and xG API.
Get Pre-Match Odds
import com.fasterxml.jackson.databind.JsonNode;
JsonNode data = FootballApi.get("/football/matches/mt_010249745/odds").get("data");
for (JsonNode book : data.get("bookmakers")) {
JsonNode matchOdds = book.path("markets").path("match_odds");
if (matchOdds.isMissingNode()) continue;
System.out.println(book.get("bookmaker").asText() + ": " + matchOdds);
}
Use /football/matches/{match_id}/odds/live for in-play odds. See the Football Odds API.
Production Tips
- Keep the API key in environment variables or a secrets manager.
- Reuse a single
HttpClientinstance - it is thread-safe and pools connections. - Cache responses to respect plan limits.
- Use pagination for backfills and run them outside request threads.
- Check availability flags such as
xg_availableandlive_odds_available.
FAQ
Can I use Java with TheStatsAPI?
Yes. TheStatsAPI is a REST JSON API, so Java's built-in HttpClient (Java 11+) works directly. The examples above parse responses with Jackson.
Do I need a Java SDK?
No. Plain HTTP requests with HttpClient and a JSON library like Jackson or Gson are enough, and they work in plain Java, Spring Boot, and Android.
How do I fetch football odds in Java?
Use /football/matches/{match_id}/odds for pre-match odds and /football/matches/{match_id}/odds/live for live odds where available.
How do I get xG data in Java?
Call /football/matches/{match_id}/stats and read overview.expected_goals.all for team xG.
Ready to Power Your Sports App?
Start your 7-day free trial. All endpoints included on every plan.