StakeAPI Client

The main async client class — your entry point for every Stake.com API call.

Overview

StakeAPI is the central class of this library. It manages the HTTP session, authentication headers and cookies, Cloudflare bypass, rate-limiting, and exposes every high-level method for casino games, sports events, user data, and betting.

All public methods are async and must be awaited inside an async function.

Import:

from stakeapi import StakeAPI

Constructor

StakeAPI(
    access_token: Optional[str] = None,
    session_cookie: Optional[str] = None,
    cf_clearance: Optional[str] = None,
    user_agent: Optional[str] = None,
    base_url: str = "https://stake.com",
    timeout: int = 30,
    rate_limit: int = 10,
)

Parameters

ParameterTypeDefaultDescription
access_tokenOptional[str]NoneYour Stake.com x-access-token header value. Required for account-specific methods.
session_cookieOptional[str]NoneValue of the session cookie from your browser. Alternative or complement to access_token.
cf_clearanceOptional[str]NoneValue of the cf_clearance cookie. Required to bypass Cloudflare protection.
user_agentOptional[str]NoneThe exact User-Agent string from the browser session that generated cf_clearance. Must match.
base_urlstr"https://stake.com"Base URL for all requests. Change only for testing or proxy use.
timeoutint30Per-request timeout in seconds. Increase for slow connections.
rate_limitint10Maximum requests per second before throttling kicks in.

Cloudflare: Stake.com is protected by Cloudflare. Without a valid cf_clearance cookie you will receive 403 Forbidden on most endpoints. See Authentication for how to obtain it.

Full Example

import asyncio
from stakeapi import StakeAPI

async def main():
    client = StakeAPI(
        access_token="your_x_access_token",
        session_cookie="your_session_cookie",
        cf_clearance="your_cf_clearance_cookie",
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
        timeout=60,
        rate_limit=5,
    )
    balance = await client.get_user_balance()
    await client.close()

asyncio.run(main())

Async Context Manager

The recommended way to use StakeAPI is as an async context manager. It automatically creates and closes the HTTP session for you.

async with StakeAPI(
    access_token="your_token",
    cf_clearance="your_cf_clearance",
    user_agent="your_user_agent",
) as client:
    balance = await client.get_user_balance()
    profile = await client.get_user_profile()
# Session is closed automatically here — no need to call client.close()

__aenter__(self)

Creates the internal aiohttp.ClientSession with all configured headers and cookies, then returns self.

__aexit__(self, exc_type, exc_val, exc_tb)

Gracefully closes the session. Called automatically at the end of an async with block, even if an exception occurred.


Session Management

_create_session()

async def _create_session(self) -> None

Creates the aiohttp.ClientSession with the following headers pre-populated:

HeaderValue
User-AgentProvided value or sensible Chrome/Windows default
Acceptapplication/graphql+json, application/json
Content-Typeapplication/json
Originhttps://stake.com
Refererhttps://stake.com/
X-Languageen
X-Access-TokenYour access_token (if provided)

Cookies session and cf_clearance are injected at the session level so they are sent with every request automatically.

You do not normally need to call this method directly — it is called automatically on first use or by __aenter__.


close()

async def close(self) -> None

Close the underlying HTTP session and free resources.

client = StakeAPI(access_token="token", cf_clearance="...")
try:
    balance = await client.get_user_balance()
finally:
    await client.close()

Prefer the async with pattern over manual close() calls — it is safer and more concise.


Casino Methods

get_casino_games(category=None)

async def get_casino_games(
    self,
    category: Optional[str] = None
) -> List[Game]

Fetch the list of casino games available on Stake.com, optionally filtered by category.

Parameters:

ParameterTypeDefaultDescription
categoryOptional[str]NoneCategory slug to filter by, e.g. "slots", "live", "table"

Returns: List[Game] — Each item is a Game object.

