Asian Handicap API: Cross-Book AH Odds from Singbet, Pinnacle & 50+ Bookmakers

Asian Handicap API - OddsPapi API Blog
How To Guides April 3, 2026

Most Odds APIs Flatten Your Asian Handicap Data. Here’s One That Doesn’t.

If you’ve tried pulling Asian Handicap data from a generic odds API, you’ve hit this problem: the API returns “spread” as a single market. AH -0.25 and AH -0.75 — fundamentally different bets with different settlement mechanics — get collapsed into the same bucket. Quarter-goal granularity? Gone. Split-stake logic? Ignored.

This is useless if you’re building an AH pricing model, a cross-book arb scanner, or a line movement tracker that needs to compare Singbet’s AH -0.5 against Pinnacle’s AH -0.5 on the same match.

OddsPapi treats each Asian Handicap line as a distinct market ID. AH -0.5 is market 1068. AH -0.25 is market 1070. AH 0 (Draw No Bet) is market 1072. You query by market ID, you get back prices from every bookmaker that offers that exact line — Singbet, Pinnacle, Betfair Exchange, and 50+ others. No flattening, no guessing.

Already familiar with Singbet specifically? Check out our Singbet API guide for a single-bookmaker deep dive. This post goes wider: cross-book AH scanning, arb detection, and why native market structures matter for serious AH trading.

Why Generic Odds APIs Break Asian Handicap

Three failure modes kill AH data quality in most odds APIs:

1. Flattened Markets

Most APIs return Asian Handicap as a single “spread” or “handicap” market. But AH -0.25 is a split-stake bet (50% on AH 0, 50% on AH -0.5). AH -0.75 is a different split (50% on AH -0.5, 50% on AH -1). These have completely different risk profiles and settlement rules. Collapsing them into one market means your model can’t distinguish between them — and your arb scanner misses opportunities that exist on specific lines.

2. Missing Sharp Books

The books that actually set Asian Handicap lines — Singbet (Crown), SBOBet, Pinnacle — aren’t available on APIs that only cover 40 bookmakers. Without sharp book prices, you have no benchmark. You’re comparing soft-book AH lines against other soft-book AH lines, which tells you nothing about true market price.

3. No Historical AH Data

Backtesting an AH model requires historical prices per handicap line — not just “what was the spread?” but “what was the AH -0.25 price at Singbet vs Pinnacle 2 hours before kickoff?” Most APIs either don’t offer historical data or charge $79+/month as an add-on. OddsPapi includes historical odds on the free tier.

Asian Handicap Data: OddsPapi vs Alternatives

Feature Scraping The Odds API Enterprise Feeds OddsPapi
AH lines as individual markets Depends on source No (flattened) Yes Yes (market IDs 1064-1076)
Quarter-goal handicaps Depends on source No Yes Yes (-0.25, -0.75, +0.25)
Singbet coverage Requires agent No $50K+/yr Free tier
Pinnacle coverage Blocked No Yes Free tier
Betfair Exchange API access needed No Varies Free tier
Books with AH data 1-3 ~10 Varies 50+
Historical AH lines No $79/mo add-on Yes Free tier
Real-time updates Minutes (scrape delay) Seconds Yes WebSocket available
Price Free + legal risk $79/mo $50K+/yr Free tier available

Asian Handicap Market IDs: The Complete Reference

OddsPapi assigns each Asian Handicap line its own market ID. This isn’t a quirk — it reflects how Asian bookmakers actually structure these markets. Each line is a separate bet with separate liquidity, separate pricing, and (for quarter-goals) separate settlement logic.

Market Market ID What It Means Books Offering*
AH -1 1064 Home team starts -1 goal 24+
AH -0.75 1066 Split: 50% on AH -0.5, 50% on AH -1 24+
AH -0.5 1068 Home team starts -0.5 goals (no push possible) 46+
AH -0.25 1070 Split: 50% on AH 0, 50% on AH -0.5 22+
AH 0 1072 Draw = push (same as Draw No Bet) 18+
AH +0.25 1074 Split: 50% on AH 0, 50% on AH +0.5 17+
AH +0.5 1076 Away team starts +0.5 goals 23+

*Typical coverage for a Premier League fixture. Bookmaker count varies by match.

