BetML Documentation

Quick Start Guide

Get started with BetML's sports analytics API in minutes. Our platform provides enterprise-grade sports analytics and machine learning capabilities through a simple, intuitive API.

1. Get Your API Key

Sign up for a BetML account and obtain your API key from the dashboard. Your API key is used to authenticate all requests and track your usage. Keep it secure and never share it publicly.

2. Install the SDK

We provide official SDKs for Python and Node.js. Choose the one that best fits your tech stack:

# Python installation
pip install betml

# Node.js installation
npm install @betml/sdk

3. Basic Usage

Here's a complete example showing how to fetch real-time odds and set up automated trading:

# Python Example
from betml import BetML
import logging

# Initialize client with logging
logging.basicConfig(level=logging.INFO)
client = BetML(api_key="your_api_key")

# Configure market preferences
client.configure({
    "sports": ["NFL", "NBA", "MLB"],
    "markets": ["spread", "moneyline", "totals"],
    "update_interval": 1000  # ms
})

# Set up real-time odds monitoring
@client.on("odds_update")
async def handle_odds_update(data):
    # Analyze the opportunity
    analysis = await client.analyze_market({
        "event_id": data.event_id,
        "market_type": data.market_type,
        "current_odds": data.odds
    })
    
    # Execute trade if confidence is high
    if analysis.confidence > 0.85:
        trade = await client.execute_trade({
            "event_id": data.event_id,
            "side": analysis.recommended_side,
            "stake": calculate_kelly(analysis)
        })
        logging.info(f"Trade executed: {trade.id}")

# Start monitoring
client.connect()

Authentication

BetML uses API keys for authentication. Your API key should be included in the Authorization header for all requests. We use industry-standard JWT tokens for WebSocket connections.

REST API Authentication

Include your API key in the Authorization header using the Bearer scheme:

curl -H "Authorization: Bearer your_api_key" \
     https://api.betml.com/v1/odds

WebSocket Authentication

For WebSocket connections, first obtain a session token:

session = await client.create_session()
await client.connect(session_token=session.token)

API Key Security

  • Never share your API key or commit it to version control
  • Rotate keys regularly using the dashboard
  • Use environment variables to store keys securely
  • Monitor key usage in real-time through the dashboard

WebSocket Streams

Our WebSocket API provides real-time updates for odds, scores, and market movements. You can subscribe to specific markets and receive instant notifications about relevant changes.

Available Streams

  • odds_update - Real-time odds changes
  • score_update - Live game scores
  • market_update - Market status changes
  • position_update - Position value changes

Advanced WebSocket Usage

# Configure multiple stream handlers
from betml import BetML, MarketType

client = BetML(api_key="your_key")

@client.on("odds_update", markets=[MarketType.SPREAD, MarketType.TOTALS])
async def handle_odds(data):
    if data.movement > 0.5:  # Significant line movement
        await analyze_opportunity(data)

@client.on("score_update")
async def handle_score(data):
    if data.is_momentum_shift:
        await adjust_positions(data)

# Custom error handling
@client.on_error
async def handle_error(error):
    if error.is_connection_error:
        await reconnect_with_backoff()
    else:
        log_error(error)

# Start streaming with configuration
await client.connect(
    heartbeat_interval=30,
    reconnect_attempts=3,
    compression=True
)

Error Handling

Implement robust error handling to ensure your application can gracefully handle API issues, rate limits, and network problems.

Error Types

  • BetMLAuthError - Authentication issues
  • BetMLRateLimitError - Rate limit exceeded
  • BetMLValidationError - Invalid request data
  • BetMLAPIError - General API errors
  • BetMLConnectionError - Network/connection issues

Comprehensive Error Handling

from betml.exceptions import (
    BetMLAuthError,
    BetMLRateLimitError,
    BetMLConnectionError
)

async def fetch_with_retry(client, market_id):
    max_retries = 3
    retry_count = 0
    
    while retry_count < max_retries:
        try:
            return await client.get_market(market_id)
        except BetMLRateLimitError as e:
            # Handle rate limiting with exponential backoff
            await asyncio.sleep(2 ** retry_count)
            retry_count += 1
        except BetMLAuthError:
            # Authentication issues require immediate attention
            await refresh_credentials()
            retry_count += 1
        except BetMLConnectionError:
            # Network issues might be temporary
            if retry_count < max_retries - 1:
                await asyncio.sleep(1)
                retry_count += 1
            else:
                raise  # Re-raise if max retries reached
    
    raise Exception("Max retries exceeded")

Rate Limits

Understanding and properly handling rate limits is crucial for maintaining stable integration with our API.

Rate Limit Tiers

Plan Requests/min Concurrent Connections
Free 60 1
Pro 300 5
Enterprise Unlimited Unlimited

Rate Limit Headers

All API responses include rate limit information in the headers:

  • X-RateLimit-Limit: Total requests allowed
  • X-RateLimit-Remaining: Requests remaining
  • X-RateLimit-Reset: Time until limit resets (seconds)
  • X-RateLimit-Type: Current rate limit tier

Rate Limit Best Practices

from betml import BetML
import time

class RateLimitHandler:
    def __init__(self):
        self.remaining_calls = None
        self.reset_time = None

    async def make_request(self, client):
        if self.should_wait():
            wait_time = self.reset_time - time.time()
            await asyncio.sleep(wait_time)
        
        try:
            response = await client.get_odds()
            self.update_limits(response.headers)
            return response
        except BetMLRateLimitError as e:
            self.remaining_calls = 0
            self.reset_time = time.time() + e.retry_after
            raise

    def should_wait(self):
        return (self.remaining_calls is not None and 
                self.remaining_calls <= 0 and 
                self.reset_time > time.time())

    def update_limits(self, headers):
        self.remaining_calls = int(headers['X-RateLimit-Remaining'])
        self.reset_time = time.time() + int(headers['X-RateLimit-Reset'])

Data Models

Understanding our data models is crucial for effectively working with the BetML API.

Market Data Structure

{
    "event_id": "nfl_2025_sb_kc_sf",
    "sport": "NFL",
    "market_type": "spread",
    "timestamp": "2025-01-19T20:30:00Z",
    "odds": {
        "home": {
            "line": -3.5,
            "price": -110
        },
        "away": {
            "line": 3.5,
            "price": -110
        }
    },
    "metadata": {
        "venue": "Allegiant Stadium",
        "weather": {
            "temp": 72,
            "condition": "Clear"
        }
    }
}

Position Data Structure

{
    "position_id": "pos_12345",
    "market_id": "nfl_2025_sb_kc_sf",
    "side": "home",
    "stake": 1000.00,
    "entry_odds": -110,
    "current_odds": -105,
    "pnl": {
        "realized": 0.00,
        "unrealized": 45.45
    },
    "status": "open",
    "timestamp": "2025-01-19T20:35:00Z"
}