Every way in ends with the same answer:
{
"playerId": "6f0c1c9e-0b5e-4c8f-9a0e-3f1d2c4b5a69",
"sessionToken": "mgds_...",
"expiresAt": "2026-10-24T13:00:00Z",
"refreshToken": "mgdsr_...",
"refreshExpiresAt": "2027-01-22T12:00:00Z",
"displayName": "Maffin",
"created": false,
"deviceKey": null,
"idToken": "eyJhbGciOiJSUzI1NiIs..."
}
201 when the player was just made, 200 when they already existed. Signing in again never makes
somebody new: it is the same player, with a new session.
sessionTokenis the access token. Send it with every call asAuthorization: Bearer <sessionToken>. It works for one hour (expiresAt).refreshTokengets the next pair. Keep it - after a restart too - and use it instead of signing in again. It is single use.idTokensays who the player is, signed by us, for your own game server. See Your server: who is this player?. Every refresh brings a new one.
Staying signed in
POST /auth/refresh
{ "refreshToken": "mgdsr_..." }
Answers exactly like signing in: a new access token and a new refresh token. Throw the old refresh
token away; it has just been retired. Refresh when a call answers 401, or shortly before
expiresAt. The session lasts as long as it is refreshed at least every 90 days
(refreshExpiresAt), so somebody who plays regularly is never asked to sign in again.
A refresh token is good once. If one that was already traded in turns up again, two copies of it exist and one of them is not the player's - so MGDS ends that whole session, for both, and the player signs in again. A stolen token is therefore noticed the next time either side refreshes, instead of working quietly for months. The one exception is a retry: the same refresh token again within 30 seconds (an answer lost on the way back) is answered with a fresh pair, and the pair it replaced stops working.
When /auth/refresh answers 401, sign in again.
Tokens are bearer credentials: whoever holds one is that player. Keep the refresh token where the game keeps its other private data, and the access token in memory.
Anonymous
POST /auth/anonymous
{ }
Makes a new player and returns a deviceKey with the session. Store the device key on the
device; it is the only way back to this player, and it is shown once. Next time:
POST /auth/anonymous
{ "deviceKey": "..." }
401 if the key is unknown.
Steam
Ask Steam for a ticket for the identity mgds (ISteamUser::GetAuthTicketForWebApi("mgds")), wait
for the ticket callback, and send its bytes as hex:
POST /auth/steam
{ "ticket": "140000006a..." }
401 if Steam does not accept it. Needs Steam added as a provider on the project's Authenticate
page, with its app id and publisher key.
s&box
For a game made in s&box, which is not a Steam app of its own and so has no app id or publisher key. The game asks s&box for a token and sends it with the player's SteamID:
var token = await Sandbox.Services.Auth.GetToken( "mgds" );
POST /auth/sbox
{ "steamId": "76561198000000001", "token": "..." }
MGDS asks Facepunch whether the token is real and belongs to that SteamID; 401 if not. The token is
valid for two minutes, so ask for it just before signing in. Needs s&box added as a provider on the
project's Authenticate page; there is nothing to set up.
Steam and s&box both prove a SteamID, so somebody who plays both the s&box version and a Steam
build of the same game is one player, with a login for each: logins lists "steam" and "sbox"
separately, so which way a player came in is always known.
Facepunch's check does not include the service name the token was asked for, so a token a player gave another s&box game's backend could be replayed here within those two minutes. That is how s&box tokens work.
dasmaffin.com account
The player signs in in their browser; the game waits for the result.
Start it:
POST /auth/dasmaffin { }{ "requestId": "...", "pollToken": "...", "url": "https://www.dasmaffin.com/Mgds/SignIn/...", "expiresAt": "...", "pollEverySeconds": 2 }Open
urlin the player's browser (or the Steam overlay's browser).Every
pollEverySeconds, ask:POST /auth/dasmaffin/poll { "requestId": "...", "pollToken": "..." }Code Meaning 202Not yet. Ask again. 200/201Signed in: the session, as above. Collected once. 403They chose not to allow it. 410Expired (10 minutes), or already collected. Start again.
The game never sees the player's dasmaffin.com password or tokens: MGDS signs them in through the site's own sign-in for other programs and hands the game an MGDS session.