Each market contains two outcomes: one for the home team, one for the away team. The outcome IDs follow a simple pattern — the home outcome ID matches the market ID, and the away outcome ID is the market ID + 1.

# Odds path for AH -0.5 (market 1068):
home_price = odds["bookmakerOdds"]["singbet"]["markets"]["1068"]["outcomes"]["1068"]["players"]["0"]["price"]
away_price = odds["bookmakerOdds"]["singbet"]["markets"]["1068"]["outcomes"]["1069"]["players"]["0"]["price"]

These market IDs are for soccer (sportId: 10). Basketball, tennis, and other sports have Asian Handicap markets with different IDs but the same API structure — query by market ID, parse outcomes the same way.

Python Tutorial: Compare Asian Handicap Odds Across 50+ Bookmakers

This tutorial pulls AH odds from every bookmaker for a fixture and compares them side by side. Unlike single-bookmaker guides, the value here is cross-book comparison — finding which book offers the best price on each AH line.

Step 1: Setup and Configuration

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"

# Asian Handicap market IDs (soccer)
AH_MARKETS = {
    "1064": "AH -1",    "1066": "AH -0.75", "1068": "AH -0.5",
    "1070": "AH -0.25", "1072": "AH 0",
    "1074": "AH +0.25", "1076": "AH +0.5"
}

# Sharp books to highlight in comparisons
SHARP_BOOKS = ["singbet", "pinnacle", "betfair-ex"]

def api_get(endpoint, **params):
    """Make an authenticated API call."""
    params["apiKey"] = API_KEY
    response = requests.get(f"{BASE_URL}/{endpoint}", params=params)
    response.raise_for_status()
    return response.json()

Step 2: Get a Fixture

# Fetch Premier League fixtures with odds
fixtures = api_get("fixtures", tournamentId=17, hasOdds="true")

fixture = fixtures[0]
fixture_id = fixture["fixtureId"]
home = fixture["participant1Name"]
away = fixture["participant2Name"]
print(f"{home} vs {away}")

# Fetch odds for this fixture
odds = api_get("odds", fixtureId=fixture_id)
bookmaker_odds = odds["bookmakerOdds"]
print(f"Bookmakers with odds: {len(bookmaker_odds)}")

Step 3: Cross-Book AH Scanner

This is the core script. For each AH line, it scans every bookmaker and finds the best available price — the line shopping use case that makes 50+ bookmakers valuable.

def scan_ah_lines(bookmaker_odds):
    """Scan all bookmakers for each AH line, find best prices."""
    results = {}

    for market_id, label in AH_MARKETS.items():
        home_oid = market_id                 # e.g. "1068"
        away_oid = str(int(market_id) + 1)   # e.g. "1069"

        best_home = {"price": 0, "book": ""}
        best_away = {"price": 0, "book": ""}
        book_count = 0

        for slug, bookie in bookmaker_odds.items():
            markets = bookie.get("markets", {})
            if market_id not in markets:
                continue

            outcomes = markets[market_id]["outcomes"]
            hp = outcomes.get(home_oid, {}).get("players", {}).get("0", {}).get("price", 0)
            ap = outcomes.get(away_oid, {}).get("players", {}).get("0", {}).get("price", 0)

            if not hp or not ap:
                continue

            book_count += 1
            if hp > best_home["price"]:
                best_home = {"price": hp, "book": slug}
            if ap > best_away["price"]:
                best_away = {"price": ap, "book": slug}

        results[label] = {
            "best_home": best_home,
            "best_away": best_away,
            "books": book_count
        }

    return results

# Run the scanner
results = scan_ah_lines(bookmaker_odds)

print(f"\n{'Line':<12} {'Best Home':<20} {'Price':>7}   {'Best Away':<20} {'Price':>7}   {'Books':>5}")
print("-" * 85)

for label, data in results.items():
    bh = data["best_home"]
    ba = data["best_away"]
    if bh["price"] > 0:
        print(f"{label:<12} {bh['book']:<20} {bh['price']:>7.3f}   {ba['book']:<20} {ba['price']:>7.3f}   {data['books']:>5}")

Sample output for a Premier League fixture:

