# OneFootball Scraper - News, Fixtures, Results & Standings (`abotapi/onefootball-com-scraper`) Actor

Scrape public OneFootball data including football news, upcoming fixtures, match results and league tables. Get clean, structured data for teams, competitions and matches in one place.

- **URL**: https://apify.com/abotapi/onefootball-com-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OneFootball Scraper

Collect football news, fixtures, results and league tables from OneFootball,
the football app covering 750+ competitions worldwide. This actor reads the
same structured content the website itself uses, so runs are fast, cheap and
reliable: no browsers, no queues of image downloads, just compact JSON.

### What you get

Three record kinds, every row labelled with its `recordType`:

- **news** - headline, publisher, publish timestamp, preview, image and (with
  *Read full article text*) the complete article text.
- **match** - fixtures and results with home and away teams, scores where the
  match has been played, kickoff time and match status.
- **table** - league-table rows: position, movement, played, won, drawn,
  lost, goal difference and points.

### Modes

- **Competitions, teams & news feed** (search mode): list competition slugs
  (`premier-league-9`, `bundesliga-1`, `laliga-10`, `serie-a-13`,
  `ligue-1-23`...), optional team slugs (`arsenal-2`), and optionally the
  global front-page news feed. Every competition yields its news, its
  fixtures, its results and, for leagues, its table. Pick exactly the record
  kinds you want with the four toggles.
- **My own links** (links mode): paste any OneFootball page - a competition
  page (with `/fixtures`, `/results` or `/table` for just that tab), a team
  page, a match page, a news article, or the home feed. Each link is read
  exactly as pasted.

Copied slugs matter: the number at the end is the site's own id
(`bundesliga-1` is the German Bundesliga, `bundesliga-35` is Liga Portugal).
Copy links from the site rather than inventing them.

### Content language

English is the one reliably complete edition and is the default. The site
serves other languages only partially (most non-English competition and team
routes answer with no content), so no other language is offered as a
selector. Article links you paste are read in their own language when the
site serves them.

### Recurring updates and resuming

- **Continue a previous run**: paste an earlier run id to finish an
  interrupted collection without paying for the same rows twice.
- **Recurring updates**: for scheduled runs, returns only what changed -
  every row carries a `changeType` column (`NEW`, `UPDATED`, `REAPPEARED`,
  `EXPIRED`). Scores, table numbers and article text are watched, so a
  finished match or a moved table row arrives as `UPDATED`.

### Limits and billing

- `maxItems` (default 20) is the single cap that stops a run; `0` removes it.
- `maxPages` (default 0) is a runaway guard per news feed; leave it at 0.
- **Read full article text** bills one `detail-enrichment` event per
  enriched article, on top of the per-record price. Articles that fail to
  read keep their feed data and are never billed.

### Send results into your apps (MCP connectors)

Results can be piped into the apps you already use through Model Context
Protocol (MCP) connectors. Authorize a connector under Apify, Settings, API
& Integrations, then set:

- `mcpConnectors` - one or more connector names to export to.
- `notionParentPageUrl` - the Notion page under which item pages are created
  (Notion connector only).
- `maxNotifyListings` - how many items to write per connector (default 50).

The export happens after the scrape and never changes the dataset.

### Connection

The site's content API answers on the standard connection pool, so the
default works on every plan. You can paste your own connection links if your
use case needs a specific exit country.

### Output

The dataset carries one unified table (all record kinds), plus focused
views: News, Matches and League table. Every row includes `changeType`,
`changedFields`, `firstSeenAt` and `lastSeenAt` columns for recurring runs.

# Actor input Schema

## `mode` (type: `string`):

Where to collect from: the competitions, teams and news feeds you pick below, or your own OneFootball links.

## `competitions` (type: `array`):

Only read when mode = search. One entry per competition: the link slug or the full competition link, e.g. premier-league-9, bundesliga-1, laliga-10, serie-a-13, ligue-1-23. Each competition yields its news, fixtures, results and (for leagues) its table. Find slugs on any competition page link.

## `teams` (type: `array`):

Only read when mode = search. One entry per team: the link slug or the full team link, e.g. arsenal-2 or real-madrid-1915. Each team yields its news and its recent and upcoming matches.

## `includeGlobalNews` (type: `boolean`):

Only read when mode = search. Also read the site-wide front-page news feed (the latest headlines across all competitions, in the selected language).

## `urls` (type: `array`):

Only read when mode = my own links. Paste competition pages (optionally with /fixtures, /results or /table at the end), team pages, match pages, news article pages, or the home feed. Each link is read exactly as pasted; the page it names decides what is collected.

## `language` (type: `string`):

Language of the news feeds, team pages and match pages. The site serves other languages only partially, so English is the one reliably complete edition; article links you paste are read in their own language when the site serves them.

## `includeNews` (type: `boolean`):

Collect news articles from competitions, teams and the global feed.

## `includeFixtures` (type: `boolean`):

Collect upcoming matches from competitions and teams.

## `includeResults` (type: `boolean`):

Collect played matches with final scores from competitions and teams.

## `includeTable` (type: `boolean`):

Collect league-table rows (position, played, won, drawn, lost, goal difference, points) from competitions that have one.

## `fetchDetails` (type: `boolean`):

Open each news article's own page and add the full article text to the record. Off by default: a run without it is cheaper and still carries titles, previews, publishers and timestamps.

## `maxItems` (type: `integer`):

Stop after this many records across the whole run (0 = no limit; the walk then ends when the sources run out). News, matches and table rows all count.

## `maxPages` (type: `integer`):

Runaway guard: an upper bound on how many pages are read for any single news feed. Leave 0 to go as deep as the source serves, with the record cap above as the only real limit.

## `resumeFromRunId` (type: `string`):

Paste the run id (or dataset id) of an earlier run of this Actor to continue it. Records that run already returned are skipped, so an interrupted large collection can finish without paying for the same rows twice. Leave empty for a normal run.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or weekly monitoring. The first run returns everything as NEW. Later runs return only NEW, UPDATED and REAPPEARED records, each labelled in a changeType column. Scores, table numbers and article text are watched, so a match that finished or a row that moved counts as UPDATED. Leave off for a normal one-off run.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its memory stable, or to deliberately share one memory across differently configured runs. Leave empty and the memory is keyed on the run setup automatically.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return records that have not changed since the last run, labelled UNCHANGED. This returns, and bills, rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return records that were present before and are no longer found, labelled EXPIRED (for example a match or article that scrolled out of every source). Only produced when a run covered its whole setup, so a capped or continued run never reports records as gone. This returns, and bills, extra rows.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## `proxyConfiguration` (type: `object`):

Connection used for every request. The site's content API answers on the standard connection pool; a residential pool also works but costs more per byte. You can also paste your own connection links.

## Actor input object example

```json
{
  "mode": "search",
  "competitions": [
    "premier-league-9"
  ],
  "includeGlobalNews": false,
  "urls": [
    "https://onefootball.com/en/competition/premier-league-9"
  ],
  "language": "en",
  "includeNews": true,
  "includeFixtures": true,
  "includeResults": true,
  "includeTable": true,
  "fetchDetails": false,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "search",
    "competitions": [
        "premier-league-9"
    ],
    "includeGlobalNews": false,
    "urls": [
        "https://onefootball.com/en/competition/premier-league-9"
    ],
    "language": "en",
    "includeNews": true,
    "includeFixtures": true,
    "includeResults": true,
    "includeTable": true,
    "fetchDetails": false,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "maxNotifyListings": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/onefootball-com-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "search",
    "competitions": ["premier-league-9"],
    "includeGlobalNews": False,
    "urls": ["https://onefootball.com/en/competition/premier-league-9"],
    "language": "en",
    "includeNews": True,
    "includeFixtures": True,
    "includeResults": True,
    "includeTable": True,
    "fetchDetails": False,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "maxNotifyListings": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/onefootball-com-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "search",
  "competitions": [
    "premier-league-9"
  ],
  "includeGlobalNews": false,
  "urls": [
    "https://onefootball.com/en/competition/premier-league-9"
  ],
  "language": "en",
  "includeNews": true,
  "includeFixtures": true,
  "includeResults": true,
  "includeTable": true,
  "fetchDetails": false,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/onefootball-com-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/onefootball-com-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/R4oZXbbJHaCnWSpne/builds/9PPtUXyRHb069OEjS/openapi.json
