Sign in with VRChat Legends
Register an application in Developer tools. Register the exact callback URL your application uses.
- Send the user to
GET /api/oauth2/authorizewithclient_id,redirect_uri,response_type=code,scope, and a randomstatebound to their session. - Verify returned
statebefore accepting the callback. - Exchange the code at
POST /api/oauth2/tokenusinggrant_type=authorization_code,code,redirect_uri, andclient_id. Confidential clients authenticate with their secret. Public clients use PKCE S256 and send the originalcode_verifier. - Request
GET /api/oauth2/userinfowith the returned bearer token.
The identify scope covers identity and permitted public profile data. Request email only when your application needs it and the user consents. Never put client secrets in browser JavaScript.
Use POST /api/oauth2/revoke to revoke a token. Treat authorization codes as single-use credentials and handle expiry by restarting authorization.
Request fields
| Endpoint | Fields |
|---|---|
GET /api/oauth2/authorize | client_id, exact redirect_uri, response_type=code, space-separated scope, and state |
| PKCE authorization | Also send code_challenge and code_challenge_method=S256 |
POST /api/oauth2/token | grant_type=authorization_code, code, redirect_uri, client_id, plus client authentication or code_verifier |
GET /api/oauth2/userinfo | Authorization: Bearer ACCESS_TOKEN |
POST /api/oauth2/revoke | token and application authentication |
The token endpoint accepts form or JSON bodies and supports HTTP Basic client authentication. OAuth access tokens (vrclat_…) are for the OAuth endpoints; they are not interchangeable with personal API keys (vrcl_…) used for profile editing.
Check HTTP status and the returned error before storing credentials. A user may cancel consent. A callback without the expected state, with an error, or with a reused/expired code must not create a signed-in application session. Read expires_in from the token response rather than hardcoding a lifetime.