Line         Best Home            Price   Best Away            Price   Books
-------------------------------------------------------------------------------------
AH -1        kaiyun               2.510   singbet              1.610      24
AH -0.75     kaiyun               2.080   188bet               1.840      24
AH -0.5      balkanbet.rs         1.850   188bet               2.060      46
AH -0.25     betfair-ex           1.610   pinnacle             2.440      22
AH 0         betfair-ex           1.390   betfair-ex           3.370      18
AH +0.25     betfair-ex           1.320   betfair-ex           3.910      17
AH +0.5      betfair-ex           1.270   betfair-ex           4.460      23

Notice how the best price shifts between bookmakers depending on the AH line. AH -1 home is best at kaiyun, but AH -0.5 home is best at balkanbet.rs. This is why you need cross-book scanning — no single bookmaker consistently offers the best price across all AH lines.

Step 4: Sharp Book Comparison

The scanner above finds the best prices overall. But for model building, you care about sharp book prices specifically — they represent the most efficient market. Here’s how to compare Singbet vs Pinnacle vs Betfair Exchange on a specific AH line:

def compare_sharps(bookmaker_odds, market_id="1068"):
    """Compare sharp bookmaker prices on a specific AH line."""
    label = AH_MARKETS.get(market_id, market_id)
    home_oid = market_id
    away_oid = str(int(market_id) + 1)

    print(f"\n=== Sharp Comparison: {label} ===")
    print(f"{'Bookmaker':<20} {'Home':>8} {'Away':>8} {'Margin':>8}")
    print("-" * 46)

    for slug in SHARP_BOOKS:
        if slug not in bookmaker_odds:
            continue
        market = bookmaker_odds[slug].get("markets", {}).get(market_id, {})
        if not market:
            continue
        outcomes = market["outcomes"]
        hp = outcomes.get(home_oid, {}).get("players", {}).get("0", {}).get("price", 0)
        ap = outcomes.get(away_oid, {}).get("players", {}).get("0", {}).get("price", 0)
        if hp and ap:
            margin = ((1/hp + 1/ap) - 1) * 100
            print(f"{slug:<20} {hp:>8.3f} {ap:>8.3f} {margin:>7.2f}%")

compare_sharps(bookmaker_odds)

Output:

=== Sharp Comparison: AH -0.5 ===
Bookmaker                Home     Away   Margin
----------------------------------------------
singbet              1.810    2.099    2.89%
pinnacle             1.813    2.050    3.94%
betfair-ex           1.840    2.140    1.08%

Betfair Exchange has the lowest margin (1.08%) because it’s a peer-to-peer exchange. Pinnacle at 3.94% is still tighter than most soft books (5-8%). Singbet sits between them — typical for Asian sharps.

Asian Handicap Arbitrage Scanner

Cross-book AH data makes arbitrage scanning trivial. For each AH line, find the best home price at one bookmaker and the best away price at another. If the combined implied probability is less than 100%, it’s an arb.

def find_ah_arbs(bookmaker_odds, min_margin=0.5):
    """Find arbitrage opportunities across AH lines."""
    arbs = []

    for market_id, label in AH_MARKETS.items():
        home_oid = market_id
        away_oid = str(int(market_id) + 1)

        best_home = {"price": 0, "book": ""}
        best_away = {"price": 0, "book": ""}

        for slug, bookie in bookmaker_odds.items():
            markets = bookie.get("markets", {})
            if market_id not in markets:
                continue

            outcomes = markets[market_id]["outcomes"]
            hp = outcomes.get(home_oid, {}).get("players", {}).get("0", {}).get("price", 0)
            ap = outcomes.get(away_oid, {}).get("players", {}).get("0", {}).get("price", 0)

            if hp and hp > best_home["price"]:
                best_home = {"price": hp, "book": slug}
            if ap and ap > best_away["price"]:
                best_away = {"price": ap, "book": slug}

        if best_home["price"] > 0 and best_away["price"] > 0:
            implied = (1 / best_home["price"]) + (1 / best_away["price"])
            margin = (1 - implied) * 100

            if margin >= min_margin:
                arbs.append({
                    "line": label,
                    "home_book": best_home["book"],
                    "home_price": best_home["price"],
                    "away_book": best_away["book"],
                    "away_price": best_away["price"],
                    "margin": margin
                })

    return arbs

# Scan for arbs
arbs = find_ah_arbs(bookmaker_odds)

