mcpField
E
esportsodds.gg

esportsodds.gg

本地服务
github.com/esportsodds游戏娱乐02 周前更新

关于 esportsodds.gg

esportsodds.gg 是其 CS2 数据 API 的官方 Python 客户端,面向开发比赛、队伍、选手或赛事数据功能的开发者。它将 API 响应以 Python 字典和列表返回,且仅使用标准库。

主要功能

  1. 01查询比赛与赛果
  2. 02获取地图和选手数据
  3. 03浏览队伍与赛事
  4. 04访问排名和衍生赔率
  5. 05分页获取 API 响应

适用场景

  1. 01构建 CS2 比赛数据工具
  2. 02分析选手和队伍表现
  3. 03展示赛事日程与赛果
  4. 04使用排名和衍生市场线

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"esportsodds-esportsodds": {
"command": "uvx",
"args": [
"esportsodds"
],
"env": {
"ESPORTSODDS_API_KEY": "<ESPORTSODDS_API_KEY>"
}
}
}
}
启动命令uvx esportsodds
需要配置的环境变量
ESPORTSODDS_API_KEY密钥Your esportsodds.gg API key

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiesportsodds0.4.5

工具

24

收录的工具列表 · 更新于 2 周前

参数类型必填说明
hasstring否仅返回包含以下所有子资源的比赛,例如 `["rounds", "depth"]`。多个值以逗号分隔。
sortstring否`-scheduled_at`(默认,最新优先)、`scheduled_at`(最早优先;对于已安排的比赛,即最先进行的比赛优先)、`changed_at` 或 `-changed_at`。游标与其所用的排序方式绑定。
teamstring否仅返回此队伍的比赛(id)。
limitinteger否页面大小(默认 100,最大 500)。
cursorstring否上一页返回的 `next_cursor`;第一页省略。
statusstring否`scheduled`、`live`、`completed` 或 `cancelled`。使用 `scheduled` 时,还要传入 `sort="scheduled_at"`,以获取接下来进行的比赛,而非日期最远的比赛。
date_tostring否安排在此日期或之前的比赛(UTC,包含整天)。
date_fromstring否安排在此日期或之后的比赛(UTC,包含当日)。
tournamentstring否仅返回此锦标赛的比赛(id)。
changed_sincestring否仅返回 `changed_at` 不早于此时刻的比赛;这是变更动态流(建议使用 `iter_changes`,它也会处理时间重叠)。

详细介绍

esportsodds

esportsodds.gg CS2 数据 API 的官方 Python 客户端。

Counter-Strike 2 比赛和赛果、队伍和选手统计数据、锦标赛、排名,以及衍生市场赔率,均以普通 Python 字典的形式返回。仅使用标准库:无需安装其他内容。

无需抓取 HLTV,即可获取 CS2 比赛数据和统计信息。此软件包是付费 API 的客户端;它不是官方 HLTV/Valve API。

安装

pip install esportsodds

Python 3.10 或更高版本。无依赖项。

无需账户即可先试用:将 ESPORTSODDS_API_KEY 设置为公共示例密钥 eo_sample_public,即可读取固定范围的过往比赛。该密钥由所有人共用,并按网络地址限流。 仅供评估使用;请遵守我们的条款。

还没有订阅?免费的 sandbox 密钥可读取固定范围的过往比赛,让你先基于真实响应进行开发。下面的快速入门会请求即将举行的比赛,这些比赛不在样本范围内,所以使用任一密钥时,都应先运行sandbox_tour.py,并使用指南中的锦标赛 ID。任何超出样本范围的请求都会引发 PermissionDeniedError(sandbox_scope),错误消息会列出可用的赛事。

快速入门

from esportsodds import Client

client = Client()  # reads ESPORTSODDS_API_KEY from the environment

for match in client.matches.list(status="scheduled", sort="scheduled_at", limit=5).data:
    print(match["scheduled_at"], match["team_a_name"], "vs", match["team_b_name"])
