> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wiresocket.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket Sync

> The core of WireSocket for real-time Yjs document synchronization.

The WebSocket endpoint is the core of WireSocket. All Yjs document updates, awareness state (presence, cursors), and heartbeats flow through this high-performance connection.

<Important>
  Always call the **[Discovery API](/api-reference/discovery)** first to resolve
  the current active region for a document. Connecting to the wrong region will
  result in a **4009 redirect**.
</Important>

***

## Endpoint

```http theme={null}
wss://{region}.wiresocket.net/{documentName}
```

Example: `wss://eu-central-1.wiresocket.net/my-document-id`

***

## Authentication

The Data Plane supports three ways to authenticate the WebSocket handshake. Method 1 is recommended as it keeps the token out of browser history and server logs.

| Method                        | Implementation                                    |
| :---------------------------- | :------------------------------------------------ |
| **1. WebSocket Sub-protocol** | `protocols: ['access_token', 'YOUR_JWT']`         |
| **2. Query Parameter**        | `wss://{region}.wiresocket.net?token=YOUR_JWT`    |
| **3. Authorization Header**   | `Headers: { 'Authorization': 'Bearer YOUR_JWT' }` |

***

## Connection Example

Using the standard `y-websocket` provider:

```js theme={null}
import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";

const ydoc = new Y.Doc();

// 1. Resolve URL via Discovery API first
// 2. Initialize provider
const provider = new WebsocketProvider(
  "wss://eu-central-1.wiresocket.net", // Resolved URL
  "my-document-id",
  ydoc,
  {
    // Pass JWT via sub-protocol
    protocols: ["access_token", "YOUR_JWT"],
  },
);
```

***

## Close Codes (Error Reference)

If a connection is rejected or closed, the Data Plane returns one of the following codes:

| Code     | Name             | Description                                                                                   |
| :------- | :--------------- | :-------------------------------------------------------------------------------------------- |
| **4001** | Missing Token    | No JWT was provided in the handshake.                                                         |
| **4002** | Invalid Token    | Token is expired, malformed, or has an invalid signature.                                     |
| **4003** | Forbidden        | The token is valid but the tenantId or appId claims are rejected.                             |
| **4004** | Connection Limit | Your application has reached its concurrent connection cap.                                   |
| **4005** | Document Limit   | Your application has reached its concurrent document cap.                                     |
| **4006** | Rate Limit       | Request frequency from this IP is too high.                                                   |
| **4007** | Invalid Name     | The document name violates internal naming rules.                                             |
| **4008** | User Limit       | The max number of users per document (`maxUsersPerDoc`) is reached.                           |
| **4009** | Wrong Region     | The document is active in another region. The reason field will contain `REDIRECT:wss://...`. |

***

## Handling Redirection (4009)

If you receive a `4009` close code, your client should parse the reason string to find the correct regional URL and reconnect immediately:

```js theme={null}
provider.ws.onclose = (event) => {
  if (event.code === 4009 && event.reason.startsWith("REDIRECT:")) {
    const newUrl = event.reason.replace("REDIRECT:", "");
    console.log("Redirecting to:", newUrl);
    // Trigger reconnection logic with newUrl
  }
};
```
