Link a custom account
Additionally link a custom account to the currently logged-in Player ID. After linking, whether the user logs in with the existing login method or with the custom account, the user logs in with the same Player ID and keeps using the same play data.
Like Log in with a custom account, custom account linking uses a grant key that the app server obtained. The app client does not handle the custom authentication provider's credentials directly.
1. Review the custom account linking flow
The app server and the app client share the work of custom account linking.
- The app client authenticates the user with the app server or with the authentication system that the app uses.
- The app server requests a grant key for linking from the Hive Axyl server with Issue a pre-authorization key. At this time, it also passes the custom authentication provider identifier, the user identifier from that provider, and the Player ID to link to.
- The app server passes the issued grant key to the app client.
- The app client calls
LinkCustomProviderAsync()with the grant key. - The Hive Axyl authentication server links the custom account to the currently logged-in Player ID.
A grant key is valid for only 60 seconds after it is issued and can be used only once. For the concept of the grant key and what the app server handles, see Apply additional security.
Before you call it, the user must be logged in with the session activated. Linking is processed based on the Player ID of the current session.
2. Link a custom account
LinkCustomProviderAsync
Call LinkCustomProviderAsync() to link a custom account to the currently logged-in Player ID.
Call parameters
| Field name | Type | Required | Description |
|---|---|---|---|
| request | CustomLinkRequest | Required | Custom account linking request |
| context | ApiCallContext | Optional | Per-call settings object. If omitted, the default values are used. |
CustomLinkRequest
| Field name | Type | Required | Description |
|---|---|---|---|
GrantKey | string | Required | Pre-authentication key that the app server obtained for linking and passed on |
Call example
For the result model and handling principles of common failures (Failure) that prevent the request from being performed, see Common error handling.
using Hive.Axyl.Auth;
using Hive.Axyl.Core;
using UnityEngine;
IAuthService auth = HiveCore.Resolve<IAuthService>();
var result = await auth.LinkCustomProviderAsync(new CustomLinkRequest {
GrantKey = customLinkGrantKey,
});
switch (result)
{
case AuthLinkCustomProviderResult.Success success:
Debug.Log($"Custom account linking completed: PlayerId={success.Data.PlayerId}");
break;
case AuthLinkCustomProviderResult.InvalidGrantKey:
// The grant key expired or was already used → get a new one from the app server and retry
break;
case AuthLinkCustomProviderResult.PlayerIdDoesNotMatch:
// The grant key's link target differs from the Player ID of the current session
break;
case AuthLinkCustomProviderResult.ProviderOwnedByOther:
// This custom account is already linked to another Player ID → handle the account conflict
break;
case AuthLinkCustomProviderResult.Failure failure:
HiveError err = failure.Problem;
Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
break;
// Safety net: unhandled results and unknown new results (UnknownOutcome)
default:
Debug.LogWarning($"Unhandled result: {result.GetType().Name}");
break;
}
Response data
On success, Data (ProviderLinkResponseData) of AuthLinkCustomProviderResult.Success contains the information of the linked custom account.
| Field name | Type | Required | Description |
|---|---|---|---|
Data.PlayerId | long | Required | Player ID to which the custom account is linked |
Data.ProviderId | Provider | Required | The linked login method. For a custom account, it is CustomProvider. |
Data.ProviderUserId | string | Required | User identifier of the custom authentication provider |
Data.ProviderIndex | int | Required | Numeric identifier that represents the linked login method |
Response example
Response status
We recommend handling the response cases of AuthLinkCustomProviderResult with a switch statement.
| Response case | Description | App client handling |
|---|---|---|
Success | Linking succeeded | Refresh the linking status screen |
InvalidGrantKey | The grant key has expired, has already been used, or does not match the request information | Get a new grant key from the app server and retry |
PlayerIdDoesNotMatch | The grant key's target Player ID differs from the Player ID of the current session | Check the current session and the issuance target |
ProviderTypeAlreadyExists | A custom account is already linked to the current Player ID | Inform the user of the existing linking status |
ProviderOwnedByOther | This custom account is already linked to another Player ID | Handle account linking conflicts |
ProviderAlreadyConnected | The account is already linked to the current Player ID | Treat it as a duplicate request |
ProviderNotSupported | Custom account linking is not supported | Check the login settings in the console |
ProviderConfigNotFound | There are no custom account settings in the console | Check the login settings in the console |
PlayerNotFound | The target Player ID for linking cannot be found | Check the current session |
AppIdMismatch | The app information in the request differs from the app information of the session | Check the SDK initialization status |
InvalidGatewayContext | The authentication information is not included in the request | Check the session activation status |
IpBlocked | The access IP is blocked | Inform the user of the policy |
AppNotFound | The app information cannot be found | Check the app registration status in the console |
TerminateService | The app's service has ended | Check the service operation status |
UnknownOutcome | A new result that this SDK version does not know | Log it and handle it conservatively |
Failure | Common Failure. Missing required parameters or format errors (invalid_parameter), missing required fields (missing_field), and a missing X-App-Id header (missing_app_id) also branch here, and the cause is stored in Failure.Problem.ExternalCode. See Common error handling. | Handle according to the common error handling criteria |