if arbs:
    print(f"\n{'Line':<12} {'Home Book':<20} {'Home':>7} {'Away Book':<20} {'Away':>7} {'Margin':>7}")
    print("-" * 80)
    for a in arbs:
        print(f"{a['line']:<12} {a['home_book']:<20} {a['home_price']:>7.3f} {a['away_book']:<20} {a['away_price']:>7.3f} {a['margin']:>6.2f}%")
else:
    print("No AH arbitrage opportunities found at this moment.")

Real arbs on Asian Handicap lines are rare on the main lines (AH -0.5, AH 0) because sharp books keep them tight. They’re more common on quarter-goal lines (AH -0.25, AH -0.75) where soft books are slower to adjust, and on less popular leagues where bookmaker coverage is thinner. The key is scanning continuously — arb windows open and close in minutes.

For a full multi-market arb bot with stake calculation, see our arbitrage betting bot tutorial.

What Sharp Bettors Build with AH Data

AH Pricing Models

Use Pinnacle’s AH line as the efficient market price. Model deviations at soft bookmakers — if Pinnacle has AH -0.5 at 1.81 and a soft book has 1.90, that’s a 5% edge. The per-line market IDs make this clean: query market 1068, compare Pinnacle vs the field.

Cross-Market Arbitrage

AH at an Asian sharp vs moneyline at a US sportsbook creates natural arb windows because the market structures are different. A US book pricing “Team A -1 spread” is making a different bet than an Asian book pricing “AH -1” with push rules. Different structures, different pricing inefficiencies.

CLV (Closing Line Value) Tracking

Beating Singbet’s closing AH line is the gold standard for measuring edge. If you consistently get better prices than where Singbet closes, you’re confirmed profitable long-term. OddsPapi’s free historical data lets you pull closing lines after matches settle — no paid add-on required.

Line Movement Signals

In AH markets, Singbet moves first. Pinnacle follows within minutes. Soft books lag by 10-30 minutes. That lag is your edge window. A real-time line monitor watching Singbet’s AH prices can alert you before soft books catch up. For production use, OddsPapi’s WebSocket API pushes updates in real time instead of polling.

Want to build a full scanner? See our value betting scanner tutorial which uses Pinnacle as the benchmark across all market types.

Frequently Asked Questions

What is a quarter-goal Asian Handicap?

A quarter-goal AH (e.g., -0.25 or -0.75) is a split-stake bet. AH -0.25 means half your stake goes on AH 0 (Draw No Bet) and half on AH -0.5. If the home team wins by exactly one goal, you win half and push half. This creates more granular pricing than whole or half-goal lines, which is why Asian sharps like Singbet specialize in them. In the OddsPapi API, each quarter-goal line has its own market ID — AH -0.25 is 1070, AH -0.75 is 1066.

How do I get Asian Handicap odds via API?

Sign up for a free OddsPapi API key, then query the /odds endpoint with the fixture ID. Each AH line has a dedicated market ID (1064-1076 for soccer). Pass the market IDs you want as the marketIds parameter, or omit it to get all markets. Authentication uses a query parameter: ?apiKey=YOUR_KEY — not a header.

Which bookmakers are best for Asian Handicap?

Singbet (Crown) is the primary Asian Handicap market maker — they set the lines that other books follow. Pinnacle is the global sharp benchmark with the lowest margins. Betfair Exchange often offers the tightest prices due to zero-margin peer-to-peer matching. All three are available through OddsPapi’s free tier, alongside 50+ other bookmakers that offer AH markets.

Does OddsPapi support live Asian Handicap odds?

Yes. Use the REST API to poll for current AH prices on in-play fixtures, or upgrade to WebSocket for real-time push updates. Live AH markets are particularly active in soccer, where in-play handicap lines shift with every goal and red card.

Can I get historical Asian Handicap data?

Yes, historical odds are included on OddsPapi’s free tier. You can pull historical AH prices per market ID to backtest models, track closing line value, or analyze line movement patterns over time — no paid add-on required.

Stop Flattening Your AH Data

Generic APIs give you “spread.” OddsPapi gives you AH -0.25 from Singbet, AH -0.5 from Pinnacle, and AH 0 from Betfair Exchange — all in one call, with individual market IDs, quarter-goal granularity, and free historical data. 50+ bookmakers on every AH line, sharp books included, no enterprise contract required.