2026-10-08T14:00:00Z Team A vs Team B
2026-10-08T17:30:00Z Team C vs Team D

每次调用都会以普通字典和列表的形式返回 API 发来的内容。列表调用会返回一个 Page(page.data、page.next_cursor、page.has_more、page.meta);查询单个对象的调用会返回一个字典。

除非另有说明,比赛按时间从新到旧排列,这适用于查询赛果。对于已安排的比赛,该顺序会从时间最远的赛程开始,所以快速入门中传入 sort="scheduled_at",以获取接下来要进行的比赛。

API 密钥和套餐

有两种套餐,按月或按年计费,均需预先付款:Standard 每月 $99,包含 50,000 次请求;Pro 每月 $299,包含 150,000 次请求。年付相当于付 10 个月费用:Standard 每年 $990,Pro 每年 $2,990,相当于免费获得两个月。请求按账户、按日历月(UTC)计数,涵盖该账户拥有的所有密钥。没有试用期。免费的 sandbox 密钥可读取固定范围的过往比赛,总计最多可发起 2,000 次请求,无需提供银行卡;它不是套餐,获取当前数据则需要订阅套餐。超出套餐请求额度后,调用会收到错误码为 quota_exceeded 的 429 响应,直到下个月重置;此客户端会引发 QuotaExceededError,且不会重试(重试无济于事)。sandbox 密钥用尽额度后会返回 sandbox_quota_exceeded,并以相同方式引发错误(额度永不重置);超出样本范围的请求会引发 PermissionDeniedError(sandbox_scope,不计入额度)。

批量导出(matches.bulk() 及基于它构建的遍历器)还有一项限制。对于首次订阅日期为 2026 年 10 月 30 日或之后的 Standard 账户,每月最多可发起 250 次批量导出请求;超出后,API 会返回 bulk_quota_exceeded 错误码的 429,进而引发 QuotaExceededError,且不会重试,但其他调用仍可正常使用。Pro 没有批量导出限制;首次订阅日期早于该日期的 Standard 账户也没有此限制。

订阅后,在账户中创建密钥,并妥善保管,勿将其写入代码:

export ESPORTSODDS_API_KEY="eo_live_..."
  • 客户端只会在 Authorization: Bearer 标头中发送密钥,绝不会将其放入 URL。repr() 只显示密钥的最后四个字符,错误消息或日志中也绝不会出现密钥。
  • 客户端只通过 HTTPS 通信。仅对 localhost 和其他环回地址(127.0.0.1、::1)接受普通 http://,并且绝不会跟随重定向,因此密钥不会被发送到其他主机。
  • 将密钥保存在你的服务器上。浏览器或移动应用应调用你的后端,而非直接调用 API。
  • 订阅前,你可以在公开演示中查看真实响应。

配置

环境变量含义
ESPORTSODDS_API_KEY你的 API 密钥,在未传入 api_key 时使用。
ESPORTSODDS_BASE_URLAPI 地址,在未传入 base_url 时使用。
Client(...) 参数默认值含义
api_keyNone你的密钥。省略时会读取 ESPORTSODDS_API_KEY;两者都没有时会引发 ValueError。
base_urlhttps://api.esportsodds.ggAPI 地址。仅支持 HTTPS,但 localhost 和其他环回地址除外。
game"cs2"要查询的游戏。目前只有 CS2 有数据。
timeout30.0等待回复的秒数。批量导出始终至少等待 120 秒。
max_retries3对 错误 中列出的故障进行重试的次数。0 表示关闭重试。
transportNone你自己的 HTTP 栈:任何具有 send(TransportRequest) -> TransportResponse 方法的对象。

Client 可以安全地供多个线程共用。可将其用作上下文管理器(with Client() as client:), 或在使用完毕后调用 client.close():该方法会关闭具有 close() 方法的自定义 transport (默认 transport 不会保持任何连接,因此无需释放资源)。

方法

每个端点对应一个方法。{game} 是客户端的 game,{id} 接受 UUID;对于战队、选手和锦标赛, 也接受 slug。

调用端点返回值提供的内容
client.matches.list()GET /v1/{game}/matchesPage比赛赛程和结果,按时间倒序排列;可按 status、tournament、team、日期和 has 筛选,并用 sort 排序。
client.matches.bulk()GET /v1/{game}/matches/bulkPage比赛数据,内嵌地图、统计数据等(include=),每次请求 25 场。
client.matches.get(match)GET /v1/{game}/matches/{id}dict单场比赛;include= 可内嵌队伍、赛事、赔率或子资源。
client.matches.maps(match)GET /v1/{game}/matches/{id}/mapsPage各地图的比赛结果。
client.matches.stats(match)GET /v1/{game}/matches/{id}/statsPage每位选手的统计数据,包括整场比赛和各地图的数据。
client.matches.vetoes(match)GET /v1/{game}/matches/{id}/vetoesPage地图的选取和禁用顺序。
client.matches.rounds(match)GET /v1/{game}/matches/{id}/roundsPage按回合统计的队伍数据:经济、首杀对决、残局和炸弹事件。
client.matches.history(match)GET /v1/{game}/matches/{id}/historyPage比赛信息的历史记录:每次变更及变更前后的值。
client.matches.depth(match)GET /v1/{game}/matches/{id}/depthdict每位选手的武器、手雷、命中部位、对决和闪光弹数据。
client.matches.lineups(match)GET /v1/{game}/matches/{id}/lineupsPage比赛前列出的各队阵容。
client.matches.streams(match)GET /v1/{game}/matches/{id}/streamsPage转播比赛的频道。
client.odds.list()GET /v1/{game}/oddsPage衍生市场赔率,可查看历史记录或当前赔率盘。
client.teams.list()GET /v1/{game}/teamsPage所有队伍,按字母顺序排列;可用 q 按名称查找。
client.teams.get(team)GET /v1/{game}/teams/{id}dict单支队伍。
client.teams.h2h(team, opponent=...)GET /v1/{game}/teams/{id}/h2hdict两支队伍之间的交锋记录。
client.teams.form(team)GET /v1/{game}/teams/{id}/formPage最近已结束的比赛结果,按时间倒序排列。
client.teams.ratings(team)GET /v1/{game}/teams/{id}/ratingsPage队伍的评分历史,每场比赛对应一个数据点。
client.teams.maps(team)GET /v1/{game}/teams/{id}/mapsPage队伍在各张地图上的战绩。
client.teams.round_stats(team)GET /v1/{game}/teams/{id}/round-statsdict按回合统计的打法风格数据:各方胜率、手枪局和首杀对决。
client.teams.vetoes(team)GET /v1/{game}/teams/{id}/vetoesdict队伍在各张地图上的自选、禁用和决胜图记录,并标记永久禁用图。
client.teams.results(team)GET /v1/{game}/teams/{id}/resultsPage最近比赛结果,包含每张地图的比分以及赛前双方队伍的评分。
client.teams.rivals(team)GET /v1/{game}/teams/{id}/rivalsPage队伍最常遇到的对手,以及双方交锋记录和评分差距。
client.teams.roster_history(team)GET /v1/{game}/teams/{id}/roster-historyPage各场近期比赛中上场的五位选手及阵容变动。
client.teams.players(team)GET /v1/{game}/teams/{id}/playersdict队伍最近一场比赛中的选手及其统计数据,还有过去 12 个月的数据。
client.tournaments.list()GET /v1/{game}/tournamentsPage所有赛事,按时间倒序排列;可用 q 按名称搜索。
client.tournaments.get(tournament)GET /v1/{game}/tournaments/{id}dict单项赛事。
client.tournaments.teams(tournament)GET /v1/{game}/tournaments/{id}/teamsPage参赛队伍,按种子排序。
client.players.list()GET /v1/{game}/playersPage所有选手,按昵称字母顺序排列;可用 q 按昵称搜索。
client.players.get(player)GET /v1/{game}/players/{id}dict单名选手。
client.players.career(player)GET /v1/{game}/players/{id}/statsdict选手生涯总数据和平均数据。
client.players.performance(player)GET /v1/{game}/players/{id}/performancedict过去 12 个月内已记录地图的数据,每项数据都附有其在拥有个人页面的选手中的百分位排名。
client.players.maps(player)GET /v1/{game}/players/{id}/mapsdict选手在各张已记录地图上的数据。
client.players.matches(player)GET /v1/{game}/players/{id}/matchesPage最近已结束的比赛,按时间倒序排列,并附有该选手本人的数据。
client.players.teams(player)GET /v1/{game}/players/{id}/teamsdict选手的队伍经历,按效力时段列出。
client.players.weapons(player)GET /v1/{game}/players/{id}/weaponsdict过去 12 个月的武器和命中部位汇总数据。
client.rankings.list()GET /v1/{game}/rankingsPage滚动三个月时间窗口内的队伍或选手排行榜。
client.rankings.history()GET /v1/{game}/rankings/historyPage最近各个每周时点的队伍排行榜。
client.rankings.round_stats()GET /v1/{game}/rankings/round-statsPage排行榜上顶尖队伍的回合级数据,按榜单顺序排列。
client.maps.list()GET /v1/{game}/mapsPage各张竞技地图的联赛整体数据。
client.maps.teams(map)GET /v1/{game}/maps/{id}/teamsPage各队伍在一张地图上的表现及围绕该地图的选择情况。
client.coverage.list()GET /v1/{game}/coveragePage已有的数据及其刷新频率。
client.model.metrics()GET /v1/{game}/model/metricsPage按市场划分的模型赔率透明度指标。模型赔率即将推出;列表可能为空。
client.ws_token()POST /v1/{game}/ws-tokendict用于 WebSocket 的 60 秒有效凭证。不消耗请求额度。
client.health()GET /healthdict服务状态。无需密钥,也不会重试。
筛选条件采用关键字参数,名称与 API 参考文档 一致。
对于逗号分隔的筛选条件(has=["rounds", "depth"]、include=["maps", "stats"]),
会自动为你拼接;datetime 或 date 会自动为你格式化(无时区信息的 datetime 表示 UTC);未知参数会引发 TypeError,而不会被发送。ID 在加入 URL 前会经过检查和转义。

