Skip to content

Quick Reference

福狼 edited this page May 12, 2026 · 3 revisions

steam-go Toolkit Feature Quick Reference

This page only covers generic SDK utilities and addons. It intentionally avoids detailed client.API.* business API coverage.

Purpose

steam-go is not only a Steam Web API wrapper. It also provides a practical toolkit for real-world network execution:

  • Client construction and configuration
  • API key / access token management
  • Retry, backoff, and rate limiting
  • Proxy selection and health-checked proxy pools
  • Per-traffic-class request policies
  • Store-page browser-like headers, Referer, short cache, and block detection
  • OpenID and A2S addons
  • Unified error model and URL redaction

A simple mental model:

steam-go = Steam Web API Client + Network Policy Toolkit + Steam Addons

Table of Contents


1. Client Configuration

NewClient is the root entrypoint of the SDK. It uses functional options to compose toolkit features.

client, err := steam.NewClient(
    steam.WithTimeout(10*time.Second),
    steam.WithSafeDefaults(),
)
if err != nil {
    panic(err)
}
defer client.Close()

WithSafeDefaults() enables a conservative external-traffic preset:

retry = 2
rate limit = 3 requests/second
burst = 3

This is a good starting point before tuning per-service behavior.


2. Credential Management

2.1 Static API Key

client, err := steam.NewClient(
    steam.WithAPIKey("your-steam-web-api-key"),
)

Purpose:

Automatically inject a Steam Web API key into requests.

2.2 Static Access Token

client, err := steam.NewClient(
    steam.WithAccessToken("your-access-token"),
)

Purpose:

Prepare a default access token for endpoints that need one.

2.3 Rotating API Keys

client, err := steam.NewClient(
    steam.WithAPIKeys("key-a", "key-b", "key-c"),
)

Purpose:

Rotate across multiple keys to avoid hitting the same key too often.

2.4 Health-Checked API Keys

client, err := steam.NewClient(
    steam.WithHealthCheckedAPIKeys(
        steam.DefaultAPIKeyHealthConfig(),
        "key-a",
        "key-b",
    ),
    steam.WithRetry(2),
)

Purpose:

When a key repeatedly hits 401 / 429, it enters a temporary cooldown and later requests prefer other keys.

2.5 Custom Credential Providers

client, err := steam.NewClient(
    steam.WithAPIKeyProvider(myProvider),
    steam.WithAccessTokenProvider(myTokenProvider),
)

Purpose:

Use this when keys or tokens come from a database, config center, KMS, or dynamic refresh logic.

3. Retry, Backoff, and Rate Limiting

3.1 Simple Retry

client, err := steam.NewClient(
    steam.WithRetry(2),
)

Purpose:

Handle temporary network failures, 429, and 5xx responses.

3.2 Custom Backoff

client, err := steam.NewClient(
    steam.WithRetry(3),
    steam.WithRetryBackoff(300*time.Millisecond, 3*time.Second),
    steam.WithRetryRespectRetryAfter(true),
)

Purpose:

Control retry delay and allow Retry-After to override local backoff.

3.3 Simple RPS Limit

client, err := steam.NewClient(
    steam.WithRateLimit(3),
)

Purpose:

Limit overall request speed, for example 3 requests per second.

3.4 Token Bucket Rate Limiter

client, err := steam.NewClient(
    steam.WithRateLimiter(rate.Limit(5), 10),
)

Purpose:

Tune limit and burst more precisely.

4. Response Body Size Limit

client, err := steam.NewClient(
    steam.WithMaxResponseBodyBytes(8 << 20),
)

Purpose:

Limit how many bytes the SDK buffers for one response body.
This protects clients from unexpected huge HTML pages, error pages, or large JSON payloads.

The SDK already has a default cap. Production applications should tune it explicitly when needed.


5. Custom HTTP Capabilities

5.1 Custom BaseURL

client, err := steam.NewClient(
    steam.WithBaseURL("http://127.0.0.1:8080"),
)

Purpose:

Local mocks, testing gateways, internal proxies, or record/replay tests.

5.2 Inject a Custom HTTP Client

httpClient := &http.Client{
    Timeout: 15 * time.Second,
}

client, err := steam.NewClient(
    steam.WithHTTPClient(httpClient),
)

Purpose:

Reuse the caller's existing HTTP client settings.

5.3 CookieJar

client, err := steam.NewClient(
    steam.WithDefaultCookieJar(),
)

Purpose:

Keep cookie state for OpenID, public pages, or future session-based page flows.

You can also provide your own jar:

client, err := steam.NewClient(
    steam.WithCookieJar(myJar),
)

6. Proxy System

Proxy support is centered around the ProxySelector abstraction.

type ProxySelector interface {
    Next(req *http.Request) (*url.URL, error)
}

6.1 Static Proxy

selector, err := steam.NewStaticProxySelector("http://127.0.0.1:7897")
if err != nil {
    panic(err)
}

client, err := steam.NewClient(
    steam.WithProxySelector(selector),
)

Purpose:

Route all requests through one fixed proxy.

6.2 Round-Robin Proxy

selector, err := steam.NewRoundRobinProxySelector(
    "http://127.0.0.1:7897",
    "http://127.0.0.1:7898",
)

client, err := steam.NewClient(
    steam.WithProxySelector(selector),
)

Purpose:

Rotate requests across multiple proxies.

6.3 Health-Checked Proxy Pool

selector, err := steam.NewHealthCheckedRoundRobinProxySelector(
    steam.DefaultProxyHealthConfig(),
    "http://127.0.0.1:7897",
    "http://127.0.0.1:7898",
)

client, err := steam.NewClient(
    steam.WithProxySelector(selector),
)

metrics := selector.(steam.ProxyMetricsProvider).ProxyMetricsSnapshot()
fmt.Printf("healthy=%d cooling=%d\n", metrics.HealthyProxies, metrics.CoolingProxies)

Purpose:

When a proxy repeatedly fails, it enters cooldown and is skipped temporarily.

6.4 Sticky Proxy

baseSelector, err := steam.NewRoundRobinProxySelector(
    "http://127.0.0.1:7897",
    "http://127.0.0.1:7898",
)

sticky := steam.NewStickyProxySelector(baseSelector)

client, err := steam.NewClient(
    steam.WithProxySelector(sticky),
)

ctx := steam.WithProxySessionKey(context.Background(), "browser-session-1")
_ = ctx

Purpose:

Keep the same proxy for the same explicit session key.
Useful for browser sessions, login-like flows, and OpenID callback verification.

6.5 Routing Proxy

selector, err := steam.NewRoutingProxySelector(
    steam.ProxyRoute{
        Host:       "api.steampowered.com",
        PathPrefix: "/ISteamUser/",
        ProxyURL:   "http://127.0.0.1:7897",
    },
    steam.ProxyRoute{
        Host:       "steamcommunity.com",
        PathPrefix: "/openid/",
        ProxyURL:   "",
    },
)

Purpose:

Choose different proxies by host and path.
An empty ProxyURL means direct connection.

6.6 Standalone Proxy-Aware HTTP Client

selector, _ := steam.NewStaticProxySelector("http://127.0.0.1:7897")

httpClient, err := steam.NewHTTPClientWithProxySelector(
    selector,
    10*time.Second,
)

Purpose:

Reuse the same proxy selection logic for addons or non-core SDK HTTP flows.

7. Traffic Policy

TrafficPolicy lets different request categories use different execution strategies.

Current core traffic classes:

steam.TrafficClassOfficialAPI
steam.TrafficClassPublicStorePage

7.1 Per-Class Rate Limiting

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            RateLimiter: &steam.TrafficRateLimiterPolicy{
                Limit: 10,
                Burst: 10,
            },
        },
    ),
)

Purpose:

Official API traffic and public Store page traffic can use different rate limits.

7.2 Explicit Traffic Class Context

ctx := steam.WithTrafficClass(
    context.Background(),
    steam.TrafficClassPublicStorePage,
)

