> This page is for API Reference.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://contentful.com/developers/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful.com/developers/docs/_mcp/server.

## Overview

Subscribe to a preview session to receive the hydrated experience whenever it changes, without polling.

```
GET wss://preview.xdn.contentful.com/spaces/{spaceId}/environments/{environmentId}/preview_sessions/{sessionId}/subscribe?access_token={previewToken}
```

> **Info**
>
> For EU data residency, use `wss://preview.xdn.eu.contentful.com`.

This route upgrades the request to a WebSocket connection, so it isn't part of the REST reference.

## Authentication

Send a [Content Preview API](/developers/docs/references/authentication#the-content-delivery-and-preview-api) access token. Browsers can't set headers on a WebSocket handshake, so pass the token as the `access_token` query parameter. Other clients can send `Authorization: Bearer <token>` instead. If you send both, they must be identical.

Tokens in a query string can appear in logs. Use a token that only grants preview access.

## Messages

Every message is a JSON object with a `type` and a `data` field.

| Type    | Direction        | Data                                                                                                                                                                                |
| ------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `next`  | Server to client | The current hydrated experience, in the same shape as the response of [Get the current preview experience](/developers/docs/references/preview-session-api/preview/get-current-preview-experience). |
| `error` | Server to client | An error object with `sys.id` and `message`. Recoverable errors leave the connection open. Keep displaying the last valid view, if one exists.                                      |
| `ping`  | Client to server | An empty object, `{}`.                                                                                                                                                              |
| `pong`  | Server to client | An empty object, `{}`, in reply to `ping`.                                                                                                                                          |

After connecting, the server sends the current preview or an error. Later updates contain the latest preview state. Rapid edits may be combined into one update, so a `next` message does not acknowledge an individual edit.

If the preview token becomes invalid or loses access, the server sends an error and closes the connection with `1008` and the reason `authorization-lost`.

\<!-- prettier-ignore -->

```json
{"type":"ping","data":{}}
```

Send the exact compact JSON text above, for example with `JSON.stringify({ type: "ping", data: {} })`.

A `next` message larger than 7,000,000 UTF-8 bytes, including its JSON envelope, is replaced by an `error` message with the ID `PayloadTooLarge`.

## Connection errors

The server refuses the upgrade with an HTTP status instead of opening the socket.

| Status | Meaning                                                                                                                                 |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The `access_token` or `resource_resolution` query parameter appears more than once.                                                     |
| `401`  | The token is missing, empty, malformed, or the header and query tokens differ.                                                          |
| `403`  | The token does not grant access to the preview.                                                                                         |
| `404`  | The session doesn't exist or has expired.                                                                                               |
| `409`  | The preview token or `resource_resolution` credentials differ from those of existing connections, or the session state is incompatible. |
| `429`  | The session has reached its limit of 20 connections, including connections still opening.                                               |
| `500`  | An unexpected error prevented the connection from opening.                                                                              |
| `503`  | The service or session state is temporarily unavailable. Retry the connection.                                                          |

## Closing codes

| Code   | Reason               | Meaning                                           |
| ------ | -------------------- | ------------------------------------------------- |
| `1000` | `deleted`            | The session was deleted.                          |
| `1000` | `expired`            | The session expired.                              |
| `1008` | `authorization-lost` | The token no longer grants access to the preview. |
| `1011` | `delivery-failed`    | The server couldn't deliver a message.            |
| `1011` | `connection-error`   | A WebSocket error closed the connection.          |
| `1012` | `service-restart`    | The server restarted. Reconnect.                  |