> For the complete documentation index, see [llms.txt](https://sdk-doc.tyrads.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sdk-doc.tyrads.com/unity/sdk-integration/3.-user-login.md).

# 3. User Login

Upon initializing the SDK, the mandatory step is to log in the user. However, passing a user ID is optional and is only necessary when the publisher operates its own user system. This login process ensures that user interactions with the offerwall are accurately tracked and attributed within the application.

```csharp
LoginData loginData = new LoginData(userId: "userId"); //userID is optional
_ = await TyrSDKPlugin.Instance.LoginUserAsync(loginData);

```

{% hint style="warning" %}

* If you do not provide a user ID, it will be generated automatically and stored in app storage. In that case, uninstalling the app will erase the ID and the user’s progress.
* **Preferred: supply a backend-controlled, stable user ID (or equivalent) so progress persists across reinstalls and device changes.**&#x20;
  {% endhint %}

To determine when initialization has completed, you can await the login operation and read the relevant data from the returned **LoginResult**:

<pre class="language-csharp"><code class="lang-csharp">LoginData loginData = new LoginData(userId: "userId");
LoginResult result = await TyrSDKPlugin.Instance.LoginUserAsync(loginData);

if (result.IsSuccessful)
{
    //do anything what you want after successful init...
} else
{
    // Handle unsuccessful login.
<strong>    // For example, send result.ErrorCode and result.ErrorMessage
</strong>    // to your analytics service to gain more insight into what went wrong.
}
</code></pre>

{% hint style="info" %}
We strongly recommend handling unsuccessful login attempts and recording the error details for troubleshooting purposes.

When a login request fails, the returned result contains the following properties:

* `ErrorCode` – an error code identifying the reason for the failure.
* `ErrorMessage` – a human-readable description of the error.

These values can be forwarded to your analytics and crash-reporting systems (for example, Firebase Analytics, Firebase Crashlytics, Sentry, etc.). This information can help you diagnose integration issues and provide more details when contacting support.
{% endhint %}

If you don’t set a user ID in LoginUser, you can retrieve the generated user ID after successful initialization by calling the following method:

```csharp
var userId = TyrSDKPlugin.Instance.GetUserId();
```

#### 3.1 Advanced Practices for personalized rewards

{% hint style="warning" %}
To maximize the value to the user sending us more data about the user and where they came from allow us to customize the reward experience. This can be used to provide feedback of quality of users aswell as customize the earnings journey of different segments of users.&#x20;
{% endhint %}

To maximize the value of our Tyr SDK please follow the advanced options for user login. This will allow us to personalize the rewards for the user event further and maximize the earnings for you as publisher.&#x20;

```csharp
var userInfo = new TyradsUserInfo(
    userPhoneNumber: "+1234567890",
    userEmail: "demo@example.com",
    userGroup: "{\"promo_affinity_ratio\": 0.42, \"dynamic_payer_segment\": \"NonPayer\", \"activity_segment\": \"Tier 3\", \"seniority_segment\": \"Tier 4\", \"rewarded_video_watcher_category\": \"High\"}"
);

var mediaSourceInfo = new TyradsMediaSourceInfo(
    mediaSourceName: "Facebook", //mandatory
    mediaCampaignName: "Summer Sale Campaign",
    mediaSourceId: "fb_123",
    mediaSubSourceId: "fb_sub_456",
    incentivized: true,
    mediaAdsetName: "Summer Sale Adset",
    mediaAdsetId: "adset_789",
    mediaCreativeName: "Summer Sale Creative",
    mediaCreativeId: "creative_101",
    sub1: "campaign_source",
    sub2: "ad_group",
    sub3: "creative_type",
    sub4: "placement",
    sub5: "custom_param"
);

var engagementInfo = new TyradsEngagementInfo(
    engagementId: 12345  // Unique identifier for tracking user engagement
);

LoginData loginData = new LoginData("userID", userInfo, mediaSourceInfo, engagementInfo);
LoginResult result = await TyrSDKPlugin.Instance.LoginUserAsync(loginData);
```

[Sending Media Source Data](/getting-started/advanced-options/sending-media-source-data.md)<- For more information regarding the media source data details, please navigate this this page

[Sending User Segments / User Info](/getting-started/advanced-options/sending-user-segments-user-info.md) <- For more information regarding the userInfo and `userGroup` data, please navigate this this page

#### 3.2 User Age & Gender Requirement

Before users can participate in reward activities, the SDK requires their age and gender to comply with partner requirements and properly configure available campaigns. If this information has not been provided, the SDK will automatically display a User Information page when the user opens any SDK screen that requires reward eligibility. After the data is submitted, it is stored and the page will not appear again unless the SDK state is reset.

**Providing Age & Gender via API**

If your application already collects age and gender, you can provide this information directly to the SDK. In this case, the User Information page will not be shown, ensuring a smoother user experience without additional prompts.

```csharp
var userInfo = new TyradsUserInfo(
    userAge: 20,
    userGender: UserGender.Male
);

LoginData loginData = new LoginData("userID", userInfo);
LoginResult result = await TyrSDKPlugin.Instance.LoginUserAsync(loginData);
```

Providing user information programmatically is recommended when the application already manages user profiles or collects demographic data during onboarding.

#### **3.3** Initialization & Authentication State

After the SDK completes its startup flow, it is important to clearly understand what “initialization” means in this context.

Although internally the SDK performs an initialization request, from a product and API perspective this step is effectively a user authentication (login) process. Once this flow completes successfully, the SDK is fully ready for use.

To allow developers to reliably verify this state, the SDK exposes a dedicated property that indicates whether the initialization/authentication process has finished successfully.

```csharp
if (TyrSDKPlugin.Instance.IsInitialized)
{
    // your logic there
}
```

{% hint style="info" %}
The SDK exposes an `Init(...)` method, but its purpose is often misunderstood is sometimes misunderstood and union with `IsInitialized`.&#x20;

`Init(...)` method does not initialize the SDK. Instead, this method is responsible for configuring the SDK with the required parameters that will later be used during the authentication phase (in `LoginUserAsync(...)` method).
{% endhint %}

**Key Notes**

* `IsInitialized` reflects both:
  * Successful SDK setup
  * Successful user authentication
* A `true` value guarantees that:
  * All required backend requests are completed
  * The SDK is in a valid, ready-to-use state
* A `false` value means:
  * Initialization/authentication is still in progress, or
  * The process has failed


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://sdk-doc.tyrads.com/unity/sdk-integration/3.-user-login.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
