osu!web Documentation

您所在的位置:网站首页 apiv2是什么意思 osu!web Documentation

osu!web Documentation

#osu!web Documentation| 来源: 网络整理| 查看: 265

Introduction

Welcome to the documentation for osu!api v2. You can use this API to get information on various circles and those who click them.

Note that while we endeavour to keep this documentation up to date, consider it a work-in-progress and note that it will likely contain errors.

If you notice any errors in the documentation or encounter problems using the API, please check for (or create if necessary) issues on GitHub. Alternatively, you can ask in #osu-web on the development discord.

Code examples are provided in the dark area to the right, you can use the tabs at the top of the page to switch between bash and javascript samples.

Terms of Use

Use the API for good. Don't overdo it. If in doubt, ask before (ab)using :). this section may expand as necessary.

Current rate limit is set at an insanely high 1200 requests per minute, with burst capability of up to 200 beyond that. If you require more, you probably fall into the above category of abuse. If you are doing more than 60 requests a minute, you should probably give peppy a yell.

Wrappers

Below is a list of some language-specific wrappers maintained by the community. Your mileage may vary when using them – please report any issues to the wrapper first before reporting back to us.

ossapi (python) aiosu (python) rosu-v2 (rust) Changelog

For a full list of changes, see the Changelog on the site.

