# SportyTrader Scraper - Predictions, Odds & Live Scores (`parseforge/sportytrader-scraper`) Actor

Scrape SportyTrader odds comparison, betting tips, live scores, lineups, match stats and bookmaker reviews. 13 bookmakers, 15 football markets, 18 sports. No login, no API key, no proxy.

- **URL**: https://apify.com/parseforge/sportytrader-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** AI, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

[![ParseForge](https://raw.githubusercontent.com/ParseForge/apify-assets/main/banner.jpg)](https://apify.com/parseforge?fpr=vmoqkp)

### SportyTrader Scraper - Predictions, Odds & Live Scores

**Scrape SportyTrader football predictions, odds comparison, live scores and bookmaker reviews.** Every fixture comes with up to 15 markets priced by 13 bookmakers, the best price on each outcome, the market move, lineups, match events, statistics, team form and head-to-head. 18 sports. No login, no API key, and no cookies. Runs on Apify's datacenter proxy — no residential spend. Export to CSV, JSON, Excel, or XML.

SportyTrader publishes its odds comparison and its tipsters' predictions to anonymous visitors — no account and no API key. This reads that same public feed, filters it by competition, country, team, status, price, or market, and returns each match in one flat schema.

| Who uses it | What they scrape SportyTrader for |
|---|---|
| Odds comparison sites | 13 bookmakers priced side by side on 15 markets, with the best price already flagged |
| Arbitrage and value bettors | The overround on every market, computed from the best price at each book |
| Betting modellers | Fixtures, results, team form, and closing prices in one row per match |
| Tipster and affiliate sites | SportyTrader's own pick, model probability, and written analysis per fixture |
| Bookmaker affiliates | 23 ranked bookmaker reviews with ten sub-ratings, pros and cons |

### What it does

This Actor collects public SportyTrader data from five source types — a date range, competition pages, match URLs, prediction URLs, and bookmaker or news URLs — and returns one flat row per match by default. Every match carries:

- ⚽ **The fixture:** sport, competition, country, round, both teams with their crests, kick-off date and time, and the live status.
- 📊 **The result:** running or final score, the minute with added time while in play, and the winning side.
- 💰 **The market:** best home, draw and away price, which bookmaker offers each, the average across the book, and the overround once you shop every firm.
- 🏦 **Every bookmaker:** up to 15 markets for football, each priced by up to 13 firms, with the price, the direction it last moved, and the sign-up bonus.
- 🧠 **The prediction:** SportyTrader's pick, its model's probability per outcome with the best price for each, the author, and the full written preview.
- 👥 **Lineups:** starting eleven and formation for both sides, plus substitutes and absentees grouped by position.
- ⏱️ **Match events:** goals with the running score, own goals, yellow and red cards, and substitutions naming both players.
- 📈 **Match statistics:** possession, shots, shots on target, corners, free kicks, cards, offsides, saves, clearances and substitutions.
- 🔁 **Form and history:** each side's last six results overall, at home and away, with win rate, goal averages, BTTS and over/under rates, plus the head-to-head record.

Results export to CSV, JSON, Excel, or XML, or stream from the API.

### What you can do with SportyTrader data

**🔎 Find the best price on every outcome.**

Tick `includeOdds` and each market arrives with all 13 bookmakers, the best price flagged, and `bestOddsBookPercent` — the overround left once you take the top price at each firm.

**⚖️ Screen for arbitrage and low-margin markets.**

Set `maxOverround` to 100 and only markets that pay more than they take reach your dataset. Under-100 markets do occur: the Under/Over 2.5 book on a Champions League tie measured 98.12% across 13 firms.

**📉 Watch where the money is going.**

Every price carries `movement`, the direction it last moved. Schedule the run hourly and you have a line-movement feed without diffing snapshots yourself.

**🧾 Build a predictions dataset.**

Turn on `includePrediction` and each fixture returns the pick, the model's probability per outcome, the best price for it, and who wrote it.

**🗓️ Rebuild a season.**

Results reach back about twelve months. Run a month at a time with `includeMatchEvents` and `includeMatchStats` for goal timings and shot counts alongside the closing prices.

**🏆 Track one competition or one team.**

Set `competitionNameContains` or `teamNameContains` and schedule it daily. Filters run before any detail page is fetched, so a filtered-out match costs neither a request nor a billed row.

### Why choose this scraper

| | What you get |
|---|---|
| **No login, ever** | No account, no cookies, no session to keep alive. Nothing to get banned. |
| **Datacenter proxy only** | SportyTrader's Cloudflare edge refuses Apify's own container IPs, so runs go through the shared datacenter pool. No residential spend, and it is on by default. |
| **13 bookmakers, one row** | Stake, 1xbet, Melbet, Betwinner, 22bet, Bet365, Roobet, BC Game, 888Starz, Betway, Tonybet, Betsson and Shangrila. |
| **15 football markets** | 1X2, half time, both teams to score, double chance, draw no bet, first to score, odd/even, six over/under lines, half time/full time, and correct score. |
| **Best price already flagged** | SportyTrader marks the top price per outcome itself; that flag is carried through, not recomputed and guessed. |
| **Overround per market** | The margin left after shopping every book, so value screens need no extra maths. |
| **18 sports** | Football, tennis, basketball, rugby, baseball, handball, volleyball, ice hockey, American football, futsal, cricket, MMA, boxing, cycling, golf, darts, snooker and badminton. |
| **Six row shapes** | One row per match, per bookmaker price line, per prediction, per bookmaker review, per news article, or per competition. |
| **Opt-in extras, off by default** | Odds, predictions, lineups, events, statistics, form, head-to-head and article text are each a checkbox. Leave them off and you are never billed for them. |

### How it compares

Be clear about the trade-off before you pick this one.

**This Actor covers what SportyTrader publishes.** That is a European-led odds comparison across 13 mostly international bookmakers, with the deepest coverage in football. It is not a US sportsbook feed: for DraftKings or FanDuel prices in American odds you want a scraper built on those books.

| Feature | ParseForge | piotrv1001 | seemuapps | ichigowa |
|---|---|---|---|---|
| Source | SportyTrader | BetExplorer | Mixed sportsbooks | Mixed feeds |
| Bookmakers per market | Up to 13 | Varies | Varies | Varies |
| Football markets per match | Up to 15 | Fewer | 1X2 and totals | 1X2 and totals |
| Best price flagged by the source | Yes | No | No | No |
| Overround per market | Yes | No | No | No |
| Predictions with model probabilities | Yes | No | No | No |
| Lineups, events and match statistics | Yes | No | No | No |
| Bookmaker reviews with sub-ratings | Yes | No | No | No |
| Price per 1,000 matches | $7.00 | ~$3.00 | — | — |
| Price per 1,000 matches with full odds | $11.00 | ~$11.00 | — | — |

BetExplorer is the closest comparison, and lands at the same place on price for a match with its odds attached. What the difference buys is the columns above: the source's own best-price flag, the overround, the tipsters' predictions, and the lineups, events and statistics that let the same row train a model and settle a bet.

If you only want flat price rows, `outputMode: oddsLines` bills per price line at $0.0002, which is where the per-row scrapers sit. Filter `markets` when you use it: all 15 football markets across 13 firms is about 317 lines for a single match.

### What a match row looks like

```json
{
  "recordType": "match",
  "sport": "football",
  "matchId": 8703958,
  "matchSlug": "kairat-almaty-anderlecht",
  "homeTeam": "Kairat Almaty",
  "awayTeam": "Anderlecht",
  "homeTeamLogo": "https://static.sportytrader.com/icons/foot/teams/30x30/kairat-almaty-686bbae9ebb56.webp",
  "competition": "Europa League",
  "competitionCountry": "Europe",
  "competitionId": 481,
  "round": "Playoff Round",
  "matchDate": "2026-08-20",
  "kickoffTime": null,
  "status": "finished",
  "statusLabel": "End",
  "minute": null,
  "homeScore": 0,
  "awayScore": 3,
  "winner": "away",
  "bestHomeOdds": 3.49,
  "bestDrawOdds": 3.38,
  "bestAwayOdds": 2.27,
  "mainMarketOverround": 102.29,
  "bookmakersQuoting": 13,
  "marketCount": 15,
  "markets": [
    {
      "market": "Full Time Result",
      "marketKey": "1x2.fin_match",
      "bookmakerCount": 13,
      "bestOddsBookPercent": 102.29,
      "outcomes": [
        {
          "outcome": "1",
          "outcomeKey": "odds.1.1X2",
          "bestOdds": 3.49,
          "bestBookmaker": "22bet",
          "averageOdds": 3.326,
          "quotes": [
            { "bookmaker": "Stake", "bookmakerSlug": "stake", "odds": 3.25, "movement": "up", "bonus": "€1000" },
            { "bookmaker": "1xbet", "bookmakerSlug": "1xbet", "odds": 3.49, "movement": "up", "bonus": "$200" },
            { "bookmaker": "Bet365", "bookmakerSlug": "bet365", "odds": 3.2, "movement": "up", "bonus": null }
          ]
        }
      ]
    }
  ],
  "events": [
    { "minute": 2, "addedMinute": null, "type": "goal:own-goal", "side": "away", "player": "J. Oksanen", "relatedPlayer": null, "score": "0-1" },
    { "minute": 74, "addedMinute": null, "type": "yellow-card", "side": "away", "player": "E. Llansana", "relatedPlayer": null, "score": null },
    { "minute": 84, "addedMinute": null, "type": "substitution", "side": "away", "player": "A. Bertaccini", "relatedPlayer": "D. Sikan", "score": null }
  ],
  "statistics": [
    { "name": "Possession (%)", "home": 51, "away": 49 },
    { "name": "Total shots", "home": 4, "away": 8 },
    { "name": "Shots on target", "home": 3, "away": 5 },
    { "name": "Corners", "home": 2, "away": 8 }
  ],
  "teamForm": [
    {
      "scope": "all",
      "team": "Kairat Almaty",
      "sequence": ["L", "W", "W", "L", "L", "W"],
      "wins": 3, "draws": 0, "losses": 3, "played": 6, "winPercent": 50,
      "averageTotalGoals": 1.83, "bttsPercent": 33,
      "averageGoalsScored": 1, "averageGoalsConceded": 0.83,
      "overPercent": 17, "underPercent": 83,
      "matches": [
        { "date": "2026-08-20", "competition": "Europa League", "homeTeam": "Kairat Almaty", "awayTeam": "Anderlecht", "homeScore": 0, "awayScore": 3, "result": "L" }
      ]
    }
  ],
  "oddsUrl": "https://www.sportytrader.com/en/odds/kairat-almaty-anderlecht-8703958/",
  "liveUrl": "https://www.sportytrader.com/en/results-live/kairat-almaty-anderlecht-8703958/",
  "scrapedAt": "2026-08-25T20:31:07.512Z"
}
```

Upcoming fixtures have no score, events or statistics yet, and settled matches lose their live bookmaker prices once the market closes. `kickoffTime` is empty on a finished match because SportyTrader replaces the clock with the status once a match ends, and does not publish the kick-off time on the match page either. Small leagues often publish no lineups or statistics at all. Those are the data's real state, not gaps in the parser.

### Configure the run

Drive the Actor from five source types, alone or together: a date range with a list of sports, competition pages, match URLs, prediction URLs, and bookmaker or news URLs. Filters run as each match is read, so only matches reach your dataset. With nothing set it scrapes today's and tomorrow's football. The Input tab lists every parameter.

Today's football with every bookmaker's price:

```json
{ "dateFrom": "2026-08-26", "sports": ["football"], "includeOdds": true, "maxItems": 200 }
```

One competition over a week, with predictions attached:

```json
{ "dateFrom": "2026-08-24", "dateTo": "2026-08-31", "competitionNameContains": ["Premier League"], "includeOdds": true, "includePrediction": true, "maxItems": 500 }
```

Screen for low-margin markets only:

```json
{ "dateFrom": "2026-08-26", "sports": ["football"], "includeOdds": true, "maxOverround": 101, "minBookmakerCount": 10, "maxItems": 300 }
```

A finished day with goal timings, statistics and form:

```json
{ "dateFrom": "2026-08-20", "matchStatuses": ["finished"], "includeMatchEvents": true, "includeMatchStats": true, "includeTeamForm": true, "maxItems": 300 }
```

Flat price rows for one market across every bookmaker:

```json
{ "dateFrom": "2026-08-26", "outputMode": "oddsLines", "markets": ["1x2.fin_match"], "maxItems": 2000 }
```

One team, tracked daily:

```json
{ "dateFrom": "2026-08-26", "dateTo": "2026-09-30", "teamNameContains": ["Arsenal"], "includeOdds": true, "includePrediction": true }
```

Bookmaker reviews and a prediction by URL:

```json
{ "startUrls": [
    { "url": "https://www.sportytrader.com/en/betting-sites/bet365/" },
    { "url": "https://www.sportytrader.com/en/betting-tips/lask-linz-celtic-367798/" }
  ], "includeArticleText": true }
```

### Pricing

Pay-per-event: **$0.007 per match**, plus a $0.008 fee per sport-day that actually lists fixtures and a $0.02 run-start fee. A day outside the archive, or a sport out of season, lists nothing and is not charged. Every optional block is a separate event that is charged only when you tick its checkbox **and** it returns data.

| Matches collected | Plain | With full bookmaker odds |
|---|---|---|
| 100 | $0.74 | $1.14 |
| 1,000 | $7.10 | $11.10 |
| 10,000 | $70.90 | $110.90 |

Other row shapes: bookmaker review $0.012, prediction $0.009, news article $0.006, competition $0.004, and one bookmaker price line $0.0002 in `oddsLines` mode.

Optional blocks per match: bookmaker odds $0.004, prediction $0.005, lineups $0.004, match events $0.004, match statistics $0.003, team form $0.003, head-to-head $0.003, full analysis text $0.004.

New Apify accounts start with $5 in free credit.

### Free users

Free-plan runs return up to 10 rows as a preview. [Upgrade your Apify plan](https://console.apify.com/sign-up?fpr=vmoqkp) to collect up to 1,000,000 rows per run.

### Run it

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [SportyTrader Scraper](https://apify.com/parseforge/sportytrader-scraper?fpr=vmoqkp).
3. Set `dateFrom`, pick your sports, tick the blocks you want, and click **Start**. The default 1 GB covers every block; a plain listing run is happy at 256 MB.
4. Export the results as CSV, Excel, JSON, or XML from the **Dataset** tab.

Run it programmatically through the [Apify API](https://docs.apify.com/api/v2) or the [ApifyClient](https://docs.apify.com/api/client/js) for JavaScript and Python.

### Use with AI agents (MCP)

Give an AI agent live access to betting odds and predictions through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/sportytrader-scraper"
```

Then prompt it in plain language:

- *"Pull tomorrow's Premier League fixtures and show the best price on each home win."*
- *"Which football markets today have an overround below 101 across all bookmakers?"*
- *"Get SportyTrader's prediction for the Champions League ties this week."*

Copy this into ChatGPT, Claude, or Cursor to start:

```
Use the Apify Actor "parseforge/sportytrader-scraper" to collect betting odds and predictions from SportyTrader. Input: { "dateFrom": "<YYYY-MM-DD>", "dateTo": "<YYYY-MM-DD>", "sports": ["football"], "competitionNameContains": ["<competition>"], "includeOdds": <true|false>, "includePrediction": <true|false>, "maxItems": <n> }. It returns one row per match with teams, kick-off, status, score, the best price per outcome, every bookmaker's price on up to 15 markets, and the overround. Call it with the ApifyClient and my APIFY_TOKEN.
```

### Troubleshooting

**Why am I getting no results?**

Check the date. Results reach back about twelve months; a date older than that returns nothing, because the site answers out-of-range days with its upcoming fixtures instead, and those rows are dropped rather than written under the day you asked for. Filters also stack, so a competition plus a country plus a status can leave zero matches; drop them one at a time.

**Why does a match have no odds?**

Not every fixture on the calendar gets an odds page. Small leagues and youth fixtures often appear in the live listing with no market at all, and settled matches lose their live prices once the market closes. Set `onlyWithOdds` to drop them before they are billed.

**Why is `head-to-head` empty?**

SportyTrader renders the head-to-head block on prediction and upcoming-match pages, not on finished ones. It also skips the averages when the two sides have met only once. The win share and the previous meetings still come through.

**Why did `includePrediction` return nothing for most matches?**

SportyTrader writes tips for a small slice of the calendar — roughly a dozen football fixtures a day — and gives them their own IDs. The block is charged only when a prediction is actually found, so the misses cost you nothing.

**Why fewer rows than I asked for?**

`maxItems` is a ceiling, not a target. The day may hold fewer matches than that, or your filters removed them. Widen the date range, add sports, or relax the filters.

**Why is the run slow?**

`includeOdds` fetches a separate page per match, and those pages are large. A full day of football — 93 matches — takes about 6 seconds as a plain listing, under 3 minutes with bookmaker odds, and about 5 minutes with every block turned on. Turn the blocks off for bulk listing runs.

**Why did every request fail with a 403?**

The run lost its proxy. SportyTrader is behind Cloudflare, which refuses Apify's own container IP range, so the Apify datacenter proxy must stay on — it is the default. If you switched the proxy off, or forced a group your account cannot use, every request comes back 403 and the run writes nothing. Set the proxy back to Apify Proxy with automatic groups.

**A field stopped filling.**

SportyTrader changed its public page shape. Email us with your run ID so we can update the parser.

### FAQ

| Question | Answer |
|---|---|
| Do I need a SportyTrader account or API key? | No. It reads the public site, so there is no login, cookie, or token to manage. |
| Which bookmakers are covered? | The 13 SportyTrader compares: Stake, 1xbet, Melbet, Betwinner, 22bet, Bet365, Roobet, BC Game, 888Starz, Betway, Tonybet, Betsson and Shangrila. The same set is served regardless of where you run from. |
| Which markets are covered? | Football gets up to 15: 1X2, half time, both teams to score, double chance, draw no bet, first team to score, odd/even, six over/under goal lines, half time/full time and correct score. Tennis gets up to 5: match winner, correct score, and over/under 2.5, 3.5 and 4.5 sets. Basketball gets game winner and half time. The other sports carry fewer, and a fixture only ever returns the markets its bookmakers have priced. |
| How far back do results go? | About twelve months. Fixtures run several months into the future. |
| Are the odds decimal or fractional? | Decimal, as SportyTrader serves them. `impliedProbability` is included on flat price lines. |
| What is `bestOddsBookPercent`? | The implied probabilities of the best available price on each outcome, summed. Above 100 is the margin left after shopping every book; below 100 is an arbitrage. It is computed here, and skipped for markets whose outcomes overlap, such as double chance. |
| Can I filter by bookmaker? | Yes. Set `bookmakers` and only those firms' prices are kept. |
| Is a proxy needed? | Yes, the Apify datacenter proxy, and it is on by default. SportyTrader's Cloudflare edge answers the datacenter pool but refuses the platform's own container IPs. Residential is neither needed nor recommended. |
| How many rows per run? | Free plan: 10. Paid: up to 1,000,000, bounded by what the calendar and your filters return. |
| Does it read the site in other languages? | It reads the English site, which carries the widest competition coverage. Team and competition names come through in English. |
| Is this an official SportyTrader product? | No. It is unofficial and reads only publicly available SportyTrader data. |

### Related actors

- [Sporting Life Racing Scraper](https://apify.com/parseforge/sporting-life-racing-scraper?fpr=vmoqkp): racecards, results, runners and bookmaker odds.
- [Sportsbook Review Scraper](https://apify.com/parseforge/sportsbook-review-scraper?fpr=vmoqkp): NFL, NBA and MLB odds and betting lines.
- [Action Network Scraper](https://apify.com/parseforge/action-network-scraper?fpr=vmoqkp): odds, public betting splits and sharp money.
- [Bovada Scraper](https://apify.com/parseforge/bovada-scraper?fpr=vmoqkp): live sportsbook markets and prices.
- [Reddit Posts Scraper](https://apify.com/parseforge/reddit-posts-scraper?fpr=vmoqkp): posts, scores, and comments from any subreddit.

Browse the full [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp) for more scrapers.

🆘 **Need help?** Email parseforge@protonmail.com with your run ID, your input, and what you expected.

⚠️ **Disclaimer.** This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by SportyTrader or any bookmaker named in its output. It collects only publicly available SportyTrader data. You are responsible for using the data in compliance with SportyTrader's terms and applicable laws, including GDPR, CCPA, and PIPL. Gambling carries risk; nothing here is betting advice.

# Actor input Schema

## `dateFrom` (type: `string`):

First day to scan, as YYYY-MM-DD. Leave empty for today. Results reach back about 12 months; fixtures run several months ahead.

## `dateTo` (type: `string`):

Last day to scan, as YYYY-MM-DD. Leave empty to scan only the day in Date from.

## `sports` (type: `array`):

Which sports to scan for each day in the range. Football has the deepest coverage; the smaller sports only publish fixtures in season.

## `startUrls` (type: `array`):

Any sportytrader.com URL: an odds page, a live score page, a prediction, a bookmaker review, or a news article. Each is read directly, without a date scan.

## `competitionUrls` (type: `array`):

Competition odds or live pages, for example https://www.sportytrader.com/en/odds/football/england/premier-league-49/. Every fixture listed on the page is collected.

## `outputMode` (type: `string`):

The shape of each dataset row. 'matches' returns one row per fixture, 'oddsLines' one row per bookmaker price, and the rest one row per page type.

## `competitionNameContains` (type: `array`):

Keep only matches whose competition name contains any of these, case-insensitive. Example: Premier League, Serie A.

## `countryNameContains` (type: `array`):

Keep only matches whose competition country contains any of these. Example: England, Europe, Spain.

## `teamNameContains` (type: `array`):

Keep only matches where either side's name contains any of these.

## `matchStatuses` (type: `array`):

Keep only matches in these states. Leave empty for all.

## `kickoffTimeFrom` (type: `string`):

Keep only matches kicking off at or after this time of day, as HH:MM in the site's own clock.

## `kickoffTimeTo` (type: `string`):

Keep only matches kicking off at or before this time of day, as HH:MM.

## `minHomeOdds` (type: `number`):

Keep only matches whose best home price is at least this value. Reads the odds page, so it turns on the odds fetch.

## `maxHomeOdds` (type: `number`):

Keep only matches whose best home price is at most this value.

## `minAwayOdds` (type: `number`):

Keep only matches whose best away price is at least this value.

## `maxAwayOdds` (type: `number`):

Keep only matches whose best away price is at most this value.

## `minDrawOdds` (type: `number`):

Keep only matches whose best draw price is at least this value. Markets without a draw ignore it.

## `maxDrawOdds` (type: `number`):

Keep only matches whose best draw price is at most this value.

## `maxOverround` (type: `number`):

Keep only matches whose main market, priced at the best available odds across every bookmaker, holds at most this margin. 100 means a perfectly efficient market; below 100 is an arbitrage.

## `minBookmakerCount` (type: `integer`):

Keep only matches whose main market is priced by at least this many bookmakers.

## `onlyWithOdds` (type: `boolean`):

Drop fixtures with no priced market. Not every fixture on the calendar gets an odds page.

## `onlyWithPrediction` (type: `boolean`):

Drop fixtures with no SportyTrader tip. Requires the prediction block below.

## `bookmakers` (type: `array`):

Keep prices from these bookmakers only. Example: bet365, 1xbet, Betsson. Leave empty for all.

## `markets` (type: `array`):

Keep these markets only, matched against the market key or its label. Example: 1x2.fin\_match, btts, under\_over.

## `includeOdds` (type: `boolean`):

Attach every market and every bookmaker price to the match row, with the best price, the market move, and the overround. Football fixtures carry up to 15 markets.

## `includePrediction` (type: `boolean`):

Attach SportyTrader's tip: the pick, the model probability per outcome, and the best price for each. Only a slice of fixtures gets a tip.

## `includeLineups` (type: `boolean`):

Attach the starting eleven with the formation, plus substitutes and absentees by position.

## `includeMatchEvents` (type: `boolean`):

Attach the timeline: goals with the running score, own goals, yellow and red cards, and substitutions with both players.

## `includeMatchStats` (type: `boolean`):

Attach possession, shots, shots on target, corners, fouls, cards, offsides, saves and clearances for both sides.

## `includeTeamForm` (type: `boolean`):

Attach each side's last six results overall, at home and away, with the win rate, goal averages, BTTS and over/under rates, and the fixtures behind them.

## `includeH2H` (type: `boolean`):

Attach the head-to-head win share and the previous meetings between the two sides.

## `includeArticleText` (type: `boolean`):

Attach the written preview behind a prediction, or the body of a news article.

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

Stop after this many dataset rows. Free-plan runs return up to 10 rows as a preview.

## `maxConcurrency` (type: `integer`):

How many pages to read at once. Six is the measured sweet spot; raising it does not speed the run up and costs memory.

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

SportyTrader's Cloudflare edge refuses Apify's own container IPs, so runs go through the Apify datacenter proxy by default. Residential is not needed and is not recommended.

## Actor input object example

```json
{
  "sports": [
    "football"
  ],
  "outputMode": "matches",
  "onlyWithOdds": false,
  "onlyWithPrediction": false,
  "includeOdds": false,
  "includePrediction": false,
  "includeLineups": false,
  "includeMatchEvents": false,
  "includeMatchStats": false,
  "includeTeamForm": false,
  "includeH2H": false,
  "includeArticleText": false,
  "maxItems": 100,
  "maxConcurrency": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Every collected match, price line, prediction, bookmaker review, article or competition

# 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 = {
    "sports": [
        "football"
    ],
    "outputMode": "matches",
    "maxItems": 100,
    "maxConcurrency": 6
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/sportytrader-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 = {
    "sports": ["football"],
    "outputMode": "matches",
    "maxItems": 100,
    "maxConcurrency": 6,
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/sportytrader-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 '{
  "sports": [
    "football"
  ],
  "outputMode": "matches",
  "maxItems": 100,
  "maxConcurrency": 6
}' |
apify call parseforge/sportytrader-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parseforge/sportytrader-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/b3NGrQXRfK4dbBagq/builds/WOFatddexjkYZVnDg/openapi.json
