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

# Sign in with Text

> Add a ready-to-use Text login flow to your web app using the Accounts SDK.

**Sign in with Text** is a ready-to-use login flow built with the [Accounts SDK](#accounts-sdk). It lets you:

* Get the Text user's email, account ID, or organization ID.
* Receive an `access_token` for API calls, using the implicit grant.
* Receive a `code` for the authorization code grant with PKCE, which you then exchange for `access_token` and `refresh_token`.

Because an OAuth client can only authorize accounts in the organization that created it, Sign in with Text fits an internal tool your own team signs in to — for example, an internal dashboard or browser extension — rather than a public login button for arbitrary Text customers.

Users start the flow by clicking a **Sign in with Text** button. If they aren't signed in, they're asked to sign in, then to grant your app access to the scopes you configured. Depending on how you initialize the SDK, your app then receives either an `access_token` (implicit grant) or a `code` you exchange for `access_token` and `refresh_token` (authorization code grant with PKCE).

## Implementing Sign in with Text

### Step 1: Create an OAuth client

Go to [Settings → API access → OAuth clients](https://www.text.com/app/settings/integrations/api-access/oauth-clients) and create a new OAuth client. Configure:

* **Display name** — a name to identify your OAuth client.
* **Redirect URI whitelist** — the exact URL of the page where users click **Sign in with Text**. The button doesn't work with any other URL.
* **Access scopes** — the scopes your app needs. See [OAuth scopes](/docs/authentication/scopes) for the full list.

### Step 2: Install the SDK

```bash title="NPM module installation" theme={null}
npm install --save @livechat/accounts-sdk
```

```js title="NPM module import" theme={null}
import AccountsSDK from "@livechat/accounts-sdk";
```

### Step 3: Add the login button

```html theme={null}
<button id="login-button" style="background: url(.../livechat_sign_in.png)">
  Sign in with Text
</button>
```

By default, the SDK requests an `access_token` directly (the implicit grant):

```js title="Handle the login button click" theme={null}
const instance = new AccountsSDK({
  client_id: "<your_app_client_id>",
  redirect_uri: "<your_app_redirect_uri>",
});

document.getElementById("login-button").onclick = (e) => {
  if (e && e.preventDefault) {
    e.preventDefault();
  }

  instance
    .popup()
    .authorize()
    .then((authorizeData) => {
      const transactionData = instance.verify(authorizeData);
      if (transactionData === null) {
        console.log("Redirect state doesn't match the previous one");
        return;
      }
      // Use authorizeData.access_token to call Text APIs — avoid logging it.
      document.getElementById("login-button").style.display = "none";
    })
    .catch((e) => {
      console.error("Failed to authorize user", e);
    });
};
```

<Tip>
  Use `prompt: "consent"` to force the app to ask for access to certain
  resources again during testing.
</Tip>

To get a refresh token instead, initialize the SDK with `response_type: "code"` and PKCE enabled, then exchange the returned `code` yourself:

```js title="Handle the login button click, with PKCE" theme={null}
const instance = new AccountsSDK({
  client_id: "<your_app_client_id>",
  redirect_uri: "<your_app_redirect_uri>",
  response_type: "code",
  pkce: { enabled: true },
});

document.getElementById("login-button").onclick = (e) => {
  if (e && e.preventDefault) {
    e.preventDefault();
  }

  instance
    .popup()
    .authorize()
    .then((authorizeData) => {
      const transactionData = instance.verify(authorizeData);
      if (transactionData === null) {
        console.log("Redirect state doesn't match the previous one");
        return;
      }

      fetch(instance.options.server_url + "/v2/token", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          grant_type: "authorization_code",
          code: authorizeData.code,
          client_id: instance.options.client_id,
          redirect_uri: instance.options.redirect_uri,
          code_verifier: transactionData.code_verifier,
        }),
      })
        .then((res) => {
          if (!res.ok) {
            throw new Error(`Token exchange failed with status ${res.status}`);
          }
          return res.json();
        })
        .then((tokens) => {
          // Store tokens.access_token and tokens.refresh_token securely — avoid logging them.
          document.getElementById("login-button").style.display = "none";
        })
        .catch((e) => console.error("Failed to exchange code", e));
    })
    .catch((e) => {
      console.error("Failed to authorize user", e);
    });
};
```

See [PKCE support](/docs/sdk/accounts-sdk#pkce-support) in the Accounts SDK reference for the full set of PKCE configuration options.

## Accounts SDK

The Accounts SDK (`@livechat/accounts-sdk`) provides the classes and methods used in the Sign in with Text flow. For the full API reference — including `AccountsSDK`, `Popup`, `Redirect`, PKCE configuration, and response formats — see the [Accounts SDK documentation](/docs/sdk/accounts-sdk).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.