How to Get Football Data with Ruby - Complete API Tutorial
Step-by-step Ruby tutorial for fetching football fixtures, match stats and odds via API using net/http. Working code examples you can copy into Rails.
Ruby and Rails are a productive choice for football data products, dashboards, and internal tools. TheStatsAPI is a plain REST JSON API, so the standard net/http and json libraries are all you need - no gem required.
This tutorial shows how to fetch football data with Ruby: competitions, fixtures, pagination, match stats, and odds.
Prerequisites
You need:
- Ruby 3.0+
- A TheStatsAPI API key
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 football_api.rb:
require "net/http"
require "json"
require "uri"
BASE_URL = "https://api.thestatsapi.com/api"
def tsapi_get(endpoint, params = {})
uri = URI("#{BASE_URL}#{endpoint}")
uri.query = URI.encode_www_form(params) unless params.empty?
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch('THESTATSAPI_KEY')}"
request["Accept"] = "application/json"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
raise "API request failed: HTTP #{response.code}" if response.code.to_i >= 400
JSON.parse(response.body)
end
URI.encode_www_form handles URL-encoding. Every example below reuses tsapi_get.
Fetch Competitions
require_relative "football_api"
result = tsapi_get("/football/competitions", { search: "Premier League" })
result["data"].each do |competition|
puts "#{competition['id']} #{competition['name']} #{competition['country']}"
end
Typical output:
comp_3039 Premier League England
Save the competition ID for match and season queries.
Get Fixtures for a League
require_relative "football_api"
result = tsapi_get("/football/matches", {
competition_id: "comp_3039",
per_page: 10
})
result["data"].each do |match|
home = match["home_team"]["name"]
away = match["away_team"]["name"]
puts "#{match['utc_date']} - #{home} vs #{away} (#{match['status']})"
end
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.
require_relative "football_api"
def tsapi_get_all(endpoint, params = {})
page = 1
rows = []
loop do
result = tsapi_get(endpoint, params.merge(page: page))
rows.concat(result["data"])
total_pages = result.dig("meta", "total_pages") || 1
break if page >= total_pages
page += 1
end
rows
end
matches = tsapi_get_all("/football/matches", { competition_id: "comp_3039" })
puts "Fetched #{matches.length} matches"
For Rails apps, run this in a background job (Sidekiq, GoodJob) and cache rows in your database.
Get Match Stats
require_relative "football_api"
data = tsapi_get("/football/matches/mt_010249745/stats")["data"]
overview = data["overview"]
xg = overview["expected_goals"]["all"]
shots = overview["total_shots"]["all"]
puts "Shots: #{shots['home']} - #{shots['away']}"
puts "xG: #{xg['home']} - #{xg['away']}"
See the match stats API and xG API.
Get Pre-Match Odds
require_relative "football_api"
data = tsapi_get("/football/matches/mt_010249745/odds")["data"]
data["bookmakers"].each do |book|
match_odds = book.dig("markets", "match_odds")
next unless match_odds
puts "#{book['bookmaker']}: #{match_odds}"
end
Use /football/matches/{match_id}/odds/live for in-play odds. See the Football Odds API.
Use It Inside Rails
Wrap the helper in a service object and read the key from Rails credentials:
# app/services/football_api.rb
class FootballApi
BASE_URL = "https://api.thestatsapi.com/api"
def self.get(endpoint, params = {})
uri = URI("#{BASE_URL}#{endpoint}")
uri.query = URI.encode_www_form(params) unless params.empty?
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{Rails.application.credentials.thestatsapi_key}"
request["Accept"] = "application/json"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }
JSON.parse(response.body)
end
end
Production Tips
- Store the API key in environment variables or Rails credentials, never in source.
- Cache responses with
Rails.cacheor Redis to respect plan limits. - Use pagination for backfills inside background jobs.
- Check availability flags such as
xg_availableandlive_odds_available.
FAQ
Can I use Ruby with TheStatsAPI?
Yes. TheStatsAPI is a REST JSON API, so Ruby's standard net/http and json libraries work directly. The examples above also include a Rails service object.
Do I need a Ruby gem?
No. The standard library is enough. You can add a gem like httparty or faraday if you prefer, but it is not required.
How do I fetch football odds in Ruby?
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 Ruby?
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.