Raises: StakeAPIError, AuthenticationError

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    # Get all games
    all_games = await client.get_casino_games()
    print(f"Total games: {len(all_games)}")

    # Filter to slots only
    slots = await client.get_casino_games(category="slots")
    for game in slots[:5]:
        print(f"  {game.name} ({game.provider}) — RTP: {game.rtp}%")

get_game_details(game_id)

async def get_game_details(self, game_id: str) -> Game

Fetch full details for a single casino game by its ID.

Parameters:

ParameterTypeDescription
game_idstrThe unique game identifier (e.g. "plinko", "dice")

Returns: Game — A fully populated Game object.

Raises: GameNotFoundError if the game ID does not exist, StakeAPIError for other errors.

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    game = await client.get_game_details("plinko")
    print(f"Name: {game.name}")
    print(f"Provider: {game.provider}")
    print(f"RTP: {game.rtp}%")
    print(f"Min bet: {game.min_bet} / Max bet: {game.max_bet}")
    print(f"Volatility: {game.volatility}")
    print(f"Features: {', '.join(game.features)}")

Sports Methods

get_sports_events(sport=None)

async def get_sports_events(
    self,
    sport: Optional[str] = None
) -> List[SportEvent]

Fetch live and upcoming sports events, optionally filtered by sport.

Parameters:

ParameterTypeDefaultDescription
sportOptional[str]NoneSport slug to filter by, e.g. "football", "basketball", "tennis"

Returns: List[SportEvent] — Each item is a SportEvent object.

Raises: StakeAPIError, AuthenticationError

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    # All available events
    events = await client.get_sports_events()

    # Football only
    football = await client.get_sports_events(sport="football")
    for event in football:
        print(f"{event.home_team} vs {event.away_team}")
        print(f"  League: {event.league}")
        print(f"  Starts: {event.start_time}")
        print(f"  Live: {event.live}")
        print(f"  Odds: {event.odds}")

User Methods

get_user_profile()

async def get_user_profile(self) -> User

Fetch the authenticated user’s profile information.

Returns: User object with id, username, email, verified, created_at, country, and currency.

Raises: AuthenticationError if not authenticated.

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    user = await client.get_user_profile()
    print(f"Username:  {user.username}")
    print(f"ID:        {user.id}")
    print(f"Verified:  {user.verified}")
    print(f"Country:   {user.country}")
    print(f"Currency:  {user.currency}")
    print(f"Joined:    {user.created_at.strftime('%Y-%m-%d')}")

get_user_balance()

async def get_user_balance(self) -> Dict[str, Dict[str, float]]

Fetch the user’s wallet balances across all currencies using the GraphQL API. Returns both the spendable (available) amount and the locked (vault) amount separately.

Returns:

{
    "available": {
        "btc":  0.00104200,
        "eth":  0.05000000,
        "usdt": 150.00,
        "ltc":  0.0,
        # ... one key per currency with a non-zero balance
    },
    "vault": {
        "btc":  0.01000000,
        "eth":  0.0,
        "usdt": 0.0,
    }
}

Raises: AuthenticationError if the session is not authenticated.

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    balance = await client.get_user_balance()

    print("=== Available ===")
    for currency, amount in balance["available"].items():
        if amount > 0:
            print(f"  {currency.upper()}: {amount:.8f}")

    print("=== Vault ===")
    for currency, amount in balance["vault"].items():
        if amount > 0:
            print(f"  {currency.upper()}: {amount:.8f}")

This method uses the UserBalances GraphQL query under the hood. See GraphQL Queries for the raw query.


Betting Methods

place_bet(bet_data)

async def place_bet(self, bet_data: Dict[str, Any]) -> Bet

Place a bet on a casino game or sports event.

Parameters:

ParameterTypeDescription
bet_dataDict[str, Any]Dictionary containing all bet fields required by the endpoint

Returns: Bet object with the placed bet’s ID, status, and payout information.