赔率是我们自行推导的盘口(source="eo_market"),并非任何博彩公司提供的价格。模型盘口(source="eo_model")即将推出,目前尚未返回。

分页、批量导出和变更订阅

列表调用会返回一页数据和一个游标。你可以自行遍历:

page = client.matches.list(status="completed", limit=100)
while True:
    for match in page.data:
        print(match["id"])
    if not page.has_more:
        break
    page = client.matches.list(status="completed", limit=100, cursor=page.next_cursor)

也可以让客户端代为处理。iter() 会逐行生成结果,pages() 会逐页生成结果;两者都会按需加载,每页发送一个请求,因此提前停止不会产生额外开销。max_pages 是安全限制;生成的最后一页仍带有 next_cursor,因此任务停止(或崩溃)后,可以通过 cursor= 恢复。

for match in client.matches.iter(status="completed", date_from="2026-09-01"):
    print(match["id"])

matches、odds、teams、tournaments 和 players 均提供 iter 和 pages。

批量导出是低成本获取历史数据的方式:每个请求获取 25 场比赛,并嵌入你指定的子资源;每页请求只计入一次额度。

from datetime import date, timedelta

week_ago = date.today() - timedelta(days=7)
rows = client.matches.iter_bulk(
    status="completed", date_from=week_ago, include=["maps", "stats"], max_pages=4
)
for match in rows:
    print(match["id"], len(match["maps"]))

