SDKs
The Sudomimus SDKs are strongly typed clients generated from the public OpenAPI 3.1 contracts in sudomimus/sudomimus-spec: connect.yaml (Connect protocol), native.yaml (native-api direct-issue), and device.yaml (device-api device authorization). The SDK source lives in sudomimus/sudomimus — TypeScript, Python, and C# in one monorepo. SDKs wrap the raw HTTPS calls with serialization, request/response types, JWT parsing, application public-key caching, signature verification helpers, and structured errors — everything you’d otherwise build by hand.
If you’d rather call the API directly, see Web applications for curl, Node.js, Python, and Go HTTP snippets.
Available SDKs
Section titled “Available SDKs”All packages are currently at alpha stability — usable, with the API surface tracking the spec, but expect some churn before the first stable release.
The three packages per language split along responsibility:
connect— full Connect API client (Establish, StatusPoll, Redeem, Refresh, Info, Introspect, Logout, RevokeAll). Use this in your application backend.native— Native API client (Steam ticket direct-issue, AccessKey direct-issue). Use this in desktop apps, games, CLIs.token— token-parsing utilities only (verifyAccessToken,verifyRefreshToken, thektyconstants). Useful when a service only needs to verify tokens and doesn’t call the API.
The connect and native packages already depend on token internally, so most integrations don’t need to install it explicitly.
The Device API has a published OpenAPI reference for direct HTTP clients. A dedicated SDK package will appear here after it is introduced in the SDK repository.
Tabs below are synchronised: pick your language once and every block on the page switches with it.
Install
Section titled “Install”# pnpmpnpm add @sudomimus/connect
# npmnpm install @sudomimus/connect
# yarnyarn add @sudomimus/connect# uvuv add sudomimus-connect
# pippip install sudomimus-connectInitialise the client
Section titled “Initialise the client”The client needs to know how to sign /establish requests with your application’s client-auth private key. Supply the key once at construction time; the SDK signs internally on every relevant call.
import { ConnectClient } from "@sudomimus/connect";
const client = new ConnectClient({ baseUrl: "https://connect-api.sudomimus.com", // clientAuth: configure with your application's client-auth private key // so the SDK can sign /establish and /revoke-all internally. // See the package README for the exact option shape.});from sudomimus_connect import ( ConnectClient, ConnectClientAuthWithKey,)
with ConnectClient( client_auth=ConnectClientAuthWithKey( application_anchor="my-app", private_key_pem=open("client-auth-private.pem").read(), ),) as client: ...An async equivalent exists as AsyncConnectClient with the same method names.
Establish — start a session
Section titled “Establish — start a session”const inquiry = await client.establish({ applicationAnchor: process.env.SUDOMIMUS_APPLICATION_ANCHOR!, returnMethods: [ { type: "CALLBACK", payload: { callbackUrl: "https://your-app.com/auth/callback" }, }, ],});
const { exposureKey, hiddenKey } = inquiry;from sudomimus_connect import EstablishRequest
inquiry = client.establish(EstablishRequest( applicationAnchor="my-app",))# inquiry.exposureKey, inquiry.hiddenKeyRequest fields are camelCase (applicationAnchor, returnMethods) because they’re generated from the OpenAPI schema. Method names are snake_case.
Status poll — check the session
Section titled “Status poll — check the session”const status = await client.statusPoll({ exposureKey, hiddenKey });
if (status.status === "REALIZED") { const { confirmationKey } = status; // hand off to redeem}The response is discriminated on status ("PENDING" or "REALIZED"); only REALIZED carries a confirmationKey.
from sudomimus_connect import StatusPollRequest
status = client.status_poll(StatusPollRequest( exposureKey=exposure_key, hiddenKey=hidden_key,))Redeem — exchange for tokens
Section titled “Redeem — exchange for tokens”const tokens = await client.redeem({ exposureKey, hiddenKey, confirmationKey,});
const { accessToken, refreshToken } = tokens;from sudomimus_connect import RedeemRequest
tokens = client.redeem(RedeemRequest( exposureKey=exposure_key, hiddenKey=hidden_key, confirmationKey=confirmation_key,))# tokens.accessToken, tokens.refreshTokenRefresh / introspect / logout
Section titled “Refresh / introspect / logout”// Refresh rotates the token — capture and persist the new one for next time.const { accessToken, refreshToken: newRefreshToken } = await client.refresh({ refreshToken });await store.saveRefreshToken(newRefreshToken);
const { status, recommendedRecheckSeconds } = await client.introspect({ accessToken });// status: "active" | "revoked" | "expired" | "not_found"
await client.logout({ refreshToken });
const { revokedCount } = await client.revokeAll({ subject });Endpoint semantics are documented in Managing sessions. /refresh rotates the refresh token — it returns a fresh accessToken and a new refreshToken, and the presented one is consumed; persist the replacement and use it next time. /refresh, /introspect, and /logout are self-authenticating (the token is the credential); /revokeAll requires the client-auth credentials configured at construction time.
from sudomimus_connect import ( RefreshRequest, IntrospectRequest, LogoutRequest, RevokeAllRequest,)
fresh = client.refresh(RefreshRequest(refreshToken=tokens.refreshToken))state = client.introspect(IntrospectRequest(accessToken=tokens.accessToken))client.logout(LogoutRequest(refreshToken=tokens.refreshToken))revoked = client.revoke_all(RevokeAllRequest(subject="sub_9SQ5535CRWNDDM2T"))# revoked.revokedCountInfo — fetch application metadata
Section titled “Info — fetch application metadata”const info = await client.info({ applicationAnchor, locale: "en-US",});
// info.applicationName, info.applicationPublicKeyfrom sudomimus_connect import InfoRequest
info = client.info(InfoRequest( applicationAnchor="my-app", locale="en-US",))# info.applicationName, info.applicationPublicKeyVerify access tokens
Section titled “Verify access tokens”import { TokenError } from "@sudomimus/token";
try { const token = await client.verifyAccessToken(rawJwt); // token.body.subject, token.body.firstName, token.body.lastName?} catch (error) { if (error instanceof TokenError) { // structured token verification failure } throw error;}verifyAccessToken parses the JWT, checks kty === "Access", validates expiration, then calls /info for the applicationPublicKey (cached per applicationAnchor) and checks the signature. Use verifyRefreshToken for the matching kty === "Refresh" flow, and clearPublicKeyCache() to force a refetch after a key rotation.
Connect access tokens are verified per-application, not against a shared JWKS. See Tokens and verification for the full picture.
access = client.verify_access_token(tokens.accessToken)verify_refresh_token is the matching refresh-token method.
Handle API errors
Section titled “Handle API errors”import { ConnectApiError } from "@sudomimus/connect";
try { await client.redeem({ exposureKey, hiddenKey, confirmationKey });} catch (error) { if (error instanceof ConnectApiError) { // error.status — HTTP status // error.reason — stable machine-readable code (when present) // error.body — raw `{ reason?: string }` payload (when present) } throw error;}The reason field is omitted when the underlying failure symbol is marked PRIVATE; in that case only the HTTP status carries signal.
Python raises a typed exception with the same fields. See the sudomimus-connect package README for the exact class name and attributes.
The C# SDK ships two packages today, both alpha:
Sudomimus.Native— direct-issue client fornative-api(Steam ticket, AccessKey).Sudomimus.Token— token-parsing utilities, the same role as@sudomimus/token.
A Sudomimus.Connect package is not yet shipped — for the Connect protocol from C#, call the HTTPS endpoints directly (see Web applications for the request shapes) and use Sudomimus.Token to verify the tokens you receive. Source: sdks/csharp/src.