跳转到主要内容

新功能

流:通过 events 选择需要的事件类型GET /v1/listings/stream 支持 events 参数:用逗号分隔的 new、update、gone。update 约占整个流的 80%,几乎全是价格变动;只购买新挂单并删除已售出挂单的客户端可以使用 events=new,gone,流量约为原来的五分之一。不带该参数时,三种事件都会照常推送。

变更

  • 落后超过 8 MB 的流连接现在会被关闭,而不是无限缓冲。使用 Last-Event-ID 重连即可从您处理过的最后一个事件继续。如果反复发生,请用 events 和其他筛选条件缩小流量。
  • 流现在遵循与 GET /v1/listings 和快照相同的”每件实物饰品只有一条挂单”规则。同一件饰品通过多个供应商在售时,只有最便宜的一份以 new 公布;当出现更便宜的一份时,您持有的那份以 gone 退场;当已公布的那份售出时,下一份以 new 到达。此前流会公布每一份,客户端可能对同一件饰品保留两个价格,并看到快照中不存在的挂单。收到您从未收到过的 id 的 gone 属正常情况:忽略即可。上线时所有打开的连接都被关闭,此前的历史被丢弃,因此带较旧 Last-Event-ID 的重连会收到一次 resync:请从快照或 GET /v1/listings 重建视图(两者已遵循该规则),此后视图即是干净的。
  • 结账时的 item_unavailable 拒绝减少:实时价格超出您上限的挂单不再被视为已售出;在所有能够应答的市场上,挂单会在下单前先向供应商核实,因此拒绝发生在扣款之前,而不是事后退款。

新功能

流:价格变动及磨损值 / 图案稍后到达时的 update 事件GET /v1/listings/stream 现在会在您已收到的挂单价格变动,或补充 float_value / paint_seed 时发送 update(部分市场会在挂单上架几分钟后才提供这些数据)。负载是完整的 Listing,与 new 相同:请按 id 替换您的副本。借助快照以及 new / update / gone,您可以在自己一侧维护整个目录,而无需轮询 GET /v1/listings。min_price / max_price 不过滤 update,因此价格移出您范围的挂单仍会推送给您。忽略未知事件类型的客户端无需任何改动。订单失败的原因:fail_reason、fail_side、fail_message订单现在会说明失败原因,适用于 GET /v1/orders、GET /v1/orders/info、GET /v1/orders/{id} 和 order.updated 网络钩子,P2P 行也包括在内。对于 failed 或 cancelled 的订单,fail_reason 是用于程序分支判断的代码,fail_side 表示需要采取行动的一方(recipient、seller、buyer 或 market),fail_message 用一句话说明发生了什么、该怎么做。其他状态下这三个字段都为 null。此前这类订单只显示 unavailable,即使原因是收货方的库存未公开——而这恰恰只有您能解决。代码列表可能会扩充:遇到不认识的值时请按 unavailable 处理。参见 订单失败的原因。每个响应都带有速率限制头部每个携带密钥的请求,其响应都带有 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset 和 X-RateLimit-Bucket,描述该请求所消耗的额度,便于您在收到 429 之前控制节奏。GET /v1/key 会在 rate_limits 中列出密钥的全部限制。

变更

  • 携带密钥的请求现在只按密钥自身的额度计数。此前全站按 IP 的限制(约每分钟 133 次)也会计入这些请求,因此所有集成都会先于本文档中的每密钥限制被它卡住,而它返回的 x-ratelimit-limit: 1000 头部描述的也并不是您的密钥。无需密钥的端点(GET /v1/health、GET /v1/public/prices)仍按 IP 限流。参见 速率限制。
  • 交易请求(POST /v1/orders、POST /v1/market/buy、GET /v1/orders*、POST /v1/orders/{id}/claim、POST /v1/orders/{id}/cancel、GET /v1/balance)拥有独立的额度:每个密钥每分钟 3,000 次;如果密钥的读取限制更高,则以读取限制为准。以上限速度读取目录不会影响购买和订单状态轮询。
  • 来自每密钥额度的 429 rate_limit_exceeded 会指明额度:bucket(read、trading 或 buy_orders)、limit_per_min 和 retry_after_sec。Retry-After 现在是距离新的一分钟窗口开始的秒数(1–60),而不再固定为 60;snapshot_rate_limited、P2P 写操作限制和 Instant Sell 报价限制也是如此。
  • 429 too_many_streams 带有 Retry-After: 90、max_connections 和 retry_after_sec:未正常关闭就断开的流会在 90 秒内释放名额。
  • CS2 购买返回的 409 item_unavailable 会在 unknown_ids 中列出我们没有任何记录的 id:不是挂单 id(最常见的是 Steam 资产 id),或离开目录已超过一小时的挂单。unavailable_ids 仍列出所有缺失的 id。

