MCPcopy Index your code
hub / github.com/dank/rlapi

github.com/dank/rlapi @v0.1.20

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.1.20 ↗ · + Follow
399 symbols 862 edges 39 files 156 documented · 39%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

rlapi

Go Reference GitHub Release GitHub License

ITEM SHOP DEMO

rlapi is a reverse engineered collection of Rocket League's internal APIs with a Go SDK. It provides a full end-to-end flow, from authentication to accessing the item shop, player stats, inventory, match history, replays, and more. This repository also contains resources for reverse engineering and analyzing Rocket League network traffic, serving as a foundation for further exploration. Not all endpoints are fully documented—do not ask about specific ones, as I probably don't know.

Contributions

All contributions are welcome! If you discover new endpoints, extend the Go SDK, or add additional functionality, please submit a PR.

Getting Started

Refer to the godoc for detailed documentation on the Go SDK.

Comprehensive examples are available in the examples directory.

Usage

go get github.com/dank/rlapi

Authentication

Rocket League authentication always goes through Epic Online Services (EOS), either via the Epic Games Store (EGS) or by exchanging a Steam session ticket for an EOS token.

This library provides full end-to-end authentication via EGS. Steam login and ticket generation are out of scope, but a method is provided to exchange a Steam session ticket for an EOS token, and users can leverage external libraries such as steam-user or Steamworks to obtain the ticket.

Intercepting Requests

Traditional proxy tools like Fiddler don't work with Rocket League due to certificate pinning.

To intercept traffic, we use Frida dynamic instrumentation to hook curl functions at runtime, disabling SSL verification and redirecting API traffic to a local MITM server.

MITM Server

The MITM proxy forwards both HTTP and WebSocket traffic to the official servers while intercepting and logging requests and responses. Authentication responses are rewritten so the WebSocket URL points to the local server.

[!NOTE] Refer to the respective READMEs in tools/frida/ and tools/mitm/ directories for more details and usage instructions.

Reconstructing Requests

Authentication

Rocket League initially establishes a connection with the HTTP API before transitioning to a WebSocket connection. The client sends an EOS access token via HTTP and receives session credentials, the WebSocket endpoint URL, and any tokens required for further communication. The client then connects to the WebSocket using these tokens, allowing all subsequent API calls to occur over a persistent WebSocket connection.

Signing

All API requests and responses must include a PsySig header containing a Base64-encoded HMAC-SHA256 signature. The signing keys were reverse engineered from the game binary and are XOR'd with a 4-byte pattern. To decrypt:

# Raw IDA dump
data = [0x36, 0xEA, 0x37, 0x0C, ...]  # 36 bytes total

key_bytes = [data[i] ^ data[(i % 4) + 32] for i in range(32)]
  • Request Key: c338bd36fb8c42b1a431d30add939fc7
  • Format: HMAC-SHA256(key, "-" + <request body>)
  • Response Key: 3b932153785842ac927744b292e40e52
  • Format: HMAC-SHA256(key, PsyTime + "-" + <response body>)

Request Protocol

WebSocket Schema

WebSocket messages require a custom HTTP-like schema with headers and JSON body:

PsyService: Matchmaking/StartMatchmaking v2
PsyRequestID: PsyNetMessage_X_1
PsyToken: authentication-token
PsySessionID: session-identifier
PsySig: request-signature
PsyBuildID: 151471783
User-Agent: RL Win/250811.43331.492665 gzip
PsyEnvironment: Prod

{"playlist_id": 10, "region": "USE"}

The message format is: headers (each ending with \r\n) followed by \r\n\r\n separator, then JSON body.

Required Headers

(Values may be outdated)

Name HTTP WS Value
PsyService WS event name
PsyRequestID PsyNetMessage_X_0 Incrementing idempotency key (also for request/response matching
PsyToken WS auth token
PsySessionID WS session identifier
PsySig Base64-encoded HMAC signature of the body
PsyBuildID 151471783 Varies by build
PsyEnvironment Prod Varies by build
FeatureSet PrimeUpdate55_1 Varies by build
User-Agent RL Win/250811.43331.492665 gzip Varies by build
User-Agent RL Win/250811.43331.492665 gzip (x86_64-pc-win32) curl-7.67.0 Schannel Varies by build
Content-Type application/x-www-form-urlencoded JSON body but form type

HTTP Endpoints

The HTTP API is used only for authentication and to bootstrap the WebSocket connection. Unlike before, there is no way to "downgrade" the WebSocket connection to HTTP (AFAIK).

The base URL for HTTP requests is: https://api.rlpp.psynet.gg/rpc/.

POST Auth/AuthPlayer/v2

[!NOTE] When the API refers to a "Player ID", it typically expects the following format: <platform>|<platform-specific account ID>|0 For example, on Steam: Steam|76561197960287930|0. The final 0 is always included, though its purpose is unknown.

Request
PsyRequestID: PsyNetMessage_X_0 
PsyBuildID: 151471783
PsyEnvironment: Prod
User-Agent: User-Agent: RL Win/250811.43331.492665 gzip (x86_64-pc-win32) curl-7.67.0 Schannel
PsySig: <HMAC signature>
Content-Type: application/x-www-form-urlencoded

{
  "Platform": "<platform>",
  "PlayerName": "<player name>",
  "PlayerID": "<platform account ID>",
  "Language": "INT",
  "AuthTicket": "<EOS access token>",
  "BuildRegion": "",
  "FeatureSet": "PrimeUpdate55_1", // varies by build
  "Device": "PC",
  "LocalFirstPlayerID": "<player ID>",
  "bSkipAuth": false,
  "bSetAsPrimaryAccount": true,
  "EpicAuthTicket": "<EOS auth ticket>",
  "EpicAccountID": "<Epic account ID>"
}
Response
{
  "Result": {
    "IsLastChanceAuthBan": false,
    "VerifiedPlayerName": "<player name>",
    "UseWebSocket": true, // forcing this to false doesn't do anything
    "PerConURL": "wss://...", // unused / legacy?
    "PerConURLv2": "wss://...", // url for ws connection
    "PsyToken": "<auth token>", // used by subsequent ws requests
    "SessionID": "<session id>", // used by subsequent ws requests
    "CountryRestrictions": []
  }
}

WebSocket Events

[!NOTE] For complete request/response schema definitions, refer to the godoc documentation instead.

The following is an incomplete list of WebSocket events, some events may be undocumented or partially understood.

The WebSocket endpoint URL is returned by the authentication endpoint, it is currently: wss://ws.rlpp.psynet.gg/ws/gc2.

Core symbols most depended-on inside this repo

sendRequestSync
called by 81
psynetrpc.go
Error
called by 41
psynet.go
String
called by 15
playerid.go
Close
called by 15
psynetrpc.go
NewPsyNet
called by 12
psynet.go
establishSocket
called by 10
psynet.go
readMessages
called by 9
psynetrpc.go
schedulePing
called by 8
psynetrpc.go

Shape

Struct 214
Method 120
Function 56
TypeAlias 9

Languages

Go99%
TypeScript1%
Python1%

Modules by API surface

clubs.go34 symbols
tournaments.go28 symbols
party.go26 symbols
misc.go25 symbols
skills.go21 symbols
shops.go20 symbols
players.go20 symbols
challenges.go19 symbols
psynetrpc_test.go18 symbols
rocketpass.go17 symbols
psynetrpc.go17 symbols
products.go17 symbols

For agents

$ claude mcp add rlapi \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact