Auth using REST

Overview of Epic Games authentication process

Epic Games Services uses the OAuth 2.0 protocol for authentication and authorization, supporting common-use cases for web servers and client-side applications. Epic has also introduced custom grant types for some specific use cases.

Before starting, you will need to obtain OAuth 2.0 client credentials from Epic. These will be in the form of a Client ID and Client Secret, and will be used when requesting an access token from the Epic authorization server. See our guide on Getting Started with Epic Account Services for more details.

Scenarios

Game Client on the Epic Games Store

A game client launched from the Epic Games Store will authenticate with Epic's authorization server using a one-time use exchange code. This exchange code is generated by the Epic Launcher and passed to the game client as a command-line argument.

When the game client is launched, it will make a request to the Epic token endpoint that includes the client credentials and exchange code. The response will include an access token, information about the client and account that were authenticated, and an optional refresh token.

The game client will include the access token on all requests to Epic services. The access token can also be passed to trusted game servers for verification, or for use in service-to-service requests.

When applicable, a refresh token will also be included in the token response. The game client will need to use the refresh token if the access token expires. This typically occurs within 2 hours after the access token is issued.

Diagram illustrating Epic Games Launcher authentication flow. Click image to enlarge.

Web Server Applications

For server-side applications, the flow will begin by taking the user through the Epic authorization flow on a web browser so that it can obtain an authorization code. The user will be asked to log in using their Epic Games account, and may be asked to authorize your application. Once authorized, the user agent will redirect back to your web application with an authorization code included as a query parameter.

After the redirect, the web server will make a request to the Epic token endpoint using the client credentials and authorization code. The response will include an access token, as well as information about the client and account that were authenticated.

The web server will include the access token on all requests to Epic services.

Authentication

As the first step in the authentication flow, the user must authenticate with Epic Account Services. We only support OAuth 2.0 for authentication, with additional custom grant types.

Once the client has the necessary information to request a token (including the exchange code, authorization code, and user credentials), it begins by requesting an access token.

Request Access Token

To request an access token, the client must make an HTTP request to the Epic token endpoint, passing the client credentials (Client ID and Secret) and user credentials.

The Epic token endpoint is https://api.epicgames.dev/epic/oauth/v1/token.

The client credentials will be passed in the Authorization header using Basic authorization. This endpoint supports the following post parameters:

Parameter name

Description

grant_type

The grant type being used: exchange_code, password or refresh_token.

deployment_id

The deployment ID that the client is trying to authenticate with. This will impact interactions with other services that require a deployment. If the deployment is not public, only users who have been entitled will be able to log in.

scope

Space-delimited list of scopes (permissions) that will be requested from the user. For example: basic profile, friends_list, and presence

For the password grant type

username

The username (email address) for the account; only used with the password grant type.

password

The password for the account; only used with the password grant type.

For the exchange_code grant type

exchange_code

The exchange code passed by Launcher to the game client; only used with the exchange_code grant type.

For the authorization_code grant type

code

The authorization code received from the authorization server.

For the client_credentials grant type (see Web Authorization )

client_id

The OAuth Client ID for your application.

client_secret

The OAuth Client Secret for your application.

These parameters should be in the request body. Query parameters will be ignored.

The following snippet shows a sample request using password grant type:

POST /epic/oauth/v1/token HTTP/1.1
Host: api.epicgames.dev
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Zm9vOmJhcg==

grant_type=password&
deployment_id=foo&
scope=basic_profile friends_list presence&
username=user@example.com&
password=s3cr3t

The response contains the following fields:

Response

Description

access_token

The access token, which may optionally have a prefix (for example: eg1~[token]). This value should be passed as is in the Authorization header using the Bearer type on any requests to Epic services.

expires_in

The number of seconds until the token expires.

expires_at

The expire date in ISO 8601 format.

account_id

The Epic Account ID for the user that the token was generated for.

client_id

The Client ID which was used to generate this token.

application_id

The Application ID which the Client is associated with.

token_id

The type of token generated; value will always be bearer.

refresh_token

The refresh token will optionally be returned depending on the client configuration. This refresh token can be used to extend a session before or after the access token has expired.

refresh_expires

The number of seconds until the refresh token expires.

refresh_expires_at

The refresh token expire date in ISO 8601 format.

The following snippet shows a sample response:

{
  "scope": "basic_profile friends_list presence",
  "token_type": "bearer",
  "access_token": "eyJ0IjoiZXBpY19pZCIsImFsZyI6IlJTMjU2Iiwia2lkIjoibldVQzlxSFVldWRHcnBXb3FvVXVHZkFIYmVWM2NsRnlsdFRYMzhFbXJKSSJ9.eyJhdWQiOiJ4eXphNzg5MWxoeE1WWUdDT043TGduS1paOEhRR0Q1SCIsInN1YiI6Ijk2MjZmNDQxMDU1MzQ5Y2U4Y2I3ZDdkNWE0ODNlYWEyIiwidCI6ImVwaWNfaWQiLCJzY29wZSI6ImJhc2ljX3Byb2ZpbGUgZnJpZW5kc19saXN0IHByZXNlbmNlIiwiYXBwaWQiOiJmZ2hpNDU2N08wM0hST3hFandibjdrZ1hwQmhuaFd3diIsImlzcyI6Imh0dHBzOlwvXC9hcGkuZXBpY2dhbWVzLmRldlwvZXBpY1wvb2F1dGhcL3YxIiwiZG4iOiJLcm5icnkiLCJleHAiOjE1ODgyODYwODMsImlhdCI6MTU4ODI3ODg4Mywibm9uY2UiOiJuLUI1cGNsSXZaSkJaQU1KTDVsNkdvUnJDTzNiRT0iLCJqdGkiOiI2NGMzMGQwMjk4YTM0MzdjOGE3NGU1OTAxYzM0ODZiNSJ9.MZRoCRpjIb--dD7hxoo2GvjSPhUSNpOq1FhtShTBmzMJ1qlHFPzNaUiAEETAc3mabGPKyOxUP6Q1FBadr_P_UtbtB7kf34hN2VTv5czW6WOx1HdpjwUQZuxFyDc_aix7FCS0Egu4rZlC65b-B0FUVlial_s_FrH8ou5L_d-4I0KVpIwtv-b_M6EQ9jtLdQRfMaP6aV0rIerrbqFZ617Pe7XT4IO9jZFwM8F5aDTeDHkkOO41wyVibrm38799lP4B65RIv9CwbAL-TVmV1L5gFYITaZhi5ShfZzTvxAk-3Dxwp8c5JvcO68zpbya5gFSAfhsd7vt9YLU0gQR2uXq3Vw",
  "refresh_token": "eyJ0IjoiZXBpY19pZCIsImFsZyI6IlJTMjU2Iiwia2lkIjoibldVQzlxSFVldWRHcnBXb3FvVXVHZkFIYmVWM2NsRnlsdFRYMzhFbXJKSSJ9.eyJhdWQiOiJ4eXphNzg5MWxoeE1WWUdDT043TGduS1paOEhRR0Q1SCIsInN1YiI6Ijk2MjZmNDQxMDU1MzQ5Y2U4Y2I3ZDdkNWE0ODNlYWEyIiwidCI6ImVwaWNfaWQiLCJhcHBpZCI6ImZnaGk0NTY3TzAzSFJPeEVqd2JuN2tnWHBCaG5oV3d2Iiwic2NvcGUiOiJiYXNpY19wcm9maWxlIGZyaWVuZHNfbGlzdCBwcmVzZW5jZSIsImlzcyI6Imh0dHBzOlwvXC9hcGkuZXBpY2dhbWVzLmRldlwvZXBpY1wvb2F1dGhcL3YxIiwiZG4iOiJLcm5icnkiLCJleHAiOjE1ODgzMDc2ODMsImlhdCI6MTU4ODI3ODg4MywianRpIjoiYzczYjA2NmUyZDU4NGVkNTk0NjZiOThiNzI3NzJiMjAifQ.O-eVa46NimubKwxe9SwlHxciivu0XWe1-DSL74mMiA_PpPoW0yKL9DfmsLxiPCwsRB5_hQTc6_FM7G1FyfKtX_VVAp90MZPkhCbAbfKmTpQVcL0Ya6kve4KMG8KxeLVfLLhubCbJTYlnDNVHobbpvpQtHd8Ys321ZNDJj05l_tnZzdgus-xmCO6orX4UP4wDd1jAOXXeqRT47OXuLCgSE0q6Osfh-ENPwh6ph1i7ld759xPV0oNcQb8XiPxnT6_FUmFugzG1YS1z9bTnVWmbP2RmYluue5VQm5EKGJZ91Alve8s2eNEtDfUqaBLZ45pqGkc1KjbYTtP0a_1ue2BpkQ",
  "expires_in": 7200,
  "expires_at": "2020-04-30T22:34:43.549Z",
  "refresh_expires_in": 28800,
  "refresh_expires_at": "2020-05-01T04:34:43.549Z",
  "account_id": "9626f441055349ce8cb7d7d5a483eaa2",
  "client_id": "xyza7891lhxMVYGCON7LgnKZZ8HQGD5H",
  "application_id": "fghi4567O03HROxEjwbn7kgXpBhnhWwv"
}