Purpose:

Force one request into a specific traffic class.

7.3 What TrafficPolicy Can Override

steam.TrafficPolicy{
    ProxySelector:   proxySelector,
    CookieJar:       cookieJar,
    RateLimiter:     rateLimiter,
    Retry:           retryPolicy,
    HostControl:     hostControl,
    SessionControl:  sessionControl,
    Cache:           cachePolicy,
    BlockPolicy:     blockPolicy,
    HeaderProfile:   headerProfile,
    RefererSelector: refererSelector,
    TransportHook:   hook,
}

Mental model:

TrafficPolicy = per-traffic-class proxy, cookies, retry, rate limit, cache, headers, Referer, and transport extension.

8. Store Page Header Profiles

8.1 zh-CN Browser-Like Profile

profile := steam.DefaultPublicStoreHeaderProfileZH()

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            HeaderProfile: &profile,
        },
    ),
)

8.2 en-US Browser-Like Profile

profile := steam.DefaultPublicStoreHeaderProfileEN()

Purpose:

Use browser-like User-Agent, Accept, Accept-Language, and related headers for public Store page requests.

9. Referer Policies

9.1 Static Referer

referer, err := steam.NewStaticRefererSelector(
    "https://store.steampowered.com/search/",
)

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            RefererSelector: referer,
        },
    ),
)

9.2 Routing Referer

referer, err := steam.NewRoutingRefererSelector(
    steam.RefererRoute{
        Host:       "store.steampowered.com",
        PathPrefix: "/app/",
        RefererURL: "https://store.steampowered.com/",
    },
)

9.3 Context-Driven Referer

fallback, _ := steam.NewStaticRefererSelector("https://store.steampowered.com/")
selector := steam.NewContextRefererSelector(fallback)

ctx := steam.WithRefererSource(
    context.Background(),
    "https://store.steampowered.com/app/730/",
)
_ = selector
_ = ctx

Purpose:

Make a request look like it comes from a specific page transition.

10. Short Cache and Conditional Requests

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            Cache: &steam.TrafficCachePolicy{
                TTL: time.Minute,
            },
        },
    ),
)

Purpose:

Reuse short-lived GET responses.
Support conditional requests with ETag / Last-Modified revalidation.

Good fits:

Public Store pages
Public HTML
Resources that do not change frequently

11. Block Detection

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            BlockPolicy: &steam.TrafficBlockPolicy{
                HTMLSniffBytes: 4096,
            },
        },
    ),
)

Purpose:

Detect 429, 403, HTML challenge pages, and suspicious block responses.

It mainly applies to:

TrafficClassPublicStorePage

It should not be treated as a default behavior for normal official API calls.


12. Host / Session Controls

12.1 Host-Level Control

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            HostControl: &steam.TrafficHostControlPolicy{
                MaxConcurrent: 2,
                RateLimiter: &steam.TrafficRateLimiterPolicy{
                    Limit: 2,
                    Burst: 2,
                },
            },
        },
    ),
)

Purpose:

Control max concurrency and request rate for the same host.

12.2 Session-Level Control

ctx := steam.WithRequestSessionKey(context.Background(), "user-session-1")

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            SessionControl: &steam.TrafficSessionControlPolicy{
                MaxConcurrent: 1,
            },
        },
    ),
)

_ = ctx

Purpose:

Limit concurrency for the same request session.
Useful for login-like flows, browser-like page flows, and Store page access.

13. TransportHook Extension Point

TransportHook is a low-level HTTP execution stack extension point.

client, err := steam.NewClient(
    steam.WithTrafficPolicy(
        steam.TrafficClassPublicStorePage,
        steam.TrafficPolicy{
            TransportHook: steam.TransportHookFunc(
                func(class steam.TrafficClass, base *http.Client) (*http.Client, error) {
                    cloned := *base
                    return &cloned, nil
                },
            ),
        },
    ),
)

Purpose:

Replace or wrap the HTTP execution stack at the traffic-class level when normal http.Client settings are not enough.

Useful for future extensions:

