osu!web Documentation |
您所在的位置:网站首页 › apiv2是什么意思 › osu!web Documentation |
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 UseUse 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. WrappersBelow 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) ChangelogFor 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 URLThe base URL is: https://osu.ppy.sh/api/[version]/ API VersionsThis 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 LanguageLanguage 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. AuthenticationRoutes 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 GrantBefore 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 applicationBefore 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 GrantThe 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 userTo 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 siteIf 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 FormatSuccessful 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 tokenAccess 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 FormatSuccessful 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 GrantThe 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 FormatSuccessful 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 APIWith 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 OwnerThe 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 DelegationClient 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 ScopesThe following scopes are currently supported: Name Description chat.writeAllows sending chat messages on a user's behalf. delegateAllows acting as the owner of a client; only available for Client Credentials Grant. forum.writeAllows creating and editing forum posts on a user's behalf. friends.readAllows reading of the user's friend list. identifyAllows reading of the public profile of the user (/me). publicAllows 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 applicationsYour account settings page will show your registered OAuth applications, and all the OAuth applications you have granted permissions to. Reset Client SecretYou 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 BeatmapOAuth 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: RequestGET /beatmaps/lookup Response formatSee Get Beatmap Get a User Beatmap scoreOAuth 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: RequestGET /beatmaps/{beatmap}/scores/users/{user} Response FormatReturns BeatmapUserScore The position returned depends on the requested mode and mods. Get a User Beatmap scoresOAuth 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: RequestGET /beatmaps/{beatmap}/scores/users/{user}/all Response Format Field Type scores Score[] Get Beatmap scoresOAuth 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: RequestGET /beatmaps/{beatmap}/scores Response FormatReturns 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: RequestGET /beatmaps/{beatmap}/solo-scores Response FormatReturns BeatmapScores. Score object inside includes user and the included user includes country and cover. Get BeatmapsOAuth 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: RequestGET /beatmaps Response format Field Type Description beatmaps Beatmap[] Includes beatmapset (with ratings), failtimes, and max_combo. Get BeatmapOAuth 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: RequestGET /beatmaps/{beatmap} Response formatReturns Beatmap object. Following attributes are included in the response object when applicable, Attribute Notes beatmapset Includes ratings property. failtimes max_combo Get Beatmap AttributesOAuth 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: RequestPOST /beatmaps/{beatmap}/attributes Response format Field Type Attributes DifficultyAttributes Beatmapset Discussions Get Beatmapset Discussion PostsOAuth 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: RequestGET /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 VotesOAuth 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: RequestGET /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 DiscussionsOAuth 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: RequestGET /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: RequestGET /changelog/{stream}/{build} Response FormatA 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: RequestGET /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: RequestGET /changelog/{changelog} Response FormatSee Get Changelog Build. Chat Chat Keepaliverequires 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: RequestPOST /chat/ack Response Format Field Type silences UserSilence[] Create New PMrequires 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: RequestPOST /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 Updatesrequires 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: RequestGET /chat/updates Response Format Field Type messages This field is not used and will be removed. presence ChatChannel[]? silences UserSilence[]? Get Channel Messagesrequires 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: RequestGET /chat/channels/{channel}/messages Response FormatReturns an array of ChatMessage Send Message to Channelrequires 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: RequestPOST /chat/channels/{channel}/messages Response FormatThe sent ChatMessage When sending a message, the last_read_id for the ChatChannel is also updated to mark the new message as read. Join Channelrequires 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: RequestPUT /chat/channels/{channel}/users/{user} Response FormatReturns the joined ChatChannel. Leave Channelrequires 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: RequestDELETE /chat/channels/{channel}/users/{user} Response Formatempty response This endpoint will only allow the leaving of public channels initially. Mark Channel as Readrequires 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: RequestPUT /chat/channels/{channel}/mark-as-read/{message} Response Formatempty 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 Listrequires 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: RequestGET /chat/channels Response FormatReturns an array of ChatChannel Create Channelrequires 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: RequestPOST /chat/channels Response FormatReturns ChatChannel with recent_messages attribute; recent_messages is deprecated and should not be used. Get Channelrequires 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: RequestGET /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: RequestGET /comments Response FormatReturns CommentBundle. pinned_comments is only included when commentable_type and commentable_id are specified. Post a new commentrequires 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: RequestPOST /comments Response FormatReturns 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: RequestGET /comments/{comment} Response FormatReturns CommentBundle Edit Commentrequires 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: RequestPUT /comments/{comment} PATCH /comments/{comment} Response FormatReturns CommentBundle Delete Commentrequires 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: RequestDELETE /comments/{comment} Response FormatReturns CommentBundle Add Comment voterequires 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: RequestPOST /comments/{comment}/vote Response FormatReturns CommentBundle Remove Comment voterequires 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: RequestDELETE /comments/{comment}/vote Response FormatReturns CommentBundle Events Get EventsOAuth 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: RequestGET /events Response Format Field Type cursor_string CursorString events Event[] Forum Reply Topicrequires 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: RequestPOST /forums/topics/{topic}/reply Response FormatForumPost with body included. Create Topicrequires 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: RequestPOST /forums/topics Response Format Field Type Includes topic ForumTopic post ForumPost body Get Topic and PostsOAuth 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: RequestGET /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 TopicOAuth 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: RequestPUT /forums/topics/{topic} PATCH /forums/topics/{topic} Response FormatThe edited ForumTopic. Edit PostOAuth 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: RequestPUT /forums/posts/{post} PATCH /forums/posts/{post} Response FormatForumPost with body included. Home SearchOAuth 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: RequestGET /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 Scorerequires 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: RequestGET /rooms/{room}/playlist/{playlist}/scores/users/{user} Response FormatReturns MultiplayerScore object. Get ScoresOAuth 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: RequestGET /rooms/{room}/playlist/{playlist}/scores Response FormatReturns MultiplayerScores object. Get a Scorerequires 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: RequestGET /rooms/{room}/playlist/{playlist}/scores/{score} Response FormatReturns 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: RequestGET /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: RequestGET /news/{news} Response FormatReturns a NewsPost with content and navigation included. Notification Get Notificationsrequires 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: RequestGET /notifications Response FormatReturns 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 Readrequires 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: RequestPOST /notifications/mark-read Response Formatempty response OAuth Tokens Revoke current tokenOAuth 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: RequestDELETE /oauth/tokens/current Ranking Get RankingOAuth 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: RequestGET /rankings/{mode}/{type} Response FormatReturns Rankings Get SpotlightsOAuth 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: RequestGET /spotlights Response FormatReturns Spotlights Undocumented POST api/v2/beatmaps/{beatmap}/solo/scoresrequires 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: RequestPOST /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: RequestPUT /beatmaps/{beatmap}/solo/scores/{token} GET api/v2/beatmapsets/eventsOAuth 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: RequestGET /beatmapsets/events POST api/v2/beatmapsets/{beatmapset}/favouritesrequires 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: RequestPOST /beatmapsets/{beatmapset}/favourites GET api/v2/chat/presencerequires 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: RequestGET /chat/presence GET api/v2/matchesOAuth 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: RequestGET /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: RequestGET /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: RequestGET /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: RequestPUT /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: RequestDELETE /rooms/{room}/users/{user} GET api/v2/rooms/{room}/leaderboardrequires 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: RequestGET /rooms/{room}/leaderboard POST api/v2/rooms/{room}/playlist/{playlist}/scoresrequires 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: RequestPOST /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: RequestPUT /rooms/{room}/playlist/{playlist}/scores/{score} PATCH /rooms/{room}/playlist/{playlist}/scores/{score} POST api/v2/reportsrequires 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: RequestPOST /reports POST api/v2/roomsrequires 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: RequestPOST /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: RequestGET /rooms/{room} GET api/v2/seasonal-backgroundsExample 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}/downloadrequires 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: RequestGET /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: RequestGET /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: RequestGET /beatmapsets/search/{filters?} GET api/v2/beatmapsets/lookupOAuth 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: RequestGET /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: RequestGET /beatmapsets/{beatmapset} GET api/v2/friendsrequires 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: RequestGET /friends GET api/v2/me/download-quota-checkrequires 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: RequestGET /me/download-quota-check GET api/v2/beatmapsets/{beatmapset}/downloadOAuth 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: RequestGET /beatmapsets/{beatmapset}/download Users Get Own Datarequires 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: RequestGET /me/{mode?} Response formatSee Get User. Additionally, statistics_rulesets is included, containing statistics for all rulesets. Get User KudosuOAuth 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: RequestGET /users/{user}/kudosu Response formatArray of KudosuHistory. Get User ScoresOAuth 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: RequestGET /users/{user}/scores/{type} Response formatArray of Score. Following attributes are included in the response object when applicable. Attribute Notes beatmap beatmapset weight Only for type best. Get User BeatmapsOAuth 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: RequestGET /users/{user}/beatmapsets/{type} Response formatArray of BeatmapPlaycount when type is most_played; array of Beatmapset, otherwise. Get User Recent ActivityOAuth 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: RequestGET /users/{user}/recent_activity Response formatArray of Event. Get UserOAuth 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: RequestGET /users/{user}/{mode?} Response formatReturns 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 UsersOAuth 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: RequestGET /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: RequestGET /wiki/{locale}/{path} Response FormatReturns WikiPage. Using ChatTODO: 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 timeoutTo 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 listTODO: 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 channelMake 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 channelMake 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 channelMake 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 messagesChannels 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 channelMake a request to the Get Channel endpoint. Getting channel message historyMake 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 EventsWebsocket 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 eventUser 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 eventSent when a new notification is received. Payload FormatSee Notification object for notification types. read eventSent 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.joinBroadcast to the user when the user joins a chat channel. Payload FormatChatChannel with current_user_attributes, last_message_id, users additional attributes. chat.channel.partBroadcast to the user when the user leaves a chat channel. Payload FormatChatChannel with current_user_attributes, last_message_id, users additional attributes. chassage.newSent 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 CommandsWebsocket commands have the format: { "event": "some.event" } Field Type Description event string Name of the event.Commands currently do not have any payload. chat.startSend to the websocket to start receiving chat messages. webSocket.send(JSON.stringify({ event: 'chat.start' })); chat.endSend to the websocket to stop receiving chat messages. webSocket.send(JSON.stringify({ event: 'chat.start' })); Object Structures BeatmapRepresent 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 BeatmapCompactRepresent 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 stringOptional 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 FailtimesAll 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. BeatmapDifficultyAttributesRepresent 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 BeatmapPlaycountRepresent 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. BeatmapsetRepresents 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 stringThe following attributes are always included as well: Field has_favourited BeatmapsetCompactRepresents 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 booleanThose 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 statusThe 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 BeatmapsetDiscussionRepresents 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 BeatmapsetDiscussionPostRepresents 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 BeatmapsetDiscussionVoteRepresents 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 AttributesThe 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 AttributesThe 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 clientOptional 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 CommentSortAvailable 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 listingThe 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 objectOtherwise 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 CurrentUserAttributesAn object listing various related permissions and states for the current user, related to the object it is attached to. BeatmapsetDiscussionPermissionsTODO: 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]=2A 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. CursorStringA 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. EventThe 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 achievementWhen user obtained an achievement. Field Type achievement Achievement user Event.User beatmapPlaycountWhen a beatmap has been played for certain number of times. Field Type beatmap Event.Beatmap count number beatmapsetApproveWhen a beatmapset changes state. Field Type Description approval string ranked, approved, qualified, loved. beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetDeleteWhen a beatmapset is deleted. Field Type beatmapset Event.Beatmapset beatmapsetReviveWhen a beatmapset in graveyard state is updated. Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetUpdateWhen a beatmapset is updated. Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. beatmapsetUploadWhen a new beatmapset is uploaded. Field Type Description beatmapset Event.Beatmapset user Event.User Beatmapset owner. rankWhen 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 rankLostWhen a user loses first place to another user. Field Type mode GameMode beatmap Event.Beatmap user Event.User userSupportAgainWhen a user supports osu! for the second and onwards. Field Type user Event.User userSupportFirstWhen a user becomes a supporter for the first time. Field Type user Event.User userSupportGiftWhen a user is gifted a supporter tag by another user. Field Type Description user Event.User Recipient user. usernameChangeWhen 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 numberFollowing 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. GameModeAvailable 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? GroupThis 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 AttributesThe 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. MultiplayerScoreScore 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 MultiplayerScoresAn 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 MultiplayerScoresCursorAn 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). MultiplayerScoresSortSort 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 discussionDetails 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 discussionDetails 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 discussionDetails 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 beatmapsetDetails 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 lovedDetails 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 beatmapsetDetails 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 qualificationDetails 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 LovedDetails 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 resetDetails 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 messageDetails 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 messageDetails 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 RankingTypeAvailable 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 ScoreThe 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 replayOptional 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 AttributesThe 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 attributesFollowing 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 UserGroupDescribes 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 |