Squiggle API

v1.11.0

The Squiggle API offers public access to basic data (fixture, ladder, match scores) on AFL games, plus predictions made by computer models. It's available in computer-friendly formats so you can automatically import it into a spreadsheet or similar for your own analysis.

What's availableThe Standard (RESTful) APIThe Event APIHow to be niceChangelog

What's Available

This API provides only basic, public information that can be easily found elsewhere: who's playing who when & where, and what the scores are. Its main usefulness is that it's simple, reliable, and up-to-date. It doesn't offer more advanced stats, such as Inside 50s or Expected Score, which are generated by a private company (Champion Data).

The Standard (RESTful) API

Most people want the Standard API, which lets you look up data on teams, games, the ladder, and more. It's simple: You send it a request for a particular set of data, and the API returns it to you.

But if you want to be notified of events in a live match as they happen, such as tracking the scores, you might want the Event API instead.

Query Types

The Standard API offers the following query types, which you should specify in your request as parameter "q" — e.g. https://api.squiggle.com.au/?q=teams.

teamsInfo about teams (e.g. Richmond, Geelong, West Coast)
gamesInfo about games (e.g. Round 1, 2019 Richmond v Carlton)
sourcesInfo about models (e.g. Matter of Stats, GRAFT, Swinburne)
tipsInfo about tips and predictions made by models
standingsInfo about team standings (i.e. the ladder)
ladderInfo about predicted ladders generated by models
powerInfo about power rankings generated by models

Detail on each query type is below, along with Additional Examples.

Format (optional)

You may specify an output format using the parameter "format" — e.g. https://api.squiggle.com.au/?q=teams;format=json.

JSONJSON format (default)
XMLXML format
CSVComma-separated values

Additional Parameters (optional)

Each query type has additional parameters that you may specify in order to restrict the data to a particular subset that you're interested in. See below for details.

To exclude data, prepend the parameter value with an exclamation mark (!), e.g. 2020 games except Round 1.

Default behavior when parameters aren't specified (e.g. requesting "?q=games" with no "year=xxxx" parameter) is undefined and subject to change. For example, at present, "?q=games" returns data on all games, but in the future, it may default to the current year. For reliability, supply parameters to identify the exact data you want.

How To Import API Data

Google Sheets

To automatically import data into Google Sheets, enter a formula like this into a cell:

=IMPORTXML("https://api.squiggle.com.au/?q=tips;year=2022;source=1;format=xml", "/*/*")
	

Microsoft Excel

I believe you can do the same thing in Excel. From what I've read, in newer versions you do: DataGet & TransformFrom FileFrom JSON and then can enter an URL (like https://api.squiggle.com.au/?q=tips;year=2018;source=1).

Excel can read JSON, XML, and CSV, so it shouldn't matter which you choose, so long as the URL matches the function. (That is, if you click "From JSON", don't give it an URL with ";format=xml".)

LibreOffice Calc