TLS tuning
Custom Transport
Browser-backed fallback
More complex proxy adaptation

14. OpenID Addon

addons/openid is used for browser-based Steam sign-in verification.

What it does:

1. Build the Steam OpenID login URL
2. Verify the Steam callback
3. Call check_authentication
4. Return SteamID64, ClaimedID, and state

What it does not do:

It does not replace a Steam Web API key.
It does not fetch user profile data automatically.
It does not manage your application session.

Run the example:

go run ./examples/openid

Run with a proxy:

go run ./examples/openid --proxy http://127.0.0.1:7897

Purpose:

Use it when your website needs "Sign in through Steam".

15. A2S Addon

addons/a2s is a lightweight bridge for A2S server queries.

Purpose:

Query game servers directly instead of calling the Steam Web API.

Query Server Info

go run ./examples/a2s -server 1.2.3.4:27015 -query info

Query Players

go run ./examples/a2s -server 1.2.3.4:27015 -query players

Query Rules

go run ./examples/a2s -server 1.2.3.4:27015 -query rules

Related addons:

addons/a2s
addons/a2s/master
addons/a2s/scanner

Mental model:

Web API queries Steam platform data.
A2S queries specific game server data.

16. Error Model

SDK errors use *steam.APIError.

Error stages:

request_build
transport
http_status
decode
api_response

Example:

var apiErr *steam.APIError
if errors.As(err, &apiErr) {
    fmt.Println(apiErr.Kind)
    fmt.Println(apiErr.StatusCode)
    fmt.Println(apiErr.BodyPreview)
}

Purpose:

Quickly identify whether an error happened during request construction, transport, HTTP status handling, response decoding, or API response validation.

17. URL Redaction

Steam key and access_token values are often passed through query parameters. Do not log raw URLs in production.

safeURL := steam.RedactSensitiveURL(
    "https://api.steampowered.com/xxx?key=SECRET&access_token=TOKEN&x=1",
)

fmt.Println(safeURL)
// https://api.steampowered.com/xxx?x=1

Purpose:

Remove sensitive query parameters before writing URLs to logs, traces, or error reporting systems.

18. Feature Summary Table

Feature Purpose Typical Use Case
NewClient Create SDK client Root entrypoint
WithSafeDefaults Conservative external-traffic preset Quick safe setup
WithAPIKey Static API key Normal Web API calls
WithAPIKeys Rotating API keys Multi-key scheduling
WithHealthCheckedAPIKeys Key cooldown on repeated failures 401 / 429 handling
WithAccessToken Static access token User-authorized endpoints
WithRetry Retry requests Network jitter, 5xx, 429
WithRetryBackoff Tune retry delay Controlled retry rhythm
WithRateLimit Simple rate limit Avoid sending too fast
WithRateLimiter Token bucket Fine-grained rate limiting
WithMaxResponseBodyBytes Response body cap Protect memory
WithHTTPClient Inject HTTP client Reuse custom HTTP stack
WithCookieJar Cookie session OpenID / page requests
ProxySelector Proxy selection abstraction Root of proxy features
NewStaticProxySelector Static proxy Single proxy
NewRoundRobinProxySelector Round-robin proxies Multiple proxies
NewHealthCheckedRoundRobinProxySelector Proxy cooldown on failures Proxy pool
NewStickyProxySelector Sticky proxy Login / session flows
NewRoutingProxySelector Routing proxy Split by host/path
TrafficPolicy Per-class request strategy API / Store page separation
HeaderProfile Browser-like headers Store pages
RefererSelector Referer management Page transition simulation
TrafficCachePolicy Short cache Repeated GET
TrafficBlockPolicy Block detection Store-page risk handling
HostControl Host-level concurrency control Single-domain protection
SessionControl Session-level concurrency control Single-user / session protection
TransportHook HTTP stack extension Advanced customization
addons/openid Steam sign-in verification Website login
addons/a2s Game server queries Server info / players / rules
APIError Unified error model Error classification
RedactSensitiveURL URL redaction Log safety

Clone this wiki locally