The access token should always be passed as is in the Authorization header to Epic services. For example: Authorization: Bearer eyJraWQiOiJ0RkM...

Web Applications

For web and server-side applications, you will need to get an authorization code before requesting an access token. Before using the web authorization, your Epic OAuth Client needs to be configured with a redirect URL.

To initiate the flow, your application will need to redirect the user to the authorization page where they will be asked to log in to their Epic Games account. The authorization URL is:

https://www.epicgames.com/id/authorize?client_id={client_id}&response_type=code&scope=basic_profile

You can define several redirect URLs with the additional parameter redirect_uri={redirect_uri}. The authorization URL for more than one redirect is:

https://www.epicgames.com/id/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope=basic_profile

After the user logs in, they will be redirected back to the configured redirect URL with an authorization code. Your application should use that code to get an Access Token using the authorization_code grant type as described in Request Access Token.

We also support an optional state parameter that can be used to maintain state between the request and the callback, and that is used to prevent cross-site request forgery attacks.

The following is an example redirect after the user is authenticated:

https://www.example.com/?code=cfd1de1a8d224203b0445fe977838d81&state=rfGWJux2WL86Zxr6nKApCAnDo8KexEUE

Verify Access Token

Offline Verification

The access token is a JWT (JSON Web Token) that includes a header and signature used to validate the authenticity of the token.

Before validating the signature, you will need to fetch a public key published as a JSON Web Key (JWK) from our service. We expose a single endpoint using the JWK Set format that includes all of the current public keys. While the keys are not changed frequently, it is possible that they are rotated at any time.

The JWK endpoint is https://api.epicgames.dev/epic/oauth/v1/.well-known/jwks.json

Clients fetching the public key should cache them for a reasonable period. While the keys may rotate, a key for a given key ID will not change.

The following snippet shows a sample response from the public keys endpoint:

{"keys":[{"kty":"RSA","e":"AQAB","kid":"WMS7EnkIGpcH9DGZsv2WcY9xsuFnZCtxZjj4Ahb-_8E","n":"l6XI48ujknQQlsJgpGXg4l2i_DuUxuG2GXTzkOG7UtX4MqkVBCfW1t1JIIc8q0kCInC2oBwhC599ZCmd-cOi0kS7Aquv68fjERIRK9oCUnF_lJg296jV8xcalFY0FOWX--qX3xGKL33VjJBMIrIu7ETjj06s-v4li22CnHmu2lDkrp_FPTVzFscn-XRIojqIFb7pKRFPt27m12FNE_Rd9bqlVCkvMNuE7VTpTOrSfKk5B01M5IuXKXk0pTAWnelqaD9bHjAExe2I_183lp_uFhNN4hLTjOojxl-dK8Jy2OCPEAsg5rs9Lwttp3zZ--y0sM7UttN2dE0w3F2f352MNQ"}]}

Online Verification

If offline verification is not an option, you can perform an online verification by calling the token info endpoint with a valid access token. This endpoint implements the Token Introspection specification.

The token info endpoint is https://api.epicgames.dev/epic/oauth/v1/tokenInfo

The following snippet shows a sample request to verify a token:

POST /epic/oauth/v1/tokenInfo HTTP/1.1
Host: api.epicgames.dev
Content-Type: application/x-www-form-urlencoded
token=eyJ0IjoiZXBpY19pZCIsImFsZyI6IlJTMjU2Iiwia2lkIjoibldVQzlxSFVldWRHcnBXb3FvVXVHZkFIYmVWM2NsRnlsdFRYMzhFbXJKSSJ9.eyJhdWQiOiJ4eXphNzg5MWxoeE1WWUdDT043TGduS1paOEhRR0Q1SCIsInN1YiI6Ijk2MjZmNDQxMDU1MzQ5Y2U4Y2I3ZDdkNWE0ODNlYWEyIiwidCI6ImVwaWNfaWQiLCJzY29wZSI6ImJhc2ljX3Byb2ZpbGUgZnJpZW5kc19saXN0IHByZXNlbmNlIiwiYXBwaWQiOiJmZ2hpNDU2N08wM0hST3hFandibjdrZ1hwQmhuaFd3diIsImlzcyI6Imh0dHBzOlwvXC9hcGkuZXBpY2dhbWVzLmRldlwvZXBpY1wvb2F1dGhcL3YxIiwiZG4iOiJLcm5icnkiLCJleHAiOjE1ODgyODYwODMsImlhdCI6MTU4ODI3ODg4Mywibm9uY2UiOiJuLUI1cGNsSXZaSkJaQU1KTDVsNkdvUnJDTzNiRT0iLCJqdGkiOiI2NGMzMGQwMjk4YTM0MzdjOGE3NGU1OTAxYzM0ODZiNSJ9.MZRoCRpjIb--dD7hxoo2GvjSPhUSNpOq1FhtShTBmzMJ1qlHFPzNaUiAEETAc3mabGPKyOxUP6Q1FBadr_P_UtbtB7kf34hN2VTv5czW6WOx1HdpjwUQZuxFyDc_aix7FCS0Egu4rZlC65b-B0FUVlial_s_FrH8ou5L_d-4I0KVpIwtv-b_M6EQ9jtLdQRfMaP6aV0rIerrbqFZ617Pe7XT4IO9jZFwM8F5aDTeDHkkOO41wyVibrm38799lP4B65RIv9CwbAL-TVmV1L5gFYITaZhi5ShfZzTvxAk-3Dxwp8c5JvcO68zpbya5gFSAfhsd7vt9YLU0gQR2uXq3Vw

The following snippet shows a sample response from the token info endpoint:

{
  "active": true,
  "scope": "basic_profile friends_list presence",
  "token_type": "bearer",
  "expires_in": 6761,
  "expires_at": "2020-04-30T22:34:43.549Z",
  "account_id": "9626f441055349ce8cb7d7d5a483eaa2",
  "client_id": "xyza7891lhxMVYGCON7LgnKZZ8HQGD5H",
  "application_id": "fghi4567O03HROxEjwbn7kgXpBhnhWwv"
}

Both access tokens and refresh tokens can be verified using this endpoint.

Game Client on the Epic Games Store

When using a game client connected through the Epic Games Store, the game client must use the exchange_code grant type to get an access token, passing their client credentials and the code passed to the game from the launcher.

During development, you can also use the password grant type, which will allow the game client to authenticate against Epic Services without the launcher integration.

When the game is started by the Epic Games launcher, it will be launched with the following command-line parameters:

Parameter

Description

AUTH_LOGIN

Unused for exchange code.

AUTH_PASSWORD

The credentials to be used by the game client. This will include the exchange code that will be passed to the authentication server.

epicapp

Internal application name.

epicenv

Environment that this is being launched in (always Prod).

epicusername

Display name of the account that is authenticated in the Launcher.

epicuserid

Epic Account ID for the account that is authenticated in the Launcher.

epiclocale

Preferred locale based on user preference or based on the system language.

epicovt

Full path to a file containing Ownership Verification Token information.

The following is a sample of the command line parameters passed by launcher:

-AUTH_LOGIN=unused -AUTH_PASSWORD=ed642dfd4e6f47bf8354caf1bcab2fc2 -AUTH_TYPE=exchangecode -epicapp=[AppName] -epicenv=Prod -epicusername="DisplayName" -epicuserid=ab1f86d911d74f4aa8399849e9ca9aa5 -epiclocale=en-US
-epicovt="C:/AppName/.egstore/ab1f86d911d74f4aa8399849e9ca9aa5/File.ovt"

Account Information

Once you have an access token, you will be able to make requests to Epic services on behalf of the user. For example, you can make requests to retrieve their display name, or the display names of their friends.

From the Access Token

You can retrieve some information directly from the access token. The token is encoded as a JSON Web Token (JWT), and its header includes information about the type of token and signature it uses, as well as a payload with information about the user, your client, the session, and a signature. We recommend using a library to handle decoding the JWT, but if this is not possible, refer to the JWT specification.

The payload will include the following information:

Claim

Type

Description

iss

string

The base URI of the Epic Games authentication server that issued the token.

sub

string

This claim will not be present when using the client_credentials grant type.

aud

string

The client ID specified in the authorization request.

iat

integer

The time the token was issued as a UNIX timestamp.

exp

integer

Expiration time of the token as a UNIX timestamp.

jti

string

The unique identifier for this token.

t

string

The type of token. This should always be epic_id. This replaces the version prefix that we have with EG1 tokens.

scope

string

Space delimited list of scopes that were authorized by the user.

dn

string

The user's display name.

appid

string

The application ID specified in the authorization request.

pfpid

string

The product ID for the deployment that was specified in the token request.

pfsid

string

The sandbox ID for the deployment that was specified in the token request.

pfdid

string

The deployment ID that was specified in the token request.

Using the token from the previous example, we can decode the payload to see that it includes the following:

{
  "aud": "xyza7891lhxMVYGCON7LgnKZZ8HQGD5H",
  "sub": "9626f441055349ce8cb7d7d5a483eaa2",
  "t": "epic_id",
  "scope": "basic_profile friends_list presence",
  "appid": "fghi4567O03HROxEjwbn7kgXpBhnhWwv",
  "iss": "https://api.epicgames.dev/epic/oauth/v1",
  "dn": "Krnbry",
  "exp": 1588286083,
  "iat": 1588278883,
  "nonce": "n-B5pclIvZJBZAMJL5l6GoRrCO3bE=",
  "jti": "64c30d0298a3437c8a74e5901c3486b5"
}

Fetching Accounts

In addition to the information in the access token, it is possible to request similar information about the logged-in account, or any other account that has interacted with your application.

Due to privacy concerns, you will only be able to request account information for users who have previously provided consent to your application.

The account info endpoint is https://api.epicgames.dev/epic/id/v1/accounts. When calling this endpoint, you will need to specify one or more accountId query parameters for the accounts you are trying to resolve. There is a limit of 50 accounts in a single request.

The following snippet shows a sample request to fetch multiple accounts:

GET /epic/id/v1/accounts?accountId=foo531f86d911d74f4aa8399849e9ca9ba6&accountId=barcbab941052f540c69fbd92ddc3bf9027 HTTP/1.1
Host: api.epicgames.dev
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer [token]eyJ0IjoiZXBpY19pZCIsImFsZyI6IlJTMjU2Iiwia2lkIjoibldVQzlxSFVldWRHcnBXb3FvVXVHZkFIYmVWM2NsRnlsdFRYMzhFbXJKSSJ9.eyJhdWQiOiJ4eXphNzg5MWxoeE1WWUdDT043TGduS1paOEhRR0Q1SCIsInN1YiI6Ijk2MjZmNDQxMDU1MzQ5Y2U4Y2I3ZDdkNWE0ODNlYWEyIiwidCI6ImVwaWNfaWQiLCJzY29wZSI6ImJhc2ljX3Byb2ZpbGUgZnJpZW5kc19saXN0IHByZXNlbmNlIiwiYXBwaWQiOiJmZ2hpNDU2N08wM0hST3hFandibjdrZ1hwQmhuaFd3diIsImlzcyI6Imh0dHBzOlwvXC9hcGkuZXBpY2dhbWVzLmRldlwvZXBpY1wvb2F1dGhcL3YxIiwiZG4iOiJLcm5icnkiLCJleHAiOjE1ODgyODYwODMsImlhdCI6MTU4ODI3ODg4Mywibm9uY2UiOiJuLUI1cGNsSXZaSkJaQU1KTDVsNkdvUnJDTzNiRT0iLCJqdGkiOiI2NGMzMGQwMjk4YTM0MzdjOGE3NGU1OTAxYzM0ODZiNSJ9.MZRoCRpjIb--dD7hxoo2GvjSPhUSNpOq1FhtShTBmzMJ1qlHFPzNaUiAEETAc3mabGPKyOxUP6Q1FBadr_P_UtbtB7kf34hN2VTv5czW6WOx1HdpjwUQZuxFyDc_aix7FCS0Egu4rZlC65b-B0FUVlial_s_FrH8ou5L_d-4I0KVpIwtv-b_M6EQ9jtLdQRfMaP6aV0rIerrbqFZ617Pe7XT4IO9jZFwM8F5aDTeDHkkOO41wyVibrm38799lP4B65RIv9CwbAL-TVmV1L5gFYITaZhi5ShfZzTvxAk-3Dxwp8c5JvcO68zpbya5gFSAfhsd7vt9YLU0gQR2uXq3Vw

The following snippet is an example response from this request:

[
    {
        "accountId": "531f86d911d74f4aa8399849e9ca9ba6",
        "displayName": "eas_user",
        "preferredLanguage": "en",
        "linkedAccounts": [
            {
                "identityProviderId": "xbl",
                "displayName": "eas_user_xbl"
            }
        ]
    },
    {
        "accountId": "cbab941052f540c69fbd92ddc3bf9027",
        "displayName": "other_user",
        "preferredLanguage": "en"
    }
]