新功能

每个订单都会标明人工交付订单现在在 GET /v1/orders、GET /v1/orders/info、GET /v1/orders/{id} 和 order.updated 网络钩子中带有 delivery_type(instant | manual)和 delivery_deadline_at,P2P 行也包括在内。manual 订单由真人发送,最长可能需要 12 小时,在此期间订单可能一直处于 delivering 且没有交易报价。delivery_deadline_at 在订单为 pending 或 delivering 时有值;如果卖家未能按时交付,订单会被自动取消并退款。取消尚未交付的订单:POST /v1/orders/{id}/cancelPOST /v1/orders/{id}/cancel 可取消尚无人发货的订单,并将款项退回您的余额。人工交付的订单在购买 31 分钟后可取消,其他订单在 15 分钟后可取消;过早调用会返回 425 too_early 及 retry_after_sec。玩家(P2P)挂单无法通过此接口取消。

新功能

购买 Dota 2 和 Rust 并交付到任意交易链接POST /v1/market/buy 现在与 POST /v1/orders 一样,在请求体中接受 appId:Dota 2 为 570,Rust 为 252490。不传时该端点照旧购买 CS2。
  • 付款和交付方式与 CS2 相同:只使用已结算余额,皮肤发送到由 partner + token 组成的交易链接。
  • Dota 2 或 Rust 订单最多 10 个 id,超出返回 400 too_many_items。
  • Dota 2 和 Rust 订单进入队列,因此每个皮肤最初返回 pending。请通过 GET /v1/orders/info 或 order.updated 网络钩子跟踪订单。

新功能

同一套 API 支持 Dota 2 和 Rust——用 appId 选择游戏除 CS2 外,CSBoard 现在也销售 Dota 2 和 Rust 的商品,API 通过一个新参数即可访问它们。传入 Steam 的 appId——Dota 2 为 570,Rust 为 252490——端点就会按该游戏返回。不传则返回 CS2,与之前逐字节一致。
  • appId 可作为查询参数用于 GET /v1/listings、GET /v1/prices 和 GET /v1/listings/availability,也可作为请求体字段用于 POST /v1/orders。
  • Dota 2 和 Rust 的行与 CS2 的行键名相同。仅 CS2 才有的字段为 null,stickers 为 [],一个解析器即可读取三个游戏。
  • 在其他游戏下发送仅限 CS2 的过滤参数(wear、min_float、max_float、stat_trak、souvenir、available_after、sort=newest),会返回 400 invalid_param,而不是被悄悄忽略。
  • 您的密钥无法使用的 appId 会返回 400 unsupported_game,并附带 supported_app_ids。新端点 GET /v1/games 列出您的密钥可读取的游戏,以及是否可以在其中购买。
  • Dota 2 和 Rust 订单返回 delivery: "pending" 和 expected_minutes: null。
SSE 流、批量快照和 POST /v1/market/buy 仍然仅支持 CS2。无需密钥的价格数据源:GET /v1/public/pricesGET /v1/public/prices 为 CS2、Dota 2 或 Rust 的每个 market_hash_name 返回一个最低报价。无需 API 密钥,也无需余额。CS2 的多普勒相位会合并到 Steam 的基础名称下,因此每个键都对应一个真实的 Steam 名称。数据源每分钟重建一次,每个 IP 每分钟限 1 次请求。通过 API 在 P2P 市场上架您自己的饰品——免费五个新端点让密钥可以将其所有者的 CS2 物品发布到 CSBoard P2P 市场出售。无余额要求,也无需交易权限——任何有效密钥均可。网站上的卖家规则原样适用;售出的物品仍需通过 Steam 发出并用 Steam 令牌确认,款项才会计入您的余额。有一处刻意的不同:低于我们市场价一半的价格会以 422 price_below_market 拒绝。通过密钥无法确认绕过这一下限,因此泄露的密钥无法被用来贱卖您的库存。写操作限制为每个密钥每分钟 30 次。P2P 上架指南介绍了完整流程。

修复

购买超时现在返回 504 而非 500。 当市场在购买过程中停止响应时,结果确实是未知的——购买仍可能已经完成。POST /market/buy 和 POST /orders 现在为此返回 504 upstream_timeout,并明确说明这一点。关键在于:幂等声明现在会被保留而不是释放。重新发送相同的 custom_id / Idempotency-Key 会重放原始结果,而不会再次购买;在原请求尚未确定时发送的重试将返回 409 idempotency_in_progress。在将 504 视为失败之前,请先轮询订单列表。确定性错误(价格变动、余额不足、商品不可用)保持不变。并发冲突现在返回 409 concurrent_update。 当两个订单同时涉及相同商品时,失败方的事务会完整回滚——未扣款、未预留。此前这会表现为 500,现在是带 Retry-After 的 409,因为此时重试正是正确的做法。

