Exchange a Steam Web API auth ticket for application tokens.
const url = 'https://native-api.sudomimus.com/direct-issue/steam-ticket';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"applicationAnchor":"example","steamTicketHex":"example","steamAppId":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://native-api.sudomimus.com/direct-issue/steam-ticket \ --header 'Content-Type: application/json' \ --data '{ "applicationAnchor": "example", "steamTicketHex": "example", "steamAppId": 1 }'The client SDK calls ISteamUser::GetAuthTicketForWebApi("sudomimus")
(the identity string MUST be exactly "sudomimus"), waits for the
GetTicketForWebApiResponse_t callback, hex-encodes the returned bytes,
and submits them with the application anchor and Steam App ID. The
ticket must satisfy the application’s configured rules and is
single-use for this exchange. Verify the returned tokens through the
application’s Session JWKS.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Public anchor identifying the integrating application.
Hex-encoded Steam Web API auth ticket bytes returned from
ISteamUser::GetAuthTicketForWebApi("sudomimus"). Hexadecimal
characters are case-insensitive.
Steam App ID under which the ticket was generated. Must be
allow-listed by the application’s STEAM_TICKET authentication
rule. Steam binds tickets to their issuing App ID; passing a
different value fails verification.
Examplegenerated
{ "applicationAnchor": "example", "steamTicketHex": "example", "steamAppId": 1}Responses
Section titled “Responses”Tokens issued.
object
Per-claim view across the five shareable claims, carried on both the 200 (why is a claim absent from the minted token) and the claim-gate 403 (what is still owed).
object
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
Short-lived access token (JWT). Payload sub is the pairwise
sector subject, sid identifies the session, and
jti identifies this token instance. It contains no profile claims
or raw account identifier; use Session API /userinfo for current
shared identity data.
Long-lived refresh token JWT with stable payload sid, version identifier jti, and positive rotationVersion. It contains no user identifier. Use Session API /refresh to obtain a new access token without re-acquiring a Steam ticket.
Example
{ "claims": { "email": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "firstName": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "lastName": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "staticAvatar": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "animatedAvatar": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" } }}Headers
Section titled “Headers”Prevent storage of the credential-bearing response.
Legacy cache instruction retained for credential responses.
Malformed request (e.g. invalid steamAppId).
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}Steam rejected the ticket.
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}The attempt was refused. The response reason distinguishes:
Layer1Denied,Layer2Denied,Layer3Denied— application policy rejected the attempt.ApplicationNotActive— the application is unavailable.AccountDisabledorAccountDeleted— the account is unavailable for issuance.EmailDomainBlocked,EmailDomainRequiresSso, orSsoAuthorityConflict— email-domain policy prevents issuance.ClaimConsentRequiredorRequiredClaimDataMissing— browser interaction is required before direct issuance can continue.
Claim-gate responses also include claims and an errand browser
handoff. Open errand.url, wait or poll its status, then acquire a
fresh Steam ticket and retry once after completion.
403 body. For the claim-gate reasons (ClaimConsentRequired,
RequiredClaimDataMissing) the claims view and the errand
handoff are present; for every other reason only reason is set.
object
Stable machine-readable reason code.
Per-claim view across the five shareable claims, carried on both the 200 (why is a claim absent from the minted token) and the claim-gate 403 (what is still owed).
object
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
One shareable claim: what the application requests (requirement)
joined with the user’s standing decision (state). UNKNOWN means
the user was never asked; DENIED means the user explicitly
declined.
object
The developer’s policy for the claim. SYNTHETIC_ONLY always
emits the generated placeholder and never asks for real data.
SYNTHETIC_FALLBACK guarantees the claim is present but uses a
generated placeholder (a stand-in name, a proxy email, or a
generated avatar) when the user has not shared real data. Unlike REQUIRED, neither
synthetic mode blocks issuance or raises an errand.
The browser side-trip that unblocks a claim-gated direct-issue: a short-lived, single-use bearer URL where the user authenticates when required, completes missing data, and manages consent. Open the URL and let the browser page guide the user.
object
Bearer key (ernd_…); also the status-poll path key.
Open this in the user’s system browser.
Example
{ "claims": { "email": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "firstName": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "lastName": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "staticAvatar": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" }, "animatedAvatar": { "requirement": "SYNTHETIC_ONLY", "state": "UNKNOWN" } }}Headers
Section titled “Headers”Prevent storage of the credential-bearing response.
Legacy cache instruction retained for credential responses.
Application anchor not found.
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}Conflict. The response reason distinguishes:
ReplayProtectionAlreadySeen— the ticket was already submitted or is being processed.AuthorizationArtifactStale— identity authority changed during the attempt.
Acquire a fresh ticket before retrying either condition.
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}Too many Steam-ticket attempts. Back off before acquiring and submitting another ticket.
Steam ticket verification is temporarily unavailable.
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}default
Section titled “default”Error response.
Error response body. Known failures may include a stable reason.
Some failures are status-only and have an empty body. A missing,
malformed, or structurally invalid JSON body returns InvalidBody.
object
Stable machine-readable reason code.
Examplegenerated
{ "reason": "example"}