Code examples
Football API code examples for server-side integrations
Every example reads the key from FOOTBALLAPI_KEY on your server. Feed IDs shown here are illustrative; confirm the real IDs in /api/football/catalogue. Sample IDs: league 1204, team 9260, player 194646.
List feeds (public, no key)
curl --fail-with-body "https://footballapi.net/api/football/catalogue"League table
curl --fail-with-body "https://footballapi.net/api/v1/football/standings?leagueId=1204" \
-H "X-API-Key: $FOOTBALLAPI_KEY"Season fixtures
curl --fail-with-body "https://footballapi.net/api/v1/football/fixtures?leagueId=1204" \
-H "X-API-Key: $FOOTBALLAPI_KEY"Team profile
curl --fail-with-body "https://footballapi.net/api/v1/football/team?teamId=9260" \
-H "X-API-Key: $FOOTBALLAPI_KEY"Player profile
curl --fail-with-body "https://footballapi.net/api/v1/football/player?playerId=194646" \
-H "X-API-Key: $FOOTBALLAPI_KEY"Download a crest
Media routes return image bytes. Venue images take the team ID. League logos are not offered.
curl --fail "https://footballapi.net/api/football/media/teams/9260" --output crest.pngErrors and retries
At most three attempts with a 15-second timeout. Retries 429 and transient upstream errors, and stops rather than waiting more than 30 seconds.
const key = process.env.FOOTBALLAPI_KEY;
if (!key) throw new Error("Set FOOTBALLAPI_KEY on your server");
const base = process.env.API_BASE_URL || "https://footballapi.net";
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function footballGet(path, params = {}) {
const url = new URL(path, base);
for (const [name, value] of Object.entries(params)) {
url.searchParams.set(name, String(value));
}
for (let attempt = 0; attempt < 3; attempt++) {
const res = await fetch(url, {
headers: { "X-API-Key": key },
signal: AbortSignal.timeout(15000),
});
const body = await res.json(); // JSON endpoints only; not media images
if (res.ok) return body;
const retryAfter = Number(res.headers.get("Retry-After") || 0);
const transientSource = res.status === 503 &&
["provider_unavailable", "image_source_unavailable"].includes(body.code);
const retryable = res.status === 429 || transientSource;
const delay = Math.max(
Number.isFinite(retryAfter) ? retryAfter * 1000 : 0,
1000 * (2 ** attempt),
);
if (!retryable || attempt === 2 || delay > 30000) {
throw Object.assign(new Error(body.error || `HTTP ${res.status}`), {
status: res.status, code: body.code,
requestId: body.requestId, retryAfter,
});
}
await sleep(delay + Math.random() * 200);
}
}
const { meta, data } = await footballGet("/api/v1/football/standings", { leagueId: "1204" });
console.log(meta, data);