Skip to content
Scores and results

Recent football results API for the past seven days

Results pages have a long tail of readers: people checking a score the morning after, fantasy managers reviewing a gameweek, editors writing round-ups. The recent results feed returns finished matches for one day in the past week. This page explains the offset, how results differ from live scores, and how to keep a results archive accurate when the source amends something.

Primary endpoint

GET/api/v1/football/recent-results

  • offset required, "1" to "7" days back

Access: All plans; Starter limited to your five saved leagues. Header: X-API-Key.

Illustration of a stack of seven dated result cards fanned out, with a football resting on the top card.
Recent results are addressed by days back from today: offset 1 is yesterday, offset 7 a week ago.
01

One day of results per request

Recent results takes one required parameter, offset, which is a whole number from 1 to 7 sent as a string. For this feed it counts days before today: offset 1 is yesterday and offset 7 is a week ago. It mirrors the upcoming feed, which uses the same values to count forward. There is no offset for today here; the current day belongs to the scores and live feeds, where matches may still be in progress.

Values outside 1 to 7, or values written as dates, are rejected with a 400 response and the invalid_parameter code. That rejection is not billed, but it leaves a hole in whatever page you were building, so validate the value on your side before sending it.

The cache time is about five minutes, which reflects the nature of the data. Results for yesterday change rarely, so frequent polling buys nothing.

02

Finished matches, as supplied

Responses use the standard envelope: a data object with the source structure and a meta object with the feed, UTC fetch time, cache time and qualification. The data is passed through without a normalised schema of our own. Identifiers are strings, and attributes that came from source attributes keep their at-sign prefix. Inspect a real response before mapping it, and expect the attributes present to vary between competitions.

Do not assume every match in the response finished normally. A day's results can include matches that were abandoned, postponed on the day or awarded by a competition authority. Display whatever state the source supplies with each match. A results page that shows an abandoned match as a nil-nil draw is making a claim the data does not support.

Results by day, then into your archiveFlow: request recent-results with offset 1 to 7, record the computed date, upsert finished matches by string ID, and roll older days into a permanent archive.01offset=1..7days back02Date itfrom fetchedAt03Upsertby match ID04Archiveafter 7 days
Results by day, then into your archive. Recent results bridge the gap between the live day and your long-term archive.
03

The morning-after page

A classic use is a page that shows yesterday's results grouped by competition, refreshed early each morning. One request with offset 1, made after the last late kick-off has finished in every timezone you cover, produces the whole page. Add offsets 2 to 7 if you want a week of results navigable by day.

Remember that offsets slide at midnight, so store each response with the date you derived from its fetch time and render headings from that stored date. A cache keyed only by offset will show the wrong day's results under a heading the moment the date changes.

  • Refresh offset 1 after late kick-offs have finished everywhere you cover.
  • Store each day under a computed date, not just its offset.
  • Group by competition and show each match state beside its score.
  • Link each result to deeper match detail where your plan includes it.
04

Rolling a week of results into storage

The example fetches all seven offsets once a day and upserts each match by its string identifier. Because the same match appears under offset 1 today and offset 2 tomorrow, upserting rather than inserting avoids duplicates and lets a correction overwrite the earlier value. Run it once each morning and once in the evening and you will catch most amendments made in the days after a match.

After seven days, a match leaves this feed. If you need it longer, keep your stored copy, or request the season through historical fixtures when you build a permanent archive.

Node.js: upsert the past week of resultsjavascript
const base = "https://footballapi.net/api/v1/football/recent-results";
const headers = { "X-API-Key": process.env.FOOTBALLAPI_KEY };

for (let n = 1; n <= 7; n++) {
  const res = await fetch(`${base}?offset=${n}`, { headers });
  const body = await res.json();
  if (!res.ok) { console.warn(n, body.code, body.requestId); continue; }
  for (const match of readMatches(body.data)) {   // your mapping from a real sample
    await upsertResult(String(match.id), match, body.meta.fetchedAt);
  }
}
05

Corrections after the final whistle

Results are not always final when the match ends. A goal may be reassigned to a different scorer, a match result may be changed after a disciplinary decision, or a data entry error may be fixed the next day. The seven-day window is useful precisely because it lets you see those corrections. If you only ever store the first version of a result you saw, you will publish the uncorrected one indefinitely.

Keep a small history of changes for each match: the previous values and when you saw the new ones. If a correction changes a scoreline, your editors may want to know, especially if a round-up has already been published. A simple daily report of changed results is cheap to build from that history and saves embarrassment.

06

Results for gameweek tools

Fantasy and prediction-league tools, the kind where friends compete to forecast scores for fun rather than money, depend on reliable results and on knowing when a result is settled. The feed tells you what the source reports; it does not certify that a result will never change. Build a settlement rule into your product, such as treating a result as final for scoring purposes a set time after it first appears, and tell your users what the rule is.

These tools also tend to run their scoring at the same moment for every user, which produces a burst of reads. Read from your stored copy, not the API. A single scheduled fetch feeds every user's score calculation.

07

Corrections after publication

Results are occasionally corrected after first publication: a goal reassigned, a score amended after review, a match awarded. Your refresh should compare each result with your stored copy by match identifier and update it when the source changes, recording the time of the change. If your product publishes results to readers through notifications or social posts, decide in advance how you will handle a correction, and avoid sending a second alert unless the score itself changed.

Keep match states as supplied. A postponed or abandoned match is not a result, and it should not be displayed with a score of nil-nil.

08

Choosing the offset window

The offset parameter takes a value from 1 to 7 and returns results for that many days before today. A one-day window suits a frequent refresh of yesterday's matches; a seven-day window suits a weekly round-up or a recovery job after downtime. Most products run a short window often and a long window once a day, which catches late corrections without requesting the same week repeatedly.

09

Errors during refresh

An offset outside 1 to 7 returns a 400 invalid_parameter response. Upstream 502 or 504 errors are temporary; keep serving stored results, retry later and log the requestId. A run of failures should alert you rather than leave a results page silently stale.

10

Plan scope

Recent results is league filtered. On Starter at EUR 29 a month, responses are filtered to your five saved leagues. Growth at EUR 99 and Pro at EUR 249 receive the available package competitions. Coverage varies by competition and date on every plan, and the feed qualification is sample received.

Seven requests twice a day is fourteen successful requests, a negligible share of any daily inclusion. Successful requests above the inclusion cost EUR 0.002 each on the monthly EUR invoice, and failed or denied requests are not billed. No free trial is offered and no VAT is currently charged.

Questions developers ask

What does offset mean for recent results?
Days before today, as a whole number from 1 to 7 sent as a string. Offset 1 is yesterday.
Can I get today's finished matches here?
No. Use the scores feed for today. Recent results starts from yesterday.
How far back does recent results go?
Seven days. For older matches, use your stored copy or the historical fixtures feed.
Can a result change after it appears?
Yes. Sources can amend results. Refresh the week and upsert by match identifier so corrections replace earlier values.
Is the feed filtered on Starter?
Yes. Starter responses contain only your saved leagues.
Will an abandoned match show as a result?
It appears with whatever state the source supplies. Display that state rather than treating the score as final.

Check the plan before you write the integration.

Starter EUR 29, Growth EUR 99, Pro EUR 249 per month. No free trial. No VAT currently charged.