You can create an API instance without directly providing an access_token by using API.createAsync!

Hierarchy (view full)

Constructors

Accessors

Methods

Beatmap Functions

Beatmapset Functions

Changelog Functions

Chat Functions

Comment Functions

Event Functions

Forum Functions

Home Functions

Multiplayer Functions

NewsPost Functions

Other Functions

Ranking Functions

User Functions

WikiPage Functions

Constructors

  • Please use API.createAsync instead of the default constructor if you don't have at least an API.access_token! An API object without an access_token is pretty much useless!

    Parameters

    • properties: Partial<API>

    Returns API

Accessors

  • get access_token(): string
  • The key that allows you to talk with the API

    Returns string

  • set access_token(token): void
  • Parameters

    • token: string

    Returns void

  • get client(): {
        id: number;
        secret: string;
    }
  • The details of your client, which you've got from https://osu.ppy.sh/home/account/edit#oauth

    Returns {
        id: number;
        secret: string;
    }

    • id: number
    • secret: string
  • set client(client): void
  • Parameters

    • client: {
          id: number;
          secret: string;
      }
      • id: number
      • secret: string

    Returns void

  • get expires(): Date
  • The expiration date of your access_token

    Returns Date

  • set expires(date): void
  • Parameters

    • date: Date

    Returns void

  • get refresh_on_401(): boolean
  • If true, upon failing a request due to a 401, it will use the API.refresh_token if it exists (defaults to true)

    Returns boolean

  • set refresh_on_401(refresh): void
  • Parameters

    • refresh: boolean

    Returns void

  • get refresh_timeout(): undefined | Timeout
  • Returns undefined | Timeout

  • set refresh_timeout(timeout): void
  • Parameters

    • timeout: Timeout

    Returns void

  • get refresh_token(): undefined | string
  • Valid for an unknown amount of time, allows you to get a new token without going through the Authorization Code Grant again! Use API.refreshToken to do that

    Returns undefined | string

  • set refresh_token(token): void
  • Parameters

    • token: undefined | string

    Returns void

  • get retry(): {
        delay: number;
        disabled: boolean;
        maximum_amount: number;
        on_automatic_refresh: boolean;
        on_status_codes: number[];
        on_timeout: boolean;
    }
  • Configure how this instance should behave when it comes to automatically retrying a request

    Returns {
        delay: number;
        disabled: boolean;
        maximum_amount: number;
        on_automatic_refresh: boolean;
        on_status_codes: number[];
        on_timeout: boolean;
    }

    • delay: number

      In seconds, how long should it wait until retrying? (defaults to 2)

    • disabled: boolean

      If true, doesn't retry under any circumstances (defaults to false)

    • maximum_amount: number

      How many retries maximum before throwing an APIError (defaults to 5)

    • on_automatic_refresh: boolean

      Should it retry a request upon successfully refreshing the token due to API.refresh_on_401 being true? (defaults to true)

    • on_status_codes: number[]

      Upon failing a request and receiving a response, because of which received status code should the request be retried? (defaults to [429])

    • on_timeout: boolean

      Should it retry a request if that request failed because it has been aborted by the API.timeout? (defaults to false)

  • set retry(retry): void
  • Parameters

    • retry: {
          delay: number;
          disabled: boolean;
          maximum_amount: number;
          on_automatic_refresh: boolean;
          on_status_codes: number[];
          on_timeout: boolean;
      }
      • delay: number

        In seconds, how long should it wait until retrying? (defaults to 2)

      • disabled: boolean

        If true, doesn't retry under any circumstances (defaults to false)

      • maximum_amount: number

        How many retries maximum before throwing an APIError (defaults to 5)

      • on_automatic_refresh: boolean

        Should it retry a request upon successfully refreshing the token due to API.refresh_on_401 being true? (defaults to true)

      • on_status_codes: number[]

        Upon failing a request and receiving a response, because of which received status code should the request be retried? (defaults to [429])

      • on_timeout: boolean

        Should it retry a request if that request failed because it has been aborted by the API.timeout? (defaults to false)

    Returns void

  • get routes(): {
        normal: string;
        token_obtention: string;
    }
  • What follows the API.server and preceeds the individual endpoints used by each request

    Returns {
        normal: string;
        token_obtention: string;
    }

  • set routes(routes): void
  • Parameters

    • routes: {
          normal: string;
          token_obtention: string;
      }

    Returns void

  • get scopes(): undefined | Scope[]
  • The Scopes your application has, assuming it acts as a user

    Returns undefined | Scope[]

  • set scopes(scopes): void
  • Parameters

    • scopes: undefined | Scope[]

    Returns void

  • get server(): string
  • The base url of the server where the requests should land (defaults to https://osu.ppy.sh)

    Returns string

  • set server(server): void
  • Parameters

    • server: string

    Returns void

  • get timeout(): number
  • The maximum amount of seconds requests should take before returning an answer (defaults to 20)

    Returns number

    0 means no maximum, no timeout

  • set timeout(timeout): void
  • Parameters

    • timeout: number

    Returns void

  • get token_type(): string
  • Should always be "Bearer"

    Returns string

  • set token_type(token): void
  • Parameters

    • token: string

    Returns void

  • get user(): undefined | number
  • The osu! user id of the user who went through the Authorization Code Grant

    Returns undefined | number

  • set user(user): void
  • Parameters

    • user: undefined | number

    Returns void

  • get verbose():
        | undefined
        | "all"
        | "none"
        | "errors"
  • Which events should be logged (defaults to none)

    Returns
        | undefined
        | "all"
        | "none"
        | "errors"

  • set verbose(verbose): void
  • Parameters

    • verbose:
          | undefined
          | "all"
          | "none"
          | "errors"

    Returns void

Methods

  • Get a websocket to get WebSocket events from!

    Parameters

    • server: string = ...

      Where the "notification websocket/server" is (defaults to the API.server's protocol and a maximum of 1 subdomain being replaced by "wss://notify." (so usually wss://notify.ppy.sh))

    Returns WebSocket

  • Returns Promise<boolean>

    Whether or not the token has been refreshed

  • The function that directly communicates with the API! Almost every functions of the API object uses this function!

    Parameters

    • method:
          | "get"
          | "post"
          | "put"
          | "delete"

      The type of request, each endpoint uses a specific one (if it uses multiple, the intent and parameters become different)

    • endpoint: string

      What comes in the URL after api/

    • parameters: {
          [k: string]: any;
      } = {}

      The things to specify in the request, such as the beatmap_id when looking for a beatmap

      • [k: string]: any
    • Optionalsettings: Omit<RequestInit, "body">

      Additional settings to add to the current settings of the fetch() request

    • info: {
          just_refreshed: boolean;
          number_try: number;
      } = ...

      Context given by a prior request

      • just_refreshed: boolean
      • number_try: number

    Returns Promise<any>

    A Promise with the API's response

  • Revoke your current token! Revokes the refresh token as well

    Returns Promise<true>

  • You can use this to specify additional settings for the method you're going to call, such as headers, an AbortSignal, and more advanced things!

    Parameters

    Returns ChildAPI

    A special version of the API that changes how requests are done

    const controller = new AbortController() // this controller can be used to abort any request that uses its signal!
    const user = await api.withSettings({signal: controller.signal}).getUser(7276846)
  • The normal way to create an API instance! Make sure to await it

    Parameters

    • client: {
          id: number;
          secret: string;
      }

      The ID and the secret of your client, can be found on https://osu.ppy.sh/home/account/edit#new-oauth-application

      • id: number
      • secret: string
    • Optionaluser: {
          code: string;
          redirect_uri: string;
      }

      If the instance is supposed to represent a user, use their Authorization Code and the Application Callback URL of your application!

      • code: string

        The code that appeared as a GET argument when they got redirected to the Application Callback URL (redirect_uri)

      • redirect_uri: string

        The Application Callback URL; Where the User has been redirected to after saying "okay" to your application doing stuff

    • Optionalverbose: "all" | "none" | "errors"
    • Optionalserver: string
    • Optionaltimeout: number

      In seconds

    Returns Promise<API>

    A promise with an API instance

Beatmap Functions

getBeatmap: ((this: API, beatmap: number | Beatmap) => Promise<WithFailtimesBeatmapset>) = Beatmap.getOne

Get extensive beatmap data about whichever beatmap you want!

Type declaration

getBeatmapDifficultyAttributes: ((this: API, beatmap: number | Beatmap, mods?: number | string[] | Mod[], ruleset?: Ruleset) => Promise<Beatmap.DifficultyAttributes.Any>) = Beatmap.DifficultyAttributes.get

Get various data about the difficulty of a beatmap!

Type declaration

    • (this, beatmap, mods?, ruleset?): Promise<Beatmap.DifficultyAttributes.Any>
    • Get various data about the difficulty of a beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap in question

      • Optionalmods: number | string[] | Mod[]

        Can be a bitset of mods, an array of mod acronyms, or an array of Mods (ignores mod settings) (defaults to No Mod)

      • Optionalruleset: Ruleset

        Useful to specify if the beatmap is a convert (defaults to the ruleset the beatmap was intended for)

      Returns Promise<Beatmap.DifficultyAttributes.Any>

      You may want to use api.getBeatmapDifficultyAttributesOsu (or Taiko or whatever) instead for better type safety

You may want to use api.getBeatmapDifficultyAttributesOsu (or Taiko or whatever) instead for better type safety

getBeatmapDifficultyAttributesFruits: ((this: API, beatmap: number | Beatmap, mods?: number | string[] | Mod[]) => Promise<Fruits>) = Beatmap.DifficultyAttributes.getFruits

Get various data about the difficulty of a ctb beatmap!

Type declaration

    • (this, beatmap, mods?): Promise<Fruits>
    • Get various data about the difficulty of a ctb beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap in question

      • Optionalmods: number | string[] | Mod[]

        Can be a bitset of mods, an array of mod acronyms, or an array of Mods (ignores mod settings) (defaults to No Mod)

      Returns Promise<Fruits>

getBeatmapDifficultyAttributesMania: ((this: API, beatmap: number | Beatmap, mods?: number | string[] | Mod[]) => Promise<Mania>) = Beatmap.DifficultyAttributes.getMania

Get various data about the difficulty of a mania beatmap!

Type declaration

    • (this, beatmap, mods?): Promise<Mania>
    • Get various data about the difficulty of a mania beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap in question

      • Optionalmods: number | string[] | Mod[]

        Can be a bitset of mods, an array of mod acronyms, or an array of Mods (ignores mod settings) (defaults to No Mod)

      Returns Promise<Mania>

getBeatmapDifficultyAttributesOsu: ((this: API, beatmap: number | Beatmap, mods?: number | string[] | Mod[]) => Promise<Osu>) = Beatmap.DifficultyAttributes.getOsu

Get various data about the difficulty of an osu! beatmap!

Type declaration

    • (this, beatmap, mods?): Promise<Osu>
    • Get various data about the difficulty of an osu! beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap in question

      • Optionalmods: number | string[] | Mod[]

        Can be a bitset of mods, an array of mod acronyms, or an array of Mods (ignores mod settings) (defaults to No Mod)

      Returns Promise<Osu>

getBeatmapDifficultyAttributesTaiko: ((this: API, beatmap: number | Beatmap, mods?: number | string[] | Mod[]) => Promise<Taiko>) = Beatmap.DifficultyAttributes.getTaiko

Get various data about the difficulty of a taiko beatmap!

Type declaration

    • (this, beatmap, mods?): Promise<Taiko>
    • Get various data about the difficulty of a taiko beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap in question

      • Optionalmods: number | string[] | Mod[]

        Can be a bitset of mods, an array of mod acronyms, or an array of Mods (ignores mod settings) (defaults to No Mod)

      Returns Promise<Taiko>

getBeatmapPack: ((this: API, pack: string | Pack, legacy_only?: boolean) => Promise<Pack>) = Beatmap.Pack.getOne

Get data about a Beatmap.Pack using its tag!

Type declaration

    • (this, pack, legacy_only?): Promise<Pack>
    • Get data about a Beatmap.Pack using its tag!

      Parameters

      • this: API
      • pack: string | Pack

        The Pack or the pack tag of the Pack you're trying to get

      • legacy_only: boolean = false

        Should lazer scores be excluded from the pack's user_completion_data? (defaults to false)

      Returns Promise<Pack>

      Currently in https://osu.ppy.sh/beatmaps/packs, when hovering a pack, its URL with its tag should be preview by your browser

Currently in https://osu.ppy.sh/beatmaps/packs, when hovering a pack, its URL with its tag should be preview by your browser

getBeatmapPacks: ((this: API, type?:
    | "standard"
    | "artist"
    | "loved"
    | "featured"
    | "tournament"
    | "chart"
    | "theme", cursor_string?: string) => Promise<{
    beatmap_packs: Pack[];
    cursor_string: string | null;
}>) = Beatmap.Pack.getMultiple

Get an Array of up to 100 Beatmap.Packs of a specific type!

Type declaration

    • (this, type?, cursor_string?): Promise<{
          beatmap_packs: Pack[];
          cursor_string: string | null;
      }>
    • Get an Array of up to 100 Beatmap.Packs of a specific type!

      Parameters

      • this: API
      • type:
            | "standard"
            | "artist"
            | "loved"
            | "featured"
            | "tournament"
            | "chart"
            | "theme" = "standard"

        The type of the BeatmapPacks (defaults to standard)

      • Optionalcursor_string: string

        Use a response's cursor_string with the same parameters to get the next "page" of results!

      Returns Promise<{
          beatmap_packs: Pack[];
          cursor_string: string | null;
      }>

getBeatmapScores: ((this: API, beatmap: number | Beatmap, config?: Beatmap.Config) => Promise<Score.WithUser[]>) = Beatmap.getScores

Get the top scores of a beatmap!

Type declaration

Please check if mods and type seem to be supported or not by the API: https://osu.ppy.sh/docs/index.html#get-beatmap-scores

getBeatmapSoloScores: ((this: API, beatmap: number | Beatmap, config?: Beatmap.Config) => Promise<Solo[]>) = Beatmap.getSoloScores

Get the top scores of a beatmap, in the "solo score" format lazer brought with it! More info on GitHub if needed https://github.com/ppy/osu-infrastructure/blob/master/score-submission.md

Type declaration

Please check if mods and type seem to be supported or not by the API: https://osu.ppy.sh/docs/index.html#get-beatmap-scores-non-legacy

getBeatmapUserScore: ((this: API, beatmap: number | Beatmap, user: number | User, config?: Beatmap.Config) => Promise<UserScore>) = Beatmap.UserScore.getOne

Get the score on a beatmap made by a specific user (with specific mods and on a specific ruleset if needed)

Type declaration

    • (this, beatmap, user, config?): Promise<UserScore>
    • Get the score on a beatmap made by a specific user (with specific mods and on a specific ruleset if needed)

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap the score was made on

      • user: number | User

        The User who made the score

      • Optionalconfig: Beatmap.Config

        Specify the score's ruleset, the score's mods, prevent a lazer score from being returned (type should not be supported)

      Returns Promise<UserScore>

      An Object with the position of the score according to the specified Mods and Ruleset, and with the score itself

An Object with the position of the score according to the specified Mods and Ruleset, and with the score itself

getBeatmapUserScores: ((this: API, beatmap: number | Beatmap, user: number | User, config?: Beatmap.Config) => Promise<Legacy[]>) = Beatmap.UserScore.getMultiple

Get the scores on a beatmap made by a specific user (with the possibility to specify if the scores are on a convert)

Type declaration

    • (this, beatmap, user, config?): Promise<Legacy[]>
    • Get the scores on a beatmap made by a specific user (with the possibility to specify if the scores are on a convert)

      Parameters

      • this: API
      • beatmap: number | Beatmap

        The Beatmap the scores were made on

      • user: number | User

        The User who made the scores

      • Optionalconfig: Beatmap.Config

        Specify the score's ruleset, prevent a lazer score from being returned (mods and type should not be supported)

      Returns Promise<Legacy[]>

getBeatmaps: ((this: API, beatmaps: (number | Beatmap)[]) => Promise<WithFailtimesMaxcombo[]>) = Beatmap.getMultiple

Get extensive beatmap data for up to 50 beatmaps at once!

Type declaration

    • (this, beatmaps): Promise<WithFailtimesMaxcombo[]>
    • Get extensive beatmap data for up to 50 beatmaps at once!

      Parameters

      • this: API
      • beatmaps: (number | Beatmap)[]

        An array of beatmaps or of objects that have the id of the beatmaps you're trying to get

      Returns Promise<WithFailtimesMaxcombo[]>

lookupBeatmap: ((this: API, query: {
    checksum?: string;
    filename?: string;
    id?: number;
}) => Promise<WithFailtimesBeatmapset>) = Beatmap.lookup

Get extensive beatmap data about whichever beatmap you want!

Type declaration

    • (this, query): Promise<WithFailtimesBeatmapset>
    • Get extensive beatmap data about whichever beatmap you want!

      Parameters

      • this: API
      • query: {
            checksum?: string;
            filename?: string;
            id?: number;
        }

        What to specify in order to find the right beatmap

        • Optionalchecksum?: string
        • Optionalfilename?: string
        • Optionalid?: number

      Returns Promise<WithFailtimesBeatmapset>

Beatmapset Functions

getBeatmapset: ((this: API, beatmapset: number | Beatmapset) => Promise<Plus>) = Beatmapset.getOne

Get extensive beatmapset data about whichever beatmapset you want!

Type declaration

    • (this, beatmapset): Promise<Plus>
    • Get extensive beatmapset data about whichever beatmapset you want!

      Parameters

      • this: API
      • beatmapset: number | Beatmapset

        The beatmapset or the id of the beatmapset you're trying to get

      Returns Promise<Plus>

getBeatmapsetDiscussionPosts: ((this: API, from?: {
    discussion?: number | Discussion;
    user?: number | User;
}, types?: ("first" | "reply" | "system")[], config?: Beatmapset.Config) => Promise<{
    beatmapsets: WithHype[];
    cursor_string: string | null;
    posts: Beatmapset.Discussion.Post[];
    users: User[];
}>) = Beatmapset.Discussion.Post.getMultiple

Get complex data about the posts of a beatmapset's discussion or of a user!

Type declaration

    • (this, from?, types?, config?): Promise<{
          beatmapsets: WithHype[];
          cursor_string: string | null;
          posts: Beatmapset.Discussion.Post[];
          users: User[];
      }>
    • Get complex data about the posts of a beatmapset's discussion or of a user!

      Parameters

      • this: API
      • Optionalfrom: {
            discussion?: number | Discussion;
            user?: number | User;
        }

        From where/who are the posts coming from? A specific discussion, a specific user?

      • Optionaltypes: ("first" | "reply" | "system")[]

        What kind of posts?

      • Optionalconfig: Beatmapset.Config

        How many results maximum, how to sort them, which page of those, maybe a cursor_string...

      Returns Promise<{
          beatmapsets: WithHype[];
          cursor_string: string | null;
          posts: Beatmapset.Discussion.Post[];
          users: User[];
      }>

      Relevant posts and info about them

      (2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

(2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

Relevant posts and info about them

getBeatmapsetDiscussionVotes: ((this: API, from?: {
    discussion?: number | Discussion;
    vote_giver?: number | User;
    vote_receiver?: number | User;
}, score?: 1 | -1, config?: Beatmapset.Config) => Promise<{
    cursor_string: string | null;
    discussions: Discussion[];
    users: WithGroups[];
    votes: Vote[];
}>) = Beatmapset.Discussion.Vote.getMultiple

Get complex data about the votes of a beatmapset's discussions or/and received/given by a specific user!

Type declaration

    • (this, from?, score?, config?): Promise<{
          cursor_string: string | null;
          discussions: Discussion[];
          users: WithGroups[];
          votes: Vote[];
      }>
    • Get complex data about the votes of a beatmapset's discussions or/and received/given by a specific user!

      Parameters

      • this: API
      • Optionalfrom: {
            discussion?: number | Discussion;
            vote_giver?: number | User;
            vote_receiver?: number | User;
        }

        The discussion with the votes, the user who voted, the user who's gotten the votes...

        • Optionaldiscussion?: number | Discussion
        • Optionalvote_giver?: number | User
        • Optionalvote_receiver?: number | User
      • Optionalscore: 1 | -1

        An upvote (1) or a downvote (-1)

      • Optionalconfig: Beatmapset.Config

        How many results maximum, how to sort them, which page of those, maybe a cursor_string...

      Returns Promise<{
          cursor_string: string | null;
          discussions: Discussion[];
          users: WithGroups[];
          votes: Vote[];
      }>

      Relevant votes and info about them

      (2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

(2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

Relevant votes and info about them

getBeatmapsetDiscussions: ((this: API, from?: {
    beatmapset?: number | Beatmapset;
    status?:
        | "all"
        | "ranked"
        | "qualified"
        | "disqualified"
        | "never_qualified";
    user?: number | User;
}, filter?: {
    only_unresolved?: boolean;
    types?: (
        | "suggestion"
        | "problem"
        | "mapper_note"
        | "praise"
        | "hype"
        | "review")[];
}, config?: Beatmapset.Config) => Promise<{
    beatmaps: Beatmap.Extended[];
    beatmapsets: Beatmapset.Extended[];
    cursor_string: string | null;
    discussions: WithStartingpost[];
    included_discussions: WithStartingpost[];
    reviews_config: {
        max_blocks: number;
    };
    users: WithGroups[];
}>) = Beatmapset.Discussion.getMultiple

Get complex data about the discussion page of any beatmapet that you want!

Type declaration

    • (this, from?, filter?, config?): Promise<{
          beatmaps: Beatmap.Extended[];
          beatmapsets: Beatmapset.Extended[];
          cursor_string: string | null;
          discussions: WithStartingpost[];
          included_discussions: WithStartingpost[];
          reviews_config: {
              max_blocks: number;
          };
          users: WithGroups[];
      }>
    • Get complex data about the discussion page of any beatmapet that you want!

      Parameters

      • this: API
      • Optionalfrom: {
            beatmapset?: number | Beatmapset;
            status?:
                | "all"
                | "ranked"
                | "qualified"
                | "disqualified"
                | "never_qualified";
            user?: number | User;
        }

        From where/who are the discussions coming from? Maybe only qualified sets?

        • Optionalbeatmapset?: number | Beatmapset
        • Optionalstatus?:
              | "all"
              | "ranked"
              | "qualified"
              | "disqualified"
              | "never_qualified"
        • Optionaluser?: number | User
      • Optionalfilter: {
            only_unresolved?: boolean;
            types?: (
                | "suggestion"
                | "problem"
                | "mapper_note"
                | "praise"
                | "hype"
                | "review")[];
        }

        Should those discussions only be unresolved problems, for example?

        • Optionalonly_unresolved?: boolean
        • Optionaltypes?: (
              | "suggestion"
              | "problem"
              | "mapper_note"
              | "praise"
              | "hype"
              | "review")[]
      • Optionalconfig: Beatmapset.Config

        How many results maximum, how to sort them, which page of those, maybe a cursor_string...

      Returns Promise<{
          beatmaps: Beatmap.Extended[];
          beatmapsets: Beatmapset.Extended[];
          cursor_string: string | null;
          discussions: WithStartingpost[];
          included_discussions: WithStartingpost[];
          reviews_config: {
              max_blocks: number;
          };
          users: WithGroups[];
      }>

      Relevant discussions and info about them

      (2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

(2024-03-11) For months now, the API's documentation says the response is likely to change, so beware

Relevant discussions and info about them

getBeatmapsetEvents: ((this: API, from?: {
    beatmapset?: number | Beatmapset;
    max_date?: Date;
    min_date?: Date;
    user?: number | User;
}, types?: (
    | "nominate"
    | "love"
    | "remove_from_loved"
    | "qualify"
    | "disqualify"
    | "approve"
    | "rank"
    | "kudosu_allow"
    | "kudosu_deny"
    | "kudosu_gain"
    | "kudosu_lost"
    | "kudosu_recalculate"
    | "issue_resolve"
    | "issue_reopen"
    | "discussion_lock"
    | "discussion_unlock"
    | "discussion_delete"
    | "discussion_restore"
    | "discussion_post_delete"
    | "discussion_post_restore"
    | "nomination_reset"
    | "nomination_reset_received"
    | "genre_edit"
    | "language_edit"
    | "nsfw_toggle"
    | "offset_edit"
    | "tags_edit"
    | "beatmap_owner_change")[], config?: Beatmapset.Config) => Promise<{
    events: Beatmapset.Event.Any[];
    users: WithGroups[];
}>) = Beatmapset.Event.getMultiple

Get complex data about the events of a beatmapset and the users involved with them!

Type declaration

    • (this, from?, types?, config?): Promise<{
          events: Beatmapset.Event.Any[];
          users: WithGroups[];
      }>
    • Get complex data about the events of a beatmapset and the users involved with them!

      Parameters

      • this: API
      • Optionalfrom: {
            beatmapset?: number | Beatmapset;
            max_date?: Date;
            min_date?: Date;
            user?: number | User;
        }

        Which beatmapset, or caused by which user? When?

        • Optionalbeatmapset?: number | Beatmapset
        • Optionalmax_date?: Date
        • Optionalmin_date?: Date
        • Optionaluser?: number | User
      • Optionaltypes: (
            | "nominate"
            | "love"
            | "remove_from_loved"
            | "qualify"
            | "disqualify"
            | "approve"
            | "rank"
            | "kudosu_allow"
            | "kudosu_deny"
            | "kudosu_gain"
            | "kudosu_lost"
            | "kudosu_recalculate"
            | "issue_resolve"
            | "issue_reopen"
            | "discussion_lock"
            | "discussion_unlock"
            | "discussion_delete"
            | "discussion_restore"
            | "discussion_post_delete"
            | "discussion_post_restore"
            | "nomination_reset"
            | "nomination_reset_received"
            | "genre_edit"
            | "language_edit"
            | "nsfw_toggle"
            | "offset_edit"
            | "tags_edit"
            | "beatmap_owner_change")[]

        What kinds of events?

      • Optionalconfig: Beatmapset.Config

        How many results maximum, how to sort them, which page of those, maybe a cursor_string...

      Returns Promise<{
          events: Beatmapset.Event.Any[];
          users: WithGroups[];
      }>

      Relevant events and users

      (2024-03-11) For months now, the API's documentation says the response is likely to change, so beware, and also there's no documentation for this route in the API, so this is only the result of my interpretation of the website's code lol

(2024-03-11) For months now, the API's documentation says the response is likely to change, so beware, and also there's no documentation for this route in the API, so this is only the result of my interpretation of the website's code lol

Relevant events and users

lookupBeatmapset: ((this: API, beatmap: number | Beatmap) => Promise<Plus>) = Beatmapset.lookup

Get extensive data about a beatmapset by using a beatmap!

Type declaration

    • (this, beatmap): Promise<Plus>
    • Get extensive data about a beatmapset by using a beatmap!

      Parameters

      • this: API
      • beatmap: number | Beatmap

        A beatmap from the beatmapset you're looking for

      Returns Promise<Plus>

searchBeatmapsets: ((this: API, query?: {
    categories?:
        | "Any"
        | "Ranked"
        | "Qualified"
        | "Loved"
        | "Favourites"
        | "Pending"
        | "WIP"
        | "Graveyard"
        | "My Maps";
    cursor_string?: string;
    extra?: ("must_have_video" | "must_have_storyboard")[];
    general?: (
        | "Recommended difficulty"
        | "Include converted beatmaps"
        | "Subscribed mappers"
        | "Spotlighted beatmaps"
        | "Featured Artists")[];
    genre?:
        | Unspecified
        | any[any]
        | Anime
        | Rock
        | Pop
        | Other
        | Novelty
        | any[any]
        | Electronic
        | Metal
        | Classical
        | Folk
        | Jazz;
    hide_explicit_content?: true;
    keywords?: string;
    language?:
        | Unspecified
        | English
        | Japanese
        | Chinese
        | Instrumental
        | Korean
        | French
        | German
        | Swedish
        | Spanish
        | Italian
        | Russian
        | Polish
        | Other;
    mode?: Ruleset;
    played?: "Played" | "Unplayed";
    rank_achieved?: (
        | "A"
        | "Silver SS"
        | "SS"
        | "Silver S"
        | "S"
        | "B"
        | "C"
        | "D")[];
    sort?: {
        by:
            | "title"
            | "artist"
            | "ranked"
            | "difficulty"
            | "rating"
            | "plays"
            | "favourites"
            | "updated";
        in: "desc" | "asc";
    };
}) => Promise<{
    beatmapsets: WithBeatmapPacktags[];
    cursor_string: string | null;
    error: any | null;
    recommended_difficulty: number | null;
    total: number;
}>) = Beatmapset.search

Search for beatmapsets as if you were on the website or on lazer!

Type declaration

    • (this, query?): Promise<{
          beatmapsets: WithBeatmapPacktags[];
          cursor_string: string | null;
          error: any | null;
          recommended_difficulty: number | null;
          total: number;
      }>
    • Search for beatmapsets as if you were on the website or on lazer!

      Parameters

      • this: API
      • Optionalquery: {
            categories?:
                | "Any"
                | "Ranked"
                | "Qualified"
                | "Loved"
                | "Favourites"
                | "Pending"
                | "WIP"
                | "Graveyard"
                | "My Maps";
            cursor_string?: string;
            extra?: ("must_have_video" | "must_have_storyboard")[];
            general?: (
                | "Recommended difficulty"
                | "Include converted beatmaps"
                | "Subscribed mappers"
                | "Spotlighted beatmaps"
                | "Featured Artists")[];
            genre?:
                | Unspecified
                | any[any]
                | Anime
                | Rock
                | Pop
                | Other
                | Novelty
                | any[any]
                | Electronic
                | Metal
                | Classical
                | Folk
                | Jazz;
            hide_explicit_content?: true;
            keywords?: string;
            language?:
                | Unspecified
                | English
                | Japanese
                | Chinese
                | Instrumental
                | Korean
                | French
                | German
                | Swedish
                | Spanish
                | Italian
                | Russian
                | Polish
                | Other;
            mode?: Ruleset;
            played?: "Played" | "Unplayed";
            rank_achieved?: (
                | "A"
                | "Silver SS"
                | "SS"
                | "Silver S"
                | "S"
                | "B"
                | "C"
                | "D")[];
            sort?: {
                by:
                    | "title"
                    | "artist"
                    | "ranked"
                    | "difficulty"
                    | "rating"
                    | "plays"
                    | "favourites"
                    | "updated";
                in: "desc" | "asc";
            };
        }

        All the filters and sorting options that you'd normally find on the website or on lazer

        • Optionalcategories?:
              | "Any"
              | "Ranked"
              | "Qualified"
              | "Loved"
              | "Favourites"
              | "Pending"
              | "WIP"
              | "Graveyard"
              | "My Maps"

          Filter in sets depending on their status or on their relation with the authorized user (defaults to all that have a leaderboard)

        • Optionalcursor_string?: string

          The thing you've got from a previous request to get another page of results!

        • Optionalextra?: ("must_have_video" | "must_have_storyboard")[]

          Should all sets have a video, a storyboard, maybe both at once?

        • Optionalgeneral?: (
              | "Recommended difficulty"
              | "Include converted beatmaps"
              | "Subscribed mappers"
              | "Spotlighted beatmaps"
              | "Featured Artists")[]

          Various filters to activate

        • Optionalgenre?:
              | Unspecified
              | any[any]
              | Anime
              | Rock
              | Pop
              | Other
              | Novelty
              | any[any]
              | Electronic
              | Metal
              | Classical
              | Folk
              | Jazz

          Specify the musical genre of the music of the beatmapsets you're searching for (don't specify to get any genre)

          "Any"/0 actually looks up sets that specifically have the Genre "Any" such as 5947, it's excluded because it's counter-intuitive and near useless (but you can do something like 1-1 if you actually want that!)

        • Optionalhide_explicit_content?: true

          Use this to hide all sets that are marked as explicit

        • Optionalkeywords?: string

          What you'd put in the searchbar, like the name of a beatmapset or a mapper!

        • Optionallanguage?:
              | Unspecified
              | English
              | Japanese
              | Chinese
              | Instrumental
              | Korean
              | French
              | German
              | Swedish
              | Spanish
              | Italian
              | Russian
              | Polish
              | Other

          Specify the spoken language of the music of the beatmapsets you're searching for (don't specify to get any language)

          "Any"/0 actually looks up sets that specifically have the Language "Any" (and no set has that), it's excluded because it's counter-intuitive and near useless (but you can do something like 1-1 if you actually want that!)

        • Optionalmode?: Ruleset

          Only get sets that have maps that you can play in the ruleset of your choice

        • Optionalplayed?: "Played" | "Unplayed"

          Does the authorized user with osu!supporter have already played those sets, or have they not played them yet?

        • Optionalrank_achieved?: (
              | "A"
              | "Silver SS"
              | "SS"
              | "Silver S"
              | "S"
              | "B"
              | "C"
              | "D")[]

          Does the authorized user with osu!supporter have already achieved certain ranks on those sets?

        • Optionalsort?: {
              by:
                  | "title"
                  | "artist"
                  | "ranked"
                  | "difficulty"
                  | "rating"
                  | "plays"
                  | "favourites"
                  | "updated";
              in: "desc" | "asc";
          }

          Sort by what, in ascending/descending order

          • by:
                | "title"
                | "artist"
                | "ranked"
                | "difficulty"
                | "rating"
                | "plays"
                | "favourites"
                | "updated"
          • in: "desc" | "asc"

      Returns Promise<{
          beatmapsets: WithBeatmapPacktags[];
          cursor_string: string | null;
          error: any | null;
          recommended_difficulty: number | null;
          total: number;
      }>

      Relevant Beatmapsets that contain Beatmaps, and a cursor_string to allow you to look for more of the same!

      This does not bypass the current osu!supporter requirement for certain filters

This does not bypass the current osu!supporter requirement for certain filters

Relevant Beatmapsets that contain Beatmaps, and a cursor_string to allow you to look for more of the same!

Changelog Functions

getChangelogBuild: ((this: API, stream: string, build: string) => Promise<WithChangelogentriesVersions>) = Changelog.Build.getOne

Get details about the version/update/build of something related to osu!

Type declaration

    • (this, stream, build): Promise<WithChangelogentriesVersions>
    • Get details about the version/update/build of something related to osu!

      Parameters

      • this: API
      • stream: string

        The name of the thing related to osu!, like lazer, web, cuttingedge, beta40, stable40

      • build: string

        The name of the version! Usually something like 2023.1026.0 for lazer, or 20230326 for stable

      Returns Promise<WithChangelogentriesVersions>

getChangelogBuilds: ((this: API, stream?: string, range?: {
    from?: string;
    to?: string | number;
}, message_formats?: ("html" | "markdown")[]) => Promise<WithUpdatestreamsChangelogentries[]>) = Changelog.Build.getMultiple

Get up to 21 versions/updates/builds!

Type declaration

    • (this, stream?, range?, message_formats?): Promise<WithUpdatestreamsChangelogentries[]>
    • Get up to 21 versions/updates/builds!

      Parameters

      • this: API
      • Optionalstream: string

        Only get builds from a specific stream

      • Optionalrange: {
            from?: string;
            to?: string | number;
        }

        Get builds that were released before/after (and including) those builds

        • Optionalfrom?: string

          The name of the build

        • Optionalto?: string | number

          The name or the id of the build

      • message_formats: ("html" | "markdown")[] = ...

        changelog_entries will have a message property if markdown, message_html property if html (defaults to both)

      Returns Promise<WithUpdatestreamsChangelogentries[]>

getChangelogStreams: ((this: API) => Promise<WithLatestbuildUsercount[]>) = Changelog.UpdateStream.getAll

An effective way to get all available streams, as well as their latest version!

Type declaration

    • (this): Promise<WithLatestbuildUsercount[]>
    • An effective way to get all available streams, as well as their latest version!

      Parameters

      Returns Promise<WithLatestbuildUsercount[]>

      const names_of_streams = (await api.getChangelogStreams()).map(s => s.name)
      
lookupChangelogBuild: ((this: API, changelog: string | number, message_formats?: ("html" | "markdown")[]) => Promise<WithChangelogentriesVersions>) = Changelog.Build.lookup

Get details about the version/update/build of something related to osu!

Type declaration

    • (this, changelog, message_formats?): Promise<WithChangelogentriesVersions>
    • Get details about the version/update/build of something related to osu!

      Parameters

      • this: API
      • changelog: string | number

        A stream name like lazer, a build version like 2023.1026.0, or the id of a build

      • message_formats: ("html" | "markdown")[] = ...

        changelog_entries will have a message property if markdown, message_html property if html (defaults to both)

      Returns Promise<WithChangelogentriesVersions>

Chat Functions

createChatAnnouncementChannel: ((this: API, channel: {
    description: string;
    name: string;
}, user_targets: (number | User)[], message: string) => Promise<Channel>) = Chat.Channel.createAnnouncement

Create a new announcement!

Type declaration

    • (this, channel, user_targets, message): Promise<Channel>
    • Create a new announcement!

      Parameters

      • this: API
      • channel: {
            description: string;
            name: string;
        }

        Details of the channel you're creating

        • description: string
        • name: string
      • user_targets: (number | User)[]

        The people that will receive your message

      • message: string

        The message to send with the announcement

      Returns Promise<Channel>

      The newly created channel!

      "chat.write_manage"

      From my understanding, this WILL 403 unless the user is kinda special

From my understanding, this WILL 403 unless the user is kinda special

The newly created channel!

createChatPrivateChannel: ((this: API, user_target: number | User) => Promise<Channel>) = Chat.Channel.createPrivate

Create/Open/Join a private messages chat channel!

Type declaration

    • (this, user_target): Promise<Channel>
    • Create/Open/Join a private messages chat channel!

      Parameters

      • this: API
      • user_target: number | User

        The other user able to read and send messages in this channel

      Returns Promise<Channel>

      The newly created channel!

The newly created channel!

getChatChannel: ((this: API, channel: number | Channel) => Promise<WithDetails>) = Chat.Channel.getOne

Get a ChatChannel that you have joined, and the users in it if it is a private channel!

Type declaration

    • (this, channel): Promise<WithDetails>
    • Get a ChatChannel that you have joined, and the users in it if it is a private channel!

      Parameters

      • this: API
      • channel: number | Channel

        The channel in question

      Returns Promise<WithDetails>

      "chat.read"

      Will 404 if the user has not joined the channel (use joinChatChannel for that)

Will 404 if the user has not joined the channel (use joinChatChannel for that)

getChatChannels: ((this: API) => Promise<Channel[]>) = Chat.Channel.getAll

Get a list of all publicly joinable channels!

Type declaration

getChatMessages: ((this: API, channel: number | Channel, limit?: number, since?: number | Message, until?: number | Message) => Promise<Message[]>) = Chat.Message.getMultiple

Get the recent messages of a specific ChatChannel!

Type declaration

    • (this, channel, limit?, since?, until?): Promise<Message[]>
    • Get the recent messages of a specific ChatChannel!

      Parameters

      • this: API
      • channel: number | Channel

        The Channel you wanna get the messages from

      • limit: number = 20

        The maximum amount of messages you want to get, up to 50! (defaults to 20)

      • Optionalsince: number | Message

        Get the messages sent after this message

      • Optionaluntil: number | Message

        Get the messages sent up to but not including this message

      Returns Promise<Message[]>

joinChatChannel: ((this: API, channel: number | Channel, user?: number | User) => Promise<WithDetails>) = Chat.Channel.joinOne

Join a public or multiplayer ChatChannel, allowing you to interact with it!

Type declaration

    • (this, channel, user?): Promise<WithDetails>
    • Join a public or multiplayer ChatChannel, allowing you to interact with it!

      Parameters

      • this: API
      • channel: number | Channel

        The channel you wanna join

      • Optionaluser: number | User

        The user joining the channel (defaults to the presumed authorized user (api.user))

      Returns Promise<WithDetails>

keepChatAlive: ((this: API, since?: {
    message?: number | Message;
    user_silence?: number | UserSilence;
}) => Promise<UserSilence[]>) = Chat.keepAlive

Needs to be done periodically to reset chat activity timeout

Type declaration

    • (this, since?): Promise<UserSilence[]>
    • Needs to be done periodically to reset chat activity timeout

      Parameters

      • this: API
      • Optionalsince: {
            message?: number | Message;
            user_silence?: number | UserSilence;
        }

        UserSilences that are before that will not be returned!

      Returns Promise<UserSilence[]>

      A list of recent silences

      "chat.read"

      Every 30 seconds is a good idea

Every 30 seconds is a good idea

A list of recent silences

leaveChatChannel: ((this: API, channel: number | Channel, user?: number | User) => Promise<void>) = Chat.Channel.leaveOne

Leave/Close a public ChatChannel!

Type declaration

    • (this, channel, user?): Promise<void>
    • Leave/Close a public ChatChannel!

      Parameters

      • this: API
      • channel: number | Channel

        The channel you wanna leave/close

      • Optionaluser: number | User

        The user leaving/closing the channel (defaults to the presumed authorized user (api.user))

      Returns Promise<void>

markChatChannelAsRead: ((this: API, channel: number | Channel, message: number | Message) => Promise<void>) = Chat.Channel.markAsRead

Mark a certain channel as read up to a given message!

Type declaration

    • (this, channel, message): Promise<void>
    • Mark a certain channel as read up to a given message!

      Parameters

      • this: API
      • channel: number | Channel

        The channel in question

      • message: number | Message

        You're marking this and all the messages before it as read!

      Returns Promise<void>

sendChatMessage: ((this: API, channel: number | Channel, message: string, is_action?: boolean) => Promise<Message>) = Chat.Message.send

Send a message in a ChatChannel!

Type declaration

    • (this, channel, message, is_action?): Promise<Message>
    • Send a message in a ChatChannel!

      Parameters

      • this: API
      • channel: number | Channel

        The channel in which you want to send your message

      • message: string

        The message you wanna send

      • is_action: boolean = false

        Is it a command? Like /me dances (defaults to false)

      Returns Promise<Message>

      The newly sent ChatMessage!

The newly sent ChatMessage!

sendChatPrivateMessage: ((this: API, user_target: number | User, message: string, is_action?: boolean, uuid?: string) => Promise<{
    channel: Channel;
    message: Message;
}>) = Chat.Message.sendPrivate

Send a private message to someone!

Type declaration

    • (this, user_target, message, is_action?, uuid?): Promise<{
          channel: Channel;
          message: Message;
      }>
    • Send a private message to someone!

      Parameters

      • this: API
      • user_target: number | User

        The User you wanna send your message to!

      • message: string

        The message you wanna send

      • is_action: boolean = false

        Is it a command? Like /me dances (defaults to false)

      • Optionaluuid: string

        A client-side message identifier

      Returns Promise<{
          channel: Channel;
          message: Message;
      }>

      The message you sent

      "chat.write"

      You don't need to use createChatPrivateChannel before sending a message

You don't need to use createChatPrivateChannel before sending a message

The message you sent

Comment Functions

getComment: ((this: API, comment: number | Comment) => Promise<Bundle>) = Comment.getOne

Get a specific comment by using its id!

Type declaration

    • (this, comment): Promise<Bundle>
    • Get a specific comment by using its id!

      Parameters

      • this: API
      • comment: number | Comment

        The comment in question

      Returns Promise<Bundle>

getComments: ((this: API, from?: {
    id: number;
    type: "beatmapset" | "build" | "news_post";
}, parent?: number | Comment, sort?: {
    after?: number | Comment;
    cursor?: null | {
        created_at: Date;
        id: number;
    };
    type?: "new" | "top" | "old";
}) => Promise<WithTotalToplevelcount>) = Comment.getMultiple

Get comments that meet any of your requirements!

Type declaration

    • (this, from?, parent?, sort?): Promise<WithTotalToplevelcount>
    • Get comments that meet any of your requirements!

      Parameters

      • this: API
      • Optionalfrom: {
            id: number;
            type: "beatmapset" | "build" | "news_post";
        }

        From where are the comments coming from? Maybe a beatmapset, but then, which beatmapset?

        • id: number
        • type: "beatmapset" | "build" | "news_post"
      • Optionalparent: number | Comment

        The comments are replying to which comment? Make the id 0 to filter out replies (and only get top level comments)

      • Optionalsort: {
            after?: number | Comment;
            cursor?: null | {
                created_at: Date;
                id: number;
            };
            type?: "new" | "top" | "old";
        }

        Should the comments be sorted by votes? Should they be from after a certain date? Maybe you can give a cursor?

        • Optionalafter?: number | Comment
        • Optionalcursor?: null | {
              created_at: Date;
              id: number;
          }
        • Optionaltype?: "new" | "top" | "old"

      Returns Promise<WithTotalToplevelcount>

Event Functions

getEvents: ((this: API, sort?: "id_desc" | "id_asc", cursor_string?: string) => Promise<{
    cursor_string: string | null;
    events: Event.Any[];
}>) = Event.getMultiple

Get everything note-worthy that happened on osu! recently!

Type declaration

    • (this, sort?, cursor_string?): Promise<{
          cursor_string: string | null;
          events: Event.Any[];
      }>
    • Get everything note-worthy that happened on osu! recently!

      Parameters

      • this: API
      • sort: "id_desc" | "id_asc" = "id_desc"

        "id_asc" to have the oldest recent event first, "id_desc" to have the newest instead (defaults to id_desc)

      • Optionalcursor_string: string

        Use a response's cursor_string with the same parameters to get the next "page" of results, so events in this instance!

      Returns Promise<{
          cursor_string: string | null;
          events: Event.Any[];
      }>

Forum Functions

createForumTopic: ((this: API, forum_id: number, title: string, text: string, poll?: {
    hide_results?: boolean;
    length_days: number;
    max_options?: number;
    options: string[];
    title: string;
    vote_change?: boolean;
}) => Promise<{
    post: Forum.Post;
    topic: Topic;
}>) = Forum.Topic.create

Create a new ForumTopic in the forum of your choice!

Type declaration

    • (this, forum_id, title, text, poll?): Promise<{
          post: Forum.Post;
          topic: Topic;
      }>
    • Create a new ForumTopic in the forum of your choice!

      Parameters

      • this: API
      • forum_id: number

        The id of the forum you're creating your topic in

      • title: string

        The topic's title

      • text: string

        The first post's content/message

      • Optionalpoll: {
            hide_results?: boolean;
            length_days: number;
            max_options?: number;
            options: string[];
            title: string;
            vote_change?: boolean;
        }

        If you want to make a poll, specify the parameters of that poll!

        • Optionalhide_results?: boolean

          Should the results of the poll be hidden while the voting period is still active? (defaults to false)

        • length_days: number

          Length of voting period in days, 0 means forever

        • Optionalmax_options?: number

          The maximum amount of votes per user! (defaults to 1)

        • options: string[]

          The things the users can vote for

        • title: string
        • Optionalvote_change?: boolean

          Do you allow users to change their vote? (defaults to false)

      Returns Promise<{
          post: Forum.Post;
          topic: Topic;
      }>

      An object with the topic you've made, and its first initial post (which uses your text)

      "forum.write"

      Some users may not be allowed to do that, such as newly registered users, so this can 403 even with the right scopes

Some users may not be allowed to do that, such as newly registered users, so this can 403 even with the right scopes

An object with the topic you've made, and its first initial post (which uses your text)

editForumPost: ((this: API, post: number | Forum.Post, new_text: string) => Promise<Forum.Post>) = Forum.Post.edit

Edit a ForumPost! Note that it can be the initial one of a ForumTopic!

Type declaration

    • (this, post, new_text): Promise<Forum.Post>
    • Edit a ForumPost! Note that it can be the initial one of a ForumTopic!

      Parameters

      • this: API
      • post: number | Forum.Post

        The post or the id of the post in question

      • new_text: string

        The new content of the post (replaces the old content)

      Returns Promise<Forum.Post>

      The edited ForumPost

The edited ForumPost

editForumTopicTitle: ((this: API, topic: number | Topic, new_title: string) => Promise<Topic>) = Forum.Topic.editTitle

Edit the title of a Forum.Topic!

Type declaration

    • (this, topic, new_title): Promise<Topic>
    • Edit the title of a Forum.Topic!

      Parameters

      • this: API
      • topic: number | Topic

        The topic or the id of the topic in question

      • new_title: string

        The new title of the topic

      Returns Promise<Topic>

      The edited ForumTopic

      "forum.write"

      Use editForumPost if you wanna edit the post at the top of the topic

Use editForumPost if you wanna edit the post at the top of the topic

The edited ForumTopic

getForumTopicAndPosts: ((this: API, topic: number | Topic, config?: {
    cursor_string?: string;
    first_post?: number | Forum.Post;
    limit?: number;
    sort?: "id_desc" | "id_asc";
}) => Promise<{
    cursor_string: string | null;
    posts: Forum.Post[];
    topic: Topic;
}>) = Forum.getTopicAndPosts

Get a forum topic, as well as its main post (content) and the posts that were sent in it!

Type declaration

    • (this, topic, config?): Promise<{
          cursor_string: string | null;
          posts: Forum.Post[];
          topic: Topic;
      }>
    • Get a forum topic, as well as its main post (content) and the posts that were sent in it!

      Parameters

      • this: API
      • topic: number | Topic

        An object with the id of the topic in question

      • Optionalconfig: {
            cursor_string?: string;
            first_post?: number | Forum.Post;
            limit?: number;
            sort?: "id_desc" | "id_asc";
        }

        How many results maximum, how to sort them, etc...

        • Optionalcursor_string?: string

          Use a response's cursor_string with the same parameters to get the next "page" of results, so posts in this instance!

        • Optionalfirst_post?: number | Forum.Post

          The id (or the post itself) of the first post to be returned in posts (irrelevant if using a cursor_string)

        • Optionallimit?: number

          How many posts maximum, up to 50

        • Optionalsort?: "id_desc" | "id_asc"

          "id_asc" to have the oldest post at the beginning of the posts array, "id_desc" to have the newest instead

      Returns Promise<{
          cursor_string: string | null;
          posts: Forum.Post[];
          topic: Topic;
      }>

      The oldest post of a topic is the text of a topic

The oldest post of a topic is the text of a topic

replyForumTopic: ((this: API, topic: number | Topic, text: string) => Promise<Forum.Post>) = Forum.Topic.reply

Make and send a Forum.Post in a Forum.Topic!

Type declaration

    • (this, topic, text): Promise<Forum.Post>
    • Make and send a Forum.Post in a Forum.Topic!

      Parameters

      • this: API
      • topic: number | Topic

        The topic or the id of the topic you're making your reply in

      • text: string

        Your reply! Your message!

      Returns Promise<Forum.Post>

      The reply you've made, as a Forum.Post!

      "forum.write"

      Replying when the last post was made by the authorized user will likely cause the server to return a 403

Replying when the last post was made by the authorized user will likely cause the server to return a 403

The reply you've made, as a Forum.Post!

Home Functions

searchUser: ((this: API, query: string, page?: number) => Promise<{
    data: User[];
    total: number;
}>) = Home.Search.getUsers

Look for a user like you would on the website!

Type declaration

    • (this, query, page?): Promise<{
          data: User[];
          total: number;
      }>
    • Look for a user like you would on the website!

      Parameters

      • this: API
      • query: string

        What you would put in the searchbar

      • page: number = 1

        You normally get the first 20 results, but if page is 2, you'd get results 21 to 40 instead for example! (defaults to 1)

      Returns Promise<{
          data: User[];
          total: number;
      }>

searchWiki: ((this: API, query: string, page?: number) => Promise<{
    data: WikiPage[];
    total: number;
}>) = Home.Search.getWikiPages

Look for a wiki page like you would on the website!

Type declaration

    • (this, query, page?): Promise<{
          data: WikiPage[];
          total: number;
      }>
    • Look for a wiki page like you would on the website!

      Parameters

      • this: API
      • query: string

        What you would put in the searchbar

      • page: number = 1

        You normally get the first 50 results, but if page is 2, you'd get results 51 to 100 instead for example! (defaults to 1)

      Returns Promise<{
          data: WikiPage[];
          total: number;
      }>

Multiplayer Functions

getMatch: ((this: API, match: number | Info, query?: {
    after?: number | Multiplayer.Match.Event;
    before?: number | Multiplayer.Match.Event;
    limit?: number;
}) => Promise<Match>) = Multiplayer.Match.getOne

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, match, query?): Promise<Match>
    • Get data of a multiplayer lobby from the stable (non-lazer) client that have URLs with community/matches or mp

      Parameters

      • this: API
      • match: number | Info

        The id of a match can be found at the end of its URL

      • Optionalquery: {
            after?: number | Multiplayer.Match.Event;
            before?: number | Multiplayer.Match.Event;
            limit?: number;
        }

        Filter and limit the amount of events shown

        • Optionalafter?: number | Multiplayer.Match.Event

          Filter FOR events AFTER this one

        • Optionalbefore?: number | Multiplayer.Match.Event

          Filter FOR events BEFORE this one

        • Optionallimit?: number

          From 1 to 101 events (defaults to 100)

          0 is treated as 1, anything above 101 is treated as 101

      Returns Promise<Match>

getMatches: ((this: API, query?: {
    first_match_in_array?: number | Info;
    limit?: number;
    sort?: "id_desc" | "id_asc";
}) => Promise<Info[]>) = Multiplayer.Match.getMultiple

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, query?): Promise<Info[]>
    • Get the info about several matches!

      Parameters

      • this: API
      • Optionalquery: {
            first_match_in_array?: number | Info;
            limit?: number;
            sort?: "id_desc" | "id_asc";
        }

        The id of the first match of the array, and the sorting and size of said array

        • Optionalfirst_match_in_array?: number | Info

          Which match should be featured at index 0 of the returned array? Will get one with a similar id if it is unavailable

          You can use this argument differently to get all matches before/after (depending of query.sort) a certain match, by adding +1/-1 to its id! So if you want all matches after match_id 10 with sorting is_desc, just have this argument be 10 + 1, or 11!

        • Optionallimit?: number

          The maximum amount of elements returned in the array (defaults to 50)

        • Optionalsort?: "id_desc" | "id_asc"

          "id_desc" has the biggest id (most recent start_time) at the beginning of the array, "id_asc" is the opposite (defaults to id_desc)

      Returns Promise<Info[]>

getPlaylistItemScores: ((this: API, item: PlaylistItem | {
    id: number;
    room_id: number;
}, limit?: number, sort?: "score_asc" | "score_desc", cursor_string?: string) => Promise<Scores>) = Multiplayer.Room.PlaylistItem.getScores

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, item, limit?, sort?, cursor_string?): Promise<Scores>
    • Get the scores on a specific item of a room!

      Parameters

      • this: API
      • item: PlaylistItem | {
            id: number;
            room_id: number;
        }

        An object with the id of the item in question, as well as the id of the room

      • limit: number = 50

        How many scores maximum? Defaults to 50, the maximum the API will return

      • sort: "score_asc" | "score_desc" = "score_desc"

        Sort by scores, ascending or descending? Defaults to descending

      • Optionalcursor_string: string

        Use a Multiplayer.Scores' params and cursor_string to get the next page (scores 51 to 100 for example)

      Returns Promise<Scores>

      (2024-03-04) This may not work for rooms from before March 5th 2024, use at your own risk https://github.com/ppy/osu-web/issues/10725

getRoom: ((this: API, room: number | Room) => Promise<Room>) = Multiplayer.Room.getOne

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, room): Promise<Room>
    • Get data about a lazer multiplayer room (realtime or playlists)!

      Parameters

      • this: API
      • room: number | Room

        The room or the id of the room, can be found at the end of its URL (after /multiplayer/rooms/)

      Returns Promise<Room>

getRoomLeaderboard: ((this: API, room: number | Room) => Promise<{
    leaderboard: Leader[];
    user_score: WithPosition | null;
}>) = Multiplayer.Room.Leader.getMultiple

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, room): Promise<{
          leaderboard: Leader[];
          user_score: WithPosition | null;
      }>
    • Get the room stats of all the users of that room!

      Parameters

      • this: API
      • room: number | Room

        The room or the id of the room in question

      Returns Promise<{
          leaderboard: Leader[];
          user_score: WithPosition | null;
      }>

      An object with the leaderboard, and the score and position of the authorized user under user_score

      "public"

getRooms: ((this: API, type: "realtime" | "playlists", mode:
    | "all"
    | "active"
    | "ended"
    | "participated"
    | "owned", limit?: number, sort?: "ended" | "created", season_id?: number) => Promise<Room[]>) = Multiplayer.Room.getMultiple

Get data about a lazer multiplayer room (realtime or playlists)!

Type declaration

    • (this, type, mode, limit?, sort?, season_id?): Promise<Room[]>
    • Get playlists/realtime rooms that are active, that have ended, that the user participated in, that the user made, or just simply any room!

      Parameters

      • this: API
      • type: "realtime" | "playlists"

        Whether the multiplayer rooms are in playlist format (like current spotlights) or realtime

      • mode:
            | "all"
            | "active"
            | "ended"
            | "participated"
            | "owned"

        The state of the room, or the relation of the authorized user with the room

      • limit: number = 10

        The maximum amount of rooms to return, defaults to 10

      • sort: "ended" | "created" = "created"

        Sort (where most recent is first) by creation date or end date, defaults to the creation date

      • Optionalseason_id: number

        Only get rooms (playlists) that belong to a specific (modern) Beatmap Spotlights season id (so 5'd be summer 2020's mania rooms, not winter 2022!!)

      Returns Promise<Room[]>

      "public"

NewsPost Functions

getNewsPost: ((this: API, post: string | number | NewsPost) => Promise<WithContentNavigation>) = NewsPost.getOne

Get a NewsPost, its content, and the NewsPosts right before and right after it!

Type declaration

getNewsPosts: ((this: API, year?: number) => Promise<NewsPost[]>) = NewsPost.getMultiple

Get all the NewsPosts of a specific year!

Type declaration

    • (this, year?): Promise<NewsPost[]>
    • Get all the NewsPosts of a specific year!

      Parameters

      • this: API
      • Optionalyear: number

        The year the posts were made (defaults to current year)

      Returns Promise<NewsPost[]>

      If the specified year is invalid/has no news, it fallbacks to the default year

If the specified year is invalid/has no news, it fallbacks to the default year

Other Functions

getReplay: ((this: API, score: number | Score) => Promise<string>) = Score.getReplay

Get the replay for a score!

Type declaration

    • (this, score): Promise<string>
    • Get the replay for a score!

      Parameters

      • this: API
      • score: number | Score

        The score that has created the replay

      Returns Promise<string>

      The correctly encoded content of what would be a replay file (you can just fs.writeFileSync with it!)

      "public"

The correctly encoded content of what would be a replay file (you can just fs.writeFileSync with it!)

getSpotlights: ((this: API) => Promise<Spotlight[]>) = Spotlight.getAll

