Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse)
Pricing
from $0.80 / 1,000 results
Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse)
Collect live and prematch betting odds from 1xBet, Melbet, Linebet and Paripulse. Give it the brands and feeds you want and get one row per event with its 1X2 prices, over/under lines, teams, league and start time.
Pricing
from $0.80 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
8
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Features
Share
Sportsbook Odds Scraper: Live and Prematch Odds from 1xBet, Melbet, Linebet and Paripulse
Sportsbook Odds Scraper turns four bookmakers that run the same betting platform, 1xBet, Melbet, Linebet and Paripulse, into one clean odds feed. Get 1X2 home, draw and away prices and every over/under line for football, tennis, basketball and every other sport these bookmakers list, for both upcoming (prematch) and in-play (live) events, plus the current score once a match kicks off. Read a whole bulk feed across one or more of the four brands, or paste specific match links to fetch exactly the games you want, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- Four bookmakers, one run. 1xBet, Melbet, Linebet and Paripulse are covered together in the same call, so you can compare their prices on the same events.
- Prematch and live, your choice. Pull upcoming fixtures, in-play events with the current score, or both feeds in the same run.
- Full 1X2 and over/under pricing. Home, draw and away decimal odds, every over/under line, plus the complete flattened market list so no price is left out.
- Bulk feed or a single match. Run a broad feed across sports and leagues, or switch to URL mode and paste the exact match links you care about.
- Reads the bookmakers' own public feed. No login, no account and no bet placed, just the same odds data the site itself shows its visitors.
- Fails loud, not quiet. If every bookmaker or every pasted link comes back unreadable, the run stops with an error message instead of reporting an empty dataset as a success.
Use Cases
- Odds comparison tools: line up 1X2 and totals prices from four bookmakers side by side on the same fixture.
- Line movement tracking: schedule repeat runs and build your own time series of how a match's prices shift before kickoff.
- Live odds dashboards: feed in-play events, their current score and live prices into your own site or bot.
- Sports content and tipster sites: back match previews and picks with real, sourced pricing instead of guesses.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
recordType | "event" |
bookmaker | "linebet" |
feed | "prematch" |
eventId | "812345678" |
sport | "Football" |
league | "Sample League" |
home | "Home Team" |
away | "Away Team" |
startTime | "2026-11-08T19:00:00.000Z" |
isLive | false |
scoreHome | null |
scoreAway | null |
oddsHome | 2.05 |
oddsDraw | 3.45 |
oddsAway | 3.65 |
totals | [{"line": 2.5, "over": 1.9, "under": 1.85}] |
markets | [{"group": 1, "type": 1, "line": null, "odds": 2.05}, ...] |
url | "https://linebet.com/en/line" |
scrapedAt | "2026-11-01T09:15:00.000Z" |
matchId, kickoff, startTimestamp | same values as eventId, startTime, startTs |
country, status, score, venue, tournamentStage | "England", "scheduled", "1-0", "Sample Park", "Round 1" |
homeLogo, awayLogo | team logo URLs |
odds | {"home": 2.05, "draw": 3.45, "away": 3.65, "doubleChance": {"homeOrDraw": 1.3, "homeOrAway": 1.25, "drawOrAway": 1.7}, "btts": {"yes": 1.8, "no": 1.95}} (a market the feed does not carry is null) |
outcomes | [{"market": "Match Result (1X2)", "marketId": 1, "group": 1, "type": 1, "name": "Home Team", "line": null, "odds": 2.05}, ...] |
marketsOnFeed, totalMarketsAvailable | priced outcomes on the row, markets the bookmaker offers for the event |
Each record also carries a few secondary fields: num (the bookmaker's internal event number), sportId and leagueId (numeric ids alongside the sport and league names), startTs (the epoch-seconds version of startTime) and period (the match's current period name once play has started, for example a live match's second half; null before kickoff).
How to Use
- Pick a Collection mode: Bulk feed (reads the selected bookmakers' odds feeds) or Specific match URLs (paste individual match links).
- For Bulk feed, choose the bookmakers, the feeds (prematch, live, or both) and an optional sports filter.
- Set Max events to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
All four bookmakers, prematch, football only, capped:
{"feeds": ["prematch"],"sports": ["Football"],"maxEvents": 100}
Live odds from one bookmaker:
{"mode": "bulk","bookmakers": ["linebet"],"feeds": ["live"],"maxEvents": 50}
Two bookmakers, both feeds, tennis only:
{"bookmakers": ["1xbet", "melbet"],"feeds": ["prematch", "live"],"sports": ["Tennis"]}
Fetch one specific match by link:
{"mode": "url","eventUrls": ["https://linebet.com/en/line/football/2979441-australia-a-league-women/768728649-melbourne-city-women-newcastle-jets-women"]}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/sportsbook-odds-scraper").call(run_input={"feeds": ["prematch"], "maxEvents": 100})for event in client.dataset(run["defaultDatasetId"]).iterate_items():print(event["bookmaker"], event["home"], event["away"], event["oddsHome"], event["oddsDraw"], event["oddsAway"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/sportsbook-odds-scraper').call({ feeds: ['prematch'], maxEvents: 100 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
URL mode notes
- Default examples. If you choose URL mode and leave Match URLs untouched, the actor scrapes the two example links in the field (one event-detail API link and one bulk feed API link). Earlier versions required you to paste links first. The example event may have finished by the time you run, in which case it is skipped with a warning and the feed example still returns events.
- Supported link shapes. Match page links (
/en/line/<sport>/<league>/<event>), event-detail API links (.../LineFeed/GetGameZip?id=<event>or.../LiveFeed/GetGameZip?id=<event>), and bulk feed API links (.../main-line-feed/v3/games1x2?...for prematch,.../main-live-feed/v3/games1x2?...for live). A feed link returns that bookmaker's feed, capped by Max events. Anything else is skipped with a warning. - Mode is explicit. In
urlmode,bookmakers,feedsandeventsPerRequestare ignored;sportsstill applies as a filter, andmaxEventsstill stops the run once that many links have resolved. API callers that omitmodebut send a non-emptyeventUrlsstill get URL mode, for backward compatibility. - Full URLs only, no bare ids. The bookmaker is read from the URL's own host (1xbet.com, melbet.com, linebet.com or paripulse.com), so a bare numeric event id has no way to say which of the four brands it belongs to. Paste the full match link instead.
- Both endpoints are tried per event. A given event id only answers on one of the two backend endpoints, and nothing about the id or URL says which ahead of time, so the actor tries the prematch endpoint first, then the live one, and reports whichever answered in the
feedfield. A URL-mode fetch can therefore cost up to two requests per event. - A bad or stale link is skipped, not fatal, but a run with nothing resolved fails. An unsupported host, or an event id that is not found on either endpoint (typically because the match has finished, though a prematch link can also stop resolving once the match kicks off), is logged as a warning and skipped rather than crashing the run. If none of the pasted links resolve to a record, though, the whole run is still reported as failed rather than a quiet empty success, so paste at least one link you expect to be upcoming or in play.
- Live scores appear only once the match has kicked off. Before that,
scoreHomeandscoreAwayarenull, the same as a prematch bulk-mode row.
Caching
There is no useCache option: odds change by the second, so every run reads the feed live and a cached row would be stale by definition.
Incremental and resume mode
Turn on Incremental mode and schedule the actor from the Schedules tab: it remembers every event between runs (keyed on your bookmakers, feeds, filters and links, or on the State key you set) and labels each output row with changeType (NEW, UPDATED, REAPPEARED, UNCHANGED or EXPIRED), changedFields, firstSeenAt and lastSeenAt. Events whose odds, score and status did not change are skipped and are not charged unless you tick Also output unchanged events. scrapedAt never counts as a change; add more names to Ignore fields when detecting changes. A bulk feed is a bounded window of the bookmaker's list, so a missing event there proves nothing and bulk runs never report EXPIRED; in URL mode with match links, a pasted match whose id stops answering is reported once as EXPIRED, as a charged row. With incremental mode off the output is exactly as before. Resume from run ID skips the events an earlier run already collected, so an interrupted run does not collect or charge them twice.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | bulk | line, live and both read the prematch, live or both feeds (they set feeds). bulk reads the selected bookmakers' feeds; url fetches only the match URLs in eventUrls. |
bookmakers | array of strings | [] (means all four) | Which brands to collect: 1xbet, melbet, linebet, paripulse. Leave empty for all four. The input form pre-fills this with ["linebet"] as a starting example; that is a form prefill, not the schema default. |
feeds | array of strings | [] (falls back to ["prematch"]) | prematch = upcoming events; live = in-play events, including the current score. The input form pre-fills this with ["prematch"]. |
eventUrls | array of strings | [] | Used when mode is url; paste one or more complete match links from the supported bookmakers. The input form pre-fills one sample link as a starting example. |
sports | array of strings | [] | Keep only events whose sport name or numeric sport id matches one of these (all keeps everything). Leave empty for every sport in the feed. |
eventsPerRequest | integer | 40 | How many events each feed request asks for. The source caps this at 40; higher values are refused. |
maxEvents | integer | 0 | Stop after this many events. 0 means no limit. |
maxMatches | integer | 0 | Alias of maxEvents, used when maxEvents is 0. |
matchUrls | array of strings | [] | Alias of eventUrls; both lists are combined and switch the run to URL mode. |
leagueUrls | array of strings | [] | League filter: league page URLs or numeric league ids. Empty means every league. |
includeOutcomes | boolean | true | Adds the named outcomes array to each event. |
deepMarkets | boolean | false | In bulk mode, fetches each event's full market list with sub-games (corners, cards, halves). One extra request per event. URL mode always returns the full list. |
resumeFromRunId | string | (empty) | Run ID of an earlier run; events it already collected are skipped. |
incrementalMode | boolean | false | Label rows NEW / UPDATED / REAPPEARED and skip unchanged events. |
stateKey | string | (derived from your scope) | Name of the remembered baseline; reuse it on every scheduled run. |
emitUnchanged | boolean | false | Incremental mode only: also output unchanged events (charged rows). |
emitExpired | boolean | true | Incremental mode only: report a pasted match that stopped answering as EXPIRED (URL mode). |
ignoreFieldsForChanges | array | [] | Incremental mode only: field names that never count as a change. |
mcpConnectors | array | [] | Optional connectors that receive a summary of each event (see the MCP section). |
notionParentPageUrl | string | (empty) | Notion page for the Notion connector. |
maxNotifyListings | integer | 50 | Cap on events sent to each connector per run. |
proxy | object | (input form pre-fills the standard Apify proxy pool) | Connection settings. The standard pool is pre-selected and serves melbet, linebet and paripulse. 1xbet answers with a verification page on both the standard and the Residential pool, so it may come back empty. A bookmaker refuses some individual standard-pool connections, so a failed request is retried on fresh connections: after the first three or four standard-pool attempts of one request fail, the remaining attempts for that request (at most two) go through the Apify Residential pool on your plan, and a brand that refused every attempt is skipped for the rest of the run. A backup connection is otherwise used only when the selected proxy itself is refused, or as the last attempt of a request when Residential is the selected pool. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"recordType": "event","bookmaker": "linebet","feed": "prematch","eventId": "812345678","num": 305214,"sport": "Football","sportId": 1,"league": "Sample League","leagueId": 55210,"home": "Home Team","away": "Away Team","startTime": "2026-11-08T19:00:00.000Z","startTs": 1794164400,"period": null,"scoreHome": null,"scoreAway": null,"isLive": false,"oddsHome": 2.05,"oddsDraw": 3.45,"oddsAway": 3.65,"totals": [{ "line": 2.5, "over": 1.9, "under": 1.85 }],"markets": [{ "group": 1, "type": 1, "line": null, "odds": 2.05 },{ "group": 1, "type": 2, "line": null, "odds": 3.45 },{ "group": 1, "type": 3, "line": null, "odds": 3.65 },{ "group": 17, "type": 9, "line": 2.5, "odds": 1.9 },{ "group": 17, "type": 10, "line": 2.5, "odds": 1.85 }],"url": "https://linebet.com/en/line","scrapedAt": "2026-11-01T09:15:00.000Z"}
Plan Requirement
The standard Apify proxy pool is pre-selected and no residential plan is required: in our checks melbet, linebet and paripulse served their feeds as plain JSON through it. 1xbet answers with a verification page on both the standard and the Residential pool, so it may come back empty. A bookmaker refuses some individual standard-pool connections, so a failed request is retried on fresh connections: after the first three or four standard-pool attempts of one request fail, the remaining attempts for that request (at most two) go through the Apify Residential pool on your plan, and a brand that refused every attempt is skipped for the rest of the run. The backup connection is otherwise used only when the selected proxy itself is refused, or as the last attempt of a request when Residential is the selected pool (free Apify plans do not include residential proxies, and you can also supply your own proxy URLs). Match-page links open a block page on some brands, so the actor reads the same event through the bookmaker's event-detail API instead. A brand that answers with a verification page can still come back empty, and the run reports that clearly instead of finishing silently. Coverage is the bookmaker's own 1X2 feed, the set of main events each brand promotes for 1X2 and over/under betting, not every market buried deep in a league page. A live row is a snapshot of the moment it was collected, since odds and scores keep moving while a match is in play. The run retries a refused request on a fresh connection, and only fails if every attempt across every bookmaker or link comes back refused. This actor is informational only: it does not place bets and needs no bookmaker account.
FAQ
How much does it cost?
You pay a flat fee to start the run, plus a small per-event fee for each row written to the dataset, the same in bulk mode and URL mode. There is no separate charge for prematch versus live, and no extra toggle that adds a surcharge. The Pricing tab shows the current rates. Use Max events to cap the cost of a bulk run.
Is it legal to scrape these bookmakers?
This actor collects only publicly available odds data that these bookmakers already display to their own visitors, and it never logs in, places a bet or touches any account. You are responsible for how you use the results: check the terms that apply to you and any rules on sports betting data in your market, and get legal advice before any commercial use.
Can I track how a price changes over time?
Yes. Turn on Incremental mode and schedule repeat runs from the Schedules tab: each row says whether the event is new or updated and names the fields that moved (changedFields, for example oddsHome). Unchanged events are skipped and not charged. For a full time series, also tick Also output unchanged events or keep the datasets of each run.
Why did my run fail instead of returning an empty dataset?
If every bookmaker feed you asked for comes back unreadable, or answers with literally zero events, the run is reported as failed rather than a plain empty success, since a bookmaker's bulk feed being genuinely empty is rare and usually signals a block instead. The same applies in URL mode: if none of the pasted links resolve, whether that is an unsupported host or an event id not found on either endpoint (typically because the match already finished), the run fails. A clean empty result only happens when your sports filter excludes every event a feed actually returned. Run it again in a few minutes, or with a different link.
What happens once a match kicks off or finishes?
There is no separate status field. A prematch row simply has no score (scoreHome and scoreAway are null); a live row carries whatever current score its feed reports. Bookmakers commonly move an event from the prematch endpoint to the live one once it kicks off, but a pasted prematch link can stop resolving at that point too, not only once the match finishes; either way, once neither endpoint recognizes an event's id at all, the actor can no longer return it, so a finished match disappears from later runs rather than showing up as a "finished" record.
Can I use it with AI agents?
Yes. Call it from any Apify integration, or trigger it from your own code with the apify-client library shown above.
Send results into your apps (MCP connectors)
Optionally send a readable summary of each event into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed and the full record always stays there.
| Parameter | Type | Default | Description |
|---|---|---|---|
mcpConnectors | array | empty | Connectors to receive the events. Authorize one under Apify Settings first. Leave empty to skip. |
notionParentPageUrl | string | none | Notion page under which event pages are created. Only used by the Notion connector. |
maxNotifyListings | integer | 50 | Cap on events sent to each connector per run. |
Connector write errors never fail the run, and the actor never sees your third-party credentials.
🔗 Want more sports data?
Pair this actor with these related scrapers from the same team:
| ⚽ bet365 Odds Scraper Scrape bet365 live in-play and pre-match odds across 20+ sports. Extract fixture... | ⚽ FanDuel Odds Scraper Scrape FanDuel sportsbook odds, including moneylines, spreads, totals, player props and... |
| ⚽ SofaScore Scraper ⚽ Live Scores, Stats, Players & Odds Pull structured sports data from SofaScore across football, basketball, tennis, and 20+... | ⚽ FotMob Scraper ⚽ Match Details, Stats, Lineups & Players Pull structured football data from FotMob: match details with scores, team stats, events... |
| ⚽ OneFootball Scraper Scrape public OneFootball data including football news, upcoming fixtures, match results... | ⚽ Sportsbet AU Scraper 🏅 Sports Odds & Racing Prices Scrape sportsbet.com.au odds: events, markets, selections and prices for AFL, NRL... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.