Skip to main content
GET
/
bets
/
lines
Betting Lines
curl --request GET \
  --url https://v1.basketball.sportsapipro.com/bets/lines \
  --header 'x-api-key: <api-key>'
{
  "lines": {
    "gameId": 123,
    "markets": {
      "spread": {
        "home": {
          "line": 123,
          "odds": 123
        },
        "away": {
          "line": 123,
          "odds": 123
        }
      },
      "moneyline": {
        "home": 123,
        "away": 123
      },
      "total": {
        "line": 123,
        "over": 123,
        "under": 123
      }
    }
  }
}

Overview

Returns detailed betting lines for specified games, including multiple market types such as Full Time Result (1X2), Correct Score, and more. Each line includes current odds, original odds, trend indicators, and outcome information for concluded markets.

Query Parameters

games
string
required
Comma-separated list of game IDs to retrieve betting lines for.
appTypeId
integer
Application type identifier. Auto-resolved by upstream.
langId
integer
Language identifier. Auto-resolved by upstream.
timezoneName
string
Timezone for date/time values (auto-resolved, or specify e.g., America/New_York).
All startTime fields in game data use ISO 8601 format with a dynamic timezone offset based on the resolved or specified timezone.
userCountryId
integer
User’s country for localization. Auto-resolved by upstream.

Response Structure

lines
array
Array of betting line objects.
bookmakers
array
Array of bookmaker information.
sports
array
Available sports definitions.
countries
array
Country information for competitors.
competitions
array
Competition details.
games
array
Full game details for requested games.

Common Line Types

IDNameShort NameDescription
1Full Time Result1X2Match winner (Home/Draw/Away)
126Correct Score-Exact final score prediction

Odds Trend Values

ValueMeaningDescription
1DriftingOdds have increased (less likely)
2StableOdds unchanged
3ShorteningOdds have decreased (more likely)

Example Request

curl -X GET "https://v1.football.sportsapipro.com/bets/lines?games=4609055" \
  -H "x-api-key: YOUR_API_KEY"

Example Response

{
  "lines": [
    {
      "lineId": 1622846746,
      "gameId": 4609055,
      "bookmakerId": 14,
      "lineTypeId": 1,
      "lineType": {
        "id": 1,
        "name": "Full Time Result",
        "shortName": "1X2",
        "title": "Full Time Result",
        "internalOptionType": -1
      },
      "options": [
        {
          "num": 1,
          "name": "1",
          "rate": {
            "decimal": 1.62,
            "fractional": "5/8",
            "american": "-161"
          },
          "originalRate": {
            "decimal": 1.3,
            "fractional": "3/10",
            "american": "-333"
          },
          "trend": 2,
          "isWon": true
        },
        {
          "num": 2,
          "name": "X",
          "rate": {
            "decimal": 4.2,
            "fractional": "16/5",
            "american": "+320"
          },
          "originalRate": {
            "decimal": 5.0,
            "fractional": "4/1",
            "american": "+400"
          },
          "trend": 2
        },
        {
          "num": 3,
          "name": "2",
          "rate": {
            "decimal": 5.0,
            "fractional": "4/1",
            "american": "+400"
          },
          "originalRate": {
            "decimal": 8.0,
            "fractional": "7/1",
            "american": "+700"
          },
          "trend": 2
        }
      ],
      "outcomeOptionNum": 1,
      "isConcluded": true
    },
    {
      "lineId": 1622846929,
      "gameId": 4609055,
      "bookmakerId": 14,
      "lineTypeId": 126,
      "lineType": {
        "id": 126,
        "name": "Correct Score",
        "title": "Correct Score",
        "internalOptionType": 1
      },
      "options": [
        {
          "num": 1,
          "name": "Yes",
          "rate": {
            "decimal": 8.5,
            "fractional": "15/2",
            "american": "+750"
          },
          "originalRate": {
            "decimal": 7.0,
            "fractional": "6/1",
            "american": "+600"
          },
          "trend": 2,
          "isWon": true
        }
      ],
      "internalOption": "2-0",
      "internalOptionValue": "2-0",
      "internalOptions": [2.0, 0.0],
      "outcomeOptionNum": 1,
      "isConcluded": true
    }
  ],
  "bookmakers": [...],
  "sports": [...],
  "countries": [...],
  "competitions": [...],
  "games": [...]
}

Use Cases

Display All Markets for a Game

Retrieve all available betting markets for a single game to display comprehensive odds.

Track Odds Movement

Compare rate with originalRate and use trend to show odds movement direction.

Show Settled Markets

Filter by isConcluded: true and highlight winning options using isWon: true.

Correct Score Grid

Build a score prediction grid using lines with lineTypeId: 126, grouping by internalOption.

Complete Workflow: EPL Odds Data for CLV Analysis

This section demonstrates the full workflow for fetching EPL matches and calculating Closing Line Value (CLV).

Step 1: Get EPL Match IDs

First, use /games/results to get concluded EPL matches with their game IDs:
const BASE_URL = "https://v1.football.sportsapipro.com";
const API_KEY = "YOUR_API_KEY";
const EPL_COMPETITION_ID = 7;

// Get recent EPL results
async function getEPLResults() {
  const response = await fetch(
    `${BASE_URL}/games/results?competitions=${EPL_COMPETITION_ID}&showOdds=true`,
    { headers: { "x-api-key": API_KEY } }
  );
  const data = await response.json();
  
  return data.games.map(game => ({
    id: game.id,
    home: game.homeCompetitor.name,
    away: game.awayCompetitor.name,
    score: `${game.homeCompetitor.score}-${game.awayCompetitor.score}`,
    date: game.startTime
  }));
}

