开发者

API 参考

通过 HTTPS 只读访问物品目录、价格、在售商品以及您自己的订单和钱包,并通过签名 Webhook 接收账户上的事件。

概览

所有接口都是此基础地址下的 GET 请求,返回 JSON。金额以美元计,格式为十进制字符串。OpenAPI 文档描述了每个字段。

BASEhttps://api.cs2sell.com/v1/public
GEThttps://api.cs2sell.com/v1/openapi.jsonOpenAPI 3 文档

认证

以 Bearer 令牌形式发送密钥。密钥以 sk_ 开头,仅在创建时显示一次。每个密钥都带有权限范围,除 /v1/public/me 外,每个接口都需要其中之一。 在“账户 → 安全”中创建密钥。

curl https://api.cs2sell.com/v1/public/me \
  -H "Authorization: Bearer sk_…"
{
  "api_key_id": "6f1c2d3e-…",
  "user_id": "0b7e9a41-…",
  "tier": "free",
  "scopes": ["catalog:read", "orders:read"],
  "rate_limit_per_minute": 60
}

接口

中间一列是各接口所需的权限范围。

接口权限范围返回内容
GET /v1/public/me任意密钥当前调用所用的密钥:版本、权限范围和速率限制。
GET /v1/public/catalogcatalog:read搜索物品目录。分页
GET /v1/public/items/{id}catalog:read单个物品及其各款式。
GET /v1/public/prices/{variant_id}catalog:read某款式在各市场的价格。
GET /v1/public/marketplacescatalog:read我们追踪价格的市场。
GET /v1/public/listingslistings:readCS2Sell 上的在售商品,支持筛选。分页
GET /v1/public/ordersorders:read您的订单。分页
GET /v1/public/wallet/balancewallet:read您的可用余额和待结算余额。

分页

列表接口接受 ?page=(从 1 开始)和 ?page_size=(默认 50,最多 100),并返回如下结构:

{
  "items": [ … ],
  "page": 1,
  "page_size": 50,
  "total": 1284
}

速率限制

每个密钥的每个权限范围都有独立的每分钟额度,因此频繁查询目录不会占用订单查询的额度。每个响应都会告知当前用量。

版本每分钟请求数(每个权限范围)
免费60可用
专业600即将推出
商业3000即将推出
X-RateLimit-Limit
该权限范围每分钟允许的请求数。
X-RateLimit-Remaining
当前分钟内剩余的请求数。
X-RateLimit-Reset
距本分钟重置的秒数。
Retry-After
随 429 返回:重试前需等待的秒数。

错误

错误使用 HTTP 状态码和一个可供匹配的稳定错误码。params 用于填充错误消息的占位符,校验错误还会附带 fields 列表。

HTTP/1.1 403 Forbidden

{
  "error": {
    "code": "api_keys.scope_missing",
    "params": { "scope": "orders:read" }
  }
}

Webhook

添加端点并选择需要的事件。每个事件以 JSON 形式 POST 推送,并使用端点密钥(whsec_…)签名。 在“账户 → 安全”中添加。

事件

listing.created
您的商品已上架
listing.sold
您的商品已售出
listing.cancelled
您的商品已被您或平台下架
order.completed
您的订单已交付
order.refunded
您的订单已退款
trade.completed
机器人或 P2P 交易已完成
trade.reversed
Steam 上的交易被撤回
wallet.deposit
充值已到账
wallet.withdrawal
提现已发出或失败

请求头

X-CS2Sell-Signature
sha256= 加上以您的密钥对原始请求体计算的 HMAC-SHA256 十六进制值。
X-CS2Sell-Event
事件名称,请求体中也有。
X-CS2Sell-Delivery-Id
每次推送唯一,重试时保持不变;可用于去重。
X-CS2Sell-Timestamp
本次尝试发送时的 Unix 时间。

验证推送

请在解析之前对原始请求体计算 HMAC,并使用恒定时间比较。使用密钥 whsec_example 时,以下请求体的签名为:

X-CS2Sell-Signature: sha256=ca488ead1f388f2edbd01f592eeb29b9c27225c76da89e2e78a4abb6ca451c6e

{"id":"0b9c6f2e-4f7a-4c55-9a43-2d6f1f0e8a11","event":"listing.sold","created_at":"2026-10-08T12:00:00Z","data":{"listing_id":"5d1b2a90-7c3e-4b8e-9f0a-6a2c4e8d1f37","order_id":"c2e4f6a8-1b3d-4f5a-8c7e-9d0b2a4c6e81","price_usd":"42.50","kind":"p2p"}}

请在 10 秒内返回任意 2xx。否则将在 30 秒、5 分钟、30 分钟、2 小时、6 小时和 24 小时后重试;第六次失败后端点将被停用,并通知您。端点必须是公网 http 或 https 地址,且不会跟随重定向。

Node.js 快速上手

无需安装 SDK:API 就是普通的 HTTPS 和 JSON。每个快速上手示例都会读取 /v1/public/me 并验证 Webhook 签名。

// Node.js 18+: fetch and crypto are built in.
import { createHmac, timingSafeEqual } from 'node:crypto';

const res = await fetch('https://api.cs2sell.com/v1/public/me', {
  headers: { Authorization: `Bearer ${process.env.CS2SELL_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.code);
console.log(body.tier, res.headers.get('x-ratelimit-remaining'));

// Verify a webhook against the raw body, before parsing it.
export function verify(rawBody, signature, secret) {
  const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(signature ?? '');
  return a.length === b.length && timingSafeEqual(a, b);
}

Python 快速上手

# pip install requests
import hashlib, hmac, os
import requests

r = requests.get(
    "https://api.cs2sell.com/v1/public/me",
    headers={"Authorization": f"Bearer {os.environ['CS2SELL_API_KEY']}"},
    timeout=10,
)
r.raise_for_status()
print(r.json()["tier"], r.headers["X-RateLimit-Remaining"])

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    """Check X-CS2Sell-Signature against the raw request body."""
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

Go 快速上手

package cs2sell

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

type Me struct {
	Tier               string   `json:"tier"`
	Scopes             []string `json:"scopes"`
	RateLimitPerMinute int      `json:"rate_limit_per_minute"`
}

func FetchMe() (*Me, error) {
	req, err := http.NewRequest("GET", "https://api.cs2sell.com/v1/public/me", nil)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("CS2SELL_API_KEY"))
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("cs2sell: %s", res.Status)
	}
	var me Me
	return &me, json.NewDecoder(res.Body).Decode(&me)
}

// Verify checks X-CS2Sell-Signature against the raw request body.
func Verify(body []byte, signature, secret string) bool {
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write(body)
	expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
	return hmac.Equal([]byte(expected), []byte(signature))
}