Official Python SDK for the Owls Insight real-time sports betting odds API
Project description
Owls Insight Python SDK
Official Python SDK for the Owls Insight real-time sports betting odds API. Sync and async clients, fully typed with Pydantic v2, plus a Socket.io WebSocket client for live streams.
pip install owls-insight
Requires Python 3.9+. Get an API key at owlsinsight.com.
Quick start (sync)
from owls_insight import OwlsInsight
client = OwlsInsight(api_key="owlsinsight_...")
# REST: current NBA odds. `data` is keyed by sportsbook -> list of events.
odds = client.rest.get_odds("nba", books=["pinnacle", "fanduel"])
for book, events in odds.data.items():
for event in events:
print(book, event.home_team, "vs", event.away_team)
# WebSocket: stream live updates
client.ws.connect()
client.ws.subscribe(sports=["nba"], books=["pinnacle"])
client.ws.on("odds-update", lambda data: print("live:", data))
# or block for the next event
update = client.ws.wait_for("odds-update", timeout=15)
client.destroy()
Quick start (async)
import asyncio
from owls_insight import AsyncOwlsInsight
async def main():
async with AsyncOwlsInsight(api_key="owlsinsight_...") as client:
odds = await client.rest.get_odds("nba", books=["pinnacle"])
print(sum(len(events) for events in odds.data.values()), "games")
await client.ws.connect()
await client.ws.subscribe(sports=["nba"], books=["pinnacle"])
update = await client.ws.wait_for("pinnacle-realtime", timeout=30)
print("realtime:", update)
asyncio.run(main())
Authentication
Pass your API key to the constructor. REST uses the Authorization: Bearer header; the WebSocket uses the ?apiKey= query string. Both are handled for you.
import os
client = OwlsInsight(api_key=os.environ["OWLS_INSIGHT_API_KEY"])
REST
Method names are snake_case (the JS SDK's getOdds is get_odds here). Every method returns a typed Pydantic model; unknown fields from the evolving API are preserved (model_extra), never dropped.
Full parity with the TypeScript SDK — every endpoint is available on both client.rest (sync) and the async client.
| Area | Methods |
|---|---|
| Odds | get_odds, get_moneyline, get_spreads, get_totals, get_realtime, get_ps3838_realtime, get_esports_realtime, get_ev, list_events, get_one_x_bet_soccer, get_prophetx_odds |
| Props | get_props, get_book_props, get_props_history, get_props_stats, get_book_props_stats |
| Scores / schedule | get_scores, get_schedule, get_results, get_splits, normalize, normalize_batch |
| Stats | get_stats, get_match_stats, get_h2h, get_player_averages |
| Line history | get_odds_history, get_moneyline_history, get_spread_history, get_totals_history |
| Historical | get_history_games, get_history_odds, get_history_props, get_history_stats, get_history_tennis_stats, get_game_stats_detail, get_closing_odds, get_historical_player_props, get_public_betting, get_cs2_matches, get_cs2_match, get_cs2_players |
| v2 Source API | get_stake_v2, get_hard_rock_events/_leagues/get_hard_rock_ladder, get_bet365_v2/_leagues, get_draftkings_v2/_leagues, get_fanduel_v2/_leagues, get_mybookie_v2, get_thunderpick_v2, get_underdog_v2, get_bookmaker_v2/_leagues, get_kalshi_v2/_leagues, get_polymarket_v2/_leagues, get_pinnacle_v2/_leagues |
Methods whose response shape isn't individually modelled yet return a permissive
ApiResponseenvelope (success/data/meta, all fields preserved). Deep per-endpoint Pydantic typing is the remaining follow-on; the method surface is complete.
Hard Rock odds decoding
Hard Rock v2 selections carry a rootIdx, not inline odds. Decode it client-side:
from owls_insight import root_idx_to_american_odds
root_idx_to_american_odds(42) # -325
root_idx_to_american_odds(72) # 100 (even)
WebSocket events
odds-update, props-update (and per-book {book}-props-update), pinnacle-realtime, ps3838-realtime, esports-update, prophetx-update, and the v2 {book}-v2-update deltas.
client.ws.connect()
client.ws.subscribe(sports=["nba", "nhl"], books=["pinnacle", "fanduel"])
client.ws.subscribe_props(book="fanduel") # props stream
client.ws.update_subscription(prophetx=True) # merge, don't replace
client.ws.on("props-update", handle_props)
Errors
from owls_insight import AuthenticationError, RateLimitError, OwlsInsightError
try:
client.rest.get_odds("nba")
except AuthenticationError:
... # 401
except RateLimitError as e:
print("retry after", e.retry_after_ms, "ms")
except OwlsInsightError as e:
print(e.status, e.message)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file owls_insight-0.2.0.tar.gz.
File metadata
- Download URL: owls_insight-0.2.0.tar.gz
- Upload date:
- Size: 24.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c217443076eca7511fb2a592e912bc79acf85f5efc81107745a5fc0964542a4
|
|
| MD5 |
061cacb0e57a665d385c962ee1f4bf2d
|
|
| BLAKE2b-256 |
4ceb8eb34a72a0772e1156a40fe72c71bf6f77d61768c4bd0697754fe6a2cd0e
|
File details
Details for the file owls_insight-0.2.0-py3-none-any.whl.
File metadata
- Download URL: owls_insight-0.2.0-py3-none-any.whl
- Upload date:
- Size: 29.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
893be64d13076db616ac8802e86f042176843cfd6162852c308cc00286adb371
|
|
| MD5 |
31575c55d9ddf3168ca6d007e676c193
|
|
| BLAKE2b-256 |
5581e8d883efef370217ed73e2d7d7c65663d8c930c90066523ee17fe6d1b2b1
|