Step 2: Fetch Betting Lines for Those Matches

Use the game IDs to get detailed betting lines:
// Fetch betting lines for multiple games
async function getBettingLines(gameIds) {
  const response = await fetch(
    `${BASE_URL}/bets/lines?games=${gameIds.join(',')}`,
    { headers: { "x-api-key": API_KEY } }
  );
  return response.json();
}

// Extract 1X2 closing lines
function extract1X2Lines(linesData) {
  return linesData.lines
    .filter(line => line.lineTypeId === 1 && line.isConcluded)
    .map(line => {
      const homeOpt = line.options.find(o => o.num === 1);
      const drawOpt = line.options.find(o => o.num === 2);
      const awayOpt = line.options.find(o => o.num === 3);
      
      return {
        gameId: line.gameId,
        home: {
          closing: homeOpt?.rate?.decimal,
          opening: homeOpt?.originalRate?.decimal,
          won: homeOpt?.isWon || false
        },
        draw: {
          closing: drawOpt?.rate?.decimal,
          opening: drawOpt?.originalRate?.decimal,
          won: drawOpt?.isWon || false
        },
        away: {
          closing: awayOpt?.rate?.decimal,
          opening: awayOpt?.originalRate?.decimal,
          won: awayOpt?.isWon || false
        }
      };
    });
}

Step 3: Calculate CLV for Your Model

/**
 * Calculate Closing Line Value (CLV)
 * 
 * @param {number} modelOdds - Your model's predicted odds
 * @param {number} closingOdds - The closing odds from the API
 * @returns {number} CLV percentage (positive = found value)
 */
function calculateCLV(modelOdds, closingOdds) {
  const modelProb = 1 / modelOdds;
  const closingProb = 1 / closingOdds;
  return ((modelProb - closingProb) * 100);
}

/**
 * Calculate implied probability from decimal odds
 */
function impliedProbability(decimalOdds) {
  return (1 / decimalOdds * 100);
}

/**
 * Complete EPL CLV Analysis
 */
async function analyzeEPLCLV(modelPredictions) {
  // modelPredictions: [{ gameId, homeProb, drawProb, awayProb }]
  
  // Step 1: Get EPL results
  const eplMatches = await getEPLResults();
  const gameIds = eplMatches.slice(0, 20).map(m => m.id); // Last 20 matches
  
  // Step 2: Get betting lines
  const linesData = await getBettingLines(gameIds);
  const closingLines = extract1X2Lines(linesData);
  
  // Step 3: Calculate CLV for each prediction
  const clvResults = [];
  
  for (const prediction of modelPredictions) {
    const closing = closingLines.find(l => l.gameId === prediction.gameId);
    if (!closing) continue;
    
    // Convert model probabilities to implied odds
    const modelHomeOdds = 1 / prediction.homeProb;
    const modelDrawOdds = 1 / prediction.drawProb;
    const modelAwayOdds = 1 / prediction.awayProb;
    
    clvResults.push({
      gameId: prediction.gameId,
      homeCLV: calculateCLV(modelHomeOdds, closing.home.closing),
      drawCLV: calculateCLV(modelDrawOdds, closing.draw.closing),
      awayCLV: calculateCLV(modelAwayOdds, closing.away.closing),
      actualWinner: closing.home.won ? 'home' : closing.draw.won ? 'draw' : 'away'
    });
  }
  
  return clvResults;
}

// Example usage
const myPredictions = [
  { gameId: 4609055, homeProb: 0.65, drawProb: 0.20, awayProb: 0.15 }
];

analyzeEPLCLV(myPredictions).then(results => {
  console.log("CLV Analysis Results:");
  results.forEach(r => {
    console.log(`Game ${r.gameId}:`);
    console.log(`  Home CLV: ${r.homeCLV.toFixed(2)}%`);
    console.log(`  Draw CLV: ${r.drawCLV.toFixed(2)}%`);
    console.log(`  Away CLV: ${r.awayCLV.toFixed(2)}%`);
    console.log(`  Actual Winner: ${r.actualWinner}`);
  });
});

Understanding the CLV Results

CLV Interpretation:
  • Positive CLV: Your model identified value - you predicted higher probability than the market implied at close
  • Negative CLV: The market closed with higher implied probability than your model
  • Consistent positive CLV over time (100+ bets) indicates a potentially profitable betting model
CLVInterpretationAction
> +3%Strong value foundHigh confidence bet
+1% to +3%Moderate valueStandard bet
-1% to +1%No significant edgeConsider passing
< -1%Market had better oddsReview model

Key Fields for CLV Analysis

FieldDescriptionUse Case
rate.decimalClosing odds (for concluded games)Compare to your model odds
originalRate.decimalOpening odds when market openedTrack market movement
trendDirection of odds movement (1=up, 2=stable, 3=down)Identify steam moves
isConcludedWhether game has finishedFilter for historical analysis
isWonWhether this selection wonValidate model accuracy

Notes

  • Multiple games can be queried in a single request using comma-separated IDs
  • The endpoint has built-in caching with automatic TTL management
  • For pre-match odds preview, consider using the Bets Teaser endpoint
  • Concluded markets include outcomeOptionNum to identify the winning selection
  • For CLV analysis, always use concluded games where rate represents closing odds
  • The API does not provide explicit timestamps for when odds changed - use trend for direction

Authorizations

x-api-key
string
header
required

Your SportsAPI Pro API key

Query Parameters

gameId
integer
required

Game ID

Example:

12345

Response

200 - application/json

Betting lines retrieved successfully

lines
object