Skip to content
Fixtures and competitions

Upcoming football matches API for the next seven days

The upcoming feed answers one practical question: what is scheduled on a given day in the coming week? This page explains the offset parameter, how the feed differs from a full season schedule, and how to present matches that have not been played without implying anything about their outcome.

Primary endpoint

GET/api/v1/football/upcoming

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

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

Illustration of seven day tiles in a row with a football rolling towards the later days.
The upcoming feed is addressed by day: offset 1 is tomorrow, offset 7 is a week ahead.
01

A day-by-day look ahead

Most football products need two views of the future. One is the full season schedule for a competition, which you get from the fixtures feed with a leagueId. The other is a short, cross-competition look ahead: what is on tomorrow, what is on Saturday, which of the leagues I follow are in action this week. The upcoming feed exists for that second view. It is not tied to one competition, and it is not intended to replace a season calendar.

The feed takes a single required query parameter, offset. It is a whole number from 1 to 7, sent as a string, and it counts days after today. Offset 1 asks for tomorrow, offset 2 for the day after, and so on up to a week ahead. There is no parameter for today on this endpoint and no way to request a range in one call; a seven-day strip is seven requests. That shape is deliberate on our side: it keeps each response small and lets the gateway cache each day separately.

Today itself is better served by the score feeds, which describe match state rather than just a schedule. The usual pattern is to show upcoming days from this feed and the current day from scores or live.

02

What comes back, and what does not

Every successful JSON response from the gateway uses the same outer envelope: a data object holding the source structure, and a meta object with the feed name, a fetchedAt timestamp in UTC, the cache time in seconds and the feed qualification. The contents of data are passed through as supplied. We have not published a normalised field schema for upcoming matches, so you should inspect a real response from your own account before deciding which attributes to read.

Two conventions hold across the source structure. Identifiers are strings, and attributes that came from the source as XML-style attributes keep an at-sign prefix in their names. Keep both conventions in your storage. A team or match identifier converted to a number, or an attribute renamed to look tidier, makes it much harder to trace a problem back to what the source actually sent.

Expect missingness. A day with no covered matches can legitimately return little or nothing for your leagues, and a match listed without a confirmed kick-off time is a real state. The meta timezone note applies here as well: fetchedAt is UTC, but unzoned match dates in the source are not necessarily UTC.

A rolling seven-day windowFlow: request upcoming with offset 1 to 7, store each day under its offset and fetch date, merge by string match ID, and hand over to scores when a match day arrives.01offset=1..7one day each02Store by daywith fetchedAt03Merge by IDstring match key04Match dayswitch to scores
A rolling seven-day window. Each offset is one day ahead of today; merge days by match ID and switch to score feeds when the day arrives.
03

Building a week strip on the server

The example fetches the next seven days once on your server and writes each day to your own cache. Readers then load your cache, not the API. Doing the work server-side keeps the key private and means a thousand visitors cost you seven requests rather than seven thousand.

Notice that a failed day does not abort the others. If offset 4 returns an error, the strip can still show the other six days and a quiet note for the missing one. The error body includes a code, a message and a requestId; log the requestId so support can trace the call if you need help.

Node.js: fetch offsets 1 to 7 and cache each dayjavascript
const base = "https://footballapi.net/api/v1/football/upcoming";
const headers = { "X-API-Key": process.env.FOOTBALLAPI_KEY };

for (const offset of ["1", "2", "3", "4", "5", "6", "7"]) {
  const res = await fetch(`${base}?offset=${offset}`, { headers });
  const body = await res.json();
  if (!res.ok) {
    console.warn("upcoming", offset, body.code, body.requestId);
    continue; // keep the other days
  }
  await saveDay(offset, body); // your own cache: keep data and meta intact
}
04

Refreshing without wasting requests

The catalogue cache time for upcoming is about five minutes. Polling more often than that returns the same cached body and still counts as a successful request against your daily inclusion. For most products, refreshing the whole week a few times a day is ample, with an extra refresh on the morning of busy days when kick-off times are sometimes confirmed late.

