diff --git a/src/data/nav/platform.ts b/src/data/nav/platform.ts
index 383a459861..6b83565d5d 100644
--- a/src/data/nav/platform.ts
+++ b/src/data/nav/platform.ts
@@ -247,7 +247,7 @@ export default {
pages: [
{
name: 'Overview',
- link: '/docs/account',
+ link: '/docs/platform/account',
index: true,
},
{
diff --git a/src/pages/docs/ai-transport/messaging/citations.mdx b/src/pages/docs/ai-transport/messaging/citations.mdx
index 4bf502ca2a..d79f1c9709 100644
--- a/src/pages/docs/ai-transport/messaging/citations.mdx
+++ b/src/pages/docs/ai-transport/messaging/citations.mdx
@@ -6,7 +6,7 @@ meta_keywords: "citations, references, source attribution, message annotations,
AI agents often draw information from external sources such as documents, web pages, or databases. Citations to those sources enable users to verify information, explore sources in detail, and understand where responses came from. Ably's [message annotations](/docs/messages/annotations) provide a model-agnostic, structured way to attach source citations to AI responses without modifying the response content. It enables clients to append information to existing messages on a channel.
-This pattern works when publishing complete responses as messages on a channel or when streaming responses using the [message-per-response](/docs/ai-transport/message-per-response) pattern.
+This pattern works when publishing complete responses as messages on a channel or when streaming responses using the [message-per-response](/docs/ai-transport/token-streaming/message-per-response) pattern.
## Why citations matter
@@ -21,7 +21,7 @@ Including citations on AI responses provides:
Use [message annotations](/docs/messages/annotations) to attach source metadata to AI response messages without modifying the response content:
-1. The agent publishes an AI response as a single message, or builds it incrementally using [message appends](/docs/ai-transport/message-per-response).
+1. The agent publishes an AI response as a single message, or builds it incrementally using [message appends](/docs/ai-transport/token-streaming/message-per-response).
2. The agent publishes one or more annotations to attach citations to the response message, each referencing the response message [`serial`](/docs/messages#properties).
3. Ably automatically aggregates annotations and generates summaries showing total counts and groupings (for example, by source domain name).
4. Clients receive citation summaries automatically and can optionally subscribe to individual annotation events for detailed citation data as part of the realtime stream. Alternatively, clients can obtain annotations for a given message via the REST API.
@@ -182,7 +182,7 @@ channel.annotations.publish(msgSerial, citation2);
-When streaming response tokens using the [message-per-response](/docs/ai-transport/message-per-response) pattern, you can publish citations while the response is still streaming since the `serial` of the response message becomes known after you [publish the initial message](/docs/ai-transport/token-streaming/message-per-response#publishing).
+When streaming response tokens using the [message-per-response](/docs/ai-transport/token-streaming/message-per-response) pattern, you can publish citations while the response is still streaming since the `serial` of the response message becomes known after you [publish the initial message](/docs/ai-transport/token-streaming/message-per-response#publishing).
diff --git a/src/pages/docs/ai-transport/messaging/human-in-the-loop.mdx b/src/pages/docs/ai-transport/messaging/human-in-the-loop.mdx
index c81807289a..7a2212bdb5 100644
--- a/src/pages/docs/ai-transport/messaging/human-in-the-loop.mdx
+++ b/src/pages/docs/ai-transport/messaging/human-in-the-loop.mdx
@@ -223,7 +223,7 @@ Set [`echoMessages`](/docs/api/realtime-sdk/types#client-options) to `false` in
The agent listens for human decisions and acts accordingly. When a response arrives, the agent retrieves the pending request using the `toolCallId`, verifies that the user is permitted to approve that specific action, and either executes the action or handles the rejection.
-For audit trails, use [integration rules](/docs/integrations) to stream approval messages to external systems.
+For audit trails, use [integration rules](/docs/platform/integrations) to stream approval messages to external systems.
### Verify by user identity
diff --git a/src/pages/docs/ai-transport/sessions-identity/identifying-users-and-agents.mdx b/src/pages/docs/ai-transport/sessions-identity/identifying-users-and-agents.mdx
index f56caf3464..5a43b61ddd 100644
--- a/src/pages/docs/ai-transport/sessions-identity/identifying-users-and-agents.mdx
+++ b/src/pages/docs/ai-transport/sessions-identity/identifying-users-and-agents.mdx
@@ -414,7 +414,7 @@ Ably recommends using token authentication with short-lived tokens and minimal c
### Agent capabilities
-When using API key authentication, provision API keys through the [Ably dashboard](https://ably.com/dashboard) or [Control API](/docs/account/control-api) with only the capabilities required by the agent.
+When using API key authentication, provision API keys through the [Ably dashboard](https://ably.com/dashboard) or [Control API](/docs/platform/account/control-api) with only the capabilities required by the agent.
The following example uses the Control API to create an API key with specific capabilities for a weather agent:
diff --git a/src/pages/docs/ai-transport/sessions-identity/resuming-sessions.mdx b/src/pages/docs/ai-transport/sessions-identity/resuming-sessions.mdx
index 1e218e0cb8..434b0a0b4d 100644
--- a/src/pages/docs/ai-transport/sessions-identity/resuming-sessions.mdx
+++ b/src/pages/docs/ai-transport/sessions-identity/resuming-sessions.mdx
@@ -16,7 +16,7 @@ An agent or user might resume an existing session when:
When you attach to a channel, Ably automatically syncs the complete current presence set to your client. You can then query the presence set or subscribe to presence events without any additional hydration steps. This works the same way for both users and agents.
-For details on obtaining the synced presence set, see [Viewing who is online](/docs/ai-transport/sessions-and-identity/online-status#viewing-presence).
+For details on obtaining the synced presence set, see [Viewing who is online](/docs/ai-transport/sessions-identity/online-status#viewing-presence).
## User resumes a session
diff --git a/src/pages/docs/ai-transport/token-streaming/message-per-response.mdx b/src/pages/docs/ai-transport/token-streaming/message-per-response.mdx
index 891b3f4cd3..c258c8455d 100644
--- a/src/pages/docs/ai-transport/token-streaming/message-per-response.mdx
+++ b/src/pages/docs/ai-transport/token-streaming/message-per-response.mdx
@@ -7,7 +7,7 @@ Token streaming with message-per-response is a pattern where every token generat
This pattern is useful for chat-style applications where you want each complete AI response stored as a single message in history, making it easy to retrieve and display multi-response conversation history. Each agent response becomes a single message that grows as tokens are appended, allowing clients joining mid-stream to catch up efficiently without processing thousands of individual tokens.
-The message-per-response pattern includes [automatic rate limit protection](/docs/ai-transport/token-rate-limits#per-response) through rollups, making it the recommended approach for most token streaming use cases.
+The message-per-response pattern includes [automatic rate limit protection](/docs/ai-transport/token-streaming/token-rate-limits#per-response) through rollups, making it the recommended approach for most token streaming use cases.
## How it works
@@ -215,7 +215,7 @@ The `appendRollupWindow` parameter controls how many tokens are combined into ea
The default 40ms window strikes a balance, delivering tokens at 25 messages per second - smooth enough for a great user experience while allowing you to run two simultaneous response streams on a single connection. If you need to support more concurrent streams, increase the rollup window (up to 500ms), accepting that tokens will arrive in more noticeable batches. Alternatively, instantiate a separate Ably client which uses its own connection, giving you access to additional message rate capacity.
-For more details on rate limits and rollup behavior, see [Token streaming limits](/docs/ai-transport/token-rate-limits#rollup).
+For more details on rate limits and rollup behavior, see [Token streaming limits](/docs/ai-transport/token-streaming/token-rate-limits#rollup).
## Subscribing to token streams
diff --git a/src/pages/docs/ai-transport/token-streaming/message-per-token.mdx b/src/pages/docs/ai-transport/token-streaming/message-per-token.mdx
index dc9bfbb35e..2427e17a3c 100644
--- a/src/pages/docs/ai-transport/token-streaming/message-per-token.mdx
+++ b/src/pages/docs/ai-transport/token-streaming/message-per-token.mdx
@@ -83,7 +83,7 @@ for (Event event : stream) {
This approach maximizes throughput while maintaining ordering guarantees, allowing you to stream tokens as fast as your AI model generates them.
-Unlike the [message-per-response](/docs/ai-transport/token-streaming/message-per-response) pattern, the message-per-token pattern requires you to [manage rate limits directly](/docs/ai-transport/token-rate-limits#per-token).
+Unlike the [message-per-response](/docs/ai-transport/token-streaming/message-per-response) pattern, the message-per-token pattern requires you to [manage rate limits directly](/docs/ai-transport/token-streaming/token-rate-limits#per-token).
diff --git a/src/pages/docs/api/index.mdx b/src/pages/docs/api/index.mdx
index 37c6332da9..71ff9bc9ca 100644
--- a/src/pages/docs/api/index.mdx
+++ b/src/pages/docs/api/index.mdx
@@ -60,9 +60,9 @@ The API reference for the [Chat SDK](https://sdk.ably.com/builds/ably/ably-chat-
In addition to the API references listed previously, our developer documentation also provides information on how these interfaces are used, and this covers key concepts such as connections, channels, messages and the pub/sub pattern. You can find that information on the following pages:
-* [Client library Realtime SDK - Overview](/docs/realtime)
-* [Client library REST SDK - Overview](/docs/rest)
-* [Realtime and REST interface use cases](/docs/realtime#realtime-vs-rest)
-* [REST API - Overview](/docs/rest-api)
+* [Client library Realtime SDK - Overview](/docs/api/realtime-sdk)
+* [Client library REST SDK - Overview](/docs/api/rest-sdk)
+* [Realtime and REST interface use cases](/docs/api/realtime-sdk#realtime-vs-rest)
+* [REST API - Overview](/docs/api/rest-api)
* [SSE API - Overview](/docs/protocols/sse)
-* [Control API - Overview](/docs/platform/account/control-api)
+* [Control API - Overview](/docs/api/control-api)
diff --git a/src/pages/docs/api/realtime-sdk.mdx b/src/pages/docs/api/realtime-sdk.mdx
index 0c12de70ef..708907b2a4 100644
--- a/src/pages/docs/api/realtime-sdk.mdx
+++ b/src/pages/docs/api/realtime-sdk.mdx
@@ -206,7 +206,7 @@ A reference to the [ARTLocalDevice](/docs/api/realtime-sdk/push#local-device) ob
### `Channels` `channels`
-[Channels](/docs/api/realtime-sdk/channels#channels-object) is a reference to the [Channel](/docs/channels) collection instance for this library indexed by the channel name. You can use the [Get](/docs/api/realtime-sdk/channels#get) method of this to get a `Channel` instance. See [channels](/docs/channels) and [messages](/docs/channels/messages) for more information.
+[Channels](/docs/api/realtime-sdk/channels#channels-object) is a reference to the [Channel](/docs/channels) collection instance for this library indexed by the channel name. You can use the [Get](/docs/api/realtime-sdk/channels#get) method of this to get a `Channel` instance. See [channels](/docs/channels) and [messages](/docs/messages) for more information.
### `Connection` `connection`
diff --git a/src/pages/docs/api/realtime-sdk/history.mdx b/src/pages/docs/api/realtime-sdk/history.mdx
index c306dc3303..05565d11a2 100644
--- a/src/pages/docs/api/realtime-sdk/history.mdx
+++ b/src/pages/docs/api/realtime-sdk/history.mdx
@@ -367,7 +367,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|----------|-------------|------|
| action Action | the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { Absent, Present, Enter, Leave, Update }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `ARTPresenceAction` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `StringBuffer`, `JSON Object` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `JSON Object` `Hash`, `Array` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `JSON Object` `Hash`, `Array` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId clientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId connectionId | The connection ID of the publisher of this presence update | `String` |
@@ -701,7 +701,7 @@ Returns a new `PaginatedResult` loaded with the next page of results. If there a
`Task> NextAsync()`
-Returns a new [`PaginatedResult`](/docs/api/realtime-sdk/historypaginated-result) loaded with the next page of results. If there are no further pages, then a blank PaginatedResult will be returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`
+Returns a new [`PaginatedResult`](/docs/api/realtime-sdk/history#paginated-result) loaded with the next page of results. If there are no further pages, then a blank PaginatedResult will be returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`
diff --git a/src/pages/docs/api/realtime-sdk/presence.mdx b/src/pages/docs/api/realtime-sdk/presence.mdx
index 5e04e9ac8f..d612324043 100644
--- a/src/pages/docs/api/realtime-sdk/presence.mdx
+++ b/src/pages/docs/api/realtime-sdk/presence.mdx
@@ -1237,7 +1237,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|----------|-------------|------|
| action action Action | the event signified by a PresenceMessage. See [`Presence action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { Absent, Present, Enter, Leave, Update }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `ARTPresenceAction` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `StringBuffer`, `JSON Object` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `JSON Object` `Hash`, `Array` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Map`, `List` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `JSON Object` `Hash`, `Array` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Map`, `List` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId | The connection ID of the publisher of this presence update | `String` |
diff --git a/src/pages/docs/api/realtime-sdk/types.mdx b/src/pages/docs/api/realtime-sdk/types.mdx
index 64452764e7..bd7c646d03 100644
--- a/src/pages/docs/api/realtime-sdk/types.mdx
+++ b/src/pages/docs/api/realtime-sdk/types.mdx
@@ -615,7 +615,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|----------|-------------|------|
| action Action | The event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [Presence action](/docs/api/realtime-sdk/types#presence-action) [`PresenceAction`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `ARTPresenceAction` `enum { Absent, Present, Enter, Leave, Update }` `const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `StringBuffer`, `JSON Object` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `Bytearray`, `Dict`, `List` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `[]byte` `String`, `Map`, `List` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects | `JSONObject`, `JSONArray` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` plain C# object that can be converted to Json `String`, `[]byte` `Map`, `List` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects | `JSONObject`, `JSONArray` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` plain C# object that can be converted to Json `String`, `[]byte` `Map`, `List` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId | The connection ID of the publisher of this presence update | `String` |
diff --git a/src/pages/docs/api/rest-sdk.mdx b/src/pages/docs/api/rest-sdk.mdx
index 0967d0235c..06353568fb 100644
--- a/src/pages/docs/api/rest-sdk.mdx
+++ b/src/pages/docs/api/rest-sdk.mdx
@@ -206,7 +206,7 @@ A reference to the channels Channels
-[`Channels`](/docs/channels) is a reference to the [`Channel`](/docs/channels) collection instance for this library indexed by the channel name. You can use the [`Get`](/docs/api/rest-sdk/channels#get) method of this to get a `Channel` instance. See [channels](/docs/channels) and [messages](/docs/channels/messages/) for more information.
+[`Channels`](/docs/channels) is a reference to the [`Channel`](/docs/channels) collection instance for this library indexed by the channel name. You can use the [`Get`](/docs/api/rest-sdk/channels#get) method of this to get a `Channel` instance. See [channels](/docs/channels) and [messages](/docs/messages/) for more information.
## AblyRest Methods Ably.Rest Methods io.ably.lib.AblyRest Methods Ably::Rest::Client Methods ARTRest Methods ably.Rest Methods
diff --git a/src/pages/docs/api/rest-sdk/history.mdx b/src/pages/docs/api/rest-sdk/history.mdx
index 5fc8773130..322191315e 100644
--- a/src/pages/docs/api/rest-sdk/history.mdx
+++ b/src/pages/docs/api/rest-sdk/history.mdx
@@ -376,7 +376,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|----------|-------------|------|
| action Action Action | the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`Presence action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceAction`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { Absent, Present, Enter, Leave, Update }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE` `ARTPresenceAction` `const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `StringBuffer`, `JSON Object` `String`, `[]byte` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `Bytearray`, `Dict`, `List` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` `String`, `Binary String`, `Associative Array`, `Array` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId | The connection ID of the publisher of this presence update | `String` |
diff --git a/src/pages/docs/api/rest-sdk/presence.mdx b/src/pages/docs/api/rest-sdk/presence.mdx
index 27114807d3..2a244191a5 100644
--- a/src/pages/docs/api/rest-sdk/presence.mdx
+++ b/src/pages/docs/api/rest-sdk/presence.mdx
@@ -255,7 +255,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|----------|-------------|------|
| action Action Action | the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`Presence action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceAction`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) the event signified by a PresenceMessage. See [`PresenceMessage::action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { Absent, Present, Enter, Leave, Update }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE` `ARTPresenceAction` `const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `StringBuffer`, `JSON Object` `String`, `[]byte` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `Bytearray`, `Dict`, `List` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` `String`, `Binary String`, `Associative Array`, `Array` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` `Map`, `List` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` `Map`, `List` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId | The connection ID of the publisher of this presence update | `String` |
diff --git a/src/pages/docs/api/rest-sdk/types.mdx b/src/pages/docs/api/rest-sdk/types.mdx
index 646ef6c8f3..fdfc4f1b0b 100644
--- a/src/pages/docs/api/rest-sdk/types.mdx
+++ b/src/pages/docs/api/rest-sdk/types.mdx
@@ -469,7 +469,7 @@ A `PresenceMessage` represents an individual presence update that is sent to or
|-----------|-------------|------|
| action Action | The event signified by a PresenceMessage. See [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`Presence action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceAction`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::ACTION`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage.action`](/docs/api/realtime-sdk/types#presence-action) [`PresenceMessage::action`](/docs/api/realtime-sdk/types#presence-action) [`Presence action`](/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { Absent, Present, Enter, Leave, Update }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }` `enum { :absent, :present, :enter, :leave, :update }` `const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE` `ARTPresenceAction` `const PresenceMessage::PresenceAbsent,PresencePresent,PresenceEnter,PresenceLeave,PresenceUpdate` |
| data Data | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray` `String`, `byte[]`, plain C# object that can be converted to Json `String`, `StringBuffer`, `JSON Object` `String`, `[]byte` `String`, `Binary` (ASCII-8BIT String), `Hash`, `Array` `String`, `Bytearray`, `Dict`, `List` `String`, `NSData`, `Dictionary`, `Array` `NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` `String`, `Binary String`, `Associative Array`, `Array` `String`, `StringBuffer`, `JSON Object` |
-| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/channels/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` `Map`, `List` |
+| extras Extras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](/docs/push/publish#sub-channels), [`ref`](/docs/messages#interactions) and [`privileged`](/docs/platform/integrations/webhooks#skipping) objects | `JSONObject`, `JSONArray` plain C# object that can be converted to Json `String`, `[]byte` `JSON Object` `Hash`, `Array` `Dict`, `List` `Dictionary`, `Array` `NSDictionary *`, `NSArray *` `Associative Array`, `Array` `Map`, `List` |
| id Id | Unique ID assigned by Ably to this presence update | `String` |
| clientId client_id ClientId | The client ID of the publisher of this presence update | `String` |
| connectionId connection_id ConnectionId | The connection ID of the publisher of this presence update | `String` |
diff --git a/src/pages/docs/channels/index.mdx b/src/pages/docs/channels/index.mdx
index 803e3a4781..72b2a7cb2e 100644
--- a/src/pages/docs/channels/index.mdx
+++ b/src/pages/docs/channels/index.mdx
@@ -28,7 +28,7 @@ redirect_from:
Channels are used to separate messages into different topics. They are the building block of creating a realtime application using the publish-subscribe pattern. Channels are also the unit of security and scalability. Clients should only ever be provided the [capabilities](/docs/auth/capabilities) for channels that they should have access to.
-[Messages](/docs/channels/messages) contain the data that a client is communicating, such as the contents of an individual chat message, or an event that has occurred, such as updated financial information.
+[Messages](/docs/messages) contain the data that a client is communicating, such as the contents of an individual chat message, or an event that has occurred, such as updated financial information.
With [basic pub-sub](/docs/pub-sub) you create a channel, subscribe to it, and then publish messages to it. Most other Ably features utilize channels, or a group of channels, to provide additional functionality to your realtime applications.
@@ -134,7 +134,7 @@ channel := rest.Channels.Get("{{RANDOM_CHANNEL_NAME}}")
-Although Ably recommends that you use channels to distribute work more evenly across the cluster, there is an [associated cost](/docs/pricing) for a high number of channels.
+Although Ably recommends that you use channels to distribute work more evenly across the cluster, there is an [associated cost](/docs/platform/pricing) for a high number of channels.
Don't use different channels just to indicate different types of data, or different events, if all messages are going to the same set of clients. Use a single channel and distinguish between them using a different message `name`.
diff --git a/src/pages/docs/channels/options/deltas.mdx b/src/pages/docs/channels/options/deltas.mdx
index 7e6ef52956..c644fc3f8a 100644
--- a/src/pages/docs/channels/options/deltas.mdx
+++ b/src/pages/docs/channels/options/deltas.mdx
@@ -19,7 +19,7 @@ Using delta mode can significantly reduce the encoded size of each message when
## Delta processing
-Deltas apply to the `data` property of a [`Message`](/docs/channels/messages) payload published via Ably. Other properties, such as `clientId`, `name`, and `extras` remain unchanged and are not compressed when using deltas.
+Deltas apply to the `data` property of a [`Message`](/docs/messages) payload published via Ably. Other properties, such as `clientId`, `name`, and `extras` remain unchanged and are not compressed when using deltas.
Messages retrieved via [history](/docs/storage-history/history), and messages delivered to [integrations](/docs/platform/integrations) are not compressed.
diff --git a/src/pages/docs/channels/options/encryption.mdx b/src/pages/docs/channels/options/encryption.mdx
index 27e1ea6b14..645114aeb5 100644
--- a/src/pages/docs/channels/options/encryption.mdx
+++ b/src/pages/docs/channels/options/encryption.mdx
@@ -52,7 +52,7 @@ Encryption with Ably supports **symmetric encryption only** and requires each pa
Only the AES algorithm, with a default key length of 256 bits, and CBC mode are supported. These defaults are intended to ensure that encryption support can be provided in all target environments and platforms.
-Encryption is supported for the `data` attribute, or payload, of published [messages](/docs/channels/messages) and [presence messages](/docs/presence-occupancy/presence) on a channel, using both the REST and realtime interfaces. Decryption is supported for message and presence message subscriptions in the realtime interface, and for both the REST and realtime interfaces when using [history](/docs/storage-history/history).
+Encryption is supported for the `data` attribute, or payload, of published [messages](/docs/messages) and [presence messages](/docs/presence-occupancy/presence) on a channel, using both the REST and realtime interfaces. Decryption is supported for message and presence message subscriptions in the realtime interface, and for both the REST and realtime interfaces when using [history](/docs/storage-history/history).
Other attributes of messages and presence messages, such as event `name` and `clientId` remain un-encrypted. This means that all sensitive data should be placed in the `data` attribute to ensure it is encrypted before it is transmitted to Ably.
diff --git a/src/pages/docs/chat/moderation/direct/azure.mdx b/src/pages/docs/chat/moderation/direct/azure.mdx
index 0a5a720a77..38e7571787 100644
--- a/src/pages/docs/chat/moderation/direct/azure.mdx
+++ b/src/pages/docs/chat/moderation/direct/azure.mdx
@@ -9,7 +9,7 @@ The Azure Content Safety integration can be applied to chat rooms so that you ca
## Integration setup
-Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/account/control-api).
+Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/platform/account/control-api).
The following are the fields specific to Azure Content Safety configuration:
diff --git a/src/pages/docs/chat/moderation/direct/bodyguard.mdx b/src/pages/docs/chat/moderation/direct/bodyguard.mdx
index 9442a449c7..a666483bf1 100644
--- a/src/pages/docs/chat/moderation/direct/bodyguard.mdx
+++ b/src/pages/docs/chat/moderation/direct/bodyguard.mdx
@@ -9,7 +9,7 @@ The Bodyguard integration can be applied to chat rooms so that you can use Bodyg
## Integration setup
-Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/account/control-api).
+Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/platform/account/control-api).
The following fields are specific to Bodyguard configuration:
diff --git a/src/pages/docs/chat/moderation/direct/hive-dashboard.mdx b/src/pages/docs/chat/moderation/direct/hive-dashboard.mdx
index 2190cd8cd4..e8c9ab1635 100644
--- a/src/pages/docs/chat/moderation/direct/hive-dashboard.mdx
+++ b/src/pages/docs/chat/moderation/direct/hive-dashboard.mdx
@@ -26,7 +26,7 @@ Once you have done this you can get an API key from the [dashboard settings](htt
When the rule is enabled, it will send all published messages in the room to the dashboard for review.
Please note that messages get sent to Hive _after_ they have been published, so users will see them in the chat room until they have been deleted by a moderation rule, although in the case of automatic moderation this will be near-instantaneous.
-If you want to prevent messages from reaching users until they have been approved automatically by an AI moderation rule, check out the [Hive model only rule](/docs/chat/rooms/moderation/hive-model-only).
+If you want to prevent messages from reaching users until they have been approved automatically by an AI moderation rule, check out the [Hive model only rule](/docs/chat/moderation/direct/hive-model-only).
In order for hive dashboard to delete messages, you need to set up an [action](https://docs.thehive.ai/docs/actions) in the dashboard.
The setup is as follows:
diff --git a/src/pages/docs/chat/moderation/direct/tisane.mdx b/src/pages/docs/chat/moderation/direct/tisane.mdx
index bc60d38f07..2a39e45e5b 100644
--- a/src/pages/docs/chat/moderation/direct/tisane.mdx
+++ b/src/pages/docs/chat/moderation/direct/tisane.mdx
@@ -9,7 +9,7 @@ The Tisane integration can be applied to chat rooms so that you can use Tisane's
## Integration setup
-Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/account/control-api).
+Configure the integration in your [Ably dashboard](https://ably.com/accounts/any/apps/any/integrations) or using the [Control API](/docs/platform/account/control-api).
The following are the fields specific to Tisane configuration:
diff --git a/src/pages/docs/faq/push-faqs.mdx b/src/pages/docs/faq/push-faqs.mdx
index 2485ef1f46..849295a034 100644
--- a/src/pages/docs/faq/push-faqs.mdx
+++ b/src/pages/docs/faq/push-faqs.mdx
@@ -37,7 +37,7 @@ FAQs related to configuring push notifications for specific platforms.
### For Apple's APNs, what is the sandbox endpoint?
-Apple provides a [sandbox endpoint](/docs/push/configure/apns#sandbox) for testing push notifications. This ensures device IDs in that environment do not work in production.
+Apple provides a [sandbox endpoint](/docs/faq/push-faqs#apns-sandbox) for testing push notifications. This ensures device IDs in that environment do not work in production.
Customers often have a test/sandbox app using the `APNs` sandbox endpoint and a production app that does not. When setting up [push notifications](/docs/push) in your dashboard, enable the sandbox endpoint in the `APNs` settings if you intend to use it.
@@ -53,7 +53,7 @@ However, [publishing](/docs/channels#publish) a push notification via a [channel
### Does Ably charge for push notifications?
-Yes. Each push notification delivered to a device counts as one normal [message](/docs/channels/messages).
+Yes. Each push notification delivered to a device counts as one normal [message](/docs/messages).
## Troubleshooting
@@ -113,6 +113,6 @@ Consistent duplication on a specific device usually indicates both a `deviceId`
If you're unable to [publish](/docs/channels#publish) push notifications to [channels](/docs/channels), this is typically due to configuration or permission issues. The following are possible reasons for this issue:
-1. [Channel Rules](/docs/general/channel-rules): Channels must be explicitly enabled for push notifications via channel rules. They are disabled by default.
+1. [Channel Rules](/docs/channels#rules): Channels must be explicitly enabled for push notifications via channel rules. They are disabled by default.
2. [Permissions](/docs/auth/capabilities): The publisher must have permission to publish to that channel.
3. Invalid Payload: If the push notification payload in the `extras` field is invalid, the message may be rejected immediately.
diff --git a/src/pages/docs/liveobjects/lifecycle.mdx b/src/pages/docs/liveobjects/lifecycle.mdx
index ebc0b2cb53..c670aa3770 100644
--- a/src/pages/docs/liveobjects/lifecycle.mdx
+++ b/src/pages/docs/liveobjects/lifecycle.mdx
@@ -73,7 +73,7 @@ channel.getObjects().on(ObjectsStateEvent.SYNCED, (stateEvent) -> {
-LiveObjects synchronization events do not replace [connection](/docs/connect/states) or [channel](/docs/channel/states) states. You should still monitor these states and handle [connection](/docs/connect/states#handling-failures) and [channel](/docs/channel/states#failure) failures to ensure your application behaves as expected. LiveObjects synchronization events specifically inform you about the progress of LiveObjects data synchronization and should be used alongside other state management mechanisms.
+LiveObjects synchronization events do not replace [connection](/docs/connect/states) or [channel](/docs/channels/states) states. You should still monitor these states and handle [connection](/docs/connect/states#handling-failures) and [channel](/docs/channels/states#failure) failures to ensure your application behaves as expected. LiveObjects synchronization events specifically inform you about the progress of LiveObjects data synchronization and should be used alongside other state management mechanisms.
## Handle object lifecycle events
diff --git a/src/pages/docs/liveobjects/rest-api-usage.mdx b/src/pages/docs/liveobjects/rest-api-usage.mdx
index e5a67dcce4..6a7c997148 100644
--- a/src/pages/docs/liveobjects/rest-api-usage.mdx
+++ b/src/pages/docs/liveobjects/rest-api-usage.mdx
@@ -13,7 +13,7 @@ LiveObjects provides a comprehensive REST API that enables you to directly work
## Authentication
-View the REST API [authentication](/docs/api/rest-api#authentication) documentation for details on how to authenticate your requests.
+View the REST API [authentication](/docs/api/liveobjects-rest#authentication) documentation for details on how to authenticate your requests.
To use LiveObjects, an API key must have at least the `object-subscribe` capability. With only this capability, clients will have read-only access, preventing them from publishing operations.
@@ -807,7 +807,7 @@ The following example increments two distinct `LiveCounter` instances in a singl
## Idempotent operations
-Publish operations idempotently by specifying an `id` for the operation message, using the same approach as [idempotent message publishing](/docs/api/rest-api#idempotent-publish):
+Publish operations idempotently by specifying an `id` for the operation message, using the same approach as [idempotent message publishing](/docs/api/liveobjects-rest#idempotent-publish):
```shell
diff --git a/src/pages/docs/livesync/mongodb/index.mdx b/src/pages/docs/livesync/mongodb/index.mdx
index 2939fb868a..24d35dc975 100644
--- a/src/pages/docs/livesync/mongodb/index.mdx
+++ b/src/pages/docs/livesync/mongodb/index.mdx
@@ -8,7 +8,7 @@ Use the MongoDB database connector to distribute document changes from a MongoDB
The MongoDB database connector utilizes the MongoDB [change streams](https://www.mongodb.com/docs/v8.0/changeStreams/) feature to distribute changes from the database to clients over Ably Pub/Sub channels.
-By using Ably Pub/Sub channels and SDKs, clients subscribing to messages published by the MongoDB database connector benefit from features like [connection-recovery](/docs/connect/states), [exactly-once delivery](/docs/achieving-exactly-once-message-processing-with-ably) and [ordering guarantees](https://faqs.ably.com/reliable-message-ordering-for-connected-clients) out of the box.
+By using Ably Pub/Sub channels and SDKs, clients subscribing to messages published by the MongoDB database connector benefit from features like [connection-recovery](/docs/connect/states), [exactly-once delivery](/docs/platform/architecture/idempotency) and [ordering guarantees](https://faqs.ably.com/reliable-message-ordering-for-connected-clients) out of the box.

diff --git a/src/pages/docs/livesync/postgres/index.mdx b/src/pages/docs/livesync/postgres/index.mdx
index 5567b410f9..91cd03eee8 100644
--- a/src/pages/docs/livesync/postgres/index.mdx
+++ b/src/pages/docs/livesync/postgres/index.mdx
@@ -111,8 +111,8 @@ The Postgres database connector automatically listens for new records written to
The following describes the key columns in the outbox table:
- `channel`: the name of the channel the outbox record will be published to.
-- `name`: the [name](/docs/channels/messages#properties) given to the message.
-- `data`: the [data](/docs/channels/messages#properties) carried in the message.
+- `name`: the [name](/docs/messages#properties) given to the message.
+- `data`: the [data](/docs/messages#properties) carried in the message.
- `mutation_id` is the identifier for the mutation. Required for use with [frontend data models](/docs/livesync/postgres/models) and [optimistic updates](/docs/livesync/postgres/models#optimistic-updates).
The following table describes the full schema of the outbox table in your database:
diff --git a/src/pages/docs/livesync/postgres/models.mdx b/src/pages/docs/livesync/postgres/models.mdx
index 0801e0391a..b674a248e8 100644
--- a/src/pages/docs/livesync/postgres/models.mdx
+++ b/src/pages/docs/livesync/postgres/models.mdx
@@ -9,7 +9,7 @@ The Models SDK extends the capability of the LiveSync Postgres database connecto
## How it works
-The Models SDK is a standalone SDK built on [Ably's JavaScript SDK](/docs/getting-started/setup). It sits in your frontend applications and helps manage the state updates based on events streamed by the Postgres database connector via Ably channels.
+The Models SDK is a standalone SDK built on [Ably's JavaScript SDK](/docs/getting-started). It sits in your frontend applications and helps manage the state updates based on events streamed by the Postgres database connector via Ably channels.
A `model` in the Models SDK is a data model representation of a specific part of the frontend application. Each frontend client can have multiple data `models` within the same application.
@@ -37,7 +37,7 @@ API keys and tokens have a set of [capabilities](/docs/auth/capabilities) assign
## Install
-The Models SDK requires a realtime client created using the [Ably JavaScript SDK](/docs/getting-started/setup) to interact with the Ably service.
+The Models SDK requires a realtime client created using the [Ably JavaScript SDK](/docs/getting-started) to interact with the Ably service.
Install the Ably JavaScript SDK and the Models SDK from [NPM](https://www.npmjs.com):
@@ -162,7 +162,7 @@ Your backend should return the largest value of the `sequence_id` column from yo
Internally, the SDK replays change events starting from the point indicated by the `sequenceId` to update the model state with any realtime changes occurring since the state was read from the database.
-The `sequenceId` is automatically maintained within the [outbox table](/docs/livesync/postgres/postgres-connector#outbox-table). You can safely read the sequenceId and the initial state of your model within a database transaction using the `read committed` transaction isolation level (or greater). This guarantees a consistent view of the state across the database and Ably channel. Postgres uses [`read committed`](https://www.postgresql.org/docs/17/transaction-iso.html#XACT-READ-COMMITTED) by default.
+The `sequenceId` is automatically maintained within the [outbox table](/docs/livesync/postgres#outbox-table). You can safely read the sequenceId and the initial state of your model within a database transaction using the `read committed` transaction isolation level (or greater). This guarantees a consistent view of the state across the database and Ably channel. Postgres uses [`read committed`](https://www.postgresql.org/docs/17/transaction-iso.html#XACT-READ-COMMITTED) by default.
```sql
diff --git a/src/pages/docs/livesync/postgres/quickstart.mdx b/src/pages/docs/livesync/postgres/quickstart.mdx
index 525dff7fdd..726a6f83af 100644
--- a/src/pages/docs/livesync/postgres/quickstart.mdx
+++ b/src/pages/docs/livesync/postgres/quickstart.mdx
@@ -132,7 +132,7 @@ setModel(model);
The sync function is used by the Models SDK to fetch the latest data from your backend to hydrate the application initially upon load. There are two objects returned within the response:
-- [`sequenceId`](/docs/livesync/models#sequence-id), which is used to identify the point in the stream of change events that corresponds to the current version of the database's state.
+- [`sequenceId`](/docs/livesync/postgres/models#sequence-id), which is used to identify the point in the stream of change events that corresponds to the current version of the database's state.
- The data relevant to the expected data model, in this instance, it's the current state of the post defined by its `id`. In this example, the sync function called is [`getPost`](https://github.com/ably-labs/live-comments/lib/models/hook.ts#L11-L29), which is found in the `/lib/models/hook.ts` file of the repository you cloned.
@@ -213,7 +213,7 @@ There are two parts of the backend that are key for the LiveSync integration in
#### The sync function
-The sync function in the backend is an endpoint of a `GET` request, which returns the [`sequenceId`](/docs/livesync/models#sequence-id), used to identify the point in the stream of change events that corresponds to the current version of the database's state. This [endpoint](https://github.com/ably-labs/live-comments/app/docs/api/posts/%5Bid%5D/route.ts#L5-L18) also returns the current state of the data relevant to the expected data model, in this instance, it's the current state of the post defined by its `id`.
+The sync function in the backend is an endpoint of a `GET` request, which returns the [`sequenceId`](/docs/livesync/postgres/models#sequence-id), used to identify the point in the stream of change events that corresponds to the current version of the database's state. This [endpoint](https://github.com/ably-labs/live-comments/app/docs/api/posts/%5Bid%5D/route.ts#L5-L18) also returns the current state of the data relevant to the expected data model, in this instance, it's the current state of the post defined by its `id`.
```javascript
@@ -258,5 +258,5 @@ export async function withOutboxWrite(
This quickstart introduced the basic concepts of LiveSync and provided a quick demo to illustrate how LiveSync works. The next steps are to:
-* Read more about [LiveSync Models](/docs/livesync/models).
+* Read more about [LiveSync Models](/docs/livesync/postgres/models).
* Find out more about the [Database Connector](/docs/livesync/postgres).
diff --git a/src/pages/docs/metadata-stats/stats.mdx b/src/pages/docs/metadata-stats/stats.mdx
index 1d3206f039..87df7857cb 100644
--- a/src/pages/docs/metadata-stats/stats.mdx
+++ b/src/pages/docs/metadata-stats/stats.mdx
@@ -634,7 +634,7 @@ Connection metrics include all realtime [connections](/docs/connect) made to Abl
| **connections.all.min** | Minimum connection count. |
| **connections.all.mean** | Mean connection count. |
| **connections.all.opened** | Total number of connections opened. |
-| **connections.all.refused** | Total number of connections refused, for example for exceeding the [connection creation rate](/docs/platform/pricing/limits/connection). |
+| **connections.all.refused** | Total number of connections refused, for example for exceeding the [connection creation rate](/docs/platform/pricing/limits#connection). |
### Channels
diff --git a/src/pages/docs/platform/account/app/queues.mdx b/src/pages/docs/platform/account/app/queues.mdx
index 82a351ebca..4503803ca1 100644
--- a/src/pages/docs/platform/account/app/queues.mdx
+++ b/src/pages/docs/platform/account/app/queues.mdx
@@ -29,6 +29,6 @@ When provisioning a new queue, you'll need to specify several things:
### Set up queue rules
-Once you have provisioned a physical queue, you need to set up one or more queue rules to republish messages, presence events or channel events from pub/sub channels into a queue. Queue rules can either be used to publish to internal queues (hosted by Ably) or external external streams or queues (such as Amazon Kinesis and RabbitMQ). Publishing to external streams or queues is part of our [Ably Firehose servers](/docs/general/firehose).
+Once you have provisioned a physical queue, you need to set up one or more queue rules to republish messages, presence events or channel events from pub/sub channels into a queue. Queue rules can either be used to publish to internal queues (hosted by Ably) or external external streams or queues (such as Amazon Kinesis and RabbitMQ). Publishing to external streams or queues is part of our [Ably Firehose servers](/docs/platform/integrations/streaming).
Ably queue rules are setup in the **Integrations** tab found within your app **dashboard**. Find out more about setting up [queue rules](/docs/platform/integrations/queues#setup).
diff --git a/src/pages/docs/platform/account/organizations.mdx b/src/pages/docs/platform/account/organizations.mdx
index 18691f1446..0d76dbbaa0 100644
--- a/src/pages/docs/platform/account/organizations.mdx
+++ b/src/pages/docs/platform/account/organizations.mdx
@@ -10,7 +10,7 @@ Use organizations to manage multiple Ably accounts by centralizing user access a
Organizations enable the [primary](#primary) account to assign and adjust the roles of users and groups across all accounts.
-You can separate accounts within an organization to create isolated environments, such as production, staging, and development. Assign each environment a [package](/docs/pricing#packages) that meets its specific needs. For example, production may need high capacity with an **Enterprise** package, staging might use a **Standard** package, and development a **Free** package.
+You can separate accounts within an organization to create isolated environments, such as production, staging, and development. Assign each environment a [package](/docs/platform/pricing#packages) that meets its specific needs. For example, production may need high capacity with an **Enterprise** package, staging might use a **Standard** package, and development a **Free** package.
An [Enterprise](/docs/platform/pricing/enterprise) account is required to use organizations. [Contact us](https://ably.com/support) to enable organizations for your account.
diff --git a/src/pages/docs/platform/ai-llms/index.mdx b/src/pages/docs/platform/ai-llms/index.mdx
index 42a03a8203..656541511d 100644
--- a/src/pages/docs/platform/ai-llms/index.mdx
+++ b/src/pages/docs/platform/ai-llms/index.mdx
@@ -22,7 +22,7 @@ These markdown versions strip out navigation and UI elements, providing clean co
### llms.txt
-The [`llms.txt`](/docs/ai-llms/llms-txt) file provides a complete index of all documentation pages, organized by product category. Access it at:
+The [`llms.txt`](/docs/platform/ai-llms/llms-txt) file provides a complete index of all documentation pages, organized by product category. Access it at:
```text
diff --git a/src/pages/docs/platform/errors/codes.mdx b/src/pages/docs/platform/errors/codes.mdx
index 0e6eb53a13..acac0bd4e4 100644
--- a/src/pages/docs/platform/errors/codes.mdx
+++ b/src/pages/docs/platform/errors/codes.mdx
@@ -73,7 +73,7 @@ Examples of this error are when:
## 40009: Maximum message length exceeded
-This error occurs when the message being published exceeds the maximum size allowed set by the [limits](/docs/platform/pricing/limits#app-limits) for your current [package](/docs/pricing#packages).
+This error occurs when the message being published exceeds the maximum size allowed set by the [limits](/docs/platform/pricing/limits#app-limits) for your current [package](/docs/platform/pricing#packages).
## 40010: Invalid channel name
@@ -272,7 +272,7 @@ This error occurs when the peak [connection limit](/docs/platform/pricing/limits
## 40112: Account blocked (message limits exceeded)
-This error occurs when your account has exceeded the allocated [message limit](/docs/platform/pricing/limits#message) based on your [package](/docs/pricing#packages). Once this limit is reached, further message publishing is blocked.
+This error occurs when your account has exceeded the allocated [message limit](/docs/platform/pricing/limits#message) based on your [package](/docs/platform/pricing#packages). Once this limit is reached, further message publishing is blocked.
## 40114: Account-wide peak channel limit exceeded
@@ -284,7 +284,7 @@ Resolution: Detach unused channels to free up space for new ones.
## 40115: Account restricted (request limit exceeded)
-This error occurs when your account has exceeded the allocated [limits](/docs/platform/pricing/limits) based on your [package](/docs/pricing#packages).
+This error occurs when your account has exceeded the allocated [limits](/docs/platform/pricing/limits) based on your [package](/docs/platform/pricing#packages).
## 40125: Maximum number of rules per application exceeded
@@ -375,7 +375,7 @@ Resolution: The following steps can help resolve this issue:
## 40171: No means provided to renew auth token
-This error occurs when no [`authUrl`](/docs/auth/token#auth-url) or [`authCallback`](/docs/auth/token#auth-callback) is provided in [`clientOptions`](/docs/getting-started/setup#options) when initializing the Ably REST or Realtime SDK.
+This error occurs when no [`authUrl`](/docs/auth/token#auth-url) or [`authCallback`](/docs/auth/token#auth-callback) is provided in [`clientOptions`](/docs/getting-started#options) when initializing the Ably REST or Realtime SDK.
Tokens have a set expiration time, and once expired, they are no longer valid for communication with Ably. If `authUrl` or `authCallback` is configured, the SDK will automatically request a new token before expiration, ensuring uninterrupted operation.
@@ -424,7 +424,7 @@ An example of this error is when a client attempts to connect to an Ably app res
Resolution: The following steps can help resolve this issue:
* Ensure you are configured with the correct environment for your [region-restricted](https://faqs.ably.com/do-you-have-an-option-to-keep-my-data-in-europe-or-the-united-states) account.
-* If your account has a regional constraint, you should have been provided with a [custom](/docs/platform/account/enterprise-customization#setting-up-a-custom-environment) environment to pass to the [`ClientOptions`](/docs/getting-started/setup#options).
+* If your account has a regional constraint, you should have been provided with a [custom](/docs/platform/account/enterprise-customization#setting-up-a-custom-environment) environment to pass to the [`ClientOptions`](/docs/getting-started#options).
* Verify that your connection settings match the region assigned to your account.
## 40400: Not found
@@ -715,7 +715,7 @@ This error occurs when the maximum number of [objects](/docs/liveobjects) on the
Resolution:
* Remove any unnecessary objects from the channel to free up space, for example by [removing](/docs/liveobjects/map#remove) any references to them.
-* [Upgrade](/docs/pricing) your package to increase the [limit](/docs/platform/pricing/limits#channel) on the allowed number of objects on the channel.
+* [Upgrade](/docs/platform/pricing) your package to increase the [limit](/docs/platform/pricing/limits#channel) on the allowed number of objects on the channel.
## 92002: Unable to submit operation on tombstone object
diff --git a/src/pages/docs/platform/integrations/inbound/webhooks.mdx b/src/pages/docs/platform/integrations/inbound/webhooks.mdx
index 2cd8085b50..d344618fe9 100644
--- a/src/pages/docs/platform/integrations/inbound/webhooks.mdx
+++ b/src/pages/docs/platform/integrations/inbound/webhooks.mdx
@@ -14,7 +14,7 @@ Many web services generate webhooks to communicate with applications. These webh
Ably also supports [outbound webhooks](/docs/platform/integrations/webhooks), which send data from Ably to other external services such as AWS, Google Cloud Platform or Zapier.
-Webhook messages are subject to rate [limits](/docs/pricing/limits#integrations), similar to REST publishes.
+Webhook messages are subject to rate [limits](/docs/platform/pricing/limits#integrations), similar to REST publishes.
## Configure an incoming webhook
diff --git a/src/pages/docs/platform/integrations/queues.mdx b/src/pages/docs/platform/integrations/queues.mdx
index 3a3414be72..8750aef3c9 100644
--- a/src/pages/docs/platform/integrations/queues.mdx
+++ b/src/pages/docs/platform/integrations/queues.mdx
@@ -82,7 +82,7 @@ A [Dead Letter Queue](#deadletter) is automatically created. It stores messages
Queues cannot be modified after creation because they are immutable. Different settings require creating a new queue and migrating.
-This includes limits like TTL and max length. Even after [upgrading](/docs/account/billing-and-payments#upgrading) an Ably account, existing queues retain the limits they were created with. Replacement is required to get the higher limits from a new plan.
+This includes limits like TTL and max length. Even after [upgrading](/docs/platform/pricing/billing#package-changes) an Ably account, existing queues retain the limits they were created with. Replacement is required to get the higher limits from a new plan.
Steps to switch to a new queue:
diff --git a/src/pages/docs/platform/integrations/streaming/kafka.mdx b/src/pages/docs/platform/integrations/streaming/kafka.mdx
index 537e868d52..7b9d9f9011 100644
--- a/src/pages/docs/platform/integrations/streaming/kafka.mdx
+++ b/src/pages/docs/platform/integrations/streaming/kafka.mdx
@@ -10,7 +10,7 @@ redirect_from:
[Kafka](https://kafka.apache.org/) integrations enable you to automatically forward events that occur in Ably to Kafka topics.
-If you want to send data from Kafka to Ably, you can use the [Ably Kafka Connector.](/docs/general/kafka-connector)
+If you want to send data from Kafka to Ably, you can use the [Ably Kafka Connector.](/docs/platform/integrations/inbound/kafka-connector)
## Create a Kafka integration
diff --git a/src/pages/docs/platform/integrations/streaming/pulsar.mdx b/src/pages/docs/platform/integrations/streaming/pulsar.mdx
index a8ba253c5f..9a1c4f1c84 100644
--- a/src/pages/docs/platform/integrations/streaming/pulsar.mdx
+++ b/src/pages/docs/platform/integrations/streaming/pulsar.mdx
@@ -10,7 +10,7 @@ redirect_from:
[Pulsar](https://pulsar.apache.org) integrations enable you to automatically forward events that occur in Ably to Pulsar topics.
-This feature is only available to [enterprise](/docs/pricing/enterprise) packages.
+This feature is only available to [enterprise](/docs/platform/pricing/enterprise) packages.
## Create a Pulsar integration
diff --git a/src/pages/docs/platform/pricing/faqs.mdx b/src/pages/docs/platform/pricing/faqs.mdx
index 70b51c3305..63c9765d42 100644
--- a/src/pages/docs/platform/pricing/faqs.mdx
+++ b/src/pages/docs/platform/pricing/faqs.mdx
@@ -41,7 +41,7 @@ For example, if you have 10,000 users, and at your busiest time of the month the
### How is maximum message size measured?
-Maximum message size is based on the [package type](/docs/pricing#packages). The size is calculated as the sum of the `name`, `clientId`, `data` and `extras` [properties](/docs/api/realtime-sdk/messages#properties) before any compression or expansion occurs in the serialization process.
+Maximum message size is based on the [package type](/docs/platform/pricing#packages). The size is calculated as the sum of the `name`, `clientId`, `data` and `extras` [properties](/docs/api/realtime-sdk/messages#properties) before any compression or expansion occurs in the serialization process.
* `name` and `clientId` are calculated as the size in bytes of their UTF-8 representation.
* `data` is calculated as the size in bytes if it is in binary, or its UTF-8 byte length if it is a string.
diff --git a/src/pages/docs/presence-occupancy/presence.mdx b/src/pages/docs/presence-occupancy/presence.mdx
index 0821f8d34c..4251c2518c 100644
--- a/src/pages/docs/presence-occupancy/presence.mdx
+++ b/src/pages/docs/presence-occupancy/presence.mdx
@@ -619,7 +619,7 @@ Enabling [server-side batching](/docs/messages/batch#server-side) for a channel
The interval over which this batching occurs is configurable. The trade-off between cost efficiency and user experience is appropriate, as a higher interval will increase the latency between message deliveries. This is usually less impactful to user experience for presence events than for regular messages.
-Using server-side batching for presence events can reduce message costs when the membership of a channel is constantly changing. It also allows for a higher number of presence members per channel to be supported. By default, the number of presence members per channel is [limited](/docs/platform/pricing/limits#channel) to 200. With server-side batching enabled, this increases up to 20,000 clients depending on your [package type](/docs/pricing).
+Using server-side batching for presence events can reduce message costs when the membership of a channel is constantly changing. It also allows for a higher number of presence members per channel to be supported. By default, the number of presence members per channel is [limited](/docs/platform/pricing/limits#channel) to 200. With server-side batching enabled, this increases up to 20,000 clients depending on your [package type](/docs/platform/pricing).
### Be present without subscribing to presence events
diff --git a/src/pages/docs/protocols/sse.mdx b/src/pages/docs/protocols/sse.mdx
index 173bda2338..4d36c09dcf 100644
--- a/src/pages/docs/protocols/sse.mdx
+++ b/src/pages/docs/protocols/sse.mdx
@@ -57,9 +57,9 @@ eventSource.onmessage = function(event) {
## Authentication
-Authentication with SSE allows for two methods: [basic auth](/docs/auth/basic) using an [API key](/docs/getting-started/setup) or [token auth](/docs/auth/token), using a token from your server. For enhanced security and control over connections, token auth is recommended for client-side use. Basic auth is simpler as it omits the need for an auth server and the potential need for clients to refresh expired tokens.
+Authentication with SSE allows for two methods: [basic auth](/docs/auth/basic) using an [API key](/docs/getting-started) or [token auth](/docs/auth/token), using a token from your server. For enhanced security and control over connections, token auth is recommended for client-side use. Basic auth is simpler as it omits the need for an auth server and the potential need for clients to refresh expired tokens.
-It is possible to use either [basic auth](/docs/auth/basic), with an [API key](/docs/getting-started/setup), or [token auth](/docs/auth/token), with a [token issued from your server](/docs/auth/token), with SSE. It's recommended to use token auth on the client side for [security reasons](/docs/auth), so you have control over who can connect. Basic auth, while lacking this control, is simpler (it doesn't require you to run an auth server), and you don't have to worry about the client obtaining a new token when the old one expires.
+It is possible to use either [basic auth](/docs/auth/basic), with an [API key](/docs/getting-started), or [token auth](/docs/auth/token), with a [token issued from your server](/docs/auth/token), with SSE. It's recommended to use token auth on the client side for [security reasons](/docs/auth), so you have control over who can connect. Basic auth, while lacking this control, is simpler (it doesn't require you to run an auth server), and you don't have to worry about the client obtaining a new token when the old one expires.
If using basic auth, you can use a querystring parameter of `key` or an `Authorization: Basic ` header. If using token auth, you can use an `accessToken` querystring parameter or an `Authorization: Bearer ` header. See [REST API authentication](/docs/auth) for more information.
@@ -169,7 +169,7 @@ You can subscribe to messages in delta mode, using the SSE transport, as follows
eventSource.onmessage = function(event) {
/* event.data is JSON-encoded Ably Message
- (see https://ably.com/docs/docs/realtime/types#message) */
+ (see https://ably.com/docs/api/realtime-sdk/types#message) */
var message = JSON.parse(event.data);
var { id, extras } = message;
var { data } = message;
diff --git a/src/pages/docs/push/configure/device.mdx b/src/pages/docs/push/configure/device.mdx
index d3a740ecb1..199e06c03c 100644
--- a/src/pages/docs/push/configure/device.mdx
+++ b/src/pages/docs/push/configure/device.mdx
@@ -543,7 +543,7 @@ private ClientOptions GetAblyOptions(string clientId)
#### Test your push notification activation
-* Use the Ably [dashboard](https://ably.com/accounts) or [API](https://ably.com/docs/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered device.
+* Use the Ably [dashboard](https://ably.com/accounts) or [API](/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered device.
* Ensure your application correctly receives and handles the push notification.
@@ -624,7 +624,7 @@ This approach allows:
#### Test your push notification activation
-* Use the Ably [dashboard](https://ably.com/accounts) or [API](https://ably.com/docs/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered device.
+* Use the Ably [dashboard](https://ably.com/accounts) or [API](/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered device.
* Ensure your application correctly receives and handles the push notification.
diff --git a/src/pages/docs/push/configure/web.mdx b/src/pages/docs/push/configure/web.mdx
index 6cd825a669..40c7a558af 100644
--- a/src/pages/docs/push/configure/web.mdx
+++ b/src/pages/docs/push/configure/web.mdx
@@ -19,7 +19,7 @@ Configuration is the first step in setting up push notifications with Ably. This
The following steps configure a web browser for push notifications using the Ably JavaScript SDK:
* **Generate a VAPID (Voluntary Application Server Identification) Key:**
- * When you first activate a web browser using the Ably JavaScript [SDK](https://ably.com/docs/getting-started/setup), Ably automatically creates a VAPID key pair for your application.
+ * When you first activate a web browser using the Ably JavaScript [SDK](/docs/getting-started), Ably automatically creates a VAPID key pair for your application.
* Ably will then use the same VAPID key pair for all subsequent activations in the same application.
* **Service Worker Setup:**
* You must host a [service worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) to use to push messages.
@@ -171,7 +171,7 @@ ably.push.deactivate(async (deviceDetails, callback) => {
#### Test your push notification activation
-* Use the Ably [dashboard](https://ably.com/accounts) or [API](https://ably.com/docs/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered browser.
+* Use the Ably [dashboard](https://ably.com/accounts) or [API](/docs/api/realtime-sdk/push-admin) to send a test push notification to a registered browser.
* Ensure your application correctly receives and handles the push notification.
### Browser activation lifecycle
diff --git a/src/pages/docs/push/index.mdx b/src/pages/docs/push/index.mdx
index 637909cff7..9fbe5b7fe6 100644
--- a/src/pages/docs/push/index.mdx
+++ b/src/pages/docs/push/index.mdx
@@ -21,7 +21,7 @@ You can publish push notifications to user devices or browsers [directly](/docs/
Publishing directly sends push notifications to specific devices or browsers identified by unique identifiers, such as a `deviceId` or a `clientId`. This approach is akin to sending a personal message or alerts directly to an individual user's device or browser, bypassing the need for channel subscriptions. It excels in targeted and personalized communications, such as alerts specific to a user's actions, account notifications, or customized updates.
-Publishing via channels uses a [Pub/Sub](/docs/channels/messages) model. Messages are sent to channels to which multiple devices or browsers can subscribe. When a message is published to a channel, all devices or browsers subscribed to that channel receive the notification. This approach is particularly powerful for simultaneously publishing messages to multiple users.
+Publishing via channels uses a [Pub/Sub](/docs/messages) model. Messages are sent to channels to which multiple devices or browsers can subscribe. When a message is published to a channel, all devices or browsers subscribed to that channel receive the notification. This approach is particularly powerful for simultaneously publishing messages to multiple users.
Push subscriptions do not count toward your connection limit since devices don't need to maintain an active connection to receive push notifications. However, publishing push notifications via channels does activate those channels, so your concurrent peak channel count will equal the number of channels you publish to simultaneously.
@@ -53,7 +53,7 @@ Publish push notifications using Ably via [channels](/docs/push/publish#channel-
* Publishing directly allows for the delivery of push notifications straight to individual devices or browsers. This process is beneficial for targeting a specific device or browser using a unique [`deviceId`](/docs/push/publish#device-id), [`clientId`](/docs/push/publish#client-id), or [`recipient`](#recipient). Direct publishing is akin to sending a personal, targeted message to a user's device or browser.
-* Publishing via channels operates similarly to Ably's [Pub/Sub](/docs/channels/messages) messaging model, broadcasting notifications to all channel subscribers. This process leverages Ably [channels](/docs/channels) to distribute push notifications efficiently to all devices or browsers subscribed to those channels. It is ideal for scenarios where the same information, such as alerts or updates, needs to be sent to multiple users.
+* Publishing via channels operates similarly to Ably's [Pub/Sub](/docs/messages) messaging model, broadcasting notifications to all channel subscribers. This process leverages Ably [channels](/docs/channels) to distribute push notifications efficiently to all devices or browsers subscribed to those channels. It is ideal for scenarios where the same information, such as alerts or updates, needs to be sent to multiple users.
#### Subscribe
diff --git a/src/pages/docs/spaces/space.mdx b/src/pages/docs/spaces/space.mdx
index e544e70d21..f794c9602e 100644
--- a/src/pages/docs/spaces/space.mdx
+++ b/src/pages/docs/spaces/space.mdx
@@ -130,7 +130,7 @@ The following events will trigger a space event:
Space state contains a single object called `members`. Any events that trigger a change in space state will always return the current state of the space as an array of `member` objects.
-[Avatar stacks](/docs/spaces/avatar) and [member location](/docs/spaces/locations) events can be subscribed to on their individual namespaces; `space.members` and `space.locations`. These events are filtered versions of space state events. Only a single [message](/docs/channels/messages) is published per event by Ably, irrespective of whether you register listeners for space state or individual namespaces. If you register listeners for both, it is still only a single message.
+[Avatar stacks](/docs/spaces/avatar) and [member location](/docs/spaces/locations) events can be subscribed to on their individual namespaces; `space.members` and `space.locations`. These events are filtered versions of space state events. Only a single [message](/docs/messages) is published per event by Ably, irrespective of whether you register listeners for space state or individual namespaces. If you register listeners for both, it is still only a single message.
The key difference between subscribing to space state or to individual feature events is that space state events return the current state of the space as an array of all members in each event payload. Individual member and location event payloads only include the relevant data for the member that triggered the event.