Choose your vibe

Building on Untitled Sandbox

Register an app in Developer workspace, add a redirect URI, and send players through the standard OAuth 2.0 authorization-code flow with PKCE. Every scope is read-only. A token never shows more than the player themselves could see.

Endpoints

Authorization

https://untitled-sandbox.com/oauth/authorize

Send the player here. GET, response_type=code, PKCE S256.

Token

https://untitled-sandbox.com/api/oauth/token

POST form-encoded. authorization_code and refresh_token grants.

Revocation

https://untitled-sandbox.com/api/oauth/revoke

POST a token to revoke it. Revoking a refresh token ends the grant.

Introspection

https://untitled-sandbox.com/api/oauth/introspect

POST a token; RFC 7662 answer.

Userinfo

https://untitled-sandbox.com/api/v1/userinfo

GET with a bearer token. Needs the identity scope.

Server metadata

https://untitled-sandbox.com/.well-known/oauth-authorization-server

RFC 8414 discovery document.

OpenID configuration

https://untitled-sandbox.com/.well-known/openid-configuration

OIDC discovery. id_token is ES256.

JWKS

https://untitled-sandbox.com/.well-known/jwks.json

Keys that sign id_token.

Scopes

Open scopes come with registration. The rest need staff approval, requested from the app's editor. identity is always included.

identityOpen

Your user id, username and avatar headshot.

openidOpen

Sign you in with your Untitled Sandbox account.

emailOpen

Your verified email address.

profile.readOpen

Your public profile: blurb, bio, join date, badges and showcase.

friends.readOpen

Who your friends are.

clubs.readOpen

Which clubs you belong to, and your role in each.

forum.readOpen

The forum posts and replies you have written.

offline_accessOpen

Keep reading the above while you are away from the site.

inventory.readNeeds approval

The items you own, including serials. Not your vaults.

wallet.readNeeds approval

Your currency balances.

transactions.readNeeds approval

Your transaction history.

trading.readNeeds approval

Your trade history and open offers.

notifications.readNeeds approval

Your notifications.

The flow

1. Send the player to the authorization endpoint.

https://untitled-sandbox.com/oauth/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://example.com/callback
  &scope=identity%20profile.read
  &state=RANDOM_STATE
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &code_challenge_method=S256

2. They come back to your redirect URI with code and state. Exchange the code within a few minutes.

curl -X POST 'https://untitled-sandbox.com/api/oauth/token' \
  -u 'YOUR_CLIENT_ID:YOUR_CLIENT_SECRET' \
  -d 'grant_type=authorization_code' \
  -d 'code=THE_CODE_FROM_THE_REDIRECT' \
  -d 'redirect_uri=https://example.com/callback' \
  -d 'code_verifier=THE_PKCE_VERIFIER_YOU_GENERATED'

# Public apps drop -u and send client_id in the body instead.

3. Call the API with the access token. It lasts an hour; use the refresh token (given when offline_access was granted) to get another.

curl 'https://untitled-sandbox.com/api/v1/userinfo' \
  -H 'Authorization: Bearer THE_ACCESS_TOKEN'

Errors

JSON with error and, usually, error_description.

invalid_request400

A parameter is missing, repeated or malformed.

invalid_client401

Unknown client, wrong secret, or the app is not active.

invalid_grant400

The code or refresh token is expired, used or revoked.

invalid_scope400

A scope is unknown or not allowed for this app.

invalid_token401

The bearer token is missing, expired or revoked.

insufficient_scope403

The token lacks the scope this endpoint needs.

rate_limited429

Slow down. Retry-After says how long.

server_error500

Something went wrong on the server. Try again later.

Rate limits

Counted per client, not per IP. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. The token endpoint is capped separately at 30 requests per minute per client.

STANDARD60 requests per minute

Every new app.

ELEVATED600 requests per minute

On request, once an app has a track record.

FIRST_PARTY6,000 requests per minute

Untitled Sandbox apps only.

Privacy

[Placeholder: the third-party data policy is not written yet.]