diff --git a/content/docs/(guides)/instances.mdx b/content/docs/(guides)/instances.mdx index 6bb75d9..8424df6 100644 --- a/content/docs/(guides)/instances.mdx +++ b/content/docs/(guides)/instances.mdx @@ -1,12 +1,9 @@ --- title: Instances icon: Boxes +description: Instances are parallel "rooms" or "lobbies" of a world. Each instance can only hold a limited number of users, but there is no limit on how many instances can exist of a world. Instances are uniquely identified by the combined World ID and Instance ID. --- -Instances are parallel "rooms" or "lobbies" of a world. -Each instance can only hold a limited number of users, but there is no limit on how many instances can exist of a world. -Instances are uniquely identified by the combined World ID and Instance ID. - As of 2024-05-02, VRChat indicated in [a Developer Update](https://ask.vrchat.com/t/developer-update-2-may-2024/24284#changes-to-instance-apis-and-auto-creation-13) @@ -18,7 +15,7 @@ Instances are uniquely identified by the combined World ID and Instance ID. ## Instance ID The instance ID is the combined sum of all the arguments to the instance e.g. name, owner, and privacy setting. -The arguments are in the order of name, friends, hidden, private, canRequestInvite, region, nonce. +The arguments are formatted in the order: `name`, one of: (`friends` | hidden` | `private` | (`group`, `groupAccessType`)), `ageGate`, `canRequestInvite`, `region`, `nonce`. ### Owner ID @@ -26,20 +23,40 @@ Differentiate two concepts, "Instance Owner" and "Instance Master". The "Owner" of an instance is the creator of the instance, is permanent, and has permission to insta-kick users without having to go through the Voting system. The "Instance Master" is the Photon sync master and is responsible for object syncing. The Instance Master is whoever has stayed in the instance the longest. -### Nonce +The presence of one of the arguments `friends`, hidden`, `private`, or `group` indicates that the instance has a canonical owner. +The `group` argument indicates that an instance is a group instance. + +In particular: + +| Instance Type | InstanceID fragment | +| ------------- | -------------------------------------------- | +| Public | (n/a) | +| Friends Plus | `~hidden()` | +| Friends | `~friends()` | +| Invite Plus | `~private()~canRequestInvite` | +| Invite | `~private()` | +| Group Public | `~group()~groupAccessType(public)` | +| Group Plus | `~group()~groupAccessType(plus)` | +| Group Members | `~group()~groupAccessType(members)` | -Nonce is the Cryptographic key used to lock non-public instances to prevent people from guessing the Instance ID. It is not included in the location of public instances, and is formatted as "nonce(key)" where key is the cryptographic key. +### Age Gate + +`~ageGate` indicates that only users who are 18+ verified can join the instance. Users do not necessarily need to actively display 18+ verification on their profiles. ### Region -Region indicates the geographical location of the Photon servers used for the instance. **Default:** `us` +`~region()` indicates the geographical location of the Photon servers used for the instance. **Default:** `us` | Region | Hosted in | Token | | --------- | --------------- | ----- | -| USA, West | San José | us | -| USA, East | Washington D.C. | use | -| Europe | Amsterdam | eu | -| Japan | Tokyo | jp | +| USA, West | San José | `us` | +| USA, East | Washington D.C. | `use` | +| Europe | Amsterdam | `eu` | +| Japan | Tokyo | `jp` | + +### Nonce + +`~nonce()` is the Cryptographic key used to lock non-public instances to prevent people from guessing the Instance ID. It is not included in the location of public instances, and is formatted as "nonce(key)" where key is the cryptographic key. ### Special Values diff --git a/content/docs/(guides)/shortlinks.mdx b/content/docs/(guides)/shortlinks.mdx index 1f4741b..0c8b255 100644 --- a/content/docs/(guides)/shortlinks.mdx +++ b/content/docs/(guides)/shortlinks.mdx @@ -1,29 +1,71 @@ --- title: Short Links icon: Files +description: VRChat has a number of ways to shorten URLs for users, instances, groups, and calendar events. These redirect people to the `https://vrchat.com/home/...` pages on the website. --- -VRChat has several ways users can share links to instances, users, and groups. +VRChat has several ways users can share links to various types of content. Canonically, the URLs that many people will use are those they see in their browser, starting with `https://vrchat.com/home/...`. -But there are other URLs for users, groups, worlds, and instances that offer brevity. -Each of the following describes an HTTP `GET` request, where VRChat replies with an HTTP `302 Found` and the target URL in the `Location` header of the response. +However, there are other URLs for users, groups, worlds, instances, and calendar events that offer brevity. -### Users +## HTTP Redirects -`https://vrch.at/` redirects to `https://vrchat.com/home/user/` + +Upon receiving a `GET` request, VRChat will sometimes chain redirects, replying with `302 Found`, `302 Moved Temporarily`, or `307 Temporary Redirect` with a target url in the `Location` response header. +If the HTTP `GET` was directed at an api endpoint (URL paths starting with `/api/1/`), you will need to sumbit a properly formatted `User-Agent` header with the request. +For example, the `GET https://vrc.group/VRCHAT.0000` redirect looks like this: -### Worlds +```properties +GET /VRCHAT.0000 HTTP/1.1 +Host: vrc.group +User-Agent: example/4.2.67 example@vrchat.community; https://discord.gg/vrchat; https://github.com/vrchatapi/vrchat.community +Accept: */* + +HTTP/1.1 302 Found +Date: Mon, 06 Apr 2026 21:52:45 GMT +Content-Length: 0 +Connection: keep-alive +Location: https://vrchat.com/api/1/groups/redirect/VRCHAT.0000 +``` + + -`https://vrch.at/` redirects to `https://vrchat.com/home/world/` +### Users + +`https://vrch.at/` +- redirects to `https://vrchat.com/home/user/` + +Notably, this method does not work for users with old IDs like `8JoV9XEdpo` (the UserID for the official VRChat account), as these are interpreted as `shortName`s for instances. ### Instances -`https://vrch.at/` redirects to `https://vrchat.com/i/` -`https://vrchat.com/i/` redirects to `https://vrchat.com/home/launch?worldId=&instanceId=&shortName=` +`https://vrch.at/` +- redirects to `https://vrchat.com/i/` +- which redirects to `https://vrchat.com/home/launch?worldId=&instanceId=&shortName=` + +### Worlds + +Worlds are treated as a special case for instances. They do not link directly to the world info page. + +`https://vrch.at/` +- redirects to `https://vrchat.com/home/launch?worldId=` ### Groups -`https://vrc.group/` redirects to `https://vrchat.com/api/1/groups/redirect/` -`https://vrchat.com/api/1/groups/redirect/` redirects to `https://vrchat.com/home/group/` -This last one is actually programmatically useful, as it can be used to resolve a group code with discriminator to the group's ID without having to use the 'search groups' API endpoint. -Ex.: `GET https://vrchat.com/api/1/groups/redirect/VRCHAT.0000` redirects to `https://vrchat.com/home/group/grp_7ccb6ca3-cd36-4dab-9ab1-7bcf08d794e4` +`https://vrc.group/` +- redirects to `https://vrchat.com/api/1/groups/redirect/` +- which redirects to `https://api.vrchat.com/api/1/groups/redirect/` +- which redirects to `https://vrchat.com/home/group/` + +The last redirect is actually programmatically useful, as it can be used to resolve a group code with discriminator to the group's ID without having to use the 'search groups' API endpoint. +Ex.: `GET https://api.vrchat.com/api/1/groups/redirect/VRCHAT.0000` redirects to `https://vrchat.com/home/group/grp_7ccb6ca3-cd36-4dab-9ab1-7bcf08d794e4` + +### Calendar Events + +`https://vrch.at/c/` +- redirects to `https://vrchat.com/api/1/shortCode/c/` +- which redirects to `https://vrchat.com/home/group//calendar/` + + + As of 2026-04-06, the last redirect is speculative (as `/api/1/shortCode/c/` always returns a `404 Not Found`), but is based on unused code visible in the website. + diff --git a/content/docs/(guides)/websocket.mdx b/content/docs/(guides)/websocket.mdx index 94c2aa4..cc45bd2 100644 --- a/content/docs/(guides)/websocket.mdx +++ b/content/docs/(guides)/websocket.mdx @@ -6,7 +6,7 @@ description: VRChat's Websocket API, also known as "the pipeline", is used recei ## Connecting -Connecting to the VRChat webhook server is done via the URL: +Connecting to the VRChat websocket server is done via the URL: ``` wss://pipeline.vrchat.cloud/?authToken=authcookie_... @@ -19,7 +19,7 @@ It is possible to be connected from multiple locations at the same time. All cli **Most messages are double-encoded!** -All notification `content` values will be documented in JSON object form. The "`content`" frield is a **stringified** version of the JSON object, and needs to be unpacked separately. _(with the exception of `see-notification` and `hide-notification` events, which take a notification ID instead.)_ +All notification `content` values will be documented in JSON object form. The "`content`" field is a **stringified** version of the JSON object, and needs to be unpacked separately. _(with the exception of `see-notification` and `hide-notification` events, which take a notification ID instead.)_ ```json { @@ -30,48 +30,20 @@ All notification `content` values will be documented in JSON object form. The "` -## Note on Enumerations +### Error messages -Several JSON string values present in both Websocket API messages and HTTP API responses appear to be contained in predictably consistent sets. -Throughout both APIs, the empty string `""` is returned in places (including the immediately) where it would seem otherwise reasonable to have a `null` or undefined value. -In this part of the documentation, the following `":identifier"`s will be used to describe possible enumeration-ish values: +In some cases, although a websocket connection may open successfully, it may have or develop an invalid state, in which case an error message is sent to the client and the connection is closed. -- `":locationString"` - - `""` Pseudo-null value - - `"offline"` Implies a user currently is not either running the VRChat client or connected to the Pipeline (e.g., browser tab open) - - `"traveling"` Indicates a user's client is travelling between instances (e.g., downloading world, synchronizing world state) - - Also can be `"traveling:traveling` - - `"private"` Indicates a user's location is not visible to the currently logged-in user. (e.g., Ask Me/Do Not Disturb status, Invite/Invite+/Group instance) - - _other values_ An actual location (see [Instances](/instances)) -- `":platformString"` - - `""` Pseudo-null value - - `"standalonewindows"` - - `"android"` - - `"web"` User is on a https://vrchat.com/home page - - _other values_ Some other platform or third-party application (e.g., `"ios"` could be the value for a future build on some Apple devices) -- `":contentRefreshContentTypeEnum"` - - `"gallery"` - - `"icon"` - - `"emoji"` - - `"print"` - - `"prints"` is also a value observed, but this never has an id attached - - `"sticker"` - - `"inventory"` appears to mirror other - - `"avatar"` - - `"world"` - - _other values_ Some other user-uploaded content -- `":contentRefreshActionTypeEnum"` - - `"created"` - - `"deleted"` - - `"add"` \* - - `"delete"` \* - - _other values_ Not expected
\* _only observed with_ `"inventory"` _content type_ -- `":inventoryType"` - - `"sticker"` - - `"emoji"` - - `"bundle"` - - `"prop"` - - _other values_ Some other user-uploaded or creator economy content +```json +{ + "err": , // A text description of the error + "": // Additional properties describing the context of the error +} +``` + +For example: +- VRChat is experiencing a service outage: `{"err":"Error finding user {userId}"}` +- Websocket connection opened from a client IP address different from the one issued the `authToken`: `{"err":"authToken doesn't correspond with an active session","authToken":"{authToken}","ip":"{ipAddress}"}` ## Events @@ -568,3 +540,46 @@ Role structure matches the GroupRole object from the [Groups API](/reference/get } } ``` + +## Note on Enumerations + +Several JSON string values present in both Websocket API messages and HTTP API responses appear to be contained in predictably consistent sets. +Throughout both APIs, the empty string `""` is returned in places where it would otherwise seem reasonable to have a `null` or undefined value. +In this part of the documentation, the following `":identifier"`s will be used to describe possible enumeration-ish values: + +- `":locationString"` + - `""` Pseudo-null value + - `"offline"` Implies a user currently is not either running the VRChat client or connected to the Pipeline (e.g., browser tab open) + - `"traveling"` Indicates a user's client is travelling between instances (e.g., downloading world, synchronizing world state) + - Also can be `"traveling:traveling` + - `"private"` Indicates a user's location is not visible to the currently logged-in user. (e.g., Ask Me/Do Not Disturb status, Invite/Invite+/Group instance) + - _other values_ An actual location (see [Instances](/instances)) +- `":platformString"` + - `""` Pseudo-null value + - `"standalonewindows"` + - `"android"` + - `"web"` User is on a https://vrchat.com/home page + - _other values_ Some other platform or third-party application (e.g., `"ios"` could be the value for a future build on some Apple devices) +- `":contentRefreshContentTypeEnum"` + - `"gallery"` + - `"icon"` + - `"emoji"` + - `"print"` + - `"prints"` is also a value observed, but this never has an id attached + - `"sticker"` + - `"inventory"` appears to mirror other + - `"avatar"` + - `"world"` + - _other values_ Some other user-uploaded content +- `":contentRefreshActionTypeEnum"` + - `"created"` + - `"deleted"` + - `"add"` \* + - `"delete"` \* + - _other values_ Not expected
\* _only observed with_ `"inventory"` _content type_ +- `":inventoryType"` + - `"sticker"` + - `"emoji"` + - `"bundle"` + - `"prop"` + - _other values_ Some other user-uploaded or creator economy content