Use SheetLink to External Data and paste in the appropriate URL (like https://api.squiggle.com.au/?q=teams;format=csv). You may need to specify XML or CSV format rather than JSON.

teams

Fetch info about one or more AFL teams.

https://api.squiggle.com.au/?q=teams

Examples:
Optional Parameters:
teamTeam ID
yearYear

games

Fetch info about one or more games.

https://api.squiggle.com.au/?q=games

Examples:
Optional Parameters:
yearYear
roundRound
gameGame ID
teamTeam ID
completePercent of game complete
liveWhether game is currently in progress
Fields:
Most are hopefully self-explanatory, but:
is_final 0: Not a final
1: Some kind of final (type unspecified)
2: Elimination Final
3: Qualifying Final
4: Semi-Final
5: Preliminary Final
6: Grand Final
is_grand_final 0: Not a Grand Final
1: Grand Final

Note: The original 2020 fixture, before the pandemic caused it to be redrawn after Round 1, is accessible as "2020-original" — e.g. all originally fixtured 2020 games.

sources

Fetch info about one or more computer models.

https://api.squiggle.com.au/?q=sources

Examples:
Optional Parameters:
sourceSource ID

tips

Fetch info about one or more tips made by computer models.

https://api.squiggle.com.au/?q=tips

Examples:
Optional Parameters:
yearYear
roundRound
gameGame ID
gameSource ID
teamTeam ID
completePercent of game complete

standings

Fetch info about team standings at a point in time, i.e. the ladder.

https://api.squiggle.com.au/?q=standings

Examples:
Optional Parameters:
yearYear
roundRound *

ladder

Fetch info about one or more projected ladders generated by computer models. For the actual ladder, see standings instead.

https://api.squiggle.com.au/?q=ladder

Examples:
Optional Parameters:
yearYear
roundRound *
sourceSource ID
dummyFlag for placeholder data, not yet updated this round

power

Fetch info about power rankings generated by computer models, which rate the underlying strength of teams at a point in time. Note that different models use different scales.

https://api.squiggle.com.au/?q=power

Examples:
Optional Parameters:
yearYear
roundRound *
sourceSource ID
teamTeam ID
dummyFlag for placeholder data, not yet updated this round

Additional Examples


* A Note on 'round'

The queries standings, ladder, and power accept a round parameter, which specifies a point in time. For example, ?q=standings;round=1 returns the team standings (i.e. the ladder) after all Round 1 games were completed and before the start of Round 2.

For these queries, round always refers to the most recently-completed round, e.g. Round 10 power rankings were made with knowledge of Round 10 results.

Preseason data can be obtained by deducting 1 from the number of the season's first round, i.e. 0 for all years until 2024, at which point the AFL created a fixture with Round 0 matches, so then -1 thereafter. For example, you can view projected ladders from before the first game of 2023 with ?q=ladder;year=2023;round=0, and similarly for pre-season 2024 with ?q=ladder;year=2024;round=-1.

Omitting the round parameter will return final results — or current results, if the season is still in progress.

The Event API

The Event API is useful if you want to track live scores, and be notified of score changes as soon as possible.

You could query the Standard API over and over, sending the same request for game info every 30 seconds or so, but this is unreliable (what if a goal is kicked one second after your query?) and inefficient, requiring lots of requests for relatively little data. Instead, send a single request to the Event API, and whenever there's new data — like a goal or a behind — the Event API will immediately notify you.

The Event API supports two types of query:

gamesAn updating stream of games that are in progress or due to start soon.
eventsAn updating stream of basic score events that occur within a game, plus timing.

plus...

testA stream of random data so you can test a basic connection and parsing without waiting for an actual game.

The Event API uses the Server-Sent Events (SSE) protocol and is available in both HTTPS and HTTP flavours, making it broadly accessible to all kinds of devices, including embedded and low-power ones.

Note that the Event API rarely but occasionally restarts. Your code shouldn't assume a connection will last forever — handle disconnection and auto-reconnection.

games

Access a stream of current/soon-to-start games.

https://api.squiggle.com.au/sse/games — all games

https://api.squiggle.com.au/sse/games/<team id> — all games involving one particular team

Upon joining the channel, you will be sent a games event array containing basic data on all games that are either in progress or scheduled to start within the next 6 hours. Thereafter, you will be sent addGame and removeGame event objects as games are added to the list (because they're going to start in the near future) or removed (because they're over).

Both events broadcast the game's complete state, so if you simply want to know the final scores of all matches as soon as possible, you can monitor this stream for removeGame events.

Example output:
event:games
id:d8013623
data:[{ "id":8706, "year":2022, "round":5, "hteam":10, "ateam":7, "date":"2022-04-18T05:20:00.000Z", "tz":"+10:00", "complete":64, "winner":null, "hscore":64, "ascore":62, "hgoals":10, "hbehinds":4, "agoals":9, "abehinds":8, "venue":"M.C.G.", "timestr":"Q3 17:49", "updated":"2022-04-18T07:08:02.000Z", "is_final":0,"is_grand_final":0 }
:
:
:
:
:
event:removeGame
id:ec2f907f
data:{ "id":8706, "year":2022, "round":5, "hteam":10, "ateam":7, "date":"2022-04-18T05:20:00.000Z", "tz":"+10:00", "complete":100, "winner":10, "hscore":92, "ascore":80, "hgoals":14, "hbehinds":8, "agoals":11, "abehinds":14, "venue":"M.C.G.", "timestr":"Full Time", "updated":"2022-04-18T07:58:49.000Z", "is_final":0, "is_grand_final":0 }

events

Access a stream of events from one or more in-progress games.

https://api.squiggle.com.au/sse/events — events from all games

https://api.squiggle.com.au/sse/events/<game id> — events from one particular game

If you join the channel for a particular game, you will be sent a game event containing data about the current state of the game. Thereafter, you will be sent events as game state changes, including score, timestr, and complete*. When the game concludes, you will be sent a winner event plus a full and final game event.

Example output:
event:game
id:04120ced
data:{ "id":8706, "year":2022, "round":5, "hteam":10, "ateam":7, "date":"2022-04-18T05:20:00.000Z", "tz":"+10:00", "complete":75, "winner":null, "hscore":64, "ascore":76, "hgoals":10, "hbehinds":4, "agoals":11, "abehinds":10, "venue":"M.C.G.", "timestr":"3/4 Time", "updated":"2022-04-18T07:23:03.000Z", "is_final":0, "is_grand_final":0 }
:
:
event:complete
id:defb34a6
data:{ "gameid":8706, "complete":78 }

event:timestr
id:0b6274dc
data:{ "gameid":8706, "timestr":"Q4  4:16"}
:
:
:
event:score
id:e7d3052f
data:{ "gameid":8706, "type":"behind", "side":"ateam", "team":7, "complete":78, "timestr":"Q4  4:36", "score":{ "hscore":64, "hgoals":10, "hbehinds":4, "ascore":77, "agoals":11, "abehinds":11 } }
:
:
...snip...
:
:
event:complete
id:2b7c4230
data:{"gameid":8706,"complete":100}

event:winner
id:de7fb404
data:{"gameid":8706,"winner":10}

event:game
id:42a99a07
data:{ "id":8706, "year":2022, "round":5, "hteam":10, "ateam":7, "date":"2022-04-18T05:20:00.000Z", "tz":"+10:00", "complete":100, "winner":10, "hscore":92, "ascore":80, "hgoals":14, "hbehinds":8, "agoals":11, "abehinds":14, "venue":"M.C.G.", "timestr":"Full Time", "updated":"2022-04-20T01:31:48.000Z", "is_final":0, "is_grand_final":0 }
	

* complete is an integer that estimates the percentage of the match completed. For example, 10 is early in the first quarter, 50 is half-time, and 100 is a completed match.

test

Access a stream of random data, so you can setup and test your basic connection without having to wait for an actual game to be in progress.

https://api.squiggle.com.au/sse/test

How To Be Nice

Sometimes well-meaning scripts and bots spiral out of control and make lots of requests in a very short period. If you set your bot's UserAgent to something informative, I can contact you if this happens and explain the problem. If you don't, all I can do is block you. So if you're seeing a block message, that's why.

Please write a well-behaved bot:

  1. Set the UserAgent to something that identifies it and allows me to contact you, e.g. "Dan's Tipping Comp - dan@example.com"

  2. Cache and re-use the data you get. (I am looking right now at a bot that is fetching the names of all AFL teams in bursts of 18 identical requests, and another that asks the API every 9 seconds for every bit of data it has on everything.)

  3. Avoid making large numbers of simultaneous requests — if you need information on a season's worth of games, fetch it all in one request, not one request per game.

  4. Avoid fetching more data than you need — if you only need info on one game, don't ask for the whole season.

  5. Consider what your bot will do when it encounters an unexpected return code or data, and make it not repeat the same request over and over at maximum speed.

Changelog

Apr 20241.11.0API will refuse to supply data to requests with common scraper UserAgents. Please see instructions on setting your UserAgent.
Jan 20231.10.4teams will supply historically correct logos (mostly) when supplied with year parameter, thanks to Logopedia.
Jan 20231.10.3teams will supply historically correct team name when supplied with year parameter.
Jul 20221.10.2Fixed calculation error in unixtime output field.
Jul 20221.10.1Added unixtime output field to Standard API games query type.
Jul 20221.10.0Added team parameter to Standard API games, tips, power query types.
Jun 20221.9.0Deprecated pav and virtual query types, which will be removed in the future.
May 20221.8.3Added live parameter to games query type.
May 20221.8.2Added dummy output field to ladders, power query type.
May 20221.8.1Added teamid parameter to Event API games query type.
Added all as an acceptable value for round in the power query type.
May 20221.8.0Added power for Power Rankings.
Apr 20221.7.0Added Event API.
Apr 20221.6.1Added timestr output field to games query type.
Jan 20221.6.0Added year parameter to teams query type, and debut and retirement to its output.
Added games data for years 2000-2010.
Jun 20201.5.0Added pav for HPN Footy's Player Approximate Value ratings.
Jun 20201.4.1Restored original 2020 fixture as '2020-original'.
Mar 20201.4.0Added virtual for Virtually Season 2020.
Jun 20191.3.0Added standings for generating actual ladder at a point in time.
Jun 20191.2.0Added support for output as comma-separated values (CSV).
May 20191.1.0Added ladder for outputting ladder predictions.
Apr 20181.0.0Original version.

Max Barry

squiggle.com.au

twitter.com/squiggleAFL