Remember that offsets slide at midnight. What was offset 2 yesterday is offset 1 today. If you cache by offset alone, a stale cache can show Sunday's matches under Monday's heading. Store each response with the date you computed for it at fetch time, derived from fetchedAt, and render headings from that stored date rather than from the offset number.

05

Presenting matches that have not happened

A schedule is a statement of intent, not a result and not a forecast. Show teams, competition and time as supplied, and resist adding anything that implies an outcome. FootballAPI.net is a data provider rather than a bookmaker, and the upcoming feed carries no prices or probabilities. If your design has space beside each match, fill it with things that are true now: the competition, the venue if supplied, or a link to the season fixtures.

Rescheduling is common in the week before a match, particularly around televised slots and cup replays. Join everything on the string match identifier so that a time change updates an existing card instead of creating a second one, and keep the previous time if you want to tell readers a match has moved.

  • Order matches by supplied time within each competition group.
  • Label unconfirmed times as to be confirmed, not midnight.
  • Do not render scores, odds or predicted winners on upcoming cards.
  • Link each card to the season fixtures for the competition when you hold its leagueId.
06

Which today the offset counts from

Offsets are counted from today, and today is a slippery word for a global product. Your readers may be in several timezones, the source may express match dates in a timezone that is not UTC, and your server may run in yet another. The safest approach is to treat the offset as a request for the source's notion of a day ahead and to group matches on your page by the supplied match date rather than by the offset you asked for. Late-evening matches in one country can fall on the next calendar day for readers elsewhere, so a match fetched under offset 2 might belong under a different heading for some readers. Decide once which timezone your headings use, state it on the page, and apply it consistently. Our article on kick-off times walks through the trade-offs in more detail.

07

Plan scope for the upcoming feed

Upcoming is a league-filtered feed. On Starter, at EUR 29 a month, responses are filtered on our side to the five leagues you have saved, so a Starter customer following three domestic leagues and two cups sees only those five in the strip. On Growth at EUR 99 and Pro at EUR 249, responses include the competitions available in the package. Whether a particular competition appears on a particular day still depends on the source.

Seven requests a few times a day is a very small share of any plan's daily inclusion of 5,000, 25,000 or 250,000 successful requests per UTC day. Failed and denied requests are not billed, and the account safety ceiling of 100 requests per second is far above what a weekly strip needs. There is no free trial, and no VAT is currently charged.

08

Common mistakes we see

The first is sending offset 0 or a number above 7. Those are outside the accepted values and produce a 400 response, which does not count as a billed request but does leave a gap in your page. The second is sending the offset as a date. The parameter is a count of days, not a calendar value, and dates are not accepted here.

The third is treating the absence of a match as a cancellation. If a match you saw on Tuesday is missing from Wednesday's response for the same day, it may have moved outside the window, been rescheduled, or simply not appear in that response. Check the season fixtures for the competition before telling readers anything has been called off. The fourth is calling the feed from the browser, which exposes the key; keep requests on your server.

Questions developers ask

What values does offset accept?
A whole number from 1 to 7, sent as a string. It counts days after today, so 1 is tomorrow and 7 is a week ahead.
Can I request today's matches from upcoming?
No. Use the scores or live feeds for the current day; upcoming starts from tomorrow.
Can one request return the whole week?
No. Each request returns one day. A seven-day view is seven requests, ideally made on your server and cached.
Is upcoming a replacement for the fixtures feed?
No. Fixtures returns a full season schedule for one leagueId; upcoming is a short cross-competition look ahead.
Does Starter see every competition in upcoming?
No. Starter responses are filtered to your saved leagues. Growth and Pro receive the available package competitions.
Are kick-off times converted to UTC?
No. Match times are kept as supplied. Only the meta fetchedAt value is guaranteed to be UTC.

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.