max_pages 会在达到指定请求数后停止遍历。不设置该参数时,iter_bulk 会持续运行,直到筛选结果耗尽;对于范围较广的筛选条件,这意味着会遍历全部历史数据,每页发送一个请求。Standard 订阅每月限额为 250 个请求,长时间遍历会在当月请求用尽时以 bulk_quota_exceeded 错误停止。使用 pages_bulk() 遍历并保存每页的 next_cursor,待下个月额度重置后,通过 cursor= 恢复遍历。

繁忙时段会返回 503 和较短的 Retry-After;客户端会为你等待并重试。

变更订阅可让本地副本保持最新。向 iter_changes 传入上次存储的最新一行的 changed_at,它会按变更时间从早到晚生成此后所有发生变更的比赛:

from datetime import datetime, timedelta, timezone

since = datetime.now(timezone.utc) - timedelta(hours=1)
newest = since.isoformat()
for match in client.matches.iter_changes(since):
    newest = match["changed_at"]  # rows arrive in changed_at order
    print(match["id"], match["status"])
# Store `newest`; it is the `since` for the next run.

它会从 since 前十分钟开始(overlap=),因为一行数据可能在其携带的 changed_at 之后才可见,并会丢弃因此产生的重复项。静默一小时只需一个请求。matches.history(match) 和 matches.iter_history(match) 可查看每次变更的内容。

错误

所有错误都是 EsportsOddsError。收到错误状态的回复时,会引发 ApiError 子类;请根据类或 error.code 分支处理,切勿根据 error.message 判断。

异常API code状态码是否自动重试
AuthenticationErrormissing_api_key、invalid_api_key、unauthorized401否
PermissionDeniedErrorforbidden、sandbox_scope403否
NotFoundErrornot_found、unknown_game404否
NotFoundErrormatch_merged308否:比赛 ID 因合并而失效;请保存 err.headers.get("x-merged-into") 返回的存续 ID
InvalidRequestErrorinvalid_parameter400否
InvalidCursorErrorinvalid_cursor400否:从第一页重新开始遍历
ConflictErrorconflict409否
RateLimitErrorrate_limited429是,等待 API 返回的 Retry-After 指定的时间后重试
QuotaExceededErrorquota_exceeded429永不:月度额度重置前不会有任何变化
QuotaExceededErrorsandbox_quota_exceeded429永不:Sandbox 密钥的额度不会重置
QuotaExceededErrorsample_quota_exceeded429永不:公共示例密钥的每日额度会在 00:00 UTC 重置
QuotaExceededErrorbulk_quota_exceeded429永不:套餐的月度批量导出额度会在每月重置;其他调用仍可正常使用
ServiceUnavailableErrorunavailable503是,等待 API 返回的 Retry-After 指定的时间后重试
ServerErrorinternal_error500是,但最多重试两次
ApiError其他任意值其他仅针对 502 和 504
TransportError无:请求未收到响应无是,采用退避策略
InvalidResponseError无:回复格式与 API 文档不符2xx否

未知路径 ID 会返回 404(NotFoundError),而不是 400;对于 matches.maps(...) 这类子资源中的未知 ID,会返回空页,而不是错误。

ApiError 包含 status、code、message、request_id、retry_after、headers 和 body。报告问题时请提供 request_id;它也可通过 client.last_response.request_id 获取。

from esportsodds import QuotaExceededError, RateLimitError

try:
    client.matches.get("00000000-0000-7000-8000-000000000001")
except QuotaExceededError as error:
    print("out of requests until", error.reset_at)
except RateLimitError as error:
    print("slow down; retry in", error.retry_after, "seconds")

速率限制与重试

有两种限制:每个密钥的令牌桶限制(持续每秒 20 个请求,突发上限为 100 个)以及套餐的月度额度。Standard 套餐为每个账户 50,000 个请求,Pro 套餐为每个账户 150,000 个请求;账户的所有密钥共用该额度。每次调用后,client.last_response.rate_limit 中都会包含 API 报告的额度信息:

info = client.last_response  # None until the first call has been made
if info is not None:
    budget = info.rate_limit
    print(budget.quota_remaining, "of", budget.quota_limit, "left; resets", budget.quota_reset)

客户端只会重试适合安全重试的请求,最多重试 max_retries 次(默认为 3 次),并会在 esportsodds 日志记录器上以 INFO 级别记录每次重试:

  • 遇到 429 rate_limited 或 503 时,会等待 API 返回的 Retry-After 指定的时间,并额外加入最多半秒的随机抖动。如果等待时间超过一分钟,则直接引发错误,不会继续等待。
  • 遇到 502、504 或网络故障时,会从半秒开始退避,每次加倍,最多等待八秒,并加入随机抖动。
  • 无论 max_retries 设置得多高,500 最多只会重试两次:API 会将其计入你的额度,因此每次重试都会消耗一个你付费购买的请求。
  • 遇到 429 quota_exceeded 时绝不重试,其他情况也不会重试。

轮询通常不是最省成本的设计:变更馈送和 WebSocket 所需的请求要少得多。请求预算指南中列出了具体数据。

WebSocket(比赛更新)

WebSocket 会推送你订阅的比赛的比分和赔率变化,且不消耗请求额度:票据、连接和消息都不会计入你的额度。我们的数据采集一旦发现变化就会推送更新,因此 WebSocket 可以消除轮询延迟,但无法让数据比采集到的更新;下方链接的指南列出了典型数据时效。

此软件包不会自行打开套接字(这需要依赖项)。它会生成票据并构建地址;任何 WebSocket 库都可以连接,例如 websockets(pip install websockets):

import asyncio
import json

import websockets

from esportsodds import Client

client = Client()


async def watch(match_ids: list[str]) -> None:
    ticket = await asyncio.to_thread(client.ws_token)
    async with websockets.connect(client.ws_url(ticket)) as socket:
        await socket.send(json.dumps({"type": "subscribe", "data": {"match_ids": match_ids}}))
        async for raw in socket:
            frame = json.loads(raw)
            if frame["type"] in ("snapshot", "update"):
                print(frame["match_id"], frame["seq"], frame["type"])


asyncio.run(watch(["00000000-0000-7000-8000-000000000001"]))
  • 票据有效期为 60 秒,且并非一次性使用,因此可在有效期内重试并复用;过期后请重新生成。你的密钥不会出现在套接字地址中。
  • snapshot 是比赛的完整当前状态,update 则表示一项变化。seq 按比赛递增;如果跳过了某个序号,请重新订阅该比赛以获取最新的 snapshot。
  • 使用指数退避和随机抖动重连,并重新发送 subscribe。服务器不会重放消息。
  • 一个密钥最多可同时保持五个连接,因此可以在一个连接上订阅多场比赛。
  • 服务器每隔 54 秒发送一次 ping;websockets 会自动回复。

WebSocket 指南列出了所有帧类型。

AI 助手(MCP)

此软件包包含一个 MCP(Model Context Protocol)服务,因此 Claude 或 Cursor 等 AI 助手可以根据 API 回答问题,例如某支队伍近期的状态、某场比赛的 veto 结果,或某名选手的生涯数据。它在你的机器上运行,读取 ESPORTSODDS_API_KEY,且只读取数据。每次工具调用都会消耗一条请求额度;列表工具默认请求 20 行,除非助手设置了 limit。

将其添加到 MCP 客户端的配置中(Claude Desktop:claude_desktop_config.json;Cursor: ~/.cursor/mcp.json)。安装 uv 后,uvx 会自动获取软件包,因此无需进行其他设置:

{
  "mcpServers": {
    "esportsodds": {
      "command": "uvx",
      "args": ["esportsodds", "mcp"],
      "env": {"ESPORTSODDS_API_KEY": "eo_live_..."}
    }
  }
}

或者运行 pip install esportsodds,并将 esportsodds-mcp 用作 command,不设置 args(如果客户端找不到它,请通过 which esportsodds-mcp 获取完整路径)。在 Claude Code 中:

claude mcp add --transport stdio --env ESPORTSODDS_API_KEY="$ESPORTSODDS_API_KEY" esportsodds -- uvx esportsodds mcp

这些工具包括 matches_list、matches_get、matches_maps、matches_stats、matches_vetoes、 matches_rounds、matches_lineups、odds_list、teams_list、teams_get、teams_h2h、 teams_form、teams_maps、teams_results、teams_players、tournaments_list、 tournaments_get、tournaments_teams、players_list、players_get、players_career、 players_matches、rankings_list 和 maps_list。每个工具对应上方方法表中的一行,并接受该方法的参数;此服务可响应 2024-11-05 至 2026-07-28 期间各版本 MCP 的客户端。

示例

examples/ 文件夹中包含可运行的脚本。每个脚本都会读取 ESPORTSODDS_API_KEY。

脚本功能
quickstart.py上文的快速入门示例。
sandbox_tour.py获取一场赛事的最新结果,然后查看一场比赛的选图、地图和顶尖选手。可使用沙盒密钥运行。
upcoming_with_odds.py获取即将开始的比赛及其当前盘口。
team_report.py获取一支队伍的近期表现、交手记录和评级。
backfill_matches.py将已结束的比赛批量拉取到 JSON Lines 文件中,并支持断点续传。
follow_changes.py根据变更源更新本地文件。
handle_errors.py读取用量额度并处理各种错误。
watch_matches.py通过 WebSocket 接收比赛更新。

常见问题

这是官方 API 吗? 不是。它不是 HLTV/Valve 的官方 API,esportsodds.gg 也未与 Valve 或任何数据统计网站建立关联,也未获得其认可。

为什么不抓取网页? 网页一旦更改,抓取就会失效,而且许多网站禁止抓取。使用此 API,你无需抓取 HLTV 或其他网站即可构建应用:只需调用稳定且有文档说明的端点。

有免费套餐吗? 当前数据不提供免费套餐,也没有试用期;Standard 套餐每月 99 美元,包含 50,000 次请求;Pro 套餐每月 299 美元,包含 150,000 次请求,均需预先付款。免费的沙盒密钥可读取固定的历史比赛样本,公开演示无需账户即可展示真实响应。

一次调用的费用是多少? 每次请求都会占用月度额度,无论返回什么内容。批量页面最多包含 25 场比赛及其详情,也只计为一次请求(对于 2026 年 10 月 30 日或之后首次订阅的 Standard 账户,每月还会占用 250 次批量导出请求中的一次)。遍历器(iter、pages、iter_bulk、iter_changes)每获取一页就计为一次请求。WebSocket 不计费。

支持 asyncio 吗? 客户端是同步的,可安全地在线程间共享。在异步代码中,可在线程中运行调用:

matches = await asyncio.to_thread(client.matches.list, status="completed", limit=10)

可以使用其他 HTTP 库吗? 可以。传入 transport=,其值可以是任何具有 send(TransportRequest) -> TransportResponse 方法的对象。使用默认传输方式通过代理连接时,请传入 UrllibTransport(proxies={"https": "http://proxy.example:3128"})。

支持哪些游戏? CS2(game="cs2")。game 参数是为后续推出的游戏预留的。

提供类型标注吗? 是的:软件包包含 py.typed,并通过 mypy --strict 检查。响应是普通字典,因此类型为 dict[str, Any]。

在哪里报告此客户端的错误? 请在此代码库的 issues 中报告。账户、账单或数据相关问题,请通过 esportsodds.gg 联系。

许可

此存储库中的代码根据 MIT 许可发布。该许可 适用于此客户端,不适用于其获取的数据:根据服务条款第 4 和第 5 节,数据授权您用于自己的用途,但不得再分发。

Counter-Strike 和 CS2 是 Valve Corporation 的商标。esportsodds.gg 是独立网站,与 Valve 无关联,也未获得 Valve 的认可或赞助。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。