Уровень, ELO и статистика матчей для страниц игроков и ботов сообщества. Достаточно ключа WOK; отдельный ключ FACEIT не нужен.
Откуда данные FACEIT? Из FACEIT через интерфейс, который использует его сайт. Для запросов нужен ключ WOK; отдельный ключ FACEIT не требуется. Доступные методы описаны в документации API.
Ранг и статистика FACEIT: включены, без ключа FACEIT. 2 бесплатные проверки в сутки на один IP. Без регистрации.
Посмотреть три примера карточки игрока: полученные показатели, отсутствующие данные и сбой запроса истории.
Какой API и ключ FACEIT выбрать
Выберите источник по задаче. WOK — независимый сервис; ключ WOK и ключ официального FACEIT Data API не взаимозаменяемы.
| Интеграция | Подходящая задача | Ключ и границы доступа |
|---|
| WOK API | Карточка игрока или бот с публичным профилем Steam, ELO, уровнем CS2, общей статистикой и последними матчами FACEIT. | Храните ключ WOK на сервере. Ниже описаны поддерживаемые методы профиля, статистики и истории. Данные адаптируются из интерфейса сайта FACEIT; полное покрытие официального Data API не обещается. |
|---|
| FACEIT Data API | Приложение, напрямую использующее документированные ресурсы игроков, команд и соревнований FACEIT. | Создайте приложение в FACEIT Developer Portal и используйте ключ FACEIT по официальной документации. Этот ключ не авторизует запросы к WOK. |
|---|
FACEIT Data API · Официальная инструкция по ключам
Методы WOK и параметры запросов · Объединить Steam и FACEIT · Добавить публичные предметы CS2
- Найдите игрокаПередайте SteamID64 в
game_player_id с game=cs2. Читайте ELO и уровень из games.cs2.faceit_elo и games.cs2.skill_level. - Сохраните идентификатор игрока FACEITИспользуйте полученный
player_id в путях запросов статистики и истории. SteamID64 и никнейм не заменяют этот идентификатор. - Запросите нужные дополнительные данныеОбщая статистика находится в
lifetime; необязательный segments[] содержит разрезы Map или Competition с режимом mode из того же ответа. Метка Competition является идентификатором соревнования, а не его названием. Матчи находятся в items[]; необязательный match_stats.Headshots содержит число хедшотов, а не процент. История принимает limit от 1 до 20. Для выбора страницы используйте отдельный HTTP-запрос с page от 0 до 100. Позиции страниц могут меняться.
Скачайте руководство по полям и страницам FACEIT (Markdown, англ.). В нём описаны границы данных, необязательные поля и явный HTTP-запрос страницы; SDK 1.3.0 запрашивает только первую страницу истории.
Храните WOK_API_KEY и WOK_STEAM_ID из 17 цифр в окружении сервера. Нужен ключ тарифа Players или универсального тарифа с доступом к FACEIT; отдельный ключ FACEIT не требуется. Не размещайте ключ WOK в коде браузера, сообщениях бота или публичных URL.
Три запроса через cURL
# Задайте WOK_API_KEY и WOK_STEAM_ID в окружении сервера.
set -eu
curl --fail-with-body --max-time 35 --get \
-H "Authorization: Bearer $WOK_API_KEY" \
"https://woksteamapi.com/faceit/data/v4/players" \
--data-urlencode "game=cs2" \
--data-urlencode "game_player_id=$WOK_STEAM_ID"
# Сохраните player_id из ответа в WOK_FACEIT_PLAYER_ID.
curl --fail-with-body --max-time 35 \
-H "Authorization: Bearer $WOK_API_KEY" \
"https://woksteamapi.com/faceit/data/v4/players/$WOK_FACEIT_PLAYER_ID/stats/cs2"
curl --fail-with-body --max-time 35 \
-H "Authorization: Bearer $WOK_API_KEY" \
"https://woksteamapi.com/faceit/data/v4/players/$WOK_FACEIT_PLAYER_ID/history?game=cs2&limit=5"
Полный клиент на Python
# Python 3: установите requests; задайте WOK_API_KEY и WOK_STEAM_ID.
import json
import os
import re
import requests
steam_id = os.environ["WOK_STEAM_ID"]
if not re.fullmatch(r"[0-9]{17}", steam_id):
raise SystemExit("WOK_STEAM_ID должен содержать SteamID64 из 17 цифр")
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['WOK_API_KEY']}"
def read(path, params=None, *, allow_missing=False):
response = session.get("https://woksteamapi.com" + path,
params=params, timeout=(5, 30),
allow_redirects=False)
if allow_missing and response.status_code == 404:
return None
response.raise_for_status() # Остановиться при ошибке ключа, квоты или источника.
return response.json()
profile = read("/faceit/data/v4/players", {
"game": "cs2", "game_player_id": steam_id,
}, allow_missing=True)
if profile is None:
raise SystemExit("Для этого SteamID64 не найден профиль FACEIT CS2")
player_id = profile.get("player_id", "")
if not re.fullmatch(r"[A-Za-z0-9-]{1,64}", player_id):
raise SystemExit("В профиле отсутствует допустимый player_id")
# Эти два запроса необязательны: запрашивайте только нужные странице данные.
stats = read(f"/faceit/data/v4/players/{player_id}/stats/cs2")
history = read(f"/faceit/data/v4/players/{player_id}/history",
{"game": "cs2", "limit": 5})
print(json.dumps({
"nickname": profile.get("nickname"),
"rank": profile.get("games", {}).get("cs2", {}),
"lifetime": stats.get("lifetime", {}),
"recent_matches": history.get("items", []),
}, indent=2))
Полный клиент на Node.js
// Node.js 18+: задайте WOK_API_KEY и WOK_STEAM_ID на сервере.
const key = process.env.WOK_API_KEY;
const steamId = process.env.WOK_STEAM_ID;
if (!key || !/^[0-9]{17}$/.test(steamId || "")) {
throw new Error("Задайте WOK_API_KEY и WOK_STEAM_ID из 17 цифр");
}
async function read(path, params = {}, allowMissing = false) {
const url = new URL(path, "https://woksteamapi.com");
url.search = new URLSearchParams(params);
const response = await fetch(url, {
headers: { Authorization: `Bearer ${key}` },
signal: AbortSignal.timeout(35_000),
redirect: "error"
});
if (allowMissing && response.status === 404) return null;
if (!response.ok) throw new Error(`WOK HTTP ${response.status}`);
return response.json();
}
const profile = await read("/faceit/data/v4/players", {
game: "cs2", game_player_id: steamId
}, true);
if (!profile) throw new Error("Для этого SteamID64 не найден профиль FACEIT CS2");
if (!/^[A-Za-z0-9-]{1,64}$/.test(profile.player_id || "")) {
throw new Error("В профиле отсутствует допустимый player_id");
}
const playerPath = `/faceit/data/v4/players/${encodeURIComponent(profile.player_id)}`;
// Необязательные запросы: получайте только нужные странице игрока данные.
const stats = await read(`${playerPath}/stats/cs2`);
const history = await read(`${playerPath}/history`, { game: "cs2", limit: "5" });
console.log({ nickname: profile.nickname, rank: profile.games?.cs2,
lifetime: stats.lifetime, recent_matches: history.items });
Эти клиенты выполняют не более трёх запросов и останавливаются при ошибке; автоматических повторов нет. Полный сценарий расходует три единицы квоты, если все вызовы допущены к выполнению. Каждый запрос профиля, статистики или истории стоит одну единицу, включая ответ из кэша. GET /v1/key показывает доступ, остаток квоты и время сброса без расхода единицы запроса.
Читайте ответ, сохраняя неизвестные значения
Метрики lifetime, например Matches, Wins и Average K/D Ratio, при наличии возвращаются строками. Отсутствующее поле означает недоступные данные, а не ноль. Записи последних матчей могут содержать finished_at (Unix-время в секундах), elo, elo_delta и match_stats с картой, счётом, убийствами и смертями. Экранируйте имена и подписи перед вставкой в HTML.
Различайте отсутствие данных, проблемы доступа и временные сбои
| Ответ | Значение и дальнейшее действие |
|---|
| Профиль: HTTP 404 | Игрок FACEIT для этого SteamID и игры не найден. Это не означает ошибку аккаунта Steam. |
|---|
Статистика: HTTP 200, lifetime:{} | Общая статистика не получена. Сохраните профиль, оставьте отсутствующие показатели пустыми. |
|---|
История: HTTP 200, items:[] | Последние матчи не получены. Профиль игрока при этом остаётся действительным. |
|---|
| HTTP 400 / 422 | Проверьте идентификаторы и параметры; значение limit для истории должно быть от 1 до 20. |
|---|
| HTTP 401 / 403 / 402 | Проверьте действительность ключа, доступ к методу, состояние аккаунта и квоты. Устраните причину перед повторным запросом. |
|---|
| HTTP 429 / 503 | Учитывайте Retry-After, если он передан. Приостановите цикл опроса до снятия ограничения или восстановления доступности. |
|---|
| HTTP 502 | Источник FACEIT временно недоступен. Сохраните предыдущий результат с отметкой об устаревании и повторите запрос позже с ограничением числа попыток; не заменяйте ранг нулём. |
|---|
Кэш и границы источника данных
Снимки профиля и общей статистики используют настраиваемый TTL кэша, по умолчанию — шесть часов. Ранг из кэша может отставать от только что завершённого матча. Для последних матчей нет постоянного кэша результатов: выполняется отдельный запрос к источнику с ограниченным временем ожидания. История также зависит от доступности FACEIT и не гарантирует немедленное появление завершённого матча. Эти ответы не содержат времени наблюдения или точного возраста кэша; время получения ответа вашим клиентом не подтверждает свежесть данных.
WOK адаптирует подтверждённые публичные поля сайта-источника и не обещает полное покрытие официального FACEIT API. Необязательные memberships и friends_count не подтверждают платную подписку или полноту списка друзей. Профили и инвентари Steam запрашиваются отдельно; ни один метод не открывает закрытые данные Steam.
Как превратить ответы FACEIT в карточку игрока
Три вымышленных примера показывают, какие данные можно вывести пользователю. Это не реальные игроки, отзывы клиентов или свежие данные FACEIT. Профиль, статистика и история ниже — фрагменты отдельных HTTP-ответов; внешние подписи profile, stats, history и http_status добавлены для сравнения и не являются новым форматом ответа API.
Профиль, статистика и один полученный матч
Example playerELO 1450 · Уровень 6120 матчей · 68 победСредний K/D: 1.10Полученный матч: +20 ELO · 12 хедшотов
Сопоставить сохранённые ответы с карточкой
{
"profile": {
"http_status": 200,
"body": {
"player_id": "example-player",
"nickname": "Example player",
"games": {
"cs2": {
"faceit_elo": 1450,
"skill_level": 6
}
}
}
},
"stats": {
"http_status": 200,
"body": {
"lifetime": {
"Matches": "120",
"Wins": "68",
"Average K/D Ratio": "1.10"
}
}
},
"history": {
"http_status": 200,
"body": {
"start": 0,
"end": 1,
"items": [
{
"match_id": "example-match",
"game_id": "cs2",
"elo": 1450,
"elo_delta": 20,
"match_stats": {
"Kills": "24",
"Deaths": "16",
"Headshots": "12"
}
}
]
}
}
}
12 — число хедшотов в этом матче, а не процент. Средний K/D из lifetime относится к общей статистике; не подменяйте им K/D отдельного матча. Одна строка истории не доказывает полноту списка матчей.
Профиль есть, дополнительные данные не получены
Example playerELO 1450 · Уровень 6Матчи: недоступноСредний K/D: недоступноПоследние матчи не получены
Сопоставить сохранённые ответы с карточкой
{
"profile": {
"http_status": 200,
"body": {
"player_id": "example-player",
"nickname": "Example player",
"games": {
"cs2": {
"faceit_elo": 1450,
"skill_level": 6
}
}
}
},
"stats": {
"http_status": 200,
"body": {
"lifetime": {}
}
},
"history": {
"http_status": 200,
"body": {
"start": 0,
"end": 0,
"items": []
}
}
}
Сохраните успешно полученный профиль и ранг. Пустые lifetime и items не доказывают, что игрок никогда не играл. Не превращайте отсутствующий счётчик матчей в 0 и не выводите K/D 0.00.
Нулевые счётчики получены, история временно недоступна
Example playerELO 1450 · Уровень 60 матчей · 0 побед в ответе lifetimeСредний K/D: недоступноИстория временно недоступна
Сопоставить сохранённые ответы с карточкой
{
"profile": {
"http_status": 200,
"body": {
"player_id": "example-player",
"nickname": "Example player",
"games": {
"cs2": {
"faceit_elo": 1450,
"skill_level": 6
}
}
}
},
"stats": {
"http_status": 200,
"body": {
"lifetime": {
"Matches": "0",
"Wins": "0"
}
}
},
"history": {
"http_status": 502
}
}
Строка "0" — полученное значение; отсутствующий Average K/D Ratio остаётся неизвестным. Ошибка HTTP 502 относится к запросу истории: она не отменяет уже сохранённый успешный профиль и не означает отсутствие матчей. Эти раздельные ответы могут относиться к разным снимкам источника.
Время наблюдения и точный возраст кэша в этих ответах отсутствуют: не ставьте отметку «обновлено сейчас» по времени загрузки страницы. Клиенты выше намеренно останавливаются при ошибке. Если ваше приложение должно сохранить карточку при сбое необязательного запроса, сначала сохраните успешный ответ профиля, затем обработайте ошибку статистики или истории отдельно. Сравнение примеров не отправляет запросов и не расходует квоту.
Запустите общую карточку игрока Steam и FACEIT
Скачайте пример Steam + FACEIT на Python и следуйте инструкции по настройке и запуску (англ.). Связывайте два сервиса по найденному SteamID64; храните сведения Steam и ранг FACEIT в отдельных полях. Отсутствие аккаунта FACEIT не делает профиль Steam недействительным. Отсутствующий ранг и показатели lifetime оставляйте недоступными, не заменяйте нулём. Храните ключ WOK на сервере.
Полная справка API · Контракт OpenAPI · Добавить профиль Steam (англ.) · Обзор API CS2 (англ.) · Тарифы и лимиты запросов