This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Cloudbet API

Programmatic access to Cloudbet’s sportsbook and services.

Swagger/OpenAPI documentation can be found at https://www.cloudbet.com/api/

The docs are split into the following sections:

  • Account: Account management functions
  • Feed: Real-time sportsbook data
  • Trading: Trading API
  • Trading B2B: Trading B2B API enabling you to set your own odds based on the data we supply

Cloudbet API Keys

Trading API Key

The Trading API (aka Betting API) is meant for developers who want to place bets and allows you to perform sports betting programatically.

You should deposit the equivalent of 10 EUR in a currency of your choice and can navigate to the API key section in your account menu. You can generate and revoke keys here in case you leak it, but be careful as there is a penalty for rotating keys too often.

Cloudbet Trading API Key

Affiliate API Key

The Affiliate API is primarily meant if you want to consume Cloudbet odds without needing to place bets programatically. You can obtain the Cloudbet Affiliate API Key by logging into your Cloudbet Affiliate account and then visiting the Affiliate API Token page. Please note that there are 2 tokens on this page. Make sure to generate the token in the API Key section.

Using this Cloudbet Affiliate API Key you can then go back to https://www.cloudbet.com/api/ to test the Feed API endpoints.

If you authenticate with the Cloudbet Affiliate API Key, then the Feed API responses may be cached and up to 1 minute behind the latest updates. This is in contrast to using the Cloudbet Trading API Key, which gives you real-time updates.

1 - Markets

How to work with markets from Cloudbet API Feed and using the corresponding market URLs in the Cloudbet Trading API to place bets.

Terminology

Market Key

  • The market_key is the unique identifier for a market and optionally time period with its own settlement rules.

  • The submarket_key is a logical period grouping of the market selections and is primarily useful as an indicator of when the market is settled. It is not required for the definition of a line as explained below.

Market and Submarket Key Example

