---
title: "EOS accounts and login"
description: "Choose EOS Auth or Connect and sign in with explicit credentials."
seo:
  noindex: true
---

{/* Copyright (c) 2026 Betide Studio. All Rights Reserved. */}

For a shared login flow across providers, use [Sign in players](/crossplay/identity). Use the EOS APIs below when your game needs direct control of EOS authentication.

| You need | Login path | Identity |
| --- | --- | --- |
| Epic friends, presence, or social overlay | Epic Account / Auth | Epic Account ID; game services use the associated Product User ID |
| EOS game services without requiring an Epic account | Connect | Product User ID (PUID) |

These IDs are different. A PUID is not an Epic Account ID, Steam ID, or crossplay player handle.

## Sign in with an Epic account

Complete [EOS setup](/integrations/eos/setup). For an interactive first login, choose **Account Portal**. Create `EosAccount` (EIK Account Id) for the example’s saved account handle.

**Blueprint**

<BlueprintViewer title="Sign in through Account Portal" src="/blueprints/crossplay-eos-epic-login.txt" />

**C++**

Game module dependencies: `EIKCore`, `BetideCore`, `Engine`.

```cpp
#include "Engine/GameInstance.h"
#include "Interfaces/IEIKOnlineServices.h"
#include "Interfaces/IEIKAuth.h"

DEFINE_LOG_CATEGORY_STATIC(LogGameEosLogin, Log, All);

void LoginEpicAccount(UGameInstance &GameInstance)
{
    const auto Services = FEIKOnlineServicesFactory::Get(GameInstance.GetWorld());
    if (!Services)
        return;
    const auto Auth = Services->GetAuthInterface();
    if (!Auth)
        return;
    Auth->Login(0, FEIKLoginCredentials::AccountPortalLogin(),
                FEIKAsyncCallback<FEIKLoginResult>::CreateWeakLambda(
                    &GameInstance, [](const TEIKAsyncResult<FEIKLoginResult> &Result) {
                        if (!Result.IsSuccess())
                        {
                            UE_LOG(LogGameEosLogin, Warning, TEXT("%s"),
                                   *Result.Error.GetLogString());
                            return;
                        }
                        UE_LOG(LogGameEosLogin, Log, TEXT("EOS account ready: %s"),
                               *Result.Result.GetValue().AccountId.ToString());
                    }));
}
```

Try **Persistent Auth** for returning players; fall back to Account Portal if no usable saved authorization exists. C++ uses `FEIKLoginCredentials::PersistentAuthLogin()`. Developer Tool login is for development; launcher exchange codes must come from the current launch.

## Sign in with a platform token

Acquire the credential from its provider first. **Login with EIK Connect Interface** requires an explicit token for every external method; an empty token does not trigger Steam, Google, Apple, or Discord login.

**Blueprint**

<Accordion>
  <AccordionItem title="Connect with a Google ID token">
<BlueprintViewer title="Connect with a Google ID token" src="/blueprints/crossplay-eos-connect-google.txt" />
  </AccordionItem>
  <AccordionItem title="Connect with a device identity">
<BlueprintViewer title="Connect with a device identity" src="/blueprints/crossplay-eos-connect-device.txt" />
  </AccordionItem>
</Accordion>

**C++**

Using the same headers and dependencies:

```cpp
bool LoginEosConnect(UGameInstance &GameInstance, EEIK_EExternalCredentialType CredentialType,
                     const FString &Token, const FString &DisplayName,
                     const FEIKAsyncCallback<FEIKLoginResult> &Completion)
{
    if (Token.IsEmpty())
        return false;
    const auto Services = FEIKOnlineServicesFactory::Get(GameInstance.GetWorld());
    if (!Services)
        return false;
    const auto Auth = Services->GetAuthInterface();
    if (!Auth)
        return false;
    Auth->LoginConnect(
        0, FEIKLoginCredentials::ExternalPlatformLogin(CredentialType, Token, DisplayName),
        Completion);
    return true;
}
```

Use `EIK_ECT_GOOGLE_ID_TOKEN` with the ID token from Google for the first example. Bind `Completion` with `CreateWeakLambda`; the return value only means dispatched. After success, read the Product User ID with `UEIKAuthLibrary::GetProductUserId(&GameInstance)` (`Auth/EIKAuthLibrary.h`, module `EIKBlueprints`).

```cpp
bool LoginEosDevice(UGameInstance &GameInstance, const FString &DisplayName,
                    const FEIKAsyncCallback<FEIKLoginResult> &Completion)
{
    if (DisplayName.IsEmpty())
        return false;
    const auto Services = FEIKOnlineServicesFactory::Get(GameInstance.GetWorld());
    const auto Auth = Services ? Services->GetAuthInterface() : nullptr;
    if (!Auth)
        return false;
    Auth->LoginConnect(0, FEIKLoginCredentials::DeviceIdLogin(DisplayName), Completion);
    return true;
}
```

Choose the credential type that matches the token. [Google ID tokens](/integrations/google/setup-login) are Connect-only in EOS; a Google server authorization code is not an ID token. [Apple](/integrations/apple/setup-login) supplies an identity token, and [Discord](/integrations/discord/setup-login) supplies an access token. Never log credentials.

**Device ID** is the token-free Connect path and needs a display name. Treat it as a device-local starting identity; offer account linking before players depend on access from another device.

## Sign out

**Blueprint**

<BlueprintViewer title="Sign out of EOS" src="/blueprints/crossplay-eos-logout.txt" />

**C++**

```cpp
bool LogoutEos(UGameInstance &GameInstance, const FEIKAsyncCallbackVoid &Completion)
{
    const auto Services = FEIKOnlineServicesFactory::Get(GameInstance.GetWorld());
    if (!Services)
        return false;
    const auto Auth = Services->GetAuthInterface();
    if (!Auth)
        return false;
    Auth->Logout(0, Completion);
    return true;
}
```

Leave active multiplayer and voice flows before signing out. In a game using UCIK identity, use **Logout From Crossplay** so the unified identity state is cleared too.

<Accordion>
  <AccordionItem title="Linking accounts and avoiding duplicate progress">

Use the [Crossplay identity flow](/crossplay/identity) when players choose between an existing account and a new identity. Do not create another Product User ID as a generic recovery action when the player already has progress.

For direct C++ integration, `IEIKAuth::LinkExternalAccount(LocalUserIndex, FEIKConnectCredentials, Completion)` links an external credential to the logged-in user. Supply a fresh provider token. An account already associated with another PUID needs an explicit account-resolution flow; linking is not an automatic merge of saved progress.

  </AccordionItem>
  <AccordionItem title="Diagnose a failed login">

Check the result's error message and code, then the active sandbox/deployment, client policy, token type, and token expiry. Epic social features require an Epic-account login; a successful Connect-only login cannot supply them. Do not start a manual login while configured auto-login is still running.

Use `UEIKAuthLibrary` from `Auth/EIKAuthLibrary.h` (`EIKBlueprints`) for `IsLoggedIn`, `GetEpicAccountId`, and `GetProductUserId`. Resolve services with the current world in C++; a global service lookup can select the wrong PIE player.

  </AccordionItem>
</Accordion>