Breaking Changes 2023-02-17 content_html in ChatMessage has been deprecated; pre-rendered markdown will be removed. 2023-01-05 new_channel_id in Create New PM response has been deprecated, use channel.channel_id instead. 2022-11-21 messages has been removed from Chat Get Updates. 2022-11-11 recent_messages in ChatChannel has been deprecated, it will be removed from Create Channel response in the near future. 2022-09-27 user include in Get User Scores response has been deprecated, it will be removed in the near future. 2022-07-06 chat/presence endpoint has been deprecated, it will be removed in the near future. 2022-06-08 discussion_enabled in Beatmapset is deprecated. All beatmapsets now have it enabled. 2021-10-28 beatmap in Get Beatmap scores scores array item is removed (it's never been documented in the first place). 2021-09-01 last_read_id in ChatChannel is deprecated, use current_user_attributes.last_read_id instead. 2021-08-11 bot scope removed in favour for delegate scope Client Credentials Delegation. 2021-06-14 Removed description from UserGroup. It has been moved to an optional attribute with a different type on Group. 2021-06-09 ranked_and_approved_beatmapset_count and unranked_beatmapset_count attributes in UserCompact object have been deprecated and replaced with ranked_beatmapset_count and pending_beatmapset_count respectively. ranked_and_approved and unranked types in Get User Beatmaps have been deprecated and replaced with ranked and pending respectively. 2021-04-20 cover_url in User is deprecated, use cover.url instead. 2021-02-25 current_mode_rank has been removed from UserCompact attributes in UserStatistics have been moved around rank.country is deprecated, replaced by country_rank rank.global and pp_rank are removed, replaced by global_rank 2020-09-08 presence removed from chat/new response. 2020-08-28 /rooms/{room_id}/leaderboard no longer returns an array at the top level; an object with keys is now returned. 2020-05-01 users.read scope removed, replaced with more general public scope. 2020-02-18 Beatmap max_combo and build update stream user_count now return the values as primitives instead of numbers wrapped in an array. 2019-10-09 Ranking API response no longer returns an array at the top level; an object with keys is now returned. 2019-07-18 User now returns counts directly as primitives instead of numbers wrapped in an array. Endpoint Base URL

The base URL is: https://osu.ppy.sh/api/[version]/

API Versions

This is combined with the base endpoint to determine where requests should be sent.

Version Status v2 current v1 legacy api provided by the old site, will be deprecated soon Language

Language for the response is determined by Accept-Language header when specified. Specifying * or not setting the header will set the language to user configured language when accessing API as a user.

Authentication

Routes marked with the OAuth label require a valid OAuth2 token for access.

More information about applications you have registered and granted permissions to can be found here.

The API supports the following grant types:

Authorization Code Grant Client Credentials Grant

Before you can use the osu!api, you will need to

have registered an OAuth Application. acquire an access token by either: authorizing users for your application; requesting Client Credentials token. Registering an OAuth application

Before you can get an OAuth token, you will need to register an OAuth application on your account settings page.

To register an OAuth application you will need to provide the:

Name Description Application Name This is the name that will be visible to users of your application. The name of your application cannot be changed. Application Callback URL The URL in your application where users will be sent after authorization.

The Application Callback URL is required when for using Authorization Codes. This may be left blank if you are only using Client Credentials Grants.

Your new OAuth application will have a Client ID and Client Secret; the Client Secret is like a password for your OAuth application, it should be kept private and do not share it with anyone else.

Authorization Code Grant

The flow to authorize users for your application is:

Requesting authorization from users Users are redirected back to your site Your application accesses the API with the user's access token Restricted users can grant authorization like anyone else. If your client should not support restricted users, it can check is_restricted from the Get Own Data response. Request authorization from a user

To obtain an access token, you must first get an authorization code that is created when a user grants permissions to your application. To request permission from the user, they should be redirected to:

Example request: curl --request GET \ --get "https://osu.ppy.sh/oauth/authorize?client_id=1&redirect_uri=http%3A%2F%2Flocalhost%3A4000&response_type=code&scope=public+identify&state=randomval" const url = new URL( "https://osu.ppy.sh/oauth/authorize" ); const params = { "client_id": "1", "redirect_uri": "http://localhost:4000", "response_type": "code", "scope": "public identify", "state": "randomval", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); fetch(url, { method: "GET", }).then(response => response.json()); Received response: Request failed with error:

GET https://osu.ppy.sh/oauth/authorize

User is redirected back to your site

If the user accepts your request, they will be redirected back to your site with a temporary single-use code contained in the URL parameter. If a state value was provided in the previous request, it will be returned here.

If you are using `state` as protection against CSRF attacks, your OAuth client is responsible for validating this value.

Exchange this code for an access token:

Example request: curl --request POST \ "https://osu.ppy.sh/oauth/token" \ --header "Accept: application/json" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data "client_id=1&client_secret=clientsecret&code=receivedcode&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A4000" const url = new URL( "https://osu.ppy.sh/oauth/token" ); const headers = { "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded", }; let body = "client_id=1&client_secret=clientsecret&code=receivedcode&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A4000"; fetch(url, { method: "POST", headers, body: body, }).then(response => response.json());

Example response (200):

{ "access_token": "verylongstring", "expires_in": 86400, "refresh_token": "anotherlongstring", "token_type": "Bearer" } Received response: Request failed with error:

POST https://osu.ppy.sh/oauth/token

Response Format

Successful requests will be issued an access token:

Name Type Description token_type string The type of token, this should always be Bearer. expires_in number The number of seconds the token will be valid for. access_token string The access token. refresh_token string The refresh token. Refresh access token

Access token expires after some time as per expires_in field. Refresh the token to get new access token without going through authorization process again.

Use refresh_token received during previous access token request:

Example request: curl --request POST \ "https://osu.ppy.sh/oauth/token" \ --header "Accept: application/json" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data "client_id=1&client_secret=clientsecret&grant_type=refresh_token&refresh_token=longstring&scope=public+identify" const url = new URL( "https://osu.ppy.sh/oauth/token" ); const headers = { "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded", }; let body = "client_id=1&client_secret=clientsecret&grant_type=refresh_token&refresh_token=longstring&scope=public+identify"; fetch(url, { method: "POST", headers, body: body, }).then(response => response.json());

Example response (200):

{ "access_token": "verylongstring", "expires_in": 86400, "refresh_token": "anotherlongstring", "token_type": "Bearer" } Received response: Request failed with error:

POST https://osu.ppy.sh/oauth/token

Response Format

Successful requests will be issued an access token and a new refresh token:

Name Type Description token_type string The type of token, this should always be Bearer. expires_in number The number of seconds the token will be valid for. access_token string The access token. refresh_token string The refresh token. Client Credentials Grant

The client credential flow provides a way for developers to get access tokens that do not have associated user permissions; as such, these tokens are considered as guest users.

Example for requesting Client Credentials token:

Example request: curl --request POST \ "https://osu.ppy.sh/oauth/token" \ --header "Accept: application/json" \ --header "Content-Type: application/x-www-form-urlencoded" \ --data "client_id=1&client_secret=clientsecret&grant_type=client_credentials&scope=public" const url = new URL( "https://osu.ppy.sh/oauth/token" ); const headers = { "Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded", }; let body = "client_id=1&client_secret=clientsecret&grant_type=client_credentials&scope=public"; fetch(url, { method: "POST", headers, body: body, }).then(response => response.json());

Example response (200):

{ "access_token": "verylongstring", "expires_in": 86400, "token_type": "Bearer" } Received response: Request failed with error:

POST https://osu.ppy.sh/oauth/token

Response Format

Successful requests will be issued an access token:

Name Type Description token_type string The type of token, this should always be Bearer. expires_in number The number of seconds the token will be valid for. access_token string The access token. Using the access token to access the API

With the access token, you can make requests to osu!api on behalf of a user.

The token should be included in the header of requests to the API.

Authorization: Bearer {{token}}

# With shell, you can just pass the correct header with each request curl "https://osu.ppy.sh/api/[version]/[endpoint]" -H "Authorization: Bearer {{token}}" // This javascript example uses fetch() fetch("https://osu.ppy.sh/api/[version]/[endpoint]", { headers: { Authorization: 'Bearer {{token}}' } });

Make sure to replace {{token}} with your OAuth2 token.

You must replace {{token}} with your OAuth2 token. Resource Owner

The Resource Owner is the user that a token acts on behalf of.

For Authorization Code Grant tokens, the Resource Owner is the user authorizing the token.

Client Credentials Grant tokens do not have a Resource Owner (i.e. is a guest user), unless they have been granted the delegate scope. The Resource Owner of tokens with the delegate scope is the owner of the OAuth Application that was granted the token.

Routes marked with requires user require the use of tokens that have a Resource Owner.

Client Credentials Delegation

Client Credentials Grant tokens may be allowed to act on behalf of the owner of the OAuth client (delegation) by requesting the delegate scope, in addition to other scopes supporting delegation. When using delegation, scopes that support delegation cannot be used together with scopes that do not support delegation. Delegation is only available to Chat Bots.

The following scopes currently support delegation:

Name chat.write Scopes

The following scopes are currently supported:

Name Description chat.write

Allows sending chat messages on a user's behalf.

delegate

Allows acting as the owner of a client; only available for Client Credentials Grant.

forum.write

Allows creating and editing forum posts on a user's behalf.

friends.read

Allows reading of the user's friend list.

identify

Allows reading of the public profile of the user (/me).

public

Allows reading of publicly available data on behalf of the user.

identify is the default scope for the Authorization Code Grant and always implicitly provided. The Client Credentials Grant does not currently have any default scopes.

Routes marked with lazer are intended for use by the osu!lazer client and not currently available for use with Authorization Code or Client Credentials grants.

Using the chat.write scope requires either

a Chat Bot account to send messages on behalf of other users. Authorization code grant where the user is the same as the client's owner (send as yourself). Managing OAuth applications

Your account settings page will show your registered OAuth applications, and all the OAuth applications you have granted permissions to.

Reset Client Secret

You can generate a new Client Secret by choosing to "Reset client secret", however, this will disable all access tokens issued for the application.

Beatmaps Lookup Beatmap

OAuth public

Returns beatmap.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/lookup?checksum=alias&filename=ipsa&id=magni" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/lookup" ); const params = { "checksum": "alias", "filename": "ipsa", "id": "magni", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

"See Beatmap object section" Received response: Request failed with error: Request

GET /beatmaps/lookup

Response format

See Get Beatmap

Get a User Beatmap score

OAuth public

Return a User's score on a Beatmap

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/15/scores/users/13?mode=necessitatibus&mods=dolore" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/15/scores/users/13" ); const params = { "mode": "necessitatibus", "mods": "dolore", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmaps/{beatmap}/scores/users/{user}

Response Format

Returns BeatmapUserScore

The position returned depends on the requested mode and mods.

Get a User Beatmap scores

OAuth public

Return a User's scores on a Beatmap

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/15/scores/users/15/all?mode=eaque" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/15/scores/users/15/all" ); const params = { "mode": "eaque", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmaps/{beatmap}/scores/users/{user}/all

Response Format Field Type scores Score[] Get Beatmap scores

OAuth public

Returns the top scores for a beatmap

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/10/scores?mode=enim&mods=nostrum&type=dignissimos" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/10/scores" ); const params = { "mode": "enim", "mods": "nostrum", "type": "dignissimos", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmaps/{beatmap}/scores

Response Format

Returns BeatmapScores. Score object inside includes user and the included user includes country and cover.

Get Beatmap scores (temp)

OAuth public

Returns the top scores for a beatmap from newer client.

This is a temporary endpoint.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/3/solo-scores?mode=repudiandae&mods=dignissimos&type=qui" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/3/solo-scores" ); const params = { "mode": "repudiandae", "mods": "dignissimos", "type": "qui", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmaps/{beatmap}/solo-scores

Response Format

Returns BeatmapScores. Score object inside includes user and the included user includes country and cover.

Get Beatmaps

OAuth public

Returns a list of beatmaps.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps?ids%5B%5D=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps" ); const params = { "ids[]": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "beatmaps": [ { "id": 1, // Other Beatmap attributes... } ] } Received response: Request failed with error: Request

GET /beatmaps

Response format Field Type Description beatmaps Beatmap[] Includes beatmapset (with ratings), failtimes, and max_combo. Get Beatmap

OAuth public

Gets beatmap data for the specified beatmap ID.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmaps/4" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/4" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

"See Beatmap object section." Received response: Request failed with error: Request

GET /beatmaps/{beatmap}

Response format

Returns Beatmap object. Following attributes are included in the response object when applicable,

Attribute Notes beatmapset Includes ratings property. failtimes max_combo Get Beatmap Attributes

OAuth public

Returns difficulty attributes of beatmap with specific mode and mods combination.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/beatmaps/2/attributes" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"mods\": 1, \"ruleset\": \"osu\" }" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/2/attributes" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "mods": 1, "ruleset": "osu" }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json());

Example response (200):

{ "attributes": { "max_combo": 100, ... } } Received response: Request failed with error: Request

POST /beatmaps/{beatmap}/attributes

Response format Field Type Attributes DifficultyAttributes Beatmapset Discussions Get Beatmapset Discussion Posts

OAuth public

Returns the posts of beatmapset discussions.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/discussions/posts?beatmapset_discussion_id=et&limit=13&page=3&sort=sunt&types%5B%5D=qui&user=veniam&with_deleted=voluptas" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/discussions/posts" ); const params = { "beatmapset_discussion_id": "et", "limit": "13", "page": "3", "sort": "sunt", "types[]": "qui", "user": "veniam", "with_deleted": "voluptas", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/discussions/posts

Response Format The response of this endpoint is likely to change soon! Field Type Description beatmapsets BeatmapsetCompact cursor_string CursorString posts BeatmapsetDiscussionPost[] users UserCompact Get Beatmapset Discussion Votes

OAuth public

Returns the votes given to beatmapset discussions.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/discussions/votes?beatmapset_discussion_id=quaerat&limit=14&page=18&receiver=est&score=ab&sort=corrupti&user=ut&with_deleted=sed" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/discussions/votes" ); const params = { "beatmapset_discussion_id": "quaerat", "limit": "14", "page": "18", "receiver": "est", "score": "ab", "sort": "corrupti", "user": "ut", "with_deleted": "sed", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/discussions/votes

Response Format The response of this endpoint is likely to change soon! Field Type Description cursor_string CursorString discussions BeatmapsetDiscussion users UserCompact votes BeatmapsetDiscussionVote[] Get Beatmapset Discussions

OAuth public

Returns a list of beatmapset discussions.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/discussions?beatmap_id=suscipit&beatmapset_id=ullam&beatmapset_status=quo&limit=12&message_types%5B%5D=qui&only_unresolved=ratione&page=12&sort=error&user=consectetur&with_deleted=sunt" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/discussions" ); const params = { "beatmap_id": "suscipit", "beatmapset_id": "ullam", "beatmapset_status": "quo", "limit": "12", "message_types[]": "qui", "only_unresolved": "ratione", "page": "12", "sort": "error", "user": "consectetur", "with_deleted": "sunt", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/discussions

Response Format The response of this endpoint is likely to change soon! Field Type Description beatmaps Beatmap[] List of beatmaps associated with the discussions returned. cursor_string CursorString discussions BeatmapsetDiscussion[] List of discussions according to sort order. included_discussions BeatmapsetDiscussion[] Additional discussions related to discussions. reviews_config.max_blocks number Maximum number of blocks allowed in a review. users UserCompact[] List of users associated with the discussions returned. Changelog Get Changelog Build

Returns details of the specified build.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/changelog/stable40/20210520.2" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/changelog/stable40/20210520.2" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "id": 5778, "version": "20210520.2", "display_version": "20210520.2", "users": 22093, "created_at": "2021-05-20T14:28:04+00:00", "update_stream": { "id": 5, "name": "stable40", "display_name": "Stable", "is_featured": true }, "changelog_entries": [ { "id": null, "repository": null, "github_pull_request_id": null, "github_url": null, "url": "https://osu.ppy.sh/home/news/2021-05-20-spring-fanart-contest-results", "type": "fix", "category": "Misc", "title": "Spring is here!", "message_html": "

New seasonal backgrounds ahoy! Amazing work by the artists.

\n", "major": true, "created_at": "2021-05-20T10:56:49+00:00", "github_user": { "id": null, "display_name": "peppy", "github_url": null, "osu_username": "peppy", "user_id": 2, "user_url": "https://osu.ppy.sh/users/2" } } ], "versions": { "previous": { "id": 5774, "version": "20210519.3", "display_version": "20210519.3", "users": 10, "created_at": "2021-05-19T11:51:48+00:00", "update_stream": { "id": 5, "name": "stable40", "display_name": "Stable", "is_featured": true } } } } Received response: Request failed with error: Request

GET /changelog/{stream}/{build}

Response Format

A Build with changelog_entries, changelog_entries.github_user, and versions included.

Get Changelog Listing

Returns a listing of update streams, builds, and changelog entries.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/changelog?message_formats%5B%5D=eveniet" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/changelog" ); const params = { "message_formats[]": "eveniet", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "streams": [ { "id": 5, "name": "stable40", "display_name": "Stable", "is_featured": true, "latest_build": { "id": 5778, "version": "20210520.2", "display_version": "20210520.2", "users": 23683, "created_at": "2021-05-20T14:28:04+00:00", "update_stream": { "id": 5, "name": "stable40", "display_name": "Stable", "is_featured": true } }, "user_count": 23965 }, // ... ], "builds": [ { "id": 5823, "version": "2021.619.1", "display_version": "2021.619.1", "users": 0, "created_at": "2021-06-19T08:30:45+00:00", "update_stream": { "id": 7, "name": "lazer", "display_name": "Lazer", "is_featured": false }, "changelog_entries": [ { "id": 12925, "repository": "ppy/osu", "github_pull_request_id": 13572, "github_url": "https://github.com/ppy/osu/pull/13572", "url": null, "type": "fix", "category": "Reliability", "title": "Fix game crashes due to attempting localisation load for unsupported locales", "message_html": null, "major": true, "created_at": "2021-06-19T08:09:39+00:00", "github_user": { "id": 218, "display_name": "bdach", "github_url": "https://github.com/bdach", "osu_username": null, "user_id": null, "user_url": null } } ] }, // ... ], "search": { "stream": null, "from": null, "to": null, "max_id": null, "limit": 21 } } Received response: Request failed with error: Request

GET /changelog

Response Format Field Type Notes builds Build[] Includes changelog_entries, changelog_entries.github_user, and changelog entry message in requested formats. search.from string? from input. search.limit number Always 21. search.max_id number? max_id input. search.stream string? stream input. search.to string? to input. streams UpdateStream[] Always contains all available streams. Includes latest_build and user_count. Lookup Changelog Build

Returns details of the specified build.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/changelog/20210520.2?message_formats%5B%5D=voluptatem" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/changelog/20210520.2" ); const params = { "message_formats[]": "voluptatem", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

See "Get Changelog Build" response. Received response: Request failed with error: Request

GET /changelog/{changelog}

Response Format

See Get Changelog Build.

Chat Chat Keepalive

requires user OAuth lazer

Request periodically to reset chat activity timeout. Also returns an updated list of recent silences.

See Public channels and activity timeout

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/chat/ack?history_since=14" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/ack" ); const params = { "history_since": "14", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /chat/ack

Response Format Field Type silences UserSilence[] Create New PM

requires user OAuth chat.write

This endpoint allows you to create a new PM channel.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/chat/new" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"target_id\": 15, \"message\": \"quidem\", \"is_action\": false, \"uuid\": \"some-uuid-string\" }" const url = new URL( "https://osu.ppy.sh/api/v2/chat/new" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "target_id": 15, "message": "quidem", "is_action": false, "uuid": "some-uuid-string" }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json());

Example response (200):

{ "channel": [ { "channel_id": 1234, "current_user_attributes": { "can_message": true, "can_message_error": null, "last_read_id": 9150005005 }, "name": "peppy", "description": "", "type": "PM", "last_read_id": 9150005005, "last_message_id": 9150005005 } ], "message": { "message_id": 9150005005, "sender_id": 102, "channel_id": 1234, "timestamp": "2018-07-06T06:33:42+00:00", "content": "i can haz featured artist plz?", "is_action": false, "uuid": "some-uuid-string", "sender": { "id": 102, "username": "nekodex", "profile_colour": "#333333", "avatar_url": "https://a.ppy.sh/102?1500537068", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } }, "new_channel_id": 1234, } Received response: Request failed with error: Request

POST /chat/new

Response Format Field Type channel The new ChatChannel message the sent ChatMessage new_channel_id Deprecated; channel_id of newly created ChatChannel This endpoint will only allow the creation of PMs initially, group chat support will come later. Get Updates

requires user OAuth lazer

Returns the list of channels the current User is in along with an updated list of UserSilences.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/chat/updates?history_since=20" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/updates" ); const params = { "history_since": "20", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "presence": [ { "channel_id": 5, "current_user_attributes": { "can_message": true, "can_message_error": null, "last_read_id": 9150005005 }, "name": "#osu", "description": "The official osu! channel (english only).", "type": "public", "last_read_id": 9150005005, "last_message_id": 9150005005 }, { "channel_id": 12345, "current_user_attributes": { "can_message": true, "can_message_error": null, "last_read_id": 9150001235 }, "type": "PM", "name": "peppy", "icon": "https://a.ppy.sh/2?1519081077.png", "users": [ 2, 102 ], "last_read_id": 9150001235, "last_message_id": 9150001234 } ], "silences": [ { "id": 1, "user_id": 2 } ] } Received response: Request failed with error: Request

GET /chat/updates

Response Format Field Type messages This field is not used and will be removed. presence ChatChannel[]? silences UserSilence[]? Get Channel Messages

requires user OAuth lazer

This endpoint returns the chat messages for a specific channel.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/chat/channels/14/messages?limit=12&since=9&until=10" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/14/messages" ); const params = { "limit": "12", "since": "9", "until": "10", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "message_id": 9150005004, "sender_id": 2, "channel_id": 5, "timestamp": "2018-07-06T06:33:34+00:00", "content": "i am a lazerface", "is_action": 0, "sender": { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } }, { "message_id": 9150005005, "sender_id": 102, "channel_id": 5, "timestamp": "2018-07-06T06:33:42+00:00", "content": "uh ok then", "is_action": 0, "sender": { "id": 102, "username": "nekodex", "profile_colour": "#333333", "avatar_url": "https://a.ppy.sh/102?1500537068", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } } ] Received response: Request failed with error: Request

GET /chat/channels/{channel}/messages

Response Format

Returns an array of ChatMessage

Send Message to Channel

requires user OAuth lazer

This endpoint returns the chat messages for a specific channel.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/chat/channels/19/messages" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"message\": \"natus\", \"is_action\": false }" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/19/messages" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "message": "natus", "is_action": false }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json());

Example response (200):

{ "message_id": 9150005004, "sender_id": 2, "channel_id": 5, "timestamp": "2018-07-06T06:33:34+00:00", "content": "i am a lazerface", "is_action": 0, "sender": { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } } Received response: Request failed with error: Request

POST /chat/channels/{channel}/messages

Response Format

The sent ChatMessage

When sending a message, the last_read_id for the ChatChannel is also updated to mark the new message as read. Join Channel

requires user OAuth lazer

This endpoint allows you to join a public or multiplayer channel.

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/chat/channels/officia/users/labore" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/officia/users/labore" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json());

Example response (200):

{ "channel_id": 5, "current_user_attributes": { "can_message": true, "can_message_error": null }, "description": "The official osu! channel (english only).", "icon": "https://a.ppy.sh/2?1519081077.png", "last_message_id": 1029, "moderated": false, "name": "#osu", "type": "public" "users": [] } Received response: Request failed with error: Request

PUT /chat/channels/{channel}/users/{user}

Response Format

Returns the joined ChatChannel.

Leave Channel

requires user OAuth lazer

This endpoint allows you to leave a public channel.

Example request: curl --request DELETE \ "https://osu.ppy.sh/api/v2/chat/channels/commodi/users/qui" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/commodi/users/qui" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "DELETE", headers, }).then(response => response.json());

Example response (204):

[Empty response] Received response: Request failed with error: Request

DELETE /chat/channels/{channel}/users/{user}

Response Format

empty response

This endpoint will only allow the leaving of public channels initially. Mark Channel as Read

requires user OAuth lazer

This endpoint marks the channel as having being read up to the given message_id.

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/chat/channels/dolorem/mark-as-read/aspernatur?channel_id=quia&message_id=porro" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/dolorem/mark-as-read/aspernatur" ); const params = { "channel_id": "quia", "message_id": "porro", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json());

Example response (204):

[Empty response] Received response: Request failed with error: Request

PUT /chat/channels/{channel}/mark-as-read/{message}

Response Format

empty response

Note that the read marker cannot be moved backwards - i.e. if a channel has been marked as read up to message_id = 12, you cannot then set it backwards to message_id = 10. It will be rejected. Get Channel List

requires user OAuth lazer

This endpoint returns a list of all joinable public channels.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/chat/channels" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "channel_id": 5, "description": "The official osu! channel (english only).", "icon": "https://a.ppy.sh/2?1519081077.png", "moderated": false, "name": "#osu", "type": "public" } ] Received response: Request failed with error: Request

GET /chat/channels

Response Format

Returns an array of ChatChannel

Create Channel

requires user OAuth chat.write

Creates a new PM or announcement channel. Rejoins the PM channel if it already exists.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/chat/channels" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"target_id\": 2, \"type\": \"PM\" }" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "target_id": 2, "type": "PM" }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json());

Example response (200):

{ "channel_id": 1, "description": "best channel", "icon": "https://a.ppy.sh/2?1519081077.png", "moderated": false, "name": "#pm_1-2", "type": "PM", "recent_messages": [ { "message_id": 1, "sender_id": 1, "channel_id": 1, "timestamp": "2020-01-01T00:00:00+00:00", "content": "Happy new year", "is_action": false, "sender": { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } } ] } Received response: Request failed with error: Request

POST /chat/channels

Response Format

Returns ChatChannel with recent_messages attribute; recent_messages is deprecated and should not be used.

Get Channel

requires user OAuth lazer

Gets details of a chat channel.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/chat/channels/maxime" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/channels/maxime" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "channel": { "channel_id": 1337, "current_user_attributes": { "can_message": true, "can_message_error": null }, "name": "test channel", "description": "wheeeee", "icon": "/images/layout/[email protected]", "type": "PM", "last_message_id": 9150005005, "moderated": false, "users": [ 2, 102 ] }, "users": [ { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_deleted": false, "is_online": true, "is_supporter": true }, { "id": 102, "username": "lambchop", "profile_colour": "#3366FF", "icon": "/images/layout/[email protected]", "country_code": "NZ", "is_active": true, "is_bot": false, "is_deleted": false, "is_online": false, "is_supporter": false } ] } Received response: Request failed with error: Request

GET /chat/channels/{channel}

Response Format Field Type Description channel ChatChannel users UserCompact Users are only visible for PM channels. Comments Get Comments

Returns a list comments and their replies up to 2 levels deep.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/comments?commentable_type=beatmapset&commentable_id=1&parent_id=1&sort=new" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments" ); const params = { "commentable_type": "beatmapset", "commentable_id": "1", "parent_id": "1", "sort": "new", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /comments

Response Format

Returns CommentBundle.

pinned_comments is only included when commentable_type and commentable_id are specified.

Post a new comment

requires user OAuth lazer

Posts a new comment to a comment thread.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/comments" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /comments

Response Format

Returns CommentBundle

Get a Comment

Gets a comment and its replies up to 2 levels deep.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/comments/et" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments/et" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /comments/{comment}

Response Format

Returns CommentBundle

Edit Comment

requires user OAuth lazer

Edit an existing comment.

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/comments/voluptates" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments/voluptates" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json()); Received response: Request failed with error: Request

PUT /comments/{comment}

PATCH /comments/{comment}

Response Format

Returns CommentBundle

Delete Comment

requires user OAuth lazer

Deletes the specified comment.

Example request: curl --request DELETE \ "https://osu.ppy.sh/api/v2/comments/et" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments/et" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "DELETE", headers, }).then(response => response.json()); Received response: Request failed with error: Request

DELETE /comments/{comment}

Response Format

Returns CommentBundle

Add Comment vote

requires user OAuth lazer

Upvotes a comment.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/comments/sed/vote" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments/sed/vote" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /comments/{comment}/vote

Response Format

Returns CommentBundle

Remove Comment vote

requires user OAuth lazer

Un-upvotes a comment.

Example request: curl --request DELETE \ "https://osu.ppy.sh/api/v2/comments/rerum/vote" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/comments/rerum/vote" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "DELETE", headers, }).then(response => response.json()); Received response: Request failed with error: Request

DELETE /comments/{comment}/vote

Response Format

Returns CommentBundle

Events Get Events

OAuth public

Returns a collection of Events in order of creation time.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/events" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/events" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ events: [ { created_at: "2022-12-08T02:02:51+00:00", id: 57, type: "achievement", achievement: { ... }, user: { ... } }, ... ], cursor_string: "eyJldmVudF9pZCI6OH0" } Received response: Request failed with error: Request

GET /events

Response Format Field Type cursor_string CursorString events Event[] Forum Reply Topic

requires user OAuth forum.write

Create a post replying to the specified topic.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/forums/topics/1/reply" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"body\": \"hello\" }" const url = new URL( "https://osu.ppy.sh/api/v2/forums/topics/1/reply" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "body": "hello" }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json()); Received response: Request failed with error: Request

POST /forums/topics/{topic}/reply

Response Format

ForumPost with body included.

Create Topic

requires user OAuth forum.write

Create a new topic.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/forums/topics" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"body\": \"hello\", \"forum_id\": 1, \"title\": \"untitled\", \"with_poll\": true, \"forum_topic_poll[options]\": \"item A...\", \"forum_topic_poll[title]\": \"my poll\" }" const url = new URL( "https://osu.ppy.sh/api/v2/forums/topics" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "body": "hello", "forum_id": 1, "title": "untitled", "with_poll": true, "forum_topic_poll[options]": "item A...", "forum_topic_poll[title]": "my poll" }; fetch(url, { method: "POST", headers, body: JSON.stringify(body), }).then(response => response.json()); Received response: Request failed with error: Request

POST /forums/topics

Response Format Field Type Includes topic ForumTopic post ForumPost body Get Topic and Posts

OAuth public

Get topic and its posts.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/forums/topics/1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/forums/topics/1" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "topic": { "id": 1, "...": "..." }, "posts": [ { "id": 1, "...": "..." }, { "id": 2, "...": "..." } ], "cursor_string": "eyJoZWxsbyI6IndvcmxkIn0", "sort": "id_asc" } Received response: Request failed with error: Request

GET /forums/topics/{topic}

Response Format Field Type Notes cursor_string CursorString posts ForumPost[] Includes body. search Parameters used for current request excluding cursor. topic ForumTopic Edit Topic

OAuth forum.write

Edit topic. Only title can be edited through this endpoint.

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/forums/topics/1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"forum_topic[topic_title]\": \"titled\" }" const url = new URL( "https://osu.ppy.sh/api/v2/forums/topics/1" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "forum_topic[topic_title]": "titled" }; fetch(url, { method: "PUT", headers, body: JSON.stringify(body), }).then(response => response.json()); Received response: Request failed with error: Request

PUT /forums/topics/{topic}

PATCH /forums/topics/{topic}

Response Format

The edited ForumTopic.

Edit Post

OAuth forum.write

Edit specified forum post.

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/forums/posts/1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"body\": \"hello\" }" const url = new URL( "https://osu.ppy.sh/api/v2/forums/posts/1" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; let body = { "body": "hello" }; fetch(url, { method: "PUT", headers, body: JSON.stringify(body), }).then(response => response.json()); Received response: Request failed with error: Request

PUT /forums/posts/{post}

PATCH /forums/posts/{post}

Response Format

ForumPost with body included.

Home Search

OAuth public

Searches users and wiki pages.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/search?mode=0&query=hello&page=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/search" ); const params = { "mode": "0", "query": "hello", "page": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /search

Response Format Field Type Description user SearchResult? For all or user mode. Only first 100 results are accessible wiki_page SearchResult? For all or wiki_page mode SearchResult Field Type Description data T[] total number Multiplayer Get User High Score

requires user OAuth lazer

Returns detail of highest score of specified user and the surrounding scores.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/17/playlist/3/scores/users/6" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/17/playlist/3/scores/users/6" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{room}/playlist/{playlist}/scores/users/{user}

Response Format

Returns MultiplayerScore object.

Get Scores

OAuth public

Returns a list of scores for specified playlist item.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/10/playlist/4/scores?limit=18&sort=delectus&cursor_string=soluta" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/10/playlist/4/scores" ); const params = { "limit": "18", "sort": "delectus", "cursor_string": "soluta", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{room}/playlist/{playlist}/scores

Response Format

Returns MultiplayerScores object.

Get a Score

requires user OAuth lazer

Returns detail of specified score and the surrounding scores.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/7/playlist/2/scores/10" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/7/playlist/2/scores/10" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{room}/playlist/{playlist}/scores/{score}

Response Format

Returns MultiplayerScore object.

News Get News Listing

Returns a list of news posts and related metadata.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/news" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/news" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "news_posts": [ { "id": 964, "author": "RockRoller", "edit_url": "https://github.com/ppy/osu-wiki/tree/master/news/2021-05-27-skinning-contest-results.md", "first_image": "https://i.ppy.sh/d431ff921955d5c8792dc9bae40ac082d4e53131/68747470733a2f2f6f73752e7070792e73682f77696b692f696d616765732f7368617265642f6e6577732f323032312d30352d32372d736b696e6e696e672d636f6e746573742d726573756c74732f736b696e6e696e675f636f6e746573745f62616e6e65722e6a7067", "published_at": "2021-05-27T12:00:00+00:00", "updated_at": "2021-05-28T17:11:35+00:00", "slug": "2021-05-27-skinning-contest-results", "title": "Skinning Contest: Results Out", "preview": "The ship full of skins is now back with your votes. Check out the results for our first-ever official skinning contest right here!" }, // ... ], "news_sidebar": { "current_year": 2021, "news_posts": [ { "id": 964, "author": "RockRoller", "edit_url": "https://github.com/ppy/osu-wiki/tree/master/news/2021-05-27-skinning-contest-results.md", "first_image": "https://i.ppy.sh/d431ff921955d5c8792dc9bae40ac082d4e53131/68747470733a2f2f6f73752e7070792e73682f77696b692f696d616765732f7368617265642f6e6577732f323032312d30352d32372d736b696e6e696e672d636f6e746573742d726573756c74732f736b696e6e696e675f636f6e746573745f62616e6e65722e6a7067", "published_at": "2021-05-27T12:00:00+00:00", "updated_at": "2021-05-28T17:11:35+00:00", "slug": "2021-05-27-skinning-contest-results", "title": "Skinning Contest: Results Out" }, // ... ], "years": [2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013] }, "search": { "limit": 12, "sort": "published_desc" }, "cursor_string": "WyJodHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC93YXRjaD92PWRRdzR3OVdnWGNRIl0" } Received response: Request failed with error: Request

GET /news

Response Format Field Type Notes cursor_string CursorString news_posts NewsPost[] Includes preview. news_sidebar.current_year number Year of the first post's publish time, or current year if no posts returned. news_sidebar.news_posts NewsPost[] All posts published during current_year. news_sidebar.years number[] All years during which posts have been published. search.limit number Clamped limit input. search.sort string Always published_desc. NewsPost collections queried by year will also include posts published in November and December of the previous year if the current date is the same year and before April. Get News Post

Returns details of the specified news post.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/news/2021-04-27-results-a-labour-of-love" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/news/2021-04-27-results-a-labour-of-love" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "id": 943, "author": "pishifat", "edit_url": "https://github.com/ppy/osu-wiki/tree/master/news/2021-04-27-results-a-labour-of-love.md", "first_image": "https://i.ppy.sh/65c9c2eb2f8d9bc6008b95aba7d0ef45e1414c1e/68747470733a2f2f6f73752e7070792e73682f77696b692f696d616765732f7368617265642f6e6577732f323032302d31312d33302d612d6c61626f75722d6f662d6c6f76652f616c6f6c5f636f7665722e6a7067", "published_at": "2021-04-27T20:00:00+00:00", "updated_at": "2021-04-27T20:25:57+00:00", "slug": "2021-04-27-results-a-labour-of-love", "title": "Results - A Labour of Love", "content": "...", "navigation": { "newer": { "id": 944, "author": "pishifat", "edit_url": "https://github.com/ppy/osu-wiki/tree/master/news/2021-04-28-new-featured-artist-emilles-moonlight-serenade.md", "first_image": "https://i.ppy.sh/7e22cc5f4755c21574d999d8ce3a2f40a3268e84/68747470733a2f2f6173736574732e7070792e73682f617274697374732f3136302f6865616465722e6a7067", "published_at": "2021-04-28T08:00:00+00:00", "updated_at": "2021-04-28T09:51:28+00:00", "slug": "2021-04-28-new-featured-artist-emilles-moonlight-serenade", "title": "New Featured Artist: Emille's Moonlight Serenade" }, "older": { "id": 942, "author": "pishifat", "edit_url": "https://github.com/ppy/osu-wiki/tree/master/news/2021-04-24-new-featured-artist-grynpyret.md", "first_image": "https://i.ppy.sh/acdce813b71371b95e8240f9249c916285fdc5a0/68747470733a2f2f6173736574732e7070792e73682f617274697374732f3135392f6865616465722e6a7067", "published_at": "2021-04-24T08:00:00+00:00", "updated_at": "2021-04-24T10:23:59+00:00", "slug": "2021-04-24-new-featured-artist-grynpyret", "title": "New Featured Artist: Grynpyret" } } } Received response: Request failed with error: Request

GET /news/{news}

Response Format

Returns a NewsPost with content and navigation included.

Notification Get Notifications

requires user OAuth lazer

This endpoint returns a list of the user's unread notifications. Sorted descending by id with limit of 50.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/notifications?max_id=temporibus" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/notifications" ); const params = { "max_id": "temporibus", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "has_more": true, "notifications": [ { "id": 1, "name": "forum_topic_reply", "created_at": "2019-04-24T07:12:43+00:00", "object_type": "forum_topic", "object_id": 1, "source_user_id": 1, "is_read": false, "details": { "title": "A topic", "post_id": 2, "username": "User", "cover_url": "https://..." } } ], "unread_count": 100, "notification_endpoint": "wss://notify.ppy.sh" } Received response: Request failed with error: Request

GET /notifications

Response Format

Returns an object containing Notification and other related attributes.

Field Type has_more boolean whether or not there are more notifications notifications array of Notification unread_count total unread notifications notification_endpoint url to connect to websocket server Mark Notifications as Read

requires user OAuth lazer

This endpoint allows you to mark notifications read.

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/notifications/mark-read" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ const url = new URL( "https://osu.ppy.sh/api/v2/notifications/mark-read" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json());

Example response (204):

[Empty response] Received response: Request failed with error: Request

POST /notifications/mark-read

Response Format

empty response

OAuth Tokens Revoke current token

OAuth

Revokes currently authenticated token.

Example request: curl --request DELETE \ "https://osu.ppy.sh/api/v2/oauth/tokens/current" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/oauth/tokens/current" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "DELETE", headers, }).then(response => response.json());

Example response (204):

[Empty response] Received response: Request failed with error: Request

DELETE /oauth/tokens/current

Ranking Get Ranking

OAuth public

Gets the current ranking for the specified type and game mode.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rankings/mania/performance?country=0&filter=all&variant=4k" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rankings/mania/performance" ); const params = { "country": "0", "filter": "all", "variant": "4k", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rankings/{mode}/{type}

Response Format

Returns Rankings

Get Spotlights

OAuth public

Gets the list of spotlights.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/spotlights" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/spotlights" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /spotlights

Response Format

Returns Spotlights

Undocumented POST api/v2/beatmaps/{beatmap}/solo/scores

requires user OAuth lazer

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/beatmaps/nihil/solo/scores" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/nihil/solo/scores" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /beatmaps/{beatmap}/solo/scores

PUT api/v2/beatmaps/{beatmap}/solo/scores/{token}

requires user OAuth lazer

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/beatmaps/ex/solo/scores/enim" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmaps/ex/solo/scores/enim" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json()); Received response: Request failed with error: Request

PUT /beatmaps/{beatmap}/solo/scores/{token}

GET api/v2/beatmapsets/events

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/events" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/events" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/events

POST api/v2/beatmapsets/{beatmapset}/favourites

requires user OAuth lazer

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/beatmapsets/officiis/favourites" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/officiis/favourites" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /beatmapsets/{beatmapset}/favourites

GET api/v2/chat/presence

requires user OAuth lazer

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/chat/presence" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/chat/presence" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /chat/presence

GET api/v2/matches

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/matches" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/matches" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /matches

GET api/v2/matches/{match}

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/matches/quia" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/matches/quia" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /matches/{match}

GET api/v2/rooms/{mode?}

requires user OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/owned|participated|ended" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/owned|participated|ended" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{mode?}

PUT api/v2/rooms/{room}/users/{user}

requires user OAuth lazer

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/rooms/natus/users/qui" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/natus/users/qui" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json()); Received response: Request failed with error: Request

PUT /rooms/{room}/users/{user}

DELETE api/v2/rooms/{room}/users/{user}

requires user OAuth lazer

Example request: curl --request DELETE \ "https://osu.ppy.sh/api/v2/rooms/velit/users/delectus" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/velit/users/delectus" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "DELETE", headers, }).then(response => response.json()); Received response: Request failed with error: Request

DELETE /rooms/{room}/users/{user}

GET api/v2/rooms/{room}/leaderboard

requires user OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/eveniet/leaderboard" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/eveniet/leaderboard" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{room}/leaderboard

POST api/v2/rooms/{room}/playlist/{playlist}/scores

requires user OAuth lazer

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/rooms/inventore/playlist/impedit/scores" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/inventore/playlist/impedit/scores" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /rooms/{room}/playlist/{playlist}/scores

PUT api/v2/rooms/{room}/playlist/{playlist}/scores/{score}

requires user OAuth lazer

Example request: curl --request PUT \ "https://osu.ppy.sh/api/v2/rooms/reiciendis/playlist/eum/scores/quia" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/reiciendis/playlist/eum/scores/quia" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "PUT", headers, }).then(response => response.json()); Received response: Request failed with error: Request

PUT /rooms/{room}/playlist/{playlist}/scores/{score}

PATCH /rooms/{room}/playlist/{playlist}/scores/{score}

POST api/v2/reports

requires user OAuth lazer

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/reports" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/reports" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /reports

POST api/v2/rooms

requires user OAuth lazer

Example request: curl --request POST \ "https://osu.ppy.sh/api/v2/rooms" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "POST", headers, }).then(response => response.json()); Received response: Request failed with error: Request

POST /rooms

GET api/v2/rooms/{room}

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/rooms/excepturi" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/rooms/excepturi" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /rooms/{room}

GET api/v2/seasonal-backgrounds

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/seasonal-backgrounds" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/seasonal-backgrounds" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /seasonal-backgrounds

GET api/v2/scores/{mode}/{score}/download

requires user OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/scores/iste/odio/download" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/scores/iste/odio/download" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /scores/{mode}/{score}/download

GET api/v2/scores/{mode}/{score}

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/scores/et/quaerat" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/scores/et/quaerat" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /scores/{mode}/{score}

GET api/v2/beatmapsets/search/{filters?}

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/search/perspiciatis" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/search/perspiciatis" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/search/{filters?}

GET api/v2/beatmapsets/lookup

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/lookup" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/lookup" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/lookup

GET api/v2/beatmapsets/{beatmapset}

OAuth public

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/quo" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/quo" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/{beatmapset}

GET api/v2/friends

requires user OAuth friends.read

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/friends" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/friends" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /friends

GET api/v2/me/download-quota-check

requires user OAuth lazer

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/me/download-quota-check" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/me/download-quota-check" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /me/download-quota-check

GET api/v2/beatmapsets/{beatmapset}/download

OAuth lazer

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/beatmapsets/facere/download" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/beatmapsets/facere/download" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /beatmapsets/{beatmapset}/download

Users Get Own Data

requires user OAuth identify

Similar to Get User but with authenticated user (token owner) as user id.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/me/osu" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/me/osu" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

"See User object section" Received response: Request failed with error: Request

GET /me/{mode?}

Response format

See Get User.

Additionally, statistics_rulesets is included, containing statistics for all rulesets.

Get User Kudosu

OAuth public

Returns kudosu history.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users/1/kudosu?limit=8&offset=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users/1/kudosu" ); const params = { "limit": "8", "offset": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "id": 1, "other": "attributes..." }, { "id": 2, "other": "attributes..." } ] Received response: Request failed with error: Request

GET /users/{user}/kudosu

Response format

Array of KudosuHistory.

Get User Scores

OAuth public

This endpoint returns the scores of specified user.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users/1/scores/best?include_fails=0&mode=osu&limit=15&offset=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users/1/scores/best" ); const params = { "include_fails": "0", "mode": "osu", "limit": "15", "offset": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "id": 1, "other": "attributes..." }, { "id": 2, "other": "attributes..." } ] Received response: Request failed with error: Request

GET /users/{user}/scores/{type}

Response format

Array of Score. Following attributes are included in the response object when applicable.

Attribute Notes beatmap beatmapset weight Only for type best. Get User Beatmaps

OAuth public

Returns the beatmaps of specified user.

Type Notes favourite graveyard guest loved most_played nominated pending Previously unranked ranked Previously ranked_and_approved Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users/1/beatmapsets/favourite?limit=17&offset=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users/1/beatmapsets/favourite" ); const params = { "limit": "17", "offset": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "id": 1, "other": "attributes..." }, { "id": 2, "other": "attributes..." } ] Received response: Request failed with error: Request

GET /users/{user}/beatmapsets/{type}

Response format

Array of BeatmapPlaycount when type is most_played; array of Beatmapset, otherwise.

Get User Recent Activity

OAuth public

Returns recent activity.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users/1/recent_activity?limit=14&offset=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users/1/recent_activity" ); const params = { "limit": "14", "offset": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

[ { "id": 1, "other": "attributes..." }, { "id": 2, "other": "attributes..." } ] Received response: Request failed with error: Request

GET /users/{user}/recent_activity

Response format

Array of Event.

Get User

OAuth public

This endpoint returns the detail of specified user.

It's highly recommended to pass key parameter to avoid getting unexpected result (mainly when looking up user with numeric username or nonexistent user id). Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users/1/osu?key=id" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users/1/osu" ); const params = { "key": "id", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

"See User object section" Received response: Request failed with error: Request

GET /users/{user}/{mode?}

Response format

Returns User object. The following optional attributes on UserCompact are included:

account_history active_tournament_banner badges beatmap_playcounts_count favourite_beatmapset_count follower_count graveyard_beatmapset_count groups loved_beatmapset_count mapping_follower_count monthly_playcounts page pending_beatmapset_count previous_usernames rank_highest rank_history ranked_beatmapset_count replays_watched_counts scores_best_count scores_first_count scores_recent_count statistics statistics.country_rank statistics.rank statistics.variants support_level user_achievements Get Users

OAuth public

Returns list of users.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/users?ids%5B%5D=1" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/users" ); const params = { "ids[]": "1", }; Object.keys(params) .forEach(key => url.searchParams.append(key, params[key])); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json());

Example response (200):

{ "users": [ { "id": 1, "other": "attributes..." }, { "id": 2, "other": "attributes..." } ] } Received response: Request failed with error: Request

GET /users

Response format Field Type Description users UserCompact[] Includes: country, cover, groups, statistics_rulesets. Wiki Get Wiki Page

The wiki article or image data.

Example request: curl --request GET \ --get "https://osu.ppy.sh/api/v2/wiki/en/Welcome" \ --header "Content-Type: application/json" \ --header "Accept: application/json" const url = new URL( "https://osu.ppy.sh/api/v2/wiki/en/Welcome" ); const headers = { "Content-Type": "application/json", "Accept": "application/json", }; fetch(url, { method: "GET", headers, }).then(response => response.json()); Received response: Request failed with error: Request

GET /wiki/{locale}/{path}

Response Format

Returns WikiPage.

Using Chat

TODO: better title

Chat consists of HTTP-based and websocket-based APIs.

The Chat websocket API allows receiving updates in real-time; this requires a connection to the Notification Websocket. Sending messages is still performed through the HTTP-based API.

Websocket messages may arrive before or after the related HTTP web request completes. It is up to the client to handle this.

To begin receiving chat messages, clients should send the chat.start event across the socket connection. To stop receiving chat messages, send chat.end.

Public channels and activity timeout

To continue receiving chat messages in PUBLIC channels, clients must peridiocally request the Chat Keepalive endpoint to remain active; 30 seconds is a reasonable interval. When a client is no longer considered active, the server will stop sending messages in public channels to the client.

Private messages are not affected by this activity timeout.

Getting the user's channel list

TODO: update default parameter

To get the list of channels the user is in, make a request to Get Updates with the presence as part of the includes parameter. e.g. GET /chat/updates?includes[]=presence

Creating a channel

Make a request to the Create Channel endpoint

Only PM and ANNOUNCE type channels may be created. Creating a channel will automatically join it. Re-creating a PM channel will simply rejoin the existing channel.

Joining a channel

Make a request to the Join Channel endpoint where channel is the channel_id.

A chat.channel.join event is sent when the over the websocket when the user joins a channel.

Leaving a channel

Make a request to the Leave Channel endpoint.

Leaving a channel will remove it from the User's channel list.

A chat.channel.part event is sent over the websocket when the user leaves a channel.

Sending messages

Channels should be joined or created before messages are sent to them. To send a message a channel, make a request to the Send Message to Channel endpoint.

A chassage.new event is sent over the websocket when the user receives a message.

Getting info about a channel

Make a request to the Get Channel endpoint.

Getting channel message history

Make a request to the Get Channel Messages endpoint.

Websocket Connection wscat -c "{notification_endpoint}" -H "Authorization: Bearer {{token}}" // Requires nodejs with using ESM. // Browser WebSocket does not support header option. import WebSocket from 'ws'; const url = 'notification-endpoint'; const token = 'some-token'; const headers = { Authorization: `Bearer ${token}`}; const ws = new WebSocket(url, [], { headers }); ws.on('message', (buffer) => console.log(buffer.toString()));

The above command will wait and display new notifications as they arrive

This endpoint allows you to receive notifications and chat events without constantly polling the server.

See Websocket Events for the structure of websocket messages.

Websocket Events

Websocket events generally have the following standard format:

{ "data": {}, "event": "some.event" } Field Type Description event string Name of the event. data object? Event payload. logout event

User session using same authentication key has been logged out (not yet implemented for OAuth authentication). Server will disconnect session after sending this event so don't try to reconnect.

new event

Sent when a new notification is received.

Payload Format

See Notification object for notification types.

read event

Sent when a notification has been read.

This event does not use the data property for payload.

TODO: ids should be moved to data to match other events.

Field Type Description event string read ids number[] id of Notifications which are read chat.channel.join

Broadcast to the user when the user joins a chat channel.

Payload Format

ChatChannel with current_user_attributes, last_message_id, users additional attributes.

chat.channel.part

Broadcast to the user when the user leaves a chat channel.

Payload Format

ChatChannel with current_user_attributes, last_message_id, users additional attributes.

chassage.new

Sent to the user when the user receives a chat message.

Payload Format Field Type Description messages ChatMessage[] The messages received. users UserCompact[] The related users who sent the messages.

Messages intented for a user are always sent even if the user does not currently have the channel open. Such messages include PM and Announcement messages.

Other messages, e.g. public channel messages are not sent if the user is no longer present in the channel.

Websocket Commands

Websocket commands have the format:

{ "event": "some.event" } Field Type Description event string Name of the event.

Commands currently do not have any payload.

chat.start

Send to the websocket to start receiving chat messages.

webSocket.send(JSON.stringify({ event: 'chat.start' })); chat.end

Send to the websocket to stop receiving chat messages.

webSocket.send(JSON.stringify({ event: 'chat.start' })); Object Structures Beatmap

Represent a beatmap. This extends BeatmapCompact with additional attributes.

Additional attributes:

Field Type Description accuracy float ar float beatmapset_id integer bpm float? convert boolean count_circles integer count_sliders integer count_spinners integer cs float deleted_at Timestamp? drain float hit_length integer is_scoreable boolean last_updated Timestamp mode_int integer passcount integer playcount integer ranked integer See Rank status for list of possible values. url string BeatmapCompact

Represent a beatmap.

Field Type Description beatmapset_id integer difficulty_rating float id integer mode GameMode status string See Rank status for list of possible values. total_length integer user_id integer version string

Optional attributes:

Field Type Description beatmapset Beatmapset|BeatmapsetCompact|null Beatmapset for Beatmap object, BeatmapsetCompact for BeatmapCompact object. null if the beatmap doesn't have associated beatmapset (e.g. deleted). checksum string? failtimes Failtimes max_combo integer Failtimes

All fields are optional but there's always at least one field returned.

Field Type Description exit integer[]? Array of length 100. fail integer[]? Array of length 100. BeatmapDifficultyAttributes

Represent beatmap difficulty attributes. Following fields are always present and then there are additional fields for different rulesets.

Field Type max_combo integer star_rating float osu Field Type aim_difficulty float approach_rate float flashlight_difficulty float overall_difficulty float slider_factor float speed_difficulty float taiko Field Type stamina_difficulty float rhythm_difficulty float colour_difficulty float approach_rate float great_hit_window float fruits Field Type approach_rate float mania Field Type great_hit_window float score_multiplier float BeatmapPlaycount

Represent the playcount of a beatmap.

Field Type Description beatmap_id number beatmap BeatmapCompact? beatmapset BeatmapsetCompact? count number BeatmapScores { "scores": [], "userScore": {} } Field Type Description scores Score[] The list of top scores for the beatmap in descending order. userScore BeatmapUserScore? The score of the current user. This is not returned if the current user does not have a score. Note: will be moved to user_score in the future BeatmapUserScore { "position": 1, "score": {} } Field Type Description position number The position of the score within the requested beatmap ranking. score Score The details of the score. Beatmapset

Represents a beatmapset. This extends BeatmapsetCompact with additional attributes.

Field Type Description availability.download_disabled boolean availability.more_information string? bpm float can_be_hyped boolean deleted_at string? discussion_enabled boolean Deprecated, all beatmapsets now have discussion enabled. discussion_locked boolean hype.current integer hype.required integer is_scoreable boolean last_updated Timestamp legacy_thread_url string? nominations_summary.current integer nominations_summary.required integer ranked integer See Rank status for list of possible values. ranked_date Timestamp? source string storyboard boolean submitted_date Timestamp? tags string

The following attributes are always included as well:

Field has_favourited BeatmapsetCompact

Represents a beatmapset.

Field Type Description artist string artist_unicode string covers Covers creator string favourite_count number id number nsfw boolean offset number play_count number preview_url string source string status string spotlight boolean title string title_unicode string user_id number video boolean

Those fields are optional.

Field Type Description beatmaps Beatmap[] converts current_nominations Nomination[] current_user_attributes description discussions events genre has_favourited boolean language nominations pack_tags string[] ratings recent_favourites related_users user track_id number Covers Field Type cover string cover@2x string card string card@2x string list string list@2x string slimcover string slimcover@2x string Rank status

The possible values are denoted either as integer or string.

Integer String -2 graveyard -1 wip 0 pending 1 ranked 2 approved 3 qualified 4 loved BeatmapsetDiscussion

Represents a Beatmapset modding discussion.

Field Type Description beatmap BeatmapCompact? beatmap_id number? beatmapset BeatmapsetCompact? beatmapset_id number can_be_resolved boolean can_grant_kudosu boolean created_at Timestamp current_user_attributes CurrentUserAttributes deleted_at Timestamp? deleted_by_id number? id number kudosu_denied boolean last_post_at Timestamp message_type MessageType parent_id number? posts BeatmapsetDiscussionPost[]? resolved boolean starting_post BeatmapsetDiscussionPost? timestamp number? updated_at Timestamp user_id number MessageType Name Description hype mapper_note praise problem review suggestion BeatmapsetDiscussionPost

Represents a post in a BeatmapsetDiscussion.

Field Type Description beatmapset_discussion_id number created_at Timestamp deleted_at Timestamp? deleted_by_id number? id number last_editor_id number? message string system boolean updated_at Timestamp user_id number BeatmapsetDiscussionVote

Represents a vote on a BeatmapsetDiscussion.

Field Type Description beatmapset_discussion_id number created_at Timestamp id number score number updated_at Timestamp user_id number Build { "id": 5778, "version": "20210520.2", "display_version": "20210520.2", "users": 22059, "created_at": "2021-05-20T14:28:04+00:00", "update_stream": { "id": 5, "name": "stable40", "display_name": "Stable", "is_featured": true } } Field Type created_at Timestamp display_version string id number update_stream UpdateStream? users number version string? youtube_id string? Optional Attributes

The following are attributes which may be additionally included in responses. Relevant endpoints should list them if applicable.