Raises: InsufficientFundsError, ValidationError, AuthenticationError, StakeAPIError

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    bet = await client.place_bet({
        "game_id": "dice",
        "amount": 0.00001,
        "currency": "btc",
        "target": 50.0,   # example field — varies by game
    })
    print(f"Bet ID:     {bet.id}")
    print(f"Amount:     {bet.amount}")
    print(f"Potential:  {bet.potential_payout}")
    print(f"Status:     {bet.status}")

Always validate amounts with validate_bet_amount() before calling this method to avoid unnecessary API errors.


get_bet_history(limit=50)

async def get_bet_history(self, limit: int = 50) -> List[Bet]

Retrieve the authenticated user’s recent bet history.

Parameters:

ParameterTypeDefaultDescription
limitint50Maximum number of bets to return. Higher values may be slower.

Returns: List[Bet] — Most recent bets first.

Raises: AuthenticationError, StakeAPIError

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    bets = await client.get_bet_history(limit=100)

    wins   = [b for b in bets if b.status == "won"]
    losses = [b for b in bets if b.status == "lost"]

    print(f"Last {len(bets)} bets:")
    print(f"  Won:  {len(wins)}")
    print(f"  Lost: {len(losses)}")
    if bets:
        win_rate = len(wins) / len(bets) * 100
        print(f"  Win rate: {win_rate:.1f}%")

Internal / Low-Level Methods

These methods are used internally but are also useful for advanced users who need to make custom requests.

_graphql_request(query, variables=None, operation_name=None)

async def _graphql_request(
    self,
    query: str,
    variables: Optional[Dict[str, Any]] = None,
    operation_name: Optional[str] = None
) -> Dict[Any, Any]

Send a raw GraphQL request to /_api/graphql. Automatically handles authentication headers, checks for errors in the response, and returns the data field.

Parameters:

ParameterTypeDefaultDescription
querystrGraphQL query or mutation string
variablesOptional[Dict]NoneVariables dict for parameterised queries
operation_nameOptional[str]NoneOptional operation name sent in the payload

Returns: The data key of the GraphQL response as a dict.

Raises: StakeAPIError if the response contains a errors key.

async with StakeAPI(access_token="...", cf_clearance="...") as client:
    data = await client._graphql_request(
        query="""
          query UserProfile {
            user { id name email }
          }
        """,
        operation_name="UserProfile",
    )
    print(data["user"]["name"])

_request(method, endpoint, params=None, data=None)

async def _request(
    self,
    method: str,
    endpoint: str,
    params: Optional[Dict] = None,
    data: Optional[Dict] = None,
) -> Dict[Any, Any]

Make a raw authenticated HTTP request.

Parameters:

ParameterTypeDescription
methodstrHTTP verb: "GET", "POST", "PUT", "DELETE"
endpointstrPath relative to base_url, e.g. "/_api/graphql"
paramsOptional[Dict]URL query parameters
dataOptional[Dict]JSON request body (serialised automatically)

Raises:

StatusException
401AuthenticationError
403StakeAPIError (Cloudflare block)
429RateLimitError
4xx/5xxStakeAPIError
Network errorStakeAPIError

Complete Working Example

import asyncio
from stakeapi import StakeAPI
from stakeapi.utils import format_currency
from decimal import Decimal

async def main():
    async with StakeAPI(
        access_token="YOUR_ACCESS_TOKEN",
        cf_clearance="YOUR_CF_CLEARANCE",
        user_agent="YOUR_USER_AGENT",
    ) as client:

        # Profile
        user = await client.get_user_profile()
        print(f"Logged in as: {user.username}")

        # Balance
        balance = await client.get_user_balance()
        for currency, amount in balance["available"].items():
            if amount > 0:
                print(f"  {currency.upper()}: {amount:.8f}")

        # Casino games
        games = await client.get_casino_games(category="slots")
        print(f"\nSlots available: {len(games)}")

        # Bet history
        bets = await client.get_bet_history(limit=20)
        won = sum(1 for b in bets if b.status == "won")
        print(f"\nLast 20 bets — Won: {won}, Lost: {len(bets) - won}")

asyncio.run(main())

See Also