"markets": {
  "soccer.asian_handicap": {
    "submarkets": {
      "period=ft": {
        "sequence": "4441",
        "selections": [
          {
...

Outcomes, Grouping Parameters and Lines

  • The outcome identifies a unique selection on the market, e.g. 0:0 or home.

  • grouping_parameters include grouping information such as handicap and totals values.

  • If no grouping_parameters are present (empty string), omit the query string and format as <market_key>/<outcome>

  • A line is determined by the market_key and the grouping_parameters, all selections on a line sum up to 100% true probability, e.g. soccer.asian_handicap?handicap=-0.5 includes the home and away outcome.

Outcomes, Grouping Parameters and Lines Example

"selections": [
  {
    "outcome": "home",
    "params": "handicap=-0.75",
    "price": 1.98,
    "minStake": 0.1,
    "maxStake": 13386.98032,
    "probability": 0.488,
    "status": "SELECTION_ENABLED",
    "side": "BACK"
  }
...

Market URL

The market url can be compiled from the feed and takes the form of <market_key>/<outcome>?<grouping_parameters>. This can be sent in the payload of the /v3/bets/place endpoint when placing a bet.

Market URL Example

"marketUrl": soccer.total_goals/over?total=3

Split and Variables

This is static information available in our market list below, while it is not provided dynamically on the Cloudbet API. This information is primarily meant for market settlement, but can also be used by you to visually separate markets by using the Cloudbet Feed API, if you use our API to display markets on your website.

  • Split: List of periods and teams which affect market settlement.

  • Variables: List of variables which affect settlement of a specific market. These can also be used to visually separate lines, e.g. the handicap values on an Asian Handicap market.

Split and Variables Example

	"soccer.asian_handicap_period_extratime": {
		"Name": "Asian Handicap - Extra Time",
		"Variables": [
			"handicap"
		],
		"Split": "period=et",
		"Outcomes": {
			"away": "{{away}} {{-handicap}}",
			"home": "{{home}} {{handicap}}"
		}
	},

A list of markets is available on Github and is also made available below.

If you would like to request addition of new markets, then please create a discussion thread in the Cloudbet Docs Discussions section.

Full List of available markets on the Cloudbet API

2 - Examples

Examples showing how to query the Cloudbet API

There are several steps to fetching odds from the Cloudbet Feed API and using these to place bets afterwards with the Cloudbet Trading API. Here, we will show you how to fetch these odds after creating a Cloudbet Trading or Affiliate API Key.

In general you would follow these steps to get the latest odds:

  1. Get details about upcoming events for your desired sports. The Events or Fixtures endpoint can be used to get a list of upcoming events and competitions for a specific sport on a specific date.

  2. Obtain odds for all events of an upcoming competition that you found from the fixtures endpoint by accessing the competitions endpoint. This allows you to batch ingest odds for multiple events if desired. There is also an event endpoint if you want to get odds for a specific event.

Sports Fixtures

Information about listed events is what we refer to as “fixtures”. We break these down into sports, competitions and events that can be queried from the feed API.

Please substitute X-API-Key with your actual Cloudbet API key.

List of sports

Get a list of sports. Sports are ordered by alphabetical order.

curl -X "GET" "https://sports-api.cloudbet.com/pub/v2/odds/sports" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>"
-H "Content-Type: application/json"

Sample response:

    {
        "sports": [
            {
                "name": "American Football",
                "key": "american-football",
                "competitionCount": 2,
                "eventCount": 92
            },
            {
                "name": "Archery",
                "key": "archery",
                "competitionCount": 0,
                "eventCount": 0
            },
            .
            .
            .
            {
                "name": "Soccer",
                "key": "soccer",
                "competitionCount": 142,
                "eventCount": 1239
            }
        ]
    }

Competitions for a given sport

Get active competitions for a sport. Competitions are grouped by categories.

curl -X "GET" "https://sports-api.cloudbet.com/pub/v2/odds/sports" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>"
-H "Content-Type: application/json"

Sample response:

{
    "name": "Soccer",
    "key": "soccer",
    "competitionCount": 141,
    "eventCount": 1240,
    "categories": [
    {
        "name": "England",
        "key": "england",
        "competitions": [
            {
                "name": "Premier League",
                "key": "soccer-england-premier-league",
                "eventCount": 29
            },
            {
                "name": "FA Cup",
                "key": "soccer-england-fa-cup",
                "eventCount": 3
            },
            .
            .
            .
        ]
    },
    {
        "name": "International",
        "key": "international",
        "competitions": [
            {
                "name": "UEFA Euro 2024",
                "key": "soccer-international-euro-cup",
                "eventCount": 146
            },
            {
                "name": "World Cup",
                "key": "soccer-international-world-cup",
                "eventCount": 1
            },
            .
            .
            .
        ]
    ]
}

Fixtures for a given competition

  • Fetch Match Odds, Asian Handicap and Total Goals markets for EPL
curl -X "GET" "https://sports-api.cloudbet.com/pub/v2/odds/competitions/soccer-england-premier-league?markets=soccer.matchOdds&markets=soccer.asianHandicap&markets=soccer.totalGoals" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>"
-H "Content-Type: application/json"
  • Fetch Moneyline, Totals and Run Line markets for MLB:
curl -X "GET" "https://sports-api.cloudbet.com/pub/v2/odds/competitions/baseball-usa-mlb?markets=baseball.moneyline&markets=baseball.totals&markets=baseball.runLine" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>"
-H "Content-Type: application/json"

Sample response for NBA with Moneyline and Handicap markets:

{
  "name": "NBA",
  "key": "basketball-usa-nba",
  "sport": {
    "name": "Basketball",
    "key": "basketball"
  },
  "events": [
    {
      "sequence": "97",
      "id": 6473660,
      "home": {
        "name": "Miami Heat",
        "key": "c672-miami-heat",
        "abbreviation": "MIA"
      },
      "away": {
        "name": "Los Angeles Lakers",
        "key": "c655-los-angeles-lakers",
        "abbreviation": "LAL"
      },
      "players": {
        "c4a879-jared-dudley": {
          "name": "Jared Dudley",
          "team": "AWAY",
          "position": {
            "name": "F",
            "key": "f"
          }
        },
        "c4b25d-andre-drummond": {
          "name": "Andre Drummond",
          "team": "AWAY",
          "position": {
            "name": "C",
            "key": "c"
          }
        },
        .
        .
        .
      },
      "status": "TRADING_LIVE",
      "markets": {
        "basketball.handicap": {
          "submarkets": {
            "period=ot&period=ft": {
              "sequence": "97",
              "selections": [
                {
                  "outcome": "home",
                  "params": "handicap=-8",
                  "price": 1.915,
                  "minStake": 0.0001,
                  "probability": 0.505,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                },
                {
                  "outcome": "away",
                  "params": "handicap=-8",
                  "price": 1.95,
                  "minStake": 0.0001,
                  "probability": 0.495,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                },
                {
                  "outcome": "home",
                  "params": "handicap=-10",
                  "price": 2.248,
                  "minStake": 0.0001,
                  "probability": 0.427,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                },
                {
                  "outcome": "away",
                  "params": "handicap=-10",
                  "price": 1.672,
                  "minStake": 0.0001,
                  "probability": 0.573,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                },
                .
                .
                .
              ]
            }
          },
          "liability": 1262.505
        },
        "basketball.moneyline": {
          "submarkets": {
            "period=ot&period=ft": {
              "sequence": "97",
              "selections": [
                {
                  "outcome": "home",
                  "params": "",
                  "price": 1.264,
                  "minStake": 0.0001,
                  "probability": 0.76,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                },
                {
                  "outcome": "away",
                  "params": "",
                  "price": 4.001,
                  "minStake": 0.0001,
                  "probability": 0.24,
                  "status": "SELECTION_ENABLED",
                  "side": "BACK"
                }
              ]
            }
          },
          "liability": 631.2525
        },
      },
      "name": "Miami Heat V Los Angeles Lakers",
      "key": "c672-miami-heat-v-c655-los-angeles-lakers",
      "cutoffTime": "2021-04-08T23:30:00Z",
      "metadata": {
        "opinion": []
      },
      "startTime": "2021-04-08T23:30:00Z"
    },
    {
      "sequence": "1873",
      "id": 5030846,
      "home": null,
      "away": null,
      "players": {
          .
          .
          .
      },
      "status": "TRADING",
      "markets": {
      .
      .
      .
      },
      "name": "NBA - Awards - Coach Of The Year (reg. season)",
      "key": "nba-awards-coach-of-the-year-reg-season",
      "cutoffTime": "2021-04-08T23:30:00Z",
      "metadata": {
        "opinion": []
      },
      "startTime": "2021-04-08T23:30:00Z"
    }
  ]
}

Query a single event

For a single event, the API provides you all available markets. To delve into details about how our markets are structured, please look at the Cloudbet markets page.

curl -X 'GET' "https://sports-api.cloudbet.com/pub/v2/odds/events/6473660" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"

Sample response for a single event

{
  "sequence": "97",
  "id": 6473660,
  "sport": {
    "name": "Basketball",
    "key": "basketball"
  },
  "competition": {
    "name": "NBA",
    "key": "basketball-usa-nba",
    "category": {
      "name": "USA",
      "key": "usa"
    }
  },
  "home": {
    "name": "Miami Heat",
    "key": "c672-miami-heat",
    "abbreviation": "MIA"
  },
  "away": {
    "name": "Los Angeles Lakers",
    "key": "c655-los-angeles-lakers",
    "abbreviation": "LAL"
  },
  "players": {
    "c4a879-jared-dudley": {
      "name": "Jared Dudley",
      "team": "AWAY",
      "position": {
        "name": "F",
        "key": "f"
      }
    },
    "c4b25d-andre-drummond": {
      "name": "Andre Drummond",
      "team": "AWAY",
      "position": {
        "name": "C",
        "key": "c"
      }
    },
    "c4b269-kentavious-caldwell-pope": {
      "name": "Kentavious Caldwell-Pope",
      "team": "AWAY",
      "position": {
        "name": "G",
        "key": "g"
      }
    },
    "c4b58e-ben-mclemore": {
      "name": "Ben McLemore",
      "team": "AWAY",
      "position": {
        "name": "G",
        "key": "g"
      }
    },
    .
    .
    .
  },
  "status": "TRADING",
  "markets": {
    "basketball.handicap": {
      "submarkets": {
        "period=ot&period=ft": {
          "sequence": "97",
          "selections": [
            {
              "outcome": "home",
              "params": "handicap=-8",
              "price": 1.915,
              "minStake": 0.0001,
              "probability": 0.505,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "away",
              "params": "handicap=-8",
              "price": 1.95,
              "minStake": 0.0001,
              "probability": 0.495,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "home",
              "params": "handicap=-10",
              "price": 2.248,
              "minStake": 0.0001,
              "probability": 0.427,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "away",
              "params": "handicap=-10",
              "price": 1.672,
              "minStake": 0.0001,
              "probability": 0.573,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            .
            .
            .
          ]
        }
      },
      "liability": 1262.505
    },
    "basketball.moneyline": {
      "submarkets": {
        "period=ot&period=ft": {
          "sequence": "97",
          "selections": [
            {
              "outcome": "home",
              "params": "",
              "price": 1.264,
              "minStake": 0.0001,
              "probability": 0.76,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "away",
              "params": "",
              "price": 4.001,
              "minStake": 0.0001,
              "probability": 0.24,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            }
          ]
        }
      },
      "liability": 631.2525
    },
    "basketball.totals": {
      "submarkets": {
        "period=ot&period=ft": {
          "sequence": "97",
          "selections": [
            {
              "outcome": "over",
              "params": "total=204.5",
              "price": 1.924,
              "minStake": 0.0001,
              "probability": 0.502,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "under",
              "params": "total=204.5",
              "price": 1.942,
              "minStake": 0.0001,
              "probability": 0.498,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "over",
              "params": "total=202",
              "price": 1.682,
              "minStake": 0.0001,
              "probability": 0.57,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            {
              "outcome": "under",
              "params": "total=202",
              "price": 2.228,
              "minStake": 0.0001,
              "probability": 0.43,
              "status": "SELECTION_ENABLED",
              "side": "BACK"
            },
            .
            .
            .
            .
          ]
        }
      },
      "liability": 420.83500000000004
    }
  },
  "name": "Miami Heat V Los Angeles Lakers",
  "key": "c672-miami-heat-v-c655-los-angeles-lakers",
  "cutoffTime": "2021-04-08T23:30:00Z",
  "metadata": {
    "opinion": []
  },
  "startTime": "2021-04-08T23:30:00Z"
}

Account API for Balance Tracking

Query list of available currencies

The first thing for automated betting is knowing about our funds available. Using the endpoint below, you can find out the list of currencies available.

curl -X 'GET' "https://sports-api.cloudbet.com/pub/v1/account/currencies" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"

Sample response:

{
  "currencies": ["BONUS_EUR", "BTC", "ETH", "PLAY_EUR"]
}

Query balance for a currency

This allows you to query your balance in a specific currency. Here we query PLAY_EUR, our test funds currency that currently can be enabled on your account upon request.

curl -X 'GET' "https://sports-api.cloudbet.com/pub/v1/account/currencies/PLAY_EUR/balance" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"

Sample response:

{
  "amount": "984.69"
}

Trading API to place bets

Once you know which currency you want to place bets in, as well as the markets you want to place your bet on, you can call the place bet endpoint.

Place Bet Request

This is a POST endpoint where the request body contains details about your desired market and currency. Use a unique, randomly generated uuid in the referenceId field of your request.

Sample Place Bet request on an Asian Handicap market for a Soccer event:

curl -X 'POST' "https://sports-api.cloudbet.com/pub/v3/bets/place" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"
-d '{"acceptPriceChange":"BETTER","currency":"PLAY_EUR","eventId":"7190563","marketUrl":"soccer.asian_handicap/home?handicap=0.5","price":"1.65","referenceId":"1891d3a0-0af8-11ec-b536-11ca86b8c5a4","stake":"1.1"}'

Sample success response:

{
  "referenceId": "1891d3a0-0af8-11ec-b536-11ca86b8c5a4",
  "price": "1.652",
  "eventId": "7190563",
  "marketUrl": "soccer.asian_handicap/home?handicap=0.5",
  "side": "BACK",
  "currency": "PLAY_EUR",
  "stake": "1.1",
  "status": "ACCEPTED",
  "error": ""
}

NOTE: Quite often, your bet will not be immediately accepted while we process your betting request. Thus you will receive a PENDING_ACCEPTANCE response instead:

{
  "referenceId": "1891d3a0-0af8-11ec-b536-11ca86b8c5a4",
  "price": "1.652",
  "eventId": "7190563",
  "marketUrl": "soccer.asian_handicap/home?handicap=0.5",
  "side": "BACK",
  "currency": "PLAY_EUR",
  "stake": "1.1",
  "status": "PENDING_ACCEPTANCE",
  "error": ""
}

Bet Status Request

If you receive a PENDING_ACCEPTANCE response, you can then check the status of the bet with the referenceId field from your place bet request to confirm if it got accepted or rejected. This bet status request can also be used generally to query the status of your bets.

curl -X 'POST' "https://sports-api.cloudbet.com/pub/v3/bets/1891d3a0-0af8-11ec-b536-11ca86b8c5a4/status
" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"
-d '{"acceptPriceChange":"BETTER","currency":"PLAY_EUR","eventId":"7190563","marketUrl":"soccer.asian_handicap/home?handicap=0.5","price":"1.65","referenceId":"1891d3a0-0af8-11ec-b536-11ca86b8c5a4","stake":"1.1"}'

The response for the above bet status request will have a similar format to the bet placement request above.

NOTE: Your bet might get rejected for different reasons, with recommended new stake and price on the rejection payload. Please update your payload with a new referenceId and try again with updated fields if this happens.

Bet History for settlements

You can obtain a full history of your API bets, in addition to being able to view your settled bets in the Bet History section of the Cloudbet Website.

curl -X 'POST' "https://sports-api.cloudbet.com/pub/v3/bets/history?limit=5&offset=0
" \
-H "accept: application/json" \
-H "X-API-Key: <API Key>" \
-H "Content-Type: application/json"
-d '{"acceptPriceChange":"BETTER","currency":"PLAY_EUR","eventId":"7190563","marketUrl":"soccer.asian_handicap/home?handicap=0.5","price":"1.65","referenceId":"1891d3a0-0af8-11ec-b536-11ca86b8c5a4","stake":"1.1"}'

Sample response:

{
  "bets": [
    {
      "referenceId": "1891d3a0-0af8-11ec-b536-11ca86b8c5a4",
      "price": "1.652",
      "eventId": "7190563",
      "marketUrl": "soccer.asian_handicap/home?handicap=0.5",
      "side": "BACK",
      "currency": "PLAY_EUR",
      "stake": "1.1",
      "createTime": "2024-05-29T03:53:02Z",
      "status": "ACCEPTED",
      "returnAmount": "0.0",
      "eventName": "Manchester City v Manchester United",
      "sportsKey": "soccer",
      "competitionId": "18",
      "categoryKey": "usa",
      "customerReference": "5b1eb89f-5c87-4bd2-b8e9-82197fd6b986",
      "error": ""
    }
  ],
  "totalBets": "1"
}

3 - Handicap Odds

How to work with handicap markets on the Cloudbet API.

Special care should be taken when working with all handicap markets.

In the Cloudbet API, the handicap value refers to the home team value and is inverted on the away side.

Example:

market_key: “soccer.asian_handicap”
outcome: "away",
params: "handicap=0.5",
price: 3.3

Handicap Odds

4 - Margin Adjustments in Sports Betting

Learn how to adjust margins in sports betting to set your own odds based on the data the Cloudbet B2B API supplies.

You can integrate the Cloudbet B2B API and set your own odds based on the data supplied, enabling you to carve out a profitable margin for each transaction. Alongside margins, you can also take control of and share liability from the individual bets that players or customers place through your platform.

Basic Implied Probability Calculation

The implied probability of an outcome is initially calculated from the given odds and the overround. For a specific betting market:

$$\tag*{(1)} \text{Implied Probability} = \frac{1}{\text{Odds} \times \text{Overround}}$$

This calculation gives a base probability adjusted for the bookmaker’s initial margin embedded within the odds.

Adjusting the Overround

To reflect changes in market conditions, event specifics, or risk assessments, the overround is adjusted by adding a margin percentage:

$$\tag*{(2)} \text{Adjusted Overround} = \text{Overround} + \text{Margin Percentage}$$

This formula ensures that the total market margin is adaptive and adjusts with the origin.

Recalculating Odds with Adjusted Overround

After adjusting the overround, new odds are recalculated as follows:

$$\tag*{(3)} \text{New Odds} = \frac{1}{\text{Implied Probability} \times \text{Adjusted Overround}}$$

This method of recalculating the odds maintains the relative value between different outcomes while adjusting the overall margin.

Example Calculation

If the initial odds for a team winning are 2.0 with an overround of 1.05, the implied probability is:

$$\text{Implied Probability} = \frac{1}{2.0 \times 1.05} = 0.4762$$

If the margin percentage is adjusted to 1.10, the new odds would be:

$$\text{New Odds} = \frac{1}{0.4762 \times 1.10} = 1.91$$

These recalculated odds reflect the adjusted margin and provide a new market price for the outcome.

5 - Live Odds Banner Ads

Embedding live event odds in HTML5 banners using the Cloudbet Sports API

Live odds banners can display dynamic betting data in HTML5 ad creatives by querying the Cloudbet Sports API. These banners are typically deployed by partners via self-hosted static sites, requiring a proxy layer to comply with CORS restrictions and keep secrets secure if used.

Note: HTML5 banners cannot directly access Cloudbet APIs from the browser due to CORS. You must host a proxy that forwards requests to the Cloudbet Sports API from the same domain.

API Access

There are two main routes to access the Cloudbet Sports API for this purpose:

  1. Public routes use /sports-api/c/v6/.... and do not require an API key.
  2. Private routes use /sports-api/v6/.... and require an API key.

Public /c/ routes are cached, private proxies hit live data but add latency; pick based on freshness needs.

1. Use Public Routes without API Key

Example URL:

https://www.cloudbet.com/sports-api/c/v6/sports/competitions/
    soccer-england-premier-league/events?
    markets=soccer.match_odds
    &markets=soccer.asian_handicap
    &markets=soccer.total_goals
    &locale=en
    &include-pretrading=false
    &limit=1

Use a simple static redirect to /api/... on your host. You can skip over the private routes example and API key section if you’re using this approach (recommended).

CORS Proxy Configuration

Browsers enforce same-origin policy on fetch and XHR. Your proxy must include:

Access-Control-Allow-Origin: *

Your hosting must forward e.g. /api/* to Cloudbet and inject CORS headers. Example for Netlify (netlify.toml) using a static redirect to public endpoints /c/ where no API key is required:

[[headers]]
  for = "/api/*"
    [headers.values]
      Access-Control-Allow-Origin = "*"

[[redirects]]
  from = "/api/*"
  to   = "https://www.cloudbet.com/sports-api/c/v6/sports/competitions/:splat"
  status = 200
  force  = true
  headers = {Access-Control-Allow-Origin = "*"}

Other options:

  • Vercel (vercel.json headers & redirects)
  • Firebase Hosting (firebase.json rewrites + headers)
  • AWS S3 + CloudFront (CORSConfiguration)

Adjust per provider so browser fetches from /api/... without errors.

2. Use Real-time Routes with API Key

To use real-time odds, partners must create an API key from their Cloudbet player or affiliate account via the self-serve account menu. For this purpose, the API keys are interchangable. Refer to API Key Access and Examples for setup steps and sample requests.

Ensure that API keys and secrets stay on your server or proxy. Avoid embedding them in client code.

Use your proxy to add the X-API-Key header when forwarding requests. You can do this with e.g. Netlify functions, AWS Lambda, or Vercel serverless functions. Below is an example of a Netlify function that proxies requests to the Cloudbet Sports API.

import fetch from 'node-fetch';

export async function handler(event) {
  const match = event.rawUrl.match(/\/api(\/.*)/);
  const [ , pathAndQuery ] = match || [];
  const url = `https://www.cloudbet.com/sports-api/v6${pathAndQuery}`;

  const resp = await fetch(url, {
    headers: { 'X-API-Key': process.env.CLOUDBET_API_KEY }
  });

  const body = await resp.json();
  return {
    statusCode: resp.status,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  };
}

Set CLOUDBET_API_KEY in Netlify’s environment variables. And ensure the cross-origin header is set in the response:

Access-Control-Allow-Origin: *

HTML5 Banner Integration

Banners should be designed with placeholder text for outcomes and odds, which are dynamically updated at runtime using AJAX calls.

<div id="homeTeam"></div>
<div id="homeOdds"></div>
<div id="awayTeam"></div>
<div id="awayOdds"></div>

Below is a simplified integration flow.

Building the Request Path

Use the competition endpoint to fetch the next event (&limit=1) and desired markets:

const params = new URLSearchParams(location.search);
const locale = params.get('locale') || 'en';
const compKey = 'soccer-england-premier-league';
const markets = ['soccer.match_odds','soccer.asian_handicap','soccer.total_goals'];
const path = `/api/sports/competitions/${compKey}/events?` +
  markets.map(m => `markets=${m}`).join('&') +
  `&locale=${locale}&limit=1`;

Fetch and Render

Include this in your banner’s <script>:

document.addEventListener('DOMContentLoaded', () => {
  fetch(path)
    .then(res => res.json())
    .then(data => {
      const e = data.events[0];
      const ah = e.markets['soccer.asian_handicap']
                  .submarkets['period=ft'].selections;
      const homeSel = ah.find(s => s.outcome === 'home');
      const awaySel = ah.find(s => s.outcome === 'away');

      document.getElementById('homeTeam').textContent = e.home.name;
      document.getElementById('awayTeam').textContent = e.away.name;
      document.getElementById('homeOdds').textContent = homeSel.price;
      document.getElementById('awayOdds').textContent = awaySel.price;
    })
    .catch(console.error);
});

Swap the market key (soccer.match_odds or soccer.total_goals) as needed.

Market Structure Reference

Each market in the response follows:

"markets": {
  "soccer.asian_handicap": {
    "submarkets": {
      "period=ft": {
        "selections": [
          { "outcome": "home", "price": 1.846, "params": "handicap=-0.25" },
          { "outcome": "away", "price": 2.015, "params": "handicap=-0.25" }
        ]
      }
    }
  },
  "soccer.match_odds":   { /* similar */ },
  "soccer.total_goals":  { /* similar */ }
}

Extract the price field from the home and away selections.

Tips and Alternatives

  • Use public /c/v6 routes when no API key is needed.
  • For private data or real-time freshness, proxy with key injection.
  • Competition endpoint batches events; limit=1 returns the next match.
  • Event endpoint (/api/events/{id}) targets a single event.
  • Append &locale=… for localized team names.

Summary

Deploying live odds banners requires:

  • Self-hosted access with a reverse proxy (CORS handling)
  • HTML5 creatives with placeholders for odds
  • Minimal JS for fetching and rendering data dynamically

This setup gives affiliates flexible, real-time betting widgets embeddable across any platform or campaign. See these references for more details:

6 - Simulated Betting with Test Funds

This page provides information on accessing and using test funds with Cloudbet’s API for simulated betting. This allows users to experiment with betting strategies without risking real money.

First, ensure your account balance meets the minimum requirement of 10 EUR equivalent. This can be in any supported currency such as BTC, ETH, USDC, USDT, etc.

Once an API key is generated, a new currency option, PLAY_EUR, can be found in the account menu. A request button to credit the account with Play EUR 100 will be available. This process is self-serve, allowing users to request more funds when needed.

If you require larger amounts or wish to test the API before funding your account, please contact customer support. This ensures you can fully explore Cloudbet’s offerings and refine your strategies without risk.