Psel APIpsel.com ↗
Access sports events, real-time odds, and betting markets from Parions Sport En Ligne (FDJ) via 3 structured endpoints covering live and upcoming events.
What is the Psel API?
The Parions Sport En Ligne API gives developers structured access to sports events, betting markets, and odds from psel.com across 3 endpoints. The get_sports endpoint returns the full taxonomy of sports, categories, and competitions with their IDs. From there, search_events and get_live_events deliver upcoming and in-progress events with associated markets, outcomes, and odds — ready to filter by sport.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/cb45c7d4-f595-4c57-b39a-35101b53a751/get_sports' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace psel-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
Parions Sport En Ligne API Client
Extract sports events, odds, and betting options from FDJ.
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Optional, Dict, Any
class ParseClient:
"""Client for Parions Sport En Ligne API via Parse Bot."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: API key for Parse Bot. If not provided, reads from PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "cb45c7d4-f595-4c57-b39a-35101b53a751"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key not provided. Set PARSE_API_KEY environment variable or pass api_key parameter.")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""
Make an API call to the Parse Bot scraper.
Args:
endpoint: The endpoint name (e.g., 'get_sports')
method: HTTP method ('GET' or 'POST')
**params: Query/body parameters
Returns:
Parsed JSON response
Raises:
requests.RequestException: If the API call fails
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
try:
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params, timeout=30)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=params, timeout=30)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"API Error: {e}")
raise
def get_sports(self) -> Dict[str, Any]:
"""
Fetch list of available sports, categories, and competitions.
Returns:
Dictionary containing sports, categories, and competitions.
"""
return self._call("get_sports", method="GET")
def search_events(self, sport_id: Optional[str] = None, limit: Optional[int] = None) -> Dict[str, Any]:
"""
Search for upcoming sports events.
Args:
sport_id: Optional sport ID to filter events (e.g., '240' for Football)
limit: Optional maximum number of events to return
Returns:
Dictionary containing upcoming events with details and betting markets.
"""
params = {}
if sport_id:
params["sport_id"] = sport_id
if limit:
params["limit"] = limit
return self._call("search_events", method="GET", **params)
def get_live_events(self, limit: Optional[int] = None) -> Dict[str, Any]:
"""
Retrieve currently live sports events with their top betting markets.
Args:
limit: Optional maximum number of live events to return
Returns:
Dictionary containing live events and available betting markets.
"""
params = {}
if limit:
params["limit"] = limit
return self._call("get_live_events", method="GET", **params)
def main():
"""Demonstrate practical workflow with the API."""
# Initialize the client
client = ParseClient()
print("=" * 70)
print("PARIONS SPORT EN LIGNE - Sports Events & Betting Info")
print("=" * 70)
# Step 1: Fetch available sports and competitions
print("\n[Step 1] Fetching available sports and competitions...")
sports_data = client.get_sports()
sports_list = []
if sports_data.get("data"):
data = sports_data["data"]
if "sports" in data:
sports_list = data["sports"]
print(f"✓ Found {len(sports_list)} sports available:")
# Display available sports with their IDs
for sport in sports_list[:5]:
print(f" • {sport.get('title', 'Unknown')} (ID: {sport.get('id', 'N/A')})")
if len(sports_list) > 5:
print(f" ... and {len(sports_list) - 5} more sports")
if "competitions" in data:
competitions = data["competitions"]
print(f"\n✓ Found {len(competitions)} competitions across all sports")
else:
print("✗ No sports data available")
# Step 2: Search for upcoming events in Football
print("\n[Step 2] Searching for upcoming Football events...")
football_id = "240" # Football ID from the API spec
events_data = client.search_events(sport_id=football_id, limit=10)
if events_data.get("data") and "events" in events_data["data"]:
events = events_data["data"]["events"]
print(f"✓ Found {len(events)} upcoming Football events:")
# Display event details and betting markets
for i, event in enumerate(events[:3], 1):
print(f"\n {i}. {event.get('title', 'Unknown Event')}")
print(f" Start Time: {event.get('start_time', 'N/A')}")
print(f" League: {event.get('league', 'N/A')}")
print(f" Category: {event.get('category', 'N/A')}")
# Show available betting markets
if "markets" in event:
markets = event["markets"]
print(f" Available Markets: {len(markets)}")
for market in markets[:1]: # Show first market
print(f" • {market.get('desc', 'Market')} ({market.get('period', 'N/A')})")
# Display outcomes and odds
if "outcomes" in market:
print(f" Outcomes:")
for outcome in market["outcomes"]:
print(f" - {outcome.get('desc', 'Unknown')}: {outcome.get('price', 'N/A')}")
if len(events) > 3:
print(f"\n ... and {len(events) - 3} more Football events")
else:
print("✗ No Football events found")
# Step 3: Get live events
print("\n[Step 3] Fetching currently live events...")
live_data = client.get_live_events(limit=5)
if live_data.get("data") and "events" in live_data["data"]:
live_events = live_data["data"]["events"]
print(f"✓ Found {len(live_events)} live events:")
for i, event in enumerate(live_events[:3], 1):
print(f"\n 🔴 LIVE {i}. {event.get('title', 'Unknown')}")
print(f" Sport: {event.get('sport', 'N/A')}")
print(f" League: {event.get('league', 'N/A')}")
print(f" Start Time: {event.get('start_time', 'N/A')}")
# Show top betting markets for live events
if "markets" in event:
markets = event["markets"]
print(f" Available Markets: {len(markets)}")
for market in markets[:1]: # Show first market
print(f" • {market.get('desc', 'Market')} ({market.get('period', 'N/A')})")
# Display outcomes and odds
if "outcomes" in market:
print(f" Outcomes:")
for outcome in market["outcomes"]:
spread_info = f" (Spread: {outcome.get('spread', 0)})" if outcome.get('spread') else ""
print(f" - {outcome.get('desc', 'Unknown')}: {outcome.get('price', 'N/A')}{spread_info}")
if len(live_events) > 3:
print(f"\n ... and {len(live_events) - 3} more live events")
else:
print("✗ No live events currently available")
# Step 4: Search events by different sport (Tennis)
print("\n[Step 4] Searching for Tennis events...")
tennis_id = "239" # Tennis ID from the API spec
tennis_events = client.search_events(sport_id=tennis_id, limit=5)
if tennis_events.get("data") and "events" in tennis_events["data"]:
events = tennis_events["data"]["events"]
print(f"✓ Found {len(events)} upcoming Tennis events:")
for event in events[:2]:
print(f" • {event.get('title', 'Unknown')}")
print(f" Category: {event.get('category', 'N/A')}")
# Show if any markets have attractive odds
if "markets" in event:
for market in event["markets"]:
if "outcomes" in market:
best_odd = max(outcome.get('price', 0) for outcome in market["outcomes"])
print(f" Best Odds Available: {best_odd}")
break
else:
print("✗ No Tennis events found")
print("\n" + "=" * 70)
print("Data retrieval complete!")
print("=" * 70)
if __name__ == "__main__":
main()Fetch list of available sports, categories, and competitions from Parions Sport En Ligne. Use the returned IDs for subsequent search_events calls.
No input parameters required.
{
"type": "object",
"fields": {
"sports": "array of sport objects with id and title",
"categories": "array of category objects with id, title, and sportId",
"competitions": "array of competition objects with id, title, sportId, and categoryId"
},
"sample": {
"data": {
"sports": [
{
"id": 240,
"title": "Football"
},
{
"id": 239,
"title": "Tennis"
},
{
"id": 227,
"title": "Basketball"
}
],
"categories": [
{
"id": 58484924,
"title": "ATP",
"sportId": 239
}
],
"competitions": [
{
"id": 58531576,
"title": "Ligue 1 McDonalds",
"sportId": 240,
"categoryId": 58531496
}
]
},
"status": "success"
}
}About the Psel API
Sports Taxonomy and Navigation
The get_sports endpoint returns three parallel arrays: sports (each with an id and title), categories (with id, title, and sportId), and competitions (with id, title, sportId, and categoryId). These IDs are the entry point for all subsequent filtering — pass a sport_id to search_events to scope results. Common sport IDs include 240 for Football, 239 for Tennis, 227 for Basketball, and 22877 for Rugby.
Upcoming Events and Odds
The search_events endpoint accepts an optional sport_id string and an optional limit integer. Each event object in the events array includes id, title, start_time, sport, category, league, url, and a markets array. Each market contains outcomes with associated odds, giving you the full betting structure for a given fixture before it starts.
Live Events
The get_live_events endpoint returns in-progress events across all sports without requiring a sport filter. Each result shares the same shape as upcoming events — id, title, start_time, sport, category, league, url, and markets with real-time odds — making it straightforward to build a unified view of live and scheduled fixtures using the same response structure.
The Psel API is a managed, monitored endpoint for psel.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when psel.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official psel.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Display live odds for in-progress football or tennis matches in a betting companion app.
- Track odds movement on upcoming events by polling
search_eventswith a specificsport_idover time. - Build a fixture calendar filtered by league or competition using IDs from
get_sports. - Compare market offerings across sports by querying multiple
sport_idvalues fromsearch_events. - Monitor which sports and competitions are currently active via the
get_live_eventsresponse. - Aggregate betting market data across French sports betting to feed into odds comparison tools.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Parions Sport En Ligne have an official developer API?+
How do I filter `search_events` to a specific sport?+
sport_id parameter using an ID returned by get_sports. For example, sport_id 240 returns Football events, 239 returns Tennis, 227 Basketball, and 22877 Rugby. You can also set limit to control how many events are returned in a single response.Does `get_live_events` support filtering by sport?+
get_live_events endpoint returns live events across all sports and only accepts a limit parameter — there is no sport filter. The search_events endpoint supports sport filtering for upcoming events. You can fork this API on Parse and revise it to add sport-scoped filtering to the live events endpoint.Does the API return historical odds or past match results?+
search_events and in-progress events via get_live_events — both focused on current and future data. You can fork it on Parse and revise to add an endpoint targeting historical event data if the source exposes it.