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

# SDK Setup

Use these instructions to install, authenticate and instantiate the Chat SDK.

<Aside data-type="note">
  If you have any feedback or feature requests, [let us know](https://forms.gle/SmCLNFoRrYmkbZSf8)
</Aside>

## Authentication

<Aside data-type="important">
  Client-side applications must use [JWT authentication](/docs/auth/token/jwt). API keys should never be exposed in client-side code because they don't expire and cannot be scoped to specific users.
</Aside>

Chat requires an authenticated client with a `clientId` to identify users. The recommended approach is:

1. **Client-side apps** (browsers, iOS, Android): Use [JWT authentication](/docs/auth/token/jwt) with `authCallback` to fetch JWTs from your server
2. **Server-side apps** (Node.js, Python, etc.): Use your API key directly

[Sign up](https://ably.com/sign-up) to Ably to create an API key in the [dashboard](https://ably.com/dashboard) or use the [Control API](/docs/platform/account/control-api) to create an API key programmatically.

## Install

The Chat SDK is built on top of the Ably Pub/Sub SDK and uses that to establish a connection with Ably.

<Tabs>
  <Tab name="JavaScript / TypeScript">
    Install the Pub/Sub SDK and the Chat SDK:

    <Code>
      ```shell theme={null}
      npm install ably @ably/chat
      ```
    </Code>

    Import the SDKs into your project:

    <Code>
      ```javascript theme={null}
      import * as Ably from 'ably';
      import { ChatClient } from '@ably/chat';
      ```
    </Code>
  </Tab>

  <Tab name="React">
    Install the Pub/Sub SDK and the Chat SDK:

    <Code>
      ```shell theme={null}
      npm install ably @ably/chat
      ```
    </Code>

    Import the SDKs into your project:

    <Code>
      ```react theme={null}
      import * as Ably from 'ably';
      import { ChatClient } from '@ably/chat';
      import { ChatClientProvider } from '@ably/chat/react';
      ```
    </Code>
  </Tab>

  <Tab name="Swift">
    The SDK is distributed as a Swift Package. Install using Xcode or by adding it as a dependency in your package's `Package.swift`:

    <Code>
      ```swift theme={null}
      .package(url: "https://github.com/ably/ably-chat-swift", from: "1.0.0"),
      ```
    </Code>

    Import the SDK:

    <Code>
      ```swift theme={null}
      import AblyChat
      ```
    </Code>
  </Tab>

  <Tab name="Android / Kotlin">
    Add the dependency to your `build.gradle.kts` file:

    <Code>
      ```android theme={null}
      implementation("com.ably.chat:chat:1.2.0")
      implementation("com.ably.chat:chat-extensions-compose:1.2.0")
      ```
    </Code>
  </Tab>
</Tabs>

## Instantiate a Client

Authentication is configured on the Ably Pub/Sub client, which the Chat client wraps. The Chat SDK itself doesn't handle authentication directly - it uses the authenticated connection from the underlying Pub/Sub client.

### Client-side Authentication (Recommended)

Use token authentication for browsers and mobile apps:

<Tabs>
  <Tab name="JavaScript">
    <Code>
      ```javascript theme={null}
      import { LogLevel } from '@ably/chat'

      const realtimeClient = new Ably.Realtime({
        authCallback: async (tokenParams, callback) => {
          try {
            const response = await fetch('/api/ably-token');
            const token = await response.text();
            callback(null, token);
          } catch (error) {
            callback(error, null);
          }
        },
      });
      const chatClient = new ChatClient(realtimeClient, { logLevel: LogLevel.Error });
      ```
    </Code>
  </Tab>

  <Tab name="React">
    <Code>
      ```react theme={null}
      import { LogLevel } from '@ably/chat'

      const realtimeClient = new Ably.Realtime({
        authCallback: async (tokenParams, callback) => {
          try {
            const response = await fetch('/api/ably-token');
            const token = await response.text();
            callback(null, token);
          } catch (error) {
            callback(error, null);
          }
        },
      });
      const chatClient = new ChatClient(realtimeClient, { logLevel: LogLevel.Error });

      const App = () => {
        return (
          <ChatClientProvider client={chatClient}>
            <RestOfYourApp />
          </ChatClientProvider>
        );
      };
      ```
    </Code>
  </Tab>

  <Tab name="Swift">
    <Code>
      ```swift theme={null}
      let realtimeOptions = ARTClientOptions()
      realtimeOptions.authCallback = { tokenParams, callback in
          fetchAblyToken { result in
              switch result {
              case .success(let tokenRequest):
                  callback(tokenRequest, nil)
              case .failure(let error):
                  callback(nil, error)
              }
          }
      }
      let realtime = ARTRealtime(options: realtimeOptions)
      let chatClient = ChatClient(realtime: realtime)
      ```
    </Code>
  </Tab>

  <Tab name="Android / Kotlin">
    <Code>
      ```android theme={null}
      val realtimeClient = AblyRealtime(
          ClientOptions().apply {
              authCallback = { tokenParams, callback ->
                  fetchAblyToken { result ->
                      result.onSuccess { tokenRequest ->
                          callback.onSuccess(tokenRequest)
                      }
                      result.onFailure { error ->
                          callback.onError(ErrorInfo(error.message, 40000, 401))
                      }
                  }
              }
          },
      )

      val chatClient = ChatClient(realtimeClient)
      ```
    </Code>
  </Tab>
</Tabs>

### Server-side Authentication

For server-side applications or local development, you can use an API key directly:

<Code>
  ```javascript theme={null}
  // Server-side only: API key authentication
  // WARNING: Never use this in client-side code
  import { LogLevel } from '@ably/chat'

  const realtimeClient = new Ably.Realtime({
    key: process.env.ABLY_API_KEY,
    clientId: 'server-process-1',
  });
  const chatClient = new ChatClient(realtimeClient, { logLevel: LogLevel.Error });
  ```
</Code>

<Aside data-type="important">
  API key authentication should only be used server-side. For client-side apps, always use token authentication instead.
</Aside>

## Next Steps

* Learn about [authentication](/docs/chat/authentication)
* Understand [connections](/docs/chat/connections)
* Start building with [rooms](/docs/chat/rooms)
