krapio
Library reference

Library reference

Classes

ClassDescription
ClanApiGET /api/clan/*: a clan's profile and members
EventsApievents the key's scopes allow, kept for 30 days; own limit of 6 requests a minute on top of the key's
KpdApiplayer hacker reports; needs the kpd scope on the key
Krunkerthe three krunker apis behind one object: - the documented developer api on the root (krunker.player, krunker.market, ...), needs apiKey - krunker.game.*, what the game itself reads without any auth - krunker.as(token).*, what the game reads with the player's own frvr token
KrunkerArgumentErrora call was made with an argument the api would reject, nothing was sent
KrunkerBadRequestError400, the api rejected a parameter the local checks did not catch
KrunkerClientthe http layer under every tier: one base url, one rate limit tracker, typed errors, one retry on a 5xx or a network error
KrunkerConfigErrorno api key configured
KrunkerDeveloperApithe documented developer api; one key is one rate limit window, so keep one instance per key
KrunkerErrorthe base of every error krapio throws
KrunkerForbiddenErrorthe api key is invalid or revoked; on a token endpoint the player lacks the role (moderator, kpd reviewer)
KrunkerGameApiwhat the game reads without any auth: no key, no documented limits, shapes from live replies; reads only
KrunkerHttpErrora reply with a non 2xx status; the subclasses cover the common ones
KrunkerNetworkErrorthe request never got an http reply
KrunkerNotFoundError404, no such player, clan, map, mod or match
KrunkerRateLimitError429, or a request refused locally because the window is known to be empty
KrunkerServerErrora 5xx; retried once before it is thrown
KrunkerTokenApireads that need the player's frvr access token (FRVR.auth.getFreshAccessToken() in the game). the token is only ever sent as a bearer header, never stored or logged; every write of the game api is left out on purpose
KrunkerTokenErrora player token that is malformed or already expired, nothing was sent
KrunkerUnauthorizedErrora token endpoint without a valid token: missing, expired or rejected
LeaderboardApiGET /api/leaderboard/*: the ranked leaderboard per region
MapApiGET /api/map/* and /api/maps/*: map details, featured maps and map leaderboards
MarketApiGET /api/market/*: listings, owners and price history per skin
MatchApiGET /api/match/*: one ranked match with its participants
ModsApiGET /api/mods/*: the mod list and single mods
PlayerApiGET /api/player/*: profile, inventory, listings, ranked matches and posts of a player
PublicClansApiGET /clans/*: clan profiles, loot config, motd and the recruitment board
PublicGameApithe static game data the page loads at start plus the community map and mod records
PublicItemsApithe item page of the social market, by skin index
PublicLeaderboardsApiGET /leaderboards/*: player, clan, raid and KrunkCup boards
PublicLegacyApiapi.krunker.io, the old rest api; only the paths the page calls without a token
PublicMarketApithe market reads that answer without a token; listings, inventory and history need one (token wrapper)
PublicMatchmakerApimatchmaker.krunker.io, plain json without an envelope; the game polls the list every 60 s
PublicPlayersApiGET /players/*: the social profile, search, sales, followers and feed
PublicShopApithe shop's catalogue data; the wild offer and every purchase need the player's token
PublicSocialApithe social feed; a player's own posts are players.feed
PublicTurfApiGET /territorial-wars/*: Turf Wars status, clans, players and leaderboards
RateLimitTrackermirrors the X-RateLimit-* headers so a call can be refused before it costs a request
SkinsApiGET /api/skins/*: the skin definitions
TokenCreatorApiwhat a creator sees of their own maps and studios, plus the clan applications of the player
TokenMarketApithe market behind a login: listings, the player's inventory, sales and history, the black market
TokenPlayerApithe token's own account: /player, /account, /email, /discord, /guest
TokenRankedApiapi.krunker.io behind a token: the ranked system's own api, plain {data} without an error field on success
TokenSessionthe token bound resources plus the token's claims; made by Krunker.as(token)
TokenShopApiper player shop state and the player's own custom skins (the editor's /skins)
TokenStaffApirole gated reads: moderators and kpd reviewers; a normal token gets 403 "insufficient permissions"
TokenTradesApiplayer to player trades; creating, accepting and cancelling are writes and stay out

Type Aliases

Type AliasDescription
ApiErrorBodybody of every error reply
ApiEventone event of GET /api/events or of a webhook delivery
BlackMarketGET /market/black-market, the skin indices on offer
BlackMarketRankGET /market/black-market/rank, null without a ranked history
BrowserQuerycategory tab (index) and page (pos) of the legacy map and mod browsers, 0 based
ClanLeaderboardRowone row of GET /leaderboards/player_clan
ClanLeaderboardSortsort of the clan leaderboard
ClanLootConfigGET /clans/:id/loot-config
ClanMemberone row of a clan's member list
ClanMembersGET /api/clan/:name/members, 10 per page
ClanMotdGET /clans/:id/motd
ClanProfileGET /api/clan/:name
ClanPublicMemberone member in a public clan profile, short keys as the game sends them
ClanPublicProfileGET /clans/by-name/:name and /clans/:id/profile
ClientOptionsoptions shared by every tier; apiKey only matters for the developer api
CommunityLeaderboardQuerypage, board type and order of a community map leaderboard
CommunityMapGET /maps/by-name/:name, the community map record (the official Burg is a different thing, see OfficialMap)
CommunityMapLeaderboardGET /maps/by-name/:name/leaderboard
CreatorEventsGET /creators/events, the menu's event and survey box
CreatorPolla running survey of GET /creators/events
CustomSkina custom skin of the token's player (the skin editor)
CustomSkinsPageGET /skins, the player's custom skins paged
CustomSkinsQuerypage, page size and filters of the player's custom skins
DailySpinProgressGET api.krunker.io/daily-spin/progress
DayMapQueryturf day and map filter; today and every map when omitted
DiscordStatusGET /discord/status, the optional fields only while linked
DropCampaigna running drop campaign
EmailPreferencesGET /email/preferences
Envelopethe reply envelope of gapi.svc.krunker.io, a non-null error comes with a 4xx or 5xx
EventsPageGET /api/events
EventsQueryfilters of GET /api/events; keep them the same between calls when paging with after
EventTargetwhat an event is about, e.g. type "map" and the map id
EventTypethe types documented so far; a key only sees the types of the event scopes it holds
FeaturedMapone featured map
FeaturedMapsGET /api/maps/featured
FeedPostone post of the social feed, short keys as the game sends them
FeedTabtab of GET /social/feed; only global has been seen
FetchLikeonly the call signature, so a wrapper or a mock needs none of fetch's statics
GameApiOptionsoptions of the game tier: everything of ClientOptions but the key, no endpoint here takes one
GameListGET /game-list, every public lobby
GameListEntry[game id, region key, players, max players, options, seconds left]
GameOptionsthe options object inside a game list entry
GuestProfileGET /guest/profile, zeros without a guest token
InventoryItemone entry of GET /api/player/:name/inventory
InventoryItemMetadataundocumented: kounter stats and float data of one owned skin, every field optional; shape from the community wrapper
InventoryStackone inventory stack: skin index, count, instance id, state
ItemInstanceone row of GET /items/:id/instances: the holder's name, the serial and the wear where the skin has one
ItemListingone live listing on an item page, the same row the token tier's market/listings feed gives
ItemOwnerone of an item's top owners, short keys as the game sends them
ItemPricesGET api.krunker.io/webhooks/general/items/prices: index = skin index, null = no price
ItemSaleone day of sales of an item: kr, count, date; GET /items/:id/sales and /market/items/:id/sales-statistics
ItemSalesInfoGET /market/items/:id/sales: the ask range, circulation and the top owners' player ids, despite the path no sales
ItemViewGET /items/:id/view, the item page of the social market: the whole order book of the skin, not a page of it
KpdCallone row of GET /api/kpd/latest-calls
KpdCallContext0 public, 1 ranked, 2 comp, 3 custom
KpdCallRating0 pending, 1 banned, 2 rejected
KpdCallStatus1 not responded, 2 responded, 3 reviewed
KpdDemosQueryoffset and search of the kpd demo queue
KrunkCupPlayerRowrows of /leaderboards/krunkcup/players and .../teams/:id/contributors
KrunkCupTeamone row of GET /leaderboards/krunkcup/teams
KrunkerOptionsoptions of Krunker: ClientOptions without baseUrl, every tier picks its own host
LeaderboardEntryone row of the ranked leaderboard
LeaderboardOrder0 = ascending (lower is better), 1 = descending
LeaderboardTypewhich built in board a map has: score or time
LegacyMapListGET api.krunker.io/webhooks/general/maps/list
LegacyMapRowone row of the legacy map browser
LegacyModListGET api.krunker.io/webhooks/general/mods/list
LegacyModRowone row of the legacy mod browser
LiveListingone active listing on the live market
Loggeroptional sinks, nothing is logged without one
LootDistributionModehow a clan splits its turf earnings
LotteryGET /lottery/:id, every past draw with its prizes
MapConfigGET /maps/:id, the whole map file (120 KB for Burg), only the keys the client reads are named
MapEventDatadata of map.featured and map.unfeatured
MapInfoGET /api/map/:name
MapLeaderboardGET /api/map/:name/leaderboard, 25 per page
MapLeaderboardEntryone row of a map leaderboard
MapLeaderboardPlayerGET /api/map/:name/leaderboard/player/:player, one player's entry
MapLeaderboardQuerywhich of a map's boards to read and in which order
MarketHistoryGET /market/history
MarketHistoryEntryone completed buy or sell of the player
MarketHistoryQuerysort, cursor and limit of GET /market/history
MarketHistorySortsort of the player's market history
MarketListingone active listing of a skin on the market
MarketListingsGET /market/listings
MarketListingsQueryfilters, sort and cursor of GET /market/listings
MarketListingsSortsort of the live market listings
MarketListRequestthe body the game posts to /market/list; krapio never sends it
MarketListResultthe reply to POST /market/list: the kr left, the stack left of that skin, the new listing's market id
MarketOwnerone owner in a skin's top owners
MarketPurchaseRequestthe body the game posts to /market/purchase
MarketPurchaseResultthe reply to POST /market/purchase: the kr left, the bought instance, the listing's market id and skin index
MarketSkinGET /api/market/skin/:skinindex
MarketSkinQuerypage of listings and days of price history for a market skin
MarketStatRowone row of GET /market/stats: skin index, in circulation, on sale, and the ask range while something is listed
MarketStatsGET /market/stats, paged by cursor
MarketStatsQueryfilters, sort and cursor of GET /market/stats
MarketStatsSortsort of GET /market/stats; "rarity" is what the market tab sends, an unknown value is answered with the default order
MarketUnlistRequestthe body the game posts to /market/unlist
MarketUnlistResultthe reply to POST /market/unlist
MatchDetailsGET /api/match/:id
MatchesQuerypage and season of a player's ranked matches
MatchHistoryEntryone player's line in a match of a social profile's match_history
MatchHistoryGameone match in a social profile's match_history
MatchParticipantone player of a ranked match
MatchResult1 = win, 0 = loss, -1 = draw
MePlayerGET /player/me, data is the packed account blob the game decodes itself
ModGET /api/mods/:name
ModInfoGET /mods/by-name/:name
ModsGET /api/mods, 10 per page
MyApplicationsGET /clans/my-applications, null without any
OfficialMapGET /maps, index = id = preview image number at assets.krunker.io/img/maps/map_.png
OpenListingGET /market/sales, one of the player's own open listings
Pagethe page query every paged developer endpoint takes, 1 based
PingListregion key (as in a game entry) -> lobby host:port to ping
PlayerFollowone row of GET /players/:name/followers and /following
PlayerLeaderboardQuerysort and season of a player leaderboard
PlayerLeaderboardRowone row of a player leaderboard
PlayerLeaderboardTypethe player boards GET /leaderboards/:type knows
PlayerListingone of a player's active market listings
PlayerListingsGET /api/player/:name/listings, 10 per page
PlayerMatchone ranked match from a player's point of view
PlayerMatchesGET /api/player/:name/matches, 10 per page
PlayerPostone social post of a player
PlayerPostsGET /api/player/:name/posts, 10 per page
PlayerProfileGET /api/player/:name
PlayerRankeda player's ranked stats in one region this season
PlayerSaleone day of market sales: funds earned, count sold, date
PlayerSearchResultone hit of GET /players/search
PlayerSocialProfileGET /players/:name, the legacy flat profile the social popup renders
PlayerStatsthe packed stats blob of a social profile, the developer api's profile has the same numbers under full names
PricePointone day of a skin's price history
QueryValuea query string value; undefined leaves the parameter out
RaidLeaderboardRowGET /leaderboards/raids/:mapId, 100 rows; map 31 is a raid map, 0 is not ("invalid raid map ID")
RaidSortsort of a raid leaderboard
RaidStatsa player's raid stats on one map
RankedConnectionGET api.krunker.io/ranked/me/connection
RankedLeaderboardGET /api/leaderboard/:region, 10 per page
RankedMatchHistoryGET api.krunker.io/match-history/me/..., paged
RankedMatchHistoryQuerylimit, offset, mode, ranked flag and region of the ranked match history
RankedProfileGET api.krunker.io/player-profile/me/season/:season[/region/:region], the only place with a season accuracy total
RankedProfileEntrya player's ranked card in the season rankings
RankedQuerypage and season of the ranked leaderboard
RankedShopGET /ranked/shop, the skins bought with ranked currency
RateLimitStatewhat the tracker knows: the key's window and the routes with a window of their own
RateLimitWindowone rate limit window as the last reply described it
RecruitmentBoardGET /clans/recruitment, paged
RecruitmentPosta clan's post on the recruitment board
RecruitmentQuerypage, limit, region and language of the recruitment board
RegionIda ranked region id, one of Region or a number the api knows
RequestOptionswhat a resource passes to KrunkerClient.get for one request
SeasonRankingsGET api.krunker.io/leaderboards/rankings/season/:season[/region/:region]
SeasonRankingsQuerylimit, offset and region of the season rankings
ShopDisplayGET /shop/displays, a tree of displays with the products they show
ShopPriceone price of a shop product, real money or recurring
ShopProductone product in a shop display
SkinDefinitionextra config properties of a skin (creator, glow, frames, ...) get merged into the root, so the index signature is real
SkinsGET /api/skins, paged skin definitions
SkinsQuerypage, page size and season filter of the skin definitions
SocialNewsGET /social/news
SocialPostGET /social/post/:id
SoftErrora reply that carries its refusal inside data (wild offer: "Wild offer is not available")
SpinPoolone item pool of a spin wheel
SpinWheelGET /spins/wheels, the spin shop's wheels with their pools
Streamone live stream in the menu's stream box
Titleone player title of GET /titles
TokenApiOptionsoptions of the token tier: everything of ClientOptions but the key, the token replaces it
TokenClaimsthe claims of a frvr access token (RS256, about 24 h); nothing here is verified, krunker does that
TopStreamsGET api.krunker.io/streams/top
Tradeone trade, short keys as the game sends them
TradeCancelResultthe reply to POST /trades/:id/cancel
TradeCreateRequestthe body the game posts to /trades/create
TradeCurrencyone currency amount in a trade
TradeFundsResultthe reply to POST /trades/create and POST /trades/:id/accept: the kr left
TradeHistoryGET /trades/history
TradeHistoryQueryoffset, limit and whether open trades are included
TradeInventoriesGET /trades/inventory/:playerId, both sides
TradeItemone item in a trade, by skin index
TradePlayerGET /trades/player-search, one player by exact name
TurfClanGET /territorial-wars/clan/:id
TurfClanEarningone day's reward of a clan on one map
TurfClanMapa clan's standing on one turf map for one day
TurfContributionone day and map of a player's turf contributions
TurfPayoutsGET /territorial-wars/clan/:id/payouts
TurfPlayerGET /territorial-wars/player/:id
TurfPlayerEarningone payout to a player
TurfPlayerRowone row of GET /territorial-wars/clan/:id/players
TurfStatusone turf map with its current owner
TurfStatusEntryone of the top 5 clans of a turf map
TurfTopClanone row of the top performing clans board
TurfTopGrossingClanone row of the top grossing clans board
TurfTopPlayerone row of the top performing players board
UsernamesGET /account/usernames
VerifyWebhookOptionsknobs of verifyWebhook, for tests and for clocks that drift
VotedItemundocumented: a map or mod the player voted on, shape from the community wrapper
WalletGET /player/wallet, kr plus every studio currency
WalletCurrencyone currency in the wallet, kr or a studio currency
WebhookEventone webhook delivery; test and verify sends carry id 0, the real id is in the Krunker-Event-Id header
WebhookSignaturethe parsed Krunker-Signature header
WildOfferGET /shop/wild-offer, a SoftError when there is none
WristbandGET /krunkcup/wristband

Variables

VariableDescription
DEFAULT_BASE_URLgapi.svc.krunker.io, the host of the developer api and of most game endpoints
GAPI_URLgapi.svc.krunker.io, the game api and the developer api
GLOBAL_LIMITthe per key limit every endpoint shares; a reply showing a smaller limit is an endpoint's own window
LEGACY_API_URLapi.krunker.io, the old rest api and the ranked api
MATCHMAKER_URLmatchmaker.krunker.io, the lobby list
MAX_EVENT_TARGETStarget ids one events call may filter by
MAX_EVENTS_PER_PAGEthe largest page the events endpoint serves
MAX_HISTORY_DAYSdays of price history GET /api/market/skin/:skinindex can return
MAX_SKINS_PER_PAGEthe largest page GET /api/skins serves
RAID_MAPSmap ids known to have a raid board; not enforced, so a new raid map keeps working
Regionranked region ids as the leaderboard endpoint takes them
TURF_EPOCH_UTCturf days count whole utc days from here (season 10 epoch, from the game code)
TURF_MAPS0 Burg, 2 Sandstorm, 3 Subzero
WEBHOOK_HEADERSthe headers of every delivery
WEBHOOK_TOLERANCE_Srequests whose timestamp is further off than this are rejected, as the docs ask

Functions

FunctionDescription
decodeTokenreads the claims without verifying the signature; throws KrunkerTokenError for anything that is not a live jwt
isNotFoundtype guard for KrunkerNotFoundError
isRateLimitedtype guard for KrunkerRateLimitError
isTransientretrying makes sense for these, the request itself was fine
parseWebhookSignaturethe Krunker-Signature header split up, null when it is not of the documented form
signWebhookthe Krunker-Signature value for a body, for tests and for signing your own test deliveries
turfDaythe turf day of a date: whole utc days since TURF_EPOCH_UTC
verifyWebhooktrue when the delivery was signed with the endpoint's secret and is not older than the tolerance. the body has to be the raw request body, re-serialized json gives a different signature. answer 401 when this is false, the signature check sends deliberately bad signatures and expects that

On this page