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

# App sign-in

> Sign end users into a portal (or other signed-in experience) with phone OTP through Core

## Overview

Core always assigns an anonymous **app user ID** for tracking — no login required. Use this page when
end users sign into a **portal** or another experience where they should have an account, and you want
Embeddables to treat them as authenticated app users — not operator or admin login.

Today that usually means a customer-facing **portal**; the API lives on Core so other SDKs can reuse the
same phone OTP flow.

Anonymous identity keeps working alongside sign-in. While someone is logged in, use their authenticated
id for work that should follow the account; [`useAppUserId()`](/sdks/core/reference#hooks) still returns
the device id.

Phone OTP runs through `embeddables.auth` on the same Core instance you already initialized — see
[Overview & setup](/sdks/core/overview) first.

## Sign-in flow

<Tabs>
  <Tab title="JavaScript">
    ```typescript lines theme={null}
    await embeddables.auth.requestOtp({ phone: '+15551234567' })

    const session = await embeddables.auth.verifyOtp({
      phone: '+15551234567',
      token: '123456',
    })
    session.app_user_id

    embeddables.auth.getEffectiveUserId()

    await embeddables.auth.logout()
    ```
  </Tab>

  <Tab title="React">
    Show signed-in UI with hooks:

    ```tsx lines theme={null}
    import { useIsAuthenticated, useAuthenticatedUserId } from '@embeddables/core/react'

    function Account() {
      const isAuthenticated = useIsAuthenticated()
      const authenticatedUserId = useAuthenticatedUserId()

      if (!isAuthenticated) return <SignInForm />
      return <p>Signed in as {authenticatedUserId}</p>
    }
    ```

    Call `requestOtp`, `verifyOtp`, and `logout` on the instance from [`useEmbeddables()`](/sdks/core/reference#hooks).
  </Tab>
</Tabs>

<Note>Sandbox publishable keys accept passcode `0000`.</Note>

Optional `auth` settings on [`initEmbeddables`](/sdks/core/reference#init) (`sandboxUser`, `apiUrl`) are
documented in the Reference. Live vs sandbox follows your publishable key.

## Reference

Method and hook details — [`auth`](/sdks/core/reference#methods), [`useIsAuthenticated()`](/sdks/core/reference#hooks), and [`useAuthenticatedUserId()`](/sdks/core/reference#hooks) — are in the [Core reference](/sdks/core/reference#methods).