Field Type Notes changelog_entries ChangelogEntry[] If the build has no changelog entries, a placeholder is generated. versions Versions Versions Field Type next Build? previous Build? ChangelogEntry { "id": null, "repository": null, "github_pull_request_id": null, "github_url": null, "url": "https://osu.ppy.sh/home/news/2021-05-20-spring-fanart-contest-results", "type": "fix", "category": "Misc", "title": "Spring is here!", "message_html": "

New seasonal backgrounds ahoy! Amazing work by the artists.

\n", "major": true, "created_at": "2021-05-20T10:56:49+00:00" } Field Type category string created_at Timestamp? github_pull_request_id number? github_url string? id number? major boolean repository string? title string? type string url string? Optional Attributes

The following are attributes which may be additionally included in responses. Relevant endpoints should list them if applicable.

Field Type Notes github_user GithubUser If the changelog entry has no GitHub user, a placeholder is generated. message string? Entry message in Markdown format. Embedded HTML is allowed. message_html string? Entry message in HTML format. ChatChannel { "channel_id": 1337, "current_user_attributes": { "can_message": true, "can_message_error": null, "last_read_id": 9150005005, }, "name": "test channel", "description": "wheeeee", "icon": "/images/layout/[email protected]", "type": "GROUP", "last_read_id": 9150005005, "last_message_id": 9150005005, "moderated": false, "users": [ 2, 3, 102 ] }

Represents an individual chat "channel" in the game.

Field Type Description channel_id number name string description string? icon string? display icon for the channel type ChannelType type of channel message_length_limit number moderated boolean user can't send message when the value is true uuid string? value from requests that is relayed back to the sender.

Optional attributes:

Field Type Description current_user_attributes CurrentUserAttributes? only present on some responses last_read_id number? Deprecated; use current_user_attributes.last_read_id. last_message_id number? message_id of last known message (only returned in presence responses) recent_messages ChatMessage[]? Deprecated; up to 50 most recent messages users number[]? array of user_id that are in the channel (not included for PUBLIC channels) ChannelType Type Permission Check for Joining/Messaging PUBLIC PRIVATE is player in the allowed groups? (channel.allowed_groups) MULTIPLAYER is player currently in the mp game? SPECTATOR TEMPORARY deprecated PM see below (user_channels) GROUP is player in channel? (user_channels) ANNOUNCE is user in the announce group?

For PMs, two factors are taken into account:

Is either user blocking the other? If so, deny. Does the target only accept PMs from friends? Is the current user a friend? If not, deny. Public channels, group chats and private DMs are all considered "channels". ChatMessage { "channel_id": 5, "content": "i am a lazerface", "is_action": false, "message_id": 9150005004, "sender_id": 2, "timestamp": "2018-07-06T06:33:34+00:00", "type": "plain", "uuid": "some-uuid-string", "sender": { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true } }

Represents an individual Message within a ChatChannel.

Field Type Description channel_id number channel_id of where the message was sent content string message content content_html string? Deprecated. Markdown message content as HTML is_action boolean was this an action? i.e. /me dances message_id number unique identifier for message sender_id number user_id of the sender timestamp string when the message was sent, ISO-8601 type string type of message; 'action', 'markdown' or 'plain' uuid string? message identifier originally sent by client

Optional attributes:

Field Type Description sender UserCompact embedded UserCompact object to save additional api lookups Comment { "commentable_id": 407, "commentable_type": "news_post", "created_at": "2019-09-05T06:31:20+00:00", "deleted_at": null, "edited_at": null, "edited_by_id": null, "id": 276, "legacy_name": null, "message": "yes", "message_html": "

yes

\n", "parent_id": null, "pinned": true, "replies_count": 0, "updated_at": "2019-09-05T06:31:20+00:00", "user_id": 1, "votes_count": 0 }

Represents a single comment.

Field Type Description commentable_id number ID of the object the comment is attached to commentable_type string type of object the comment is attached to created_at string ISO 8601 date deleted_at string? ISO 8601 date if the comment was deleted; null, otherwise edited_at string? ISO 8601 date if the comment was edited; null, otherwise edited_by_id number? user id of the user that edited the post; null, otherwise id number the ID of the comment legacy_name string? username displayed on legacy comments message string? markdown of the comment's content message_html string? html version of the comment's content parent_id number? ID of the comment's parent pinned boolean Pin status of the comment replies_count number number of replies to the comment updated_at string ISO 8601 date user_id number user ID of the poster votes_count number number of votes CommentBundle { "commentable_meta": [ { "id": 407, "title": "Clicking circles linked to increased performance", "type": "news_post", "url": "https://osu.ppy.sh/home" } ], "comments": [ { "commentable_id": 407, "commentable_type": "news_post", "created_at": "2019-09-05T06:31:20+00:00", "deleted_at": null, "edited_at": null, "edited_by_id": null, "id": 276, "legacy_name": null, "message": "yes", "message_html": "

yes

\n", "parent_id": null, "replies_count": 0, "updated_at": "2019-09-05T06:31:20+00:00", "user_id": 1, "votes_count": 1337 }, { "commentable_id": 407, "commentable_type": "news_post", "created_at": "2019-09-05T07:31:20+00:00", "deleted_at": null, "edited_at": null, "edited_by_id": null, "id": 277, "legacy_name": null, "message": "absolutely", "message_html": "

absolutely

\n", "parent_id": null, "replies_count": 0, "updated_at": "2019-09-05T07:31:20+00:00", "user_id": 2, "votes_count": 1337 } ], "has_more": true, "has_more_id": 276, "included_comments": [], "pinned_comments": [], "sort": "new", "user_follow": false, "user_votes": [277], "users": [ { "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "default_group": "pippi", "id": 1, "is_active": true, "is_bot": false, "is_online": true, "is_supporter": true, "last_visit": "2025-09-05T08:35:00+00:00", "pm_friends_only": false, "profile_colour": null, "username": "pippi" }, { "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "default_group": "yuzu", "id": 2, "is_active": true, "is_bot": false, "is_online": false, "is_supporter": true, "last_visit": "2025-09-04T09:28:00+00:00", "pm_friends_only": false, "profile_colour": null, "username": "yuzu" } ] }

Comments and related data.

Field Type Description commentable_meta CommentableMeta[] ID of the object the comment is attached to comments Comment[] Array of comments ordered according to sort; cursor Cursor has_more boolean If there are more comments or replies available has_more_id number? included_comments Comment[] Related comments; e.g. parent comments and nested replies pinned_comments Comment[]? Pinned comments sort string one of the CommentSort types top_level_count number? Number of comments at the top level. Not returned for replies. total number? Total number of comments. Not retuned for replies. user_follow boolean is the current user watching the comment thread? user_votes number[] IDs of the comments in the bundle the current user has upvoted users UserCompact[] array of users related to the comments CommentSort

Available sort types are new, old, top.

Type Sort Fields new created_at (descending), id (descending) old created_at (ascending), id (ascending) top votes_count (descending), created_at (descending), id (descending) Building cursor for comments listing

The returned response will be for comments after the specified sort fields.

For example, use last loaded comment for the fields value to load more comments. Also make sure to use same sort and parent_id values.

CommentableMeta { "id": 407, "title": "Clicking circles linked to increased performance", "type": "news_post", "url": "https://osu.ppy.sh/home/" }

Metadata of the object that a comment is attached to.

If object is available:

Field Type Description current_user_attributes CurrentUserAttributes id number the ID of the object owner_id number? User ID which owns the object owner_title string? Object owner type, used for display (MAPPER for beatmapset) title string display title type string the type of the object url string url of the object

Otherwise if object has been deleted:

Field Type Description title string display title CurrentUserAttributes Field Type Description can_new_comment_reason string? null if current user can comment on it, reason sentence otherwise CurrentUserAttributes

An object listing various related permissions and states for the current user, related to the object it is attached to.

BeatmapsetDiscussionPermissions

TODO: needs a better name.

Name Description can_destroy Can delete the discussion. can_reopen Can reopen the discussion. can_moderate_kudosu Can allow or deny kudosu. can_resolve Can resolve the discussion. vote_score Current vote given to the discussion. ChatChannelUserAttributes Name Type Description can_message boolean Can send messages to this channel. can_message_error string? Reason messages cannot be sent to this channel last_read_id number message_id of last message read. Cursor { "_id": 5, "_score": 36.234 } // query string: cursor[_id]=5&cursor[_score]=36.234 { "page": 2, } // query string: cursor[page]=2

A structure included in some API responses containing the parameters to get the next set of results.

The values of the cursor should be provided to next request of the same endpoint to get the next set of results.

If there are no more results available, a cursor with a value of null is returned: "cursor": null.

Note that sort option should also be specified for it to work.

This pagination parameter is being deprecated and replaced with CursorString. CursorString

A string value included in some API responses containing the parameter to get the next set of results.

Its value will be null (or not defined) if there are no more results available.

Note that all parameters used in previous request also need to be passed.

Event

The object has different attributes depending on its type. Following are attributes available to all types.

Field Type Description created_at Timestamp id number type Event.Type Additional objects Beatmap Field Type title string url string Beatmapset Field Type title string url string User Field Type Description username string url string previousUsername string? Only for usernameChange event. Available Types achievement

When user obtained an achievement.

Field Type achievement Achievement user Event.User beatmapPlaycount

When a beatmap has been played for certain number of times.

Field Type beatmap Event.Beatmap count number beatmapsetApprove

When a beatmapset changes state.

Field Type Description approval string ranked, approved, qualified, loved. beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetDelete

When a beatmapset is deleted.

Field Type beatmapset Event.Beatmapset beatmapsetRevive

When a beatmapset in graveyard state is updated.

Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetUpdate

When a beatmapset is updated.

Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetUpload

When a new beatmapset is uploaded.

Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. rank

When a user achieves a certain rank on a beatmap.

Field Type Description scoreRank string (FIXME) rank number mode GameMode beatmap Event.Beatmap user Event.User rankLost

When a user loses first place to another user.

Field Type mode GameMode beatmap Event.Beatmap user Event.User userSupportAgain

When a user supports osu! for the second and onwards.

Field Type user Event.User userSupportFirst

When a user becomes a supporter for the first time.

Field Type user Event.User userSupportGift

When a user is gifted a supporter tag by another user.

Field Type Description user Event.User Recipient user. usernameChange

When a user changes their username.

Field Type Description user Event.User Includes previousUsername. Forum Post Field Type Description created_at Timestamp deleted_at Timestamp? edited_at Timestamp? edited_by_id number? forum_id number id number topic_id number user_id number

Following fields are optional.

Field Type Description body.html string Post content in HTML format. body.raw string Post content in BBCode format. Forum Topic Field Type created_at Timestamp deleted_at Timestamp? first_post_id number forum_id number id number is_locked boolean last_post_id number poll Poll? post_count number title string type normal | sticky | announcement updated_at Timestamp user_id number Poll Field Type allow_vote_change boolean ended_at Timestamp? hide_incomplete_results boolean last_vote_at Timestamp? max_votes number options PollOption[] started_at Timestamp title.bbcode string title.html string total_vote_count number PollOption Field Type Notes id number Unique only per-topic. text.bbcode string text.html string vote_count number? Not present if the poll is incomplete and results are hidden. GameMode

Available game modes:

Name Description fruits osu!catch mania osu!mania osu osu!standard taiko osu!taiko GithubUser { "id": 218, "display_name": "bdach", "github_url": "https://github.com/bdach", "osu_username": null, "user_id": null, "user_url": null } Field Type display_name string github_url string? id number? osu_username string? user_id number? user_url string? Group

This object is not returned by any endpoints yet. It is here only as a reference for UserGroup.

Field Type Description colour string? has_listing boolean Whether this group displays a listing at /groups/{id}. has_playmodes boolean Whether this group associates GameModes with users' memberships. id number identifier string Unique string to identify the group. is_probationary boolean Whether members of this group are considered probationary. name string short_name string Short name of the group for display. Optional Attributes

The following are attributes which may be additionally included in responses. Relevant endpoints should list them if applicable.

Field Type description Description? Description Field Type html string markdown string KudosuHistory Field Type Description id number action string One of give, vote.give, reset, vote.reset, revoke, or vote.revoke. amount number model string Object type which the exchange happened on (forum_post, etc). created_at Timestamp giver Giver? Simple detail of the user who started the exchange. post Post Simple detail of the object for display. Giver Field Type url string username string Post Field Type Description url string? Url of the object. title string Title of the object. It'll be "[deleted beatmap]" for deleted beatmaps. MultiplayerScore

Score data.

Field Type Description id number user_id number room_id number playlist_item_id number beatmap_id number rank rank total_score number accuracy number max_combo number mods Mod[] statistics Statistics passed bool position number? scores_around MultiplayerScoresAround? Scores around the specified score. user User MultiplayerScores

An object which contains scores and related data for fetching next page of the result.

Field Type Description cursor_string CursorString To be used to fetch the next page. params object Parameters used for score listing. scores MultiplayerScore[] total number? Index only. Total scores of the specified playlist item. user_score MultiplayerScore? Index only. Score of the accessing user if exists. MultiplayerScoresAround Field Type Description higher MultiplayerScores lower MultiplayerScores MultiplayerScoresCursor

An object which contains pointer for fetching further results of a request. It depends on the sort option.

Field Type Description score_id number Last score id of current result (score_asc, score_desc). total_score number Last score's total score of current result (score_asc, score_desc). MultiplayerScoresSort

Sort option for multiplayer scores index.

Name Description score_asc Sort by scores, ascending. score_desc Sort by scores, descending. NewsPost Field Type Description author string edit_url string Link to the file view on GitHub. first_image string? Link to the first image in the document. id number published_at Timestamp slug string Filename without the extension, used in URLs. title string updated_at Timestamp Optional Attributes Field Type Description content string HTML post content. navigation Navigation Navigation metadata. preview string First paragraph of content with HTML markup stripped. Navigation Field Type Description newer NewsPost? Next post. older NewsPost? Previous post. Nomination Field Type beatmapset_id number rulesets GameMode[] reset boolean user_id number Notification { "id": 1, "name": "channel_message", "created_at": "2019-04-24T07:12:43+00:00", "object_type": "channel", "object_id": 1, "source_user_id": 1, "is_read": true, "details": { "username": "someone", ... } }

Represents a notification object.

Field Type Description id number name string Name of the event created_at string ISO 8601 date object_type string object_id number source_user_id number? is_read boolean details object message_id of last known message (only returned in presence responses) Event Names Name Description beatmapset_discussion_lock Discussion on beatmap has been locked beatmapset_discussion_post_new New discussion post on beatmap beatmapset_discussion_unlock Discussion on beatmap has been unlocked beatmapset_disqualify Beatmap was disqualified beatmapset_love Beatmap was promoted to loved beatmapset_nominate Beatmap was nominated beatmapset_qualify Beatmap has gained enough nominations and entered the ranking queue beatmapset_remove_from_loved Beatmap was removed from Loved beatmapset_reset_nominations Nomination of beatmap was reset channel_message Someone sent chat message forum_topic_reply Someone replied on forum topic beatmapset_discussion_lock Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who locked discussion

Details object:

Field Type Description cover_url string Beatmap cover title string Beatmap title username string Username of source_user_id beatmapset_discussion_post_new Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number Poster of the discussion

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover discussion_id number post_id number beatmap_id number? null if posted to general all username string Username of source_user_id beatmapset_discussion_unlock Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who unlocked discussion

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_disqualify Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who disqualified beatmapset

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_love Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who promoted beatmapset to loved

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_nominate Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who nominated beatmapset

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_qualify Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User whom beatmapset nomination triggered qualification

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_remove_from_loved Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who removed beatmapset from Loved

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id beatmapset_reset_nominations Field Type Description object_id number Beatmapset id object_type string beatmapset source_user_id number User who triggered nomination reset

Details object:

Field Type Description title string Beatmap title cover_url string Beatmap cover username string Username of source_user_id channel_message Field Type Description object_id number Channel id object_type string channel source_user_id number User who posted message

Details object:

Field Type Description title string Up to 36 characters of the message (ends with ... when exceeding 36 characters) cover_url string Avatar of source_user_id username string Username of source_user_id forum_topic_reply Field Type Description object_id number Topic id object_type string forum_topic source_user_id number User who posted message

Details object:

Field Type Description title string Title of the replied topic cover_url string Topic cover post_id number Post id username string? Username of source_user_id RankingType

Available ranking types:

Name Description charts Spotlight country Country performance Performance score Score Rankings { "cursor": { }, "ranking": [ { "grade_counts": { "a": 3, "s": 2, "sh": 6, "ss": 2, "ssh": 3 }, "hit_accuracy": 92.19, "is_ranked": true, "level": { "current": 30, "progress": 0 }, "maximum_combo": 3948, "play_count": 228050, "play_time": null, "pp": 990, "global_rank": 87468, "ranked_score": 1502995536, "replays_watched_by_others": 0, "total_hits": 5856573, "total_score": 2104193750, "user": { "avatar_url": "/images/layout/avatar-guest.png", "country": { "code": "GF", "name": "French Guiana" }, "country_code": "GF", "cover": { "custom_url": null, "id": "3", "url": "http://osuweb.test/images/headers/profile-covers/c3.jpg" }, "default_group": "default", "id": 458402, "is_active": false, "is_bot": false, "is_online": false, "is_supporter": true, "last_visit": "2017-02-22T11:07:10+00:00", "pm_friends_only": false, "profile_colour": null, "username": "serdman" } } ], "total": 100 } Field Type Description beatmapsets Beatmapset[]? The list of beatmaps in the requested spotlight for the given mode; only available if type is charts cursor Cursor A cursor ranking UserStatistics[] Score details ordered by rank in descending order. spotlight Spotlight? Spotlight details; only available if type is charts total number An approximate count of ranks available Score

The following is the format returned when API v2 version header is 20220704 or lower.

Field Type Description id best_id user_id accuracy mods score max_combo perfect statistics.count_50 statistics.count_100 statistics.count_300 statistics.count_geki statistics.count_katu statistics.count_miss passed boolean pp rank created_at mode mode_int replay

Optional attributes:

Field Type Description beatmap beatmapset rank_country rank_global weight user match Spotlight { "end_date": "2019-03-22T00:00:00+00:00", "id": 1, "mode_specific": false, "name": "Best spinning circles 2019", "start_date": "2019-02-22T00:00:00+00:00", "type": "yearly", }

The details of a spotlight.

Field Type Description end_date DateTime The end date of the spotlight. id number The ID of this spotlight. mode_specific boolean If the spotlight has different mades specific to each GameMode. participant_count number? The number of users participating in this spotlight. This is only shown when viewing a single spotlight. name string The name of the spotlight. start_date DateTime The starting date of the spotlight. type string The type of spotlight. Spotlights { "spotlights": [ { "end_date": "2019-03-22T00:00:00+00:00", "id": 1, "mode_specific": false, "name": "Best spinning circles 2019", "start_date": "2019-02-22T00:00:00+00:00", "type": "yearly", }, { "end_date": "2019-03-22T00:00:00+00:00", "id": 2, "mode_specific": true, "name": "Ultimate fruit collector February 2019", "start_date": "2019-02-22T00:00:00+00:00", "type": "monthly", } ], } Field Type Description spotlights Spotlight[] An array of spotlights Timestamp "2020-01-01T00:00:00+00:00"

Timestamp string in ISO 8601 format.

UpdateStream { "id": 7, "name": "lazer", "display_name": "Lazer", "is_featured": false } Field Type display_name string? id number is_featured boolean name string Optional Attributes

The following are attributes which may be additionally included in responses. Relevant endpoints should list them if applicable.

Field Type latest_build Build? user_count number User { "avatar_url": "https://a.ppy.sh/1?1501234567.jpeg", "country_code": "AU", "default_group": "default", "id": 1, "is_active": true, "is_bot": false, "is_deleted": false, "is_online": false, "is_supporter": true, "last_visit": "2020-01-01T00:00:00+00:00", "pm_friends_only": false, "profile_colour": "#000000", "username": "osuuser", "cover_url": "https://assets.ppy.sh/user-profile-covers/1/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.jpeg", "discord": "osuuser#1337", "has_supported": true, "interests": null, "join_date": "2010-01-01T00:00:00+00:00", "kudosu": { "total": 20, "available": 10 }, "location": null, "max_blocks": 50, "max_friends": 500, "occupation": null, "playmode": "osu", "playstyle": [ "mouse", "touch" ], "post_count": 100, "profile_order": [ "me", "recent_activity", "beatmaps", "historical", "kudosu", "top_ranks", "medals" ], "title": null, "twitter": "osuuser", "website": "https://osu.ppy.sh", "country": { "code": "AU", "name": "Australia" }, "cover": { "custom_url": "https://assets.ppy.sh/user-profile-covers/1/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.jpeg", "url": "https://assets.ppy.sh/user-profile-covers/1/0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.jpeg", "id": null }, "is_restricted": false, "account_history": [], "active_tournament_banner": null, "badges": [ { "awarded_at": "2015-01-01T00:00:00+00:00", "description": "Test badge", "image_url": "https://assets.ppy.sh/profile-badges/test.png", "url": "" } ], "favourite_beatmapset_count": 10, "follower_count": 100, "graveyard_beatmapset_count": 10, "groups": [ { "id": 1, "identifier": "gmt", "name": "gmt", "short_name": "GMT", "description": "", "colour": "#FF0000" } ], "loved_beatmapset_count": 0, "monthly_playcounts": [ { "start_date": "2019-11-01", "count": 100 }, { "start_date": "2019-12-01", "count": 150 }, { "start_date": "2020-01-01", "count": 20 } ], "page": { "html": "Hello", "raw": "[centre]Hello[/centre]" }, "pending_beatmapset_count": 0, "previous_usernames": [], "ranked_beatmapset_count": 10, "replays_watched_counts": [ { "start_date": "2019-11-01", "count": 10 }, { "start_date": "2019-12-01", "count": 12 }, { "start_date": "2020-01-01", "count": 1 } ], "scores_first_count": 0, "statistics": { "level": { "current": 60, "progress": 55 }, "pp": 100, "global_rank": 2000, "ranked_score": 2000000, "hit_accuracy": 90.5, "play_count": 1000, "play_time": 100000, "total_score": 3000000, "total_hits": 6000, "maximum_combo": 500, "replays_watched_by_others": 270, "is_ranked": true, "grade_counts": { "ss": 10, "ssh": 5, "s": 50, "sh": 0, "a": 40 }, "rank": { "global": 15000, "country": 30000 } }, "support_level": 3, "user_achievements": [ { "achieved_at": "2020-01-01T00:00:00+00:00", "achievement_id": 1 } ], "rank_history": { "mode": "osu", "data": [ 16200, 15500, 15000 ] } }

Represents a User. Extends UserCompact object with additional attributes.

Field Type Description cover_url string url of profile cover. Deprecated, use cover.url instead. discord string? has_supported boolean whether or not ever being a supporter in the past interests string? join_date Timestamp kudosu.available number kudosu.total number location string? max_blocks number maximum number of users allowed to be blocked max_friends number maximum number of friends allowed to be added occupation string? playmode GameMode playstyle string[] Device choices of the user. post_count number number of forum posts profile_order ProfilePage[] ordered array of sections in user profile page title string? user-specific title title_url string? twitter string? website string?

In addition, the following optional attributes on UserCompact are included:

country cover is_restricted (present only if this is the currently authenticated user) ProfilePage Section me recent_activity beatmaps historical kudosu top_ranks medals UserCompact { "id": 2, "username": "peppy", "profile_colour": "#3366FF", "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country_code": "AU", "is_active": true, "is_bot": false, "is_deleted": false, "is_online": true, "is_supporter": true }

Mainly used for embedding in certain responses to save additional api lookups.

Field Type Description avatar_url string url of user's avatar country_code string two-letter code representing user's country default_group string? Identifier of the default Group the user belongs to. id number unique identifier for user is_active boolean has this account been active in the last x months? is_bot boolean is this a bot account? is_deleted boolean is_online boolean is the user currently online? (either on lazer or the new website) is_supporter boolean does this user have supporter? last_visit Timestamp? last access time. null if the user hides online presence pm_friends_only boolean whether or not the user allows PM from other than friends profile_colour string? colour of username/profile highlight, hex code (e.g. #333333) username string user's display name Optional attributes

Following are attributes which may be additionally included in the response. Relevant endpoints should list them if applicable.

Field Type account_history UserAccountHistory[] active_tournament_banner UserCompact.ProfileBanner? badges UserBadge[] beatmap_playcounts_count number blocks country cover favourite_beatmapset_count number follow_user_mapping number[] follower_count number friends graveyard_beatmapset_count number groups UserGroup[] guest_beatmapset_count number is_restricted boolean? loved_beatmapset_count number mapping_follower_count number monthly_playcounts UserMonthlyPlaycount[] page pending_beatmapset_count previous_usernames rank_highest RankHighest? rank_history ranked_beatmapset_count replays_watched_counts scores_best_count number scores_first_count number scores_recent_count number statistics statistics_rulesets UserStatisticsRulesets support_level unread_pm_count user_achievements user_preferences ProfileBanner Field Type Description id number tournament_id number image string RankHighest Field Type rank number updated_at Timestamp UserAccountHistory Field Type Description description string? id number length number In seconds. permanent boolean timestamp Timestamp type string note, restriction, or silence. UserBadge Field Type Description awarded_at Timestamp description string image_url string url string UserGroup

Describes a Group membership of a User. It contains all of the attributes of the Group, in addition to what is listed here.

Field Type Description playmodes string[]? GameModes associated with this membership (null if has_playmodes is unset). UserSilence { "id": 1, "user_id": 5 }

A record indicating a User was silenced.

Field Type Description id number id of this object. user_id number id of the User that was silenced UserStatistics { "count_100": 0, "count_300": 0, "count_50": 0, "count_miss": 0, "grade_counts": { "a": 3, "s": 2, "sh": 6, "ss": 2, "ssh": 3 }, "hit_accuracy": 92.19, "is_ranked": true, "level": { "current": 30, "progress": 0 }, "maximum_combo": 3948, "play_count": 228050, "play_time": null, "pp": 990, "global_rank": 87468, "ranked_score": 1502995536, "replays_watched_by_others": 0, "total_hits": 5856573, "total_score": 2104193750, "user": { "avatar_url": "https://a.ppy.sh/2?1519081077.png", "country": { "code": "AU", "name": "Australia" }, "country_code": "AU", "cover": { "custom_url": null, "id": "3", "url": "https://assets.ppy.sh/user-profile-covers/2/baba245ef60834b769694178f8f6d4f6166c5188c740de084656ad2b80f1eea7.jpeg" }, "default_group": "ppy", "id": 2, "is_active": false, "is_bot": false, "is_online": false, "is_supporter": true, "last_visit": "2019-02-22T11:07:10+00:00", "pm_friends_only": false, "profile_colour": "#3366FF", "username": "peppy" } }

A summary of various gameplay statistics for a User. Specific to a GameMode

Field Type Description count_100 number count_300 number count_50 number count_miss number country_rank number? Current country rank according to pp. grade_counts.a number Number of A ranked scores. grade_counts.s number Number of S ranked scores. grade_counts.sh number Number of Silver S ranked scores. grade_counts.ss number Number of SS ranked scores. grade_counts.ssh number Number of Silver SS ranked scores. hit_accuracy number Hit accuracy percentage is_ranked boolean Is actively ranked level.current number Current level. level.progress number Progress to next level. maximum_combo number Highest maximum combo. play_count number Number of maps played. play_time number Cumulative time played. pp number Performance points pp_exp number Experimental (lazer) performance points global_rank number? Current rank according to pp. global_rank_exp number? Current rank according to experimental (lazer) pp. ranked_score number Current ranked score. replays_watched_by_others number Number of replays watched by other users. total_hits number Total number of hits. total_score number Total score. user UserCompact The associated user. WikiPage { "available_locales": ["en", "id", "ja", "pt-br"], "layout": "markdown_page", "locale": "en", "markdown": "# osu! (game mode)\n\n![Gameplay of osu!](/wiki/shared/Interface_osu.jpg \"osu! Interface\")\n\nMarkdownMarkdownTruncated", "path": "Game_Modes/osu!", "subtitle": "Game Modes", "tags": ["tap", "circles"], "title": "osu! (game mode)" }

Represents a wiki article

Field Type Description available_locales string[] All available locales for the article. layout string The layout type for the page. locale string All lowercase BCP 47 language tag. markdown string Markdown content. path string Path of the article. subtitle string? The article's subtitle. tags string[] Associated tags for the article. title string The article's title.


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3