Get ALL legacy spotlights! (2009-2020, somewhat known as charts/ranking charts, available @ https://osu.ppy.sh/rankings/osu/charts)

Type declaration

    • (this): Promise<Spotlight[]>
    • Get ALL legacy spotlights! (2009-2020, somewhat known as charts/ranking charts, available @ https://osu.ppy.sh/rankings/osu/charts)

      Parameters

      Returns Promise<Spotlight[]>

      The data for newer spotlights (2020-, somewhat known as seasons) can be obtained through getRoom() but you can't really get the id of those newer spotlights without going through the website's URLs (https://osu.ppy.sh/seasons/latest) as far as I know :(

The data for newer spotlights (2020-, somewhat known as seasons) can be obtained through getRoom() but you can't really get the id of those newer spotlights without going through the website's URLs (https://osu.ppy.sh/seasons/latest) as far as I know :(

  • Get the backgrounds made and selected for this season or for last season!

    Returns Promise<{
        backgrounds: {
            url: string;
            user: User;
        }[];
        ends_at: Date;
    }>

    When the season ended, and for each background, its URL and its artist

Ranking Functions

getCountryRanking: ((this: API, ruleset: Ruleset, page?: number) => Promise<Country>) = Ranking.getCountry

Get the top countries of a specific ruleset!

Type declaration

    • (this, ruleset, page?): Promise<Country>
    • Get the top countries of a specific ruleset!

      Parameters

      • this: API
      • ruleset: Ruleset

        On which Ruleset should the countries be compared?

      • page: number = 1

        Imagine the array you get as a page, it can only have a maximum of 50 countries, while 50 others may be on the next one (defaults to 1)

      Returns Promise<Country>

getKudosuRanking: ((this: API) => Promise<WithKudosu[]>) = Ranking.getKudosu

Get the top 50 players who have the most total kudosu!

Type declaration

    • (this): Promise<WithKudosu[]>
    • Get the top 50 players who have the most total kudosu!

      Parameters

      Returns Promise<WithKudosu[]>

getSpotlightRanking: ((this: API, ruleset: Ruleset, spotlight: number | Spotlight, filter?: "all" | "friends") => Promise<Ranking.Spotlight>) = Ranking.getSpotlight

Get the rankings of a spotlight from 2009 to 2020 on a specific ruleset!

Type declaration

    • (this, ruleset, spotlight, filter?): Promise<Ranking.Spotlight>
    • Get the rankings of a spotlight from 2009 to 2020 on a specific ruleset!

      Parameters

      • this: API
      • ruleset: Ruleset

        Each spotlight has a different ranking (and often maps) depending on the ruleset

      • spotlight: number | Spotlight

        The spotlight in question

      • filter: "all" | "friends" = "all"

        What kind of players do you want to see? Keep in mind friends has no effect if no authorized user (defaults to all)

      Returns Promise<Ranking.Spotlight>

getUserRanking: ((this: API, ruleset: Ruleset, type: "performance" | "score", config?: {
    country?: string;
    filter?: "all" | "friends";
    page?: number;
    variant?: "4k" | "7k";
}) => Promise<Ranking.User>) = Ranking.getUser

Get the top players of the game, with some filters!

Type declaration

    • (this, ruleset, type, config?): Promise<Ranking.User>
    • Get the top players of the game, with some filters!

      Parameters

      • this: API
      • ruleset: Ruleset

        Self-explanatory, is also known as "Gamemode"

      • type: "performance" | "score"

        Rank players by their performance points or by their ranked score?

      • Optionalconfig: {
            country?: string;
            filter?: "all" | "friends";
            page?: number;
            variant?: "4k" | "7k";
        }

        Specify which page, country, filter out non-friends...

        • Optionalcountry?: string

          Only get players from a specific country, using its ISO 3166-1 alpha-2 country code! (France would be FR, United States US)

        • Optionalfilter?: "all" | "friends"

          What kind of players do you want to see? Keep in mind friends has no effect if no authorized user

        • Optionalpage?: number

          Imagine the array you get as a page, it can only have a maximum of 50 players, while 50 others may be on the next one

        • Optionalvariant?: "4k" | "7k"

          If type is performance and ruleset is mania, choose between 4k and 7k!

      Returns Promise<Ranking.User>

User Functions

getFriends: ((this: API) => Promise<WithCountryCoverGroupsStatisticsSupport[]>) = User.getFriends

Get user data of each friend of the authorized user

Type declaration

getResourceOwner: ((this: API, ruleset?: Ruleset) => Promise<WithStatisticsrulesets>) = User.getResourceOwner

Get extensive user data about the authorized user

Type declaration

getUser: ((this: API, user: string | number | User, ruleset?: Ruleset) => Promise<User.Extended>) = User.getOne

Get extensive user data about whoever you want!

Type declaration

    • (this, user, ruleset?): Promise<User.Extended>
    • Get extensive user data about whoever you want!

      Parameters

      • this: API
      • user: string | number | User

        A user id, a username or a User object!

      • Optionalruleset: Ruleset

        The data should be relevant to which ruleset? (defaults to user's default Ruleset)

      Returns Promise<User.Extended>

getUserBeatmaps: ((this: API, user: number | User, type:
    | "pending"
    | "favourite"
    | "graveyard"
    | "guest"
    | "loved"
    | "nominated"
    | "ranked", config?: User.Config) => Promise<WithBeatmap[]>) = User.getBeatmaps

Get beatmaps favourited or made by a user!

Type declaration

    • (this, user, type, config?): Promise<WithBeatmap[]>
    • Get beatmaps favourited or made by a user!

      Parameters

      • this: API
      • user: number | User

        The user in question

      • type:
            | "pending"
            | "favourite"
            | "graveyard"
            | "guest"
            | "loved"
            | "nominated"
            | "ranked"

        The relation between the user and the beatmaps

      • Optionalconfig: User.Config

        Array limit & offset

      Returns Promise<WithBeatmap[]>

getUserKudosu: ((this: API, user: number | User, config?: User.Config) => Promise<KudosuHistory[]>) = User.getKudosu

Get data about the activity of a user kudosu-wise!

Type declaration

    • (this, user, config?): Promise<KudosuHistory[]>
    • Get data about the activity of a user kudosu-wise!

      Parameters

      • this: API
      • user: number | User

        The user in question

      • Optionalconfig: User.Config

        Array limit & offset

      Returns Promise<KudosuHistory[]>

getUserMostPlayed: ((this: API, user: number | User, config?: User.Config) => Promise<Playcount[]>) = User.getMostPlayed

Get the beatmaps most played by a user!

Type declaration

    • (this, user, config?): Promise<Playcount[]>
    • Get the beatmaps most played by a user!

      Parameters

      • this: API
      • user: number | User

        The user who played the beatmaps

      • Optionalconfig: User.Config

        Array limit & offset

      Returns Promise<Playcount[]>

getUserRecentActivity: ((this: API, user: number | User, config?: User.Config) => Promise<AnyRecentActivity[]>) = User.getRecentActivity

Get an array of Events of different types that relate to a user's activity during the last 31 days! (or 100 activities, whatever comes first)

Type declaration

    • (this, user, config?): Promise<AnyRecentActivity[]>
    • Get an array of Events of different types that relate to a user's activity during the last 31 days! (or 100 activities, whatever comes first)

      Parameters

      • this: API
      • user: number | User

        The user in question

      • Optionalconfig: User.Config

        Array limit & offset

      Returns Promise<AnyRecentActivity[]>

getUserScores: ((this: API, user: number | User, type: "best" | "firsts" | "recent", ruleset?: Ruleset, include?: {
    fails?: boolean;
    lazer?: boolean;
}, config?: User.Config) => Promise<WithUserBeatmapBeatmapset[]>) = User.getScores

Get "notable" scores from a user

Type declaration

    • (this, user, type, ruleset?, include?, config?): Promise<WithUserBeatmapBeatmapset[]>
    • Get "notable" scores from a user

      Parameters

      • this: API
      • user: number | User

        The user who set the scores

      • type: "best" | "firsts" | "recent"

        Do you want scores: in the user's top 100, that are top 1 on a beatmap, that have been recently set?

      • Optionalruleset: Ruleset

        The Ruleset the scores were made in (defaults to user's default Ruleset)

      • include: {
            fails?: boolean;
            lazer?: boolean;
        } = ...

        Do you also want lazer scores and failed scores? (defaults to true for lazer & false for fails)

        • Optionalfails?: boolean
        • Optionallazer?: boolean
      • Optionalconfig: User.Config

        Array limit & offset

      Returns Promise<WithUserBeatmapBeatmapset[]>

getUsers: ((this: API, users: (number | User)[], include_variant_statistics?: boolean) => Promise<WithCountryCoverGroupsStatisticsrulesets[]>) = User.getMultiple

Get user data for up to 50 users at once!

Type declaration

    • (this, users, include_variant_statistics?): Promise<WithCountryCoverGroupsStatisticsrulesets[]>
    • Get user data for up to 50 users at once!

      Parameters

      • this: API
      • users: (number | User)[]

        An array containing user ids or/and User objects!

      • include_variant_statistics: boolean = false

        Should the response include variants, useful to get stats specific to mania 4k/7k for example? (defaults to false)

      Returns Promise<WithCountryCoverGroupsStatisticsrulesets[]>

WikiPage Functions

getWikiPage: ((this: API, path: string, locale?: string) => Promise<WikiPage>) = WikiPage.getOne

Get a wiki page!

Type declaration

    • (this, path, locale?): Promise<WikiPage>
    • Get a wiki page!

      Parameters

      • this: API
      • path: string

        What's in the page's URL after https://osu.ppy.sh/wiki/ (so the title, after the subtitle if there is a subtitle) (An example for https://osu.ppy.sh/wiki/en/Game_mode/osu! would be Game_mode/osu!)

      • locale: string = "en"

        The BCP 47 language (sub)tag lowercase (for example, for a french WikiPage, use "fr") (defaults to en)

      Returns Promise<WikiPage>