Every method here is reached through the Steam facade
(Fkrzski\LaravelSteamApiSdk\Facades\Steam): an endpoint on the resource for its Steam
interface, the rest on the facade itself. Endpoints take a
SteamId wherever they
identify a user and return readonly DTOs from the underlying SDK, documented in
Data objects.
Resources
Section titled “Resources”The base SDK groups its endpoints into one resource per Steam interface, and the facade
hands each back as the connector builds it — AppsResource, NewsResource,
PlayersResource, StatsResource, UsersResource and WebApiResource from
Fkrzski\SteamApiSdk\Http\Resources.
Steam::apps(): AppsResourceSteam::news(): NewsResourceSteam::players(): PlayersResourceSteam::stats(): StatsResourceSteam::users(): UsersResourceSteam::webApi(): WebApiResource| Resource | Steam interface | Methods |
|---|---|---|
Steam::apps() |
ISteamApps |
sdrConfig(), serversAtAddress(), upToDateCheck() |
Steam::news() |
ISteamNews |
appNews() |
Steam::players() |
IPlayerService |
badges(), communityBadgeProgress(), ownedGames(), recentlyPlayedGames(), steamLevel() |
Steam::stats() |
ISteamUserStats |
achievements(), currentPlayers(), globalAchievements(), schema(), userStats() |
Steam::users() |
ISteamUser |
bans(), friends(), groups(), resolveVanityUrl(), summaries() |
Steam::webApi() |
ISteamWebAPIUtil |
serverTime(), supportedApis() |
A resource sends through the same scoped connector the facade uses, so
fake() covers one you reached before installing the mock.
Endpoints
Section titled “Endpoints”Alphabetical, each under its resource. newsFeed() is the one the bridge adds on the facade
itself.
achievements()
Section titled “achievements()”Steam::stats()->achievements(SteamId $steamId, int $appId, ?Language $language = null): PlayerAchievementsReturns a player’s achievements for one game, each with its unlock state and time.
language localises the achievement name and description. Steam answers a private
profile and an app without achievements identically, so a 400 becomes
StatsUnavailableException either way; a 401 is the hidden-profile case.
use Fkrzski\SteamApiSdk\Enums\Language;
$result = Steam::stats()->achievements($steamId, appId: 381210, language: Language::English);
foreach ($result->achievements as $achievement) { echo $achievement->apiName, ' — ', $achievement->achieved ? 'unlocked' : 'locked', PHP_EOL;}appNews()
Section titled “appNews()”Steam::news()->appNews( int $appId, ?int $count = null, ?int $maxLength = null, ?DateTimeInterface $endDate = null, list<string> $feeds = [], list<string> $tags = [],): AppNewsReturns an app’s news, newest first: Steam’s own announcements beside the blog and press feeds
it collects. count caps the page, 20 when omitted, while total counts every post the filter
matches. feeds and tags filter by feed name and tag, and no key goes out. An app ID Steam
does not know raises, and so do some it does, such as Spacewar, because Steam answers the two
alike.
$news = Steam::news()->appNews(appId: 440, count: 5, feeds: ['steam_community_announcements']);
foreach ($news->items as $item) { echo $item->publishedAt->format('Y-m-d'), ' — ', $item->title, PHP_EOL;}badges()
Section titled “badges()”Steam::players()->badges(SteamId $steamId): PlayerBadgesReturns every badge a player has earned, with the XP and level they add up to.
Trading-card badges name the app they came from; event and milestone badges leave
appId null. An account with no badges answers with level 0 rather than raising.
$badges = Steam::players()->badges($steamId);
echo $badges->playerLevel, ' — ', $badges->xpNeededToLevelUp, ' XP to go', PHP_EOL;
foreach ($badges->badges as $badge) { echo $badge->badgeId, ' level ', $badge->level, PHP_EOL;}bans()
Section titled “bans()”Steam::users()->bans(list<SteamId> $steamIds): list<PlayerBan>Fetches community, VAC, game and economy bans for 1 to 100 players. Ban records
are public, so a hidden profile still returns a row. An empty list of IDs raises
InvalidArgumentException, more than 100 raises TooManySteamIdsException.
$bans = Steam::users()->bans([$steamId]);
foreach ($bans as $ban) { echo $ban->steamId->value, ' — ', $ban->isVacBanned ? 'VAC banned' : 'clean', PHP_EOL;}communityBadgeProgress()
Section titled “communityBadgeProgress()”Steam::players()->communityBadgeProgress(SteamId $steamId): list<CommunityBadgeQuest>Returns the quests behind the Steam community badge, each with the flag saying whether
the account finished it. Steam publishes no names for them, so questId stays opaque.
foreach (Steam::players()->communityBadgeProgress($steamId) as $quest) { echo $quest->questId, $quest->completed ? ' — done' : ' — pending', PHP_EOL;}currentPlayers()
Section titled “currentPlayers()”Steam::stats()->currentPlayers(int $appId): intReturns how many players are in a game right now, as a plain int rather than a DTO.
Steam serves it without a key; an app ID it does not know answers 404 and raises.
$playing = Steam::stats()->currentPlayers(appId: 381210);friends()
Section titled “friends()”Steam::users()->friends(SteamId $steamId, ?FriendRelationship $relationship = null): list<Friend>Lists a player’s friends, each with the relationship and the date it started.
relationship narrows the result; omit it to let Steam decide.
use Fkrzski\SteamApiSdk\Enums\FriendRelationship;
$friends = Steam::users()->friends($steamId, FriendRelationship::Friend);
foreach ($friends as $friend) { echo $friend->steamId->value, ' — since ', $friend->friendSince->format('Y-m-d'), PHP_EOL;}globalAchievements()
Section titled “globalAchievements()”Steam::stats()->globalAchievements(int $gameId): list<GlobalAchievement>Returns the share of the player base holding each achievement in a game. The argument
keeps the name the base SDK gives it — Valve spells this one endpoint’s identifier
gameid, though the value is an ordinary app ID. No key goes out here either.
foreach (Steam::stats()->globalAchievements(gameId: 381210) as $achievement) { echo $achievement->apiName, ' — ', round($achievement->percent, 2), '%', PHP_EOL;}groups()
Section titled “groups()”Steam::users()->groups(SteamId $steamId): list<UserGroup>Lists the community groups a player belongs to, each as a UserGroup carrying its
gid; empty when the player is in no group. Steam returns group IDs only — resolve
names through the community API yourself.
$groups = Steam::users()->groups($steamId);
foreach ($groups as $group) { echo $group->gid, PHP_EOL;}newsFeed()
Section titled “newsFeed()”Steam::newsFeed( int $appId, int $perPage = 20, ?int $maxLength = null, ?DateTimeInterface $endDate = null, list<string> $feeds = [], list<string> $tags = [],): LazyCollection<int, NewsItem>throws AppNewsUnavailableException throws InvalidArgumentException
Walks an app’s news lazily, newest first, sending one appNews() request per page of
perPage only as the collection is read, so ->take(30) stops once it has 30. Every page
after the first asks for posts up to the last one’s date and skips by ID what it already yielded.
A perPage below 2 raises InvalidArgumentException.
foreach (Steam::newsFeed(appId: 440)->take(30) as $item) { echo $item->title, PHP_EOL;}ownedGames()
Section titled “ownedGames()”Steam::players()->ownedGames( SteamId $steamId, list<int> $appIdsFilter = [], bool $includeAppInfo = false, bool $includePlayedFreeGames = false,): list<OwnedGame>Lists the games a player owns. appIdsFilter narrows the result to specific app
IDs, includeAppInfo adds names and icons, includePlayedFreeGames includes free
games the player has launched.
$library = Steam::players()->ownedGames( steamId: $steamId, appIdsFilter: [381210], includeAppInfo: true,);recentlyPlayedGames()
Section titled “recentlyPlayedGames()”Steam::players()->recentlyPlayedGames(SteamId $steamId, ?int $count = null): RecentlyPlayedGamesReturns what a player launched in the last two weeks. count caps how many games come
back, while totalCount stays Steam’s own figure for the window — that is how you tell a
capped list from a complete one. A player who launched nothing comes back as
totalCount: 0, not an exception.
$recent = Steam::players()->recentlyPlayedGames($steamId, count: 5);
foreach ($recent->games as $game) { echo $game->name, ' — ', $game->playtimeTwoWeeks, ' min', PHP_EOL;}resolveVanityUrl()
Section titled “resolveVanityUrl()”Steam::users()->resolveVanityUrl(string $vanityName): SteamIdResolves a vanity slug — the <name> in steamcommunity.com/id/<name> — to a
SteamId.
$steamId = Steam::users()->resolveVanityUrl('gabelogannewell');schema()
Section titled “schema()”Steam::stats()->schema(int $appId, ?Language $language = null): GameSchemaReturns every stat and achievement a game publishes, with language localising the
achievement names and descriptions. An app that publishes no schema comes back as an
empty GameSchema — a null gameName and two empty lists — rather than raising; only
an app ID Steam does not know does that.
$schema = Steam::stats()->schema(appId: 381210);
foreach ($schema->achievements as $achievement) { echo $achievement->apiName, ' — ', $achievement->hidden ? 'hidden' : $achievement->name, PHP_EOL;}sdrConfig()
Section titled “sdrConfig()”Steam::apps()->sdrConfig(int $appId): SdrConfigReturns the Steam Datagram Relay network a game connects through, its points of presence
keyed by code. A game without a network of its own gets Valve’s default one. Steam serves
it without a key, and answers an app ID it does not know with a 500 that raises at once,
however many tries the connector allows.
$config = Steam::apps()->sdrConfig(appId: 730);
foreach ($config->pointsOfPresence['waw']->relays as $relay) { echo $relay->ipv4, ':', $relay->minPort, '-', $relay->maxPort, PHP_EOL;}serversAtAddress()
Section titled “serversAtAddress()”Steam::apps()->serversAtAddress(string $address): list<GameServer>Lists the game servers Steam knows at an IPv4 address, or only the one behind
ip:queryport. An address with no servers returns an empty list, and no key goes out.
foreach (Steam::apps()->serversAtAddress('108.181.62.21') as $server) { echo $server->address, ' runs app ', $server->appId, PHP_EOL;}serverTime()
Section titled “serverTime()”Steam::webApi()->serverTime(): DateTimeImmutableReturns Steam’s clock in UTC, as a DateTimeImmutable rather than a DTO. Steam serves it
anonymously, so no key goes out, even with one configured.
$skew = Steam::webApi()->serverTime()->getTimestamp() - time();steamLevel()
Section titled “steamLevel()”Steam::players()->steamLevel(SteamId $steamId): intReturns a player’s community level as a plain int rather than a DTO. Hiding game
details leaves the level readable — only a profile Steam withholds altogether raises.
$level = Steam::players()->steamLevel($steamId);summaries()
Section titled “summaries()”Steam::users()->summaries(list<SteamId> $steamIds): list<PlayerSummary>Fetches public profile summaries for 1 to 100 players. Same bounds as
bans(): an empty list and more than 100 IDs each raise before a request is
sent.
$summaries = Steam::users()->summaries([$steamId]);
foreach ($summaries as $summary) { echo $summary->personaName, ' — ', $summary->profileUrl, PHP_EOL;}supportedApis()
Section titled “supportedApis()”Steam::webApi()->supportedApis(): list<WebApiInterface>Lists every Web API method Steam lets the caller see, grouped by interface. The key goes along
when one is configured and adds the methods it can call, while without one Steam answers with
the anonymous list. A key Steam rejects comes back as a JSON 403 rather than its usual HTML
page, and still raises.
foreach (Steam::webApi()->supportedApis() as $interface) { foreach ($interface->methods as $method) { echo $interface->name, '/', $method->name, '/v', $method->version, PHP_EOL; }}upToDateCheck()
Section titled “upToDateCheck()”Steam::apps()->upToDateCheck(int $appId, int $version): AppVersionCheckTells a game server whether its build is still the one Steam accepts, and which version to
update to if not. Steam serves it without a key, and answers an app ID it does not know
exactly like a game publishing no server version, so both raise. App ID 0 gets a 400,
which arrives as SteamApiException itself.
$check = Steam::apps()->upToDateCheck(appId: 440, version: $installedVersion);
if (! $check->isUpToDate) { echo 'Update to ', $check->requiredVersion, ': ', $check->message, PHP_EOL;}userStats()
Section titled “userStats()”Steam::stats()->userStats(SteamId $steamId, int $appId, ?Language $language = null): UserStatsReturns a player’s stats and achievement flags for one game. language localises
achievement metadata, e.g. Language::English.
$stats = Steam::stats()->userStats($steamId, appId: 381210);
foreach ($stats->stats as $stat) { echo $stat->name, ' = ', $stat->value, PHP_EOL;}Low-level helpers
Section titled “Low-level helpers”connector()
Section titled “connector()”Steam::connector(): SteamConnectorReturns the underlying Fkrzski\SteamApiSdk\SteamConnector for the current
request. Use it for Saloon features the facade does not expose.
fake()
Section titled “fake()”Steam::fake(array<class-string, mixed> $responses = []): SteamFakeAttaches Testing\SteamFake, a Saloon MockClient, to the connector and returns it.
Refused unless the application environment is testing. Its apps(), news(),
players(), stats(), users() and webApi() fake each endpoint by name and hand the mock back — see
Faking responses. The assertions and
readers sit on the facade too, under Test assertions and
Recorded traffic.
pool()
Section titled “pool()”Steam::pool( iterable<Request>|callable $requests = [], int|callable $concurrency = 5, ?callable $responseHandler = null, ?callable $exceptionHandler = null,): Saloon\Http\PoolBuilds a Saloon Pool for sending Steam requests concurrently. See
Concurrent requests.
send()
Section titled “send()”Steam::send(Saloon\Http\Request $request): Saloon\Http\ResponseSends any Saloon Request through the shared connector and returns the raw
Response — the escape hatch for requests the resources don’t cover. Decode it with
->dto() yourself; whatever the request raises reaches you unchanged.
Events
Section titled “Events”The bridge dispatches three events for Steam traffic, from Fkrzski\LaravelSteamApiSdk\Events,
each with public readonly properties. Events covers when each
fires.
SteamRequestFailed
Section titled “SteamRequestFailed”SteamRequestFailed(Throwable $exception)The exception the caller gets: an SDK one after the retries, or whatever a listener threw.
SteamRequestSending
Section titled “SteamRequestSending”SteamRequestSending(string $method, array<string, mixed> $query, int $attempt)method is the Steam path, such as ISteamUser/GetPlayerSummaries/v2, and query what Steam
receives, without the API key. attempt is 1, then 2 for the first retry.
SteamResponseReceived
Section titled “SteamResponseReceived”SteamResponseReceived( string $method, array<string, mixed> $query, int $attempt, int $status, float $duration,)The same three as SteamRequestSending, plus the HTTP status and the duration in seconds
from sending to Steam’s answer.
Test assertions
Section titled “Test assertions”Saloon’s MockClient assertions, proxied onto the facade so a test never has to
hold the mock in a variable. See Asserting.
assertNothingSent()
Section titled “assertNothingSent()”Steam::assertNothingSent(): voidAsserts that the fake recorded no requests at all.
assertNotSent()
Section titled “assertNotSent()”Steam::assertNotSent(string|callable $request): voidAsserts that no request matching the class name, URL pattern or closure was sent.
assertSent()
Section titled “assertSent()”Steam::assertSent(string|callable $value): voidAsserts that a request matching the class name, URL pattern or closure was sent. The closure receives the request and its response, so it can assert on query parameters, headers or the payload that came back.
Steam::assertSent( fn (GetPlayerBansRequest $request): bool => count($request->steamIds) === 2,);assertSentCount()
Section titled “assertSentCount()”Steam::assertSentCount(int $count, ?string $requestClass = null): voidAsserts how many requests were sent. requestClass narrows the count to a single
request; omit it to count everything the fake recorded.
assertSentInOrder()
Section titled “assertSentInOrder()”Steam::assertSentInOrder(array<Closure|class-string<Request>|string> $callbacks): voidAsserts that these requests were sent, in this order, and nothing else with them. Saloon falls back to searching the whole history when a position does not match, so the count is the part it enforces strictly.
Recorded traffic
Section titled “Recorded traffic”Saloon’s MockClient readers, proxied onto the facade for tests that inspect the
traffic rather than assert on it. See
Recorded traffic.
lastRequest()
Section titled “lastRequest()”Steam::lastRequest(): ?Saloon\Http\RequestThe last request the fake handled, or null when nothing was sent.
lastResponse()
Section titled “lastResponse()”Steam::lastResponse(): ?Saloon\Http\ResponseThe last response the fake returned, or null when nothing was sent.
recorded()
Section titled “recorded()”Steam::recorded(): array<Saloon\Http\Response>Every response the fake recorded, in the order they came back. Reach the request
behind one through $response->getPendingRequest()->getRequest().