Protocol Documentation

General

neosu uses and extends the bancho protocol.
While no official documentation exists, here is a great reference: https://github.com/Lekuruu/bancho-documentation/wiki.

Whenever "convars" or "variables" are mentioned, this means in-game variables, accessible by pressing Shift+F1.
The full list of variables is available here. This should give you a nice idea of how customizable neosu is for server admins.

You do NOT have to implement any of the features below; neosu will gracefully fallback to "vanilla" behavior.

Identification

Client Detection

Detect neosu clients via header on c. endpoint:

x-mcosu-ver: <version>

User Agent

API endpoints use this user agent:

Mozilla/5.0 (compatible; neosu/<version info>; +https://neosu.net/)

Score Submission

Enable score submission with header:

x-mcosu-features: submit=1
Regardless of this setting, scores will not submit when using PROTECTED variables.
By default, all non-vanilla mods are PROTECTED. Use the UNPROTECT_VARIABLES packet for allowing individual mods and features.

OAuth

Enabled Domains

OAuth authentication is automatically enabled for:

Local Testing: Set ssl_verify convar to 0 for neosu.local

Login Flow

Implements OAuth 2.0 Authorization Code flow with PKCE.

Step 1: Authorization

When clicking the "Log in with osu!" button, neosu will open the browser to:

GEThttps://neosu.net/connect/start?challenge={b64(sha256(verification_bytes))}

Step 2: Code Exchange

The server should then generate an URL-safe code, which will be forwarded to neosu by having the player click on a link:

neosu://login/neosu.net/{code}

Step 3: Token Request

neosu will make a request to get the refresh token:

GEThttps://neosu.net/connect/finish?code={code}&proof={b64(verification_bytes)}

Step 4: Session Login

We use the c. endpoint login packet, with:

Server returns cho-token like for regular clients.

Websockets

After logging in, neosu will attempt to connect to wss://c.neosu.net/ws/. If the server returns a different HTTP code than 101, neosu will fall back to HTTP polling, like regular clients.

If you're planning to add support for websockets on your server, remember to treat websocket connections the same as a polling client: CloudFlare tends to close websocket connections after 2 minutes, so a connection closing does not mean the client has actually stopped playing.

API Requests

In requests where the username and password hash are passed as parameters, username will be $token and password hash will be {cho-token}.

This includes score submission, where the username is passed and hashed in the score data.

Score submission

Submitted scores have an extra neosu-mods section, containing base64-encoded data representing neosu-specific mods.

Leaderboards

Requests: neosu has a "Team" leaderboard filter, which sets the parameter v=5 (as opposed to, say, v=4 for "Country").

Responses: Score lines have an extra section after the "has_replay" flag, containing base64-encoded data representing neosu-specific mods.

Custom Endpoints

Map submission

POSThttps://osu.neosu.net/web/neosu-submit-map.php

URL Parameters
Form data

Server should verify that the map md5 matches the file data.

Server Packets

128 PROTECT_VARIABLES

Marks variables as PROTECTED. Score submission disabled when value differ from defaults.

129 UNPROTECT_VARIABLES

Removes PROTECTED flag. Scores submit regardless of variable value.

130 FORCE_VALUES

Forces variables to specific values.

131 RESET_VALUES

Resets variables to client-side value.

132 REQUEST_MAP

Requests an .osu file from the client. Used for unranked/unavailable maps.

Client should send the .osu file to the neosu-submit-map endpoint.