新功能

不要再轮询新挂单——直接订阅在今天之前,发现新库存的唯一方式就是更频繁地轮询 GET /v1/listings,而这种开销无法在客户端之间分摊:十个接入方各自每分钟 300 次请求,就是对同一张表进行十次独立的深度扫描,返回的还几乎是相同的行。更糟的是,大家轮询的东西根本回答不了这个问题——sort=newest 是按记录创建时间排序的,因此从已取消订单、过期交易报价和解除冻结中回到目录的商品永远不会浮到顶部,无论轮询多快。三项新增,全部向后兼容:
  • 新端点 GET /v1/listings/stream——Server-Sent Events。一个连接即可取代任何轮询循环,并且除 new 之外还会推送 gone 事件。后者是轮询无法表达的:轮询方只能在尝试购买并失败后才发现商品已售出。通过标准的 Last-Event-ID 请求头可实现无缝重连,包括在我们发布新版本期间。
  • GET /v1/listings 新增查询参数 available_after——把轮询变成增量读取。通常的响应是一个空页面。请将水位线回退约 60 秒并按 id 去重;参数文档解释了为什么这个回退不是可选项。
  • 每个 Listing 新增字段 listed_at——商品进入目录的时间,也正是 sort=newest 现在的排序依据。重新上架的商品会与真正的新库存一起浮现。
现有结构没有变化:sort=newest 保留了名称和排序方向,只是不再隐藏重新上架的商品。

修复

修正文档中的速率限制此前公布的限额偏低,影响了您的吞吐:定点读取为 每分钟 100 次,而非 30 次;POST /v1/orders 为 每分钟 250 次,而非 30 次。如果您按旧数字设计了客户端,实际余量比您以为的更大——如果您正打算申请提额,请先试试 available_after 或流式订阅。

新功能

极速出售 API(仅限受邀访问)通过 CSBoard 的机器人网络以程序化方式出售 CS2 饰品。对 Steam 库存进行报价、创建出售订单,待 Steam 的交易保护冻结期结束(约 8 天)后,款项将结算到您的 CSBoard 余额。
  • 使用 POST /v1/sell/quotes 对任意 Steam 库存进行报价 —— 每一件符合条件的物品都会返回您将获得入账的准确美元金额。
  • 使用 POST /v1/sell/orders 创建订单,可选传入 min_total_usd 以防范价格波动,并通过 external_id 实现幂等性。
  • 使用 GET /v1/sell/orders/:id 跟踪生命周期(pending → offer_sent → received → completed)及结算金额。大批量物品可能被拆分到最多 3 个机器人处理。
  • 每个报价都会公开发送方机器人的 Steam 个人资料和 trade_offer_id,方便您向出售方展示防冒充校验信息。
  • 访问权限按账户单独开通 —— 调用 GET /v1/sell/status 查询当前状态,如需申请开通请联系客服。
完整流程请参阅 极速出售指南。

Fixes

Precise 402 error codes on POST /v1/market/buyThe endpoint now distinguishes the two out-of-funds cases instead of always returning insufficient_settled_balance:
  • insufficient_balance — the account balance is simply lower than the order total. Top up and retry.
  • insufficient_settled_balance — the balance covers the total, but part of it is still inside the reversal window and cannot fund external delivery yet.
Both responses now include balance_usd alongside required_usd and settled_usd, so a bot can tell the cases apart programmatically. If your integration matched on the insufficient_settled_balance code for generic low-funds handling, match on HTTP 402 instead.Held orders also gained a small post-unlock grace before claimable flips to true — claiming at the exact unlock instant previously failed on the marketplace side.

新功能

通过 API 领取持有订单对于进入市场持有状态的订单(status: "hold" 并带有 hold_until 时间戳),现在可以通过程序释放它们。当 hold_until 过后,调用 POST /v1/orders/:id/claim 即可领取订单。成功领取后,市场会发送一个 Steam 交易报价,您的机器人必须在约 15 分钟内接受。部分持有订单会自动交付 —— 此时该调用为无害的空操作。autoclaim 账户设置在 POST /v1/orders 或 POST /v1/market/buy 上设置 autoclaim: true,每个持有订单都会在其持有窗口结束的瞬间自动释放,无需为每个订单单独调用。该标志在账户级别持久生效。listings 和 prices 接口支持精确 name 过滤向 GET /v1/listings 或 GET /v1/prices 传递 name 查询参数,按精确的 market_hash_name 获取单个物品(不区分大小写)。与 search 不同,后者执行模糊词匹配,可能在重叠名称(例如 Spectrum Case 与 Spectrum 2 Case)上发生冲突;name 只返回您请求的物品。当同时提供两个参数时,name 优先生效 —— 无需再对响应做后续过滤。使用示例请参阅 市场数据。