Response shape
GET /api/games/:slug/current returns the full
payload — everything else is a subset of this.
{
"id": 42,
"game_slug": "rust",
"version": "2026-07-08",
"label": "post-wipe hotfix",
"pinned": true,
"published": true,
"created_at": "2026-07-08T13:45:12+00:00",
"updated_at": "2026-07-08T13:45:12+00:00",
"markdown": "…the raw admin-posted markdown…",
"offsets": {
"globals": {
"il2cpphandle": "0x10132020"
},
"structs": {
"base_player": {
"cl_active_item": "0x568",
"player_eyes": "0x490",
"player_model": "0x3D8"
},
"camera": {
"view_matrix": "0x2FC",
"position": "0x444"
}
}
},
"offsets_flat": {
"il2cpphandle": "0x10132020",
"base_player.cl_active_item": "0x568",
"base_player.player_eyes": "0x490",
"base_player.player_model": "0x3D8",
"camera.view_matrix": "0x2FC",
"camera.position": "0x444"
}
}
offsets is nested — matches how you'd write it in a C++ header.
offsets_flat is the same data as a single-level lookup map. Use whichever fits your code.
- Values are strings so hex formatting is preserved verbatim. Parse to
uintptr_t on your end.
- Only fenced
cpp code blocks are parsed. Prose, JSON blocks, decrypt-routine bodies etc. are ignored.
Auto-update polling
Every response includes an ETag derived from the
build's ID and last-modified timestamp. Send it back as
If-None-Match on the next poll — you'll get a
304 Not Modified (empty body, zero transfer cost) when
nothing has changed.
GET /api/games/rust/current
< ETag: W/"b42-a1b2c3d4e5f60718"
GET /api/games/rust/current
> If-None-Match: W/"b42-a1b2c3d4e5f60718"
< 304 Not Modified
Suggested poll interval: 5–15 minutes. Anything more aggressive
is wasted; new dumps land on game patch days, not by the minute.
The response also carries
Cache-Control: public, max-age=60 and
Last-Modified, so intermediary caches (Cloudflare, your
own reverse proxy) will do the right thing automatically.
Examples
curl
curl https://staging.147-135-112-94.sslip.io/api/games/rust/current
With If-None-Match:
curl -H 'If-None-Match: W/"b42-a1b2c3d4e5f60718"' \
https://staging.147-135-112-94.sslip.io/api/games/rust/current -i
JavaScript (browser or Node)
// Poll every 10 min. If the response was 304, cached_build stays valid.
let cached_build = null;
let last_etag = "";
async function poll() {
const res = await fetch("/api/games/rust/current", {
headers: last_etag ? { "If-None-Match": last_etag } : {}
});
if (res.status === 304) return cached_build;
if (!res.ok) throw new Error(`HTTP ${res.status}`);
cached_build = await res.json();
last_etag = res.headers.get("etag") || "";
return cached_build;
}
setInterval(poll, 10 * 60 * 1000);
poll();
Python
import time, requests
BASE = "https://staging.147-135-112-94.sslip.io"
etag = None
def poll(slug: str = "rust") -> dict | None:
global etag
headers = {"If-None-Match": etag} if etag else {}
r = requests.get(f"{BASE}/api/games/{slug}/current", headers=headers, timeout=10)
if r.status_code == 304:
return None # nothing changed
r.raise_for_status()
etag = r.headers.get("ETag")
return r.json()
while True:
build = poll("rust")
if build:
print("new dump:", build["version"])
offsets = build["offsets_flat"]
# feed into your cheat's offset table here
time.sleep(600)
C++ (WinHTTP)
// Sketch — pulls the current Rust build over HTTPS and hands the JSON
// body to whatever parser you already have (nlohmann::json / rapidjson).
// Store `etag` between calls and pass it back as If-None-Match to
// avoid re-downloading unchanged dumps.
#include <winhttp.h>
#include <string>
struct FetchResult {
int status;
std::string body;
std::string etag;
};
static FetchResult fetch_current(const std::wstring& slug,
const std::wstring& if_none_match)
{
FetchResult out{};
HINTERNET sess = WinHttpOpen(L"cheatoffsets-client/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, nullptr, nullptr, 0);
HINTERNET conn = WinHttpConnect(sess, L"staging.147-135-112-94.sslip.io",
INTERNET_DEFAULT_HTTPS_PORT, 0);
const std::wstring path = L"/api/games/" + slug + L"/current";
HINTERNET req = WinHttpOpenRequest(conn, L"GET", path.c_str(),
nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
std::wstring headers;
if (!if_none_match.empty())
headers = L"If-None-Match: " + if_none_match;
WinHttpSendRequest(req,
headers.empty() ? WINHTTP_NO_ADDITIONAL_HEADERS : headers.c_str(),
(DWORD)headers.size(),
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
WinHttpReceiveResponse(req, nullptr);
DWORD status = 0, size = sizeof(status);
WinHttpQueryHeaders(req,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
WINHTTP_HEADER_NAME_BY_INDEX, &status, &size, WINHTTP_NO_HEADER_INDEX);
out.status = (int)status;
// Read ETag for the next round trip.
wchar_t etag_buf[256]{}; DWORD etag_len = sizeof(etag_buf);
if (WinHttpQueryHeaders(req, WINHTTP_QUERY_CUSTOM,
L"ETag", etag_buf, &etag_len, WINHTTP_NO_HEADER_INDEX)) {
char narrow[256]{};
WideCharToMultiByte(CP_UTF8, 0, etag_buf, -1,
narrow, sizeof(narrow), nullptr, nullptr);
out.etag = narrow;
}
// Slurp body.
DWORD avail = 0;
while (WinHttpQueryDataAvailable(req, &avail) && avail) {
std::string chunk(avail, '\0');
DWORD read = 0;
WinHttpReadData(req, chunk.data(), avail, &read);
out.body.append(chunk, 0, read);
}
WinHttpCloseHandle(req);
WinHttpCloseHandle(conn);
WinHttpCloseHandle(sess);
return out;
}
The response JSON contains an offsets_flat map
like { "base_player.cl_active_item": "0x568", ... }.
Iterate that once at boot (and on every non-304 poll) to fill your cheat's
offset table.