Authorization

A large number of Dead by Daylight's private API endpoints require authentication with a valid Dead by Daylight account. Access is secured through token-based authentication, ensuring that only authorized users can retrieve the requested resources.


OAuth 2.0

Epic Online Services (EOS) 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. You can learn more about this process here.

OAuth Server Endpoints

  • https://api.epicgames.dev/epic/oauth/v2/exchange?consumingClientId={consumingClientId}&codeChallenge={codeChallenge}&codeChallengeMethod={codeChallengeMethod}
  • Endpoint for exchanging an authorization code for an access token. consumingClientId refers to the client application making the request, codeChallenge is the value derived from the code verifier (a cryptographically random string generated by the client), and codeChallengeMethod specifies the method used to create the codeChallenge. EOS employs the SHA-256 hashing algorithm to secure the code challenge in the Proof Key for Code Exchange (PKCE) flow.

  • https://api.epicgames.dev/epic/oauth/v2/token
  • Endpoint for obtaining an access token, refresh token, and other identity information after successfully exchanging an authorization code.

  • https://api.epicgames.dev/epic/oauth/v2/tokenInfo
  • Endpoint for obtaining detailed information about a given access token. When a client provides a valid access token, the endpoint responds with metadata associated with it.

  • https://api.epicgames.dev/epic/oauth/v2/revoke
  • Endpoint that enables clients to implement a "log out" feature by invalidating tokens, ensuring that any associated security credentials or access rights are revoked. This endpoint implements RFC 7009 - OAuth 2.0 Token Revocation.

    Errors

    The endpoints listed above return error messages in accordance with the relevant RFC specifications.


    Client Types

    OAuth categorizes clients into two types: confidential clients and public clients.

    Confidential Clients

    Confidential clients are applications that can securely authenticate with the authorization server, such as those capable of keeping their registered client secret safe.

    The client ID is a public identifier for applications registered with an OAuth 2.0 authorization server. It must be unique across all clients managed by the server to ensure requests are correctly attributed to the appropriate application.

    The client secret is a confidential credential known only to the application and the authorization server. It functions as the application's password, ensuring secure communication between the application and the server.

    These clients are able to use the authorization_code, client_credentials, exchange_code, password, and refresh_token grant types.

    Confidential clients can have ID tokens issued to them either symmetrically using their client secret (HS256) or asymmetrically using a private key (RS256), as they are capable of securely storing secrets.

    Public Clients

    Public clients, like applications running in a browser or on a mobile device, cannot securely store client secrets because these environments are not secure enough to protect them.

    These clients can only use grant types that do not require a client secret, as they cannot securely store or protect the confidentiality of such credentials.

    Since public clients cannot securely store secrets, ID tokens issued to them must be signed asymmetrically using a private key (RS256) and verified with the corresponding public key.

    Tokens

    When attempting to play Dead by Daylight, the client interacts with Epic Games' OAuth 2.0 authentication system to obtain access tokens, refresh tokens, and ID tokens.

    Access Token

    An access token is issued by the authorization server to grant the client access to protected resources on behalf of the user. This token is valid for 2 hours from the time of issuance.

    Refresh Token

    A refresh token is used to obtain a new access token without requiring the user to re-authenticate. This token remains valid for 8 hours from the time of issuance.

    ID Token

    An ID token is part of the OpenID Connect protocol, which provides a standardized method to authenticate and retrieve basic user information. It is used to verify the user's identity and contains user details in the form of claims (e.g., Epic Account ID, Epic Account display name, client ID used to authenticate the user with Epic Account Services, and other identity-related information). This token remains valid for 2 hours from the time it is issued.


    Available Scopes

    When the client attempts to connect to Dead by Daylight's servers, it requests specific scopes as part of the OAuth 2.0 authorization flow. The scope basic_profile friends_list openid presence specifies the resources and permissions the client needs to access:

  • basic_profile access allows the client to authenticate the user with Epic Account Services, retrieve information such as the user's screen name, and facilitate in-application purchases.
  • friends_list access allows the client to retrieve an Epic Account's friends list.
  • openid access allows the client to request an ID token.
  • presence access allows the client to retrieve an Epic Account's presence information, which details a user's current activity. This includes both basic status and game-specific status. Basic status provides general details, such as whether the user is online or offline and what game they are playing (if they have chosen to share this information). Game-specific status includes details unique to the game the user is playing.

  • Grant Types

    Authorization Code Grant

    This grant allows both confidential and public clients to exchange an authorization code for an access token. After the user is redirected back to the client via the specified redirect URL, the application extracts the authorization code from the URL and uses it to request an access token. You can learn more this flow here.

    Authentication using this method is only possible for clients that have a configured redirect URL. Since the Dead by Daylight client does not have a redirect URL, I will use fortnitePCGameClient to illustrate this process. Notably, jaren.wtf's unofficial Epic Games Client Documentation states that fortnitePCGameClient's client ID is ec684b8c687f479fadea3cb2ad83f5c6, and its client secret is e1f31c211f28413186262d37a13fc84d.

    Method

    1. Identify the client for which you need to obtain an access token.

    2. Make sure you are logged into your Epic Games account.

    3. Open https://www.epicgames.com/id/api/redirect?clientId=:clientId&responseType=code in your web browser, replacing :clientId with the chosen client ID. In this case, use ec684b8c687f479fadea3cb2ad83f5c6.

    4. If the request is successful, then you will receive a response with the following structure:

    {
    "redirectUrl": string,
    "authorizationCode": string,
    "exchangeCode": null,
    "sid": null,
    "ssoV2Enabled": boolean
    }
    Key Type Description
    redirectUrl String The URL to which the user will be redirected after authentication. This URL contains the authorization code as a query parameter, which the client can later use to exchange for an access token.
    authorizationCode String A temporary authorization code issued after the user successfully logs in. This code is used in the next step to request an access token from the authorization server.
    exchangeCode String (can be null) A code used to exchange for an access token in specific OAuth flows. This field is null if the exchange code hasn't been issued yet or isn't required for the current flow.
    sid String (can be null) Represents the session ID (SID) for the user's authentication session. It is null if not applicable or has not yet been assigned during the process.
    ssoV2Enabled Boolean Indicates whether Single Sign-On (SSO) version 2 is enabled for this authentication flow. If true, then the system supports SSOv2, allowing the user to authenticate across multiple services without the need to re-enter credentials.

    Note that the authorization code expires after 5 minutes. If step 5 is not completed within 5 minutes of completing step 3, then a new authorization code will need to be generated.

    5. Send a POST request to https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token:

    Request Headers:

    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic {client_id:client_secret}

    Note that the client_id:client_secret pair needs to be encoded in Base64.

    Request Body:

    grant_type=authorization_code&code={authorizationCode}

    Note that authorizationCode is obtained from the response in step 4.

    Example: Authenticating to fortnitePCGameClient

    Request Headers:

    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic ZWM2ODRiOGM2ODdmNDc5ZmFkZWEzY2IyYWQ4M2Y1YzY6ZTFmMzFjMjExZjI4NDEzMTg2MjYyZDM3YTEzZmM4NGQ=

    Request Body:

    grant_type=authorization_code&code={authorizationCode}

    If the request is successful, then the response will have the following structure:

    {
    "access_token": string,
    "expires_in": 7200,
    "expires_at": string,
    "token_type": "bearer",
    "refresh_token": string,
    "refresh_expires": 28800,
    "refresh_expires_at": string,
    "account_id": string,
    "client_id": "ec684b8c687f479fadea3cb2ad83f5c6",
    "internal_client": true,
    "client_service": "prod-fn",
    "scope": [
    "basic_profile"
    ],
    "displayName": string,
    "app": "prod-fn",
    "in_app_id": string,
    "device_id": string,
    "product_id": "prod-fn",
    "application_id": string,
    "acr": "urn:epic:loa:aal2",
    "auth_time": string
    }
    Key Type Description
    access_token String The OAuth 2.0 access token, which grants temporary access to the application's protected resources.
    expires_in Number The duration (in seconds) until the access token expires.
    expires_at String The expiration timestamp of the access token, formatted in ISO 8601.
    token_type String Indicates the type of token issued.
    refresh_token String The token that can be used to request a new access token after the current one expires.
    refresh_expires Number The duration (in seconds) before the token used to obtain a new access token expires.
    refresh_expires_at String The expiration timestamp of the refresh token, formatted in ISO 8601.
    account_id String The unique identifier for the user's account within Epic Games services.
    client_id String The unique identifier of the client making the request, typically representing the application.
    internal_client Boolean Indicates whether the client is part of Epic's internal systems.
    client_service String The service associated with the client.
    scope Array The permissions granted by the token, specifying the resources the client can access.
    displayName String The user's display name associated with the account.
    app String The application that is requesting the token.
    in_app_id String The unique ID assigned to the user within the application.
    device_id String The unique identifier of the device making the request.
    product_id String The unique identifier of the product linked to the token.
    application_id String The unique identifier of the application requesting the token. This may differ from client_id when multiple applications share the same client.
    acr String The level of security or strength of the authentication method used.
    auth_time String The timestamp, representing the moment when authentication took place, formatted in ISO 8601.

    Client Credentials Grant

    This grant allows clients to obtain an access token without user context. It is used for accessing client-specific resources rather than user-related data. You can learn about its flow here.

    Method

    1. Identify the client for which you need to obtain an access token.

    2. Send a POST request to https://api.epicgames.dev/auth/v1/oauth/token:

    Request Headers:

    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic {client_id:client_secret}

    Note that the client_id:client_secret pair needs to be encoded in Base64.

    Request Body:

    grant_type=client_credentials
    Example: Authenticating to the Dead by Daylight Client

    You can retrieve the Dead by Daylight client's ID and secret by monitoring its network traffic when launching the game through the Epic Games Launcher. Specifically, the "Authorization" request header in any requests sent to https://api.epicgames.dev/auth/v1/oauth/token or https://api.epicgames.dev/epic/oauth/v2/token will contain the value Basic eHl6YTc4OTFzSGQ4NDdVeEI0cG54WjMwT2hRRXFNZXQ6SXdYNEg4bmRDbmE0R1RpRDhMVFkyT3hqSDJncG5uYkt6cTRCaHFkL250RQ==. You can use this website to decode the Base64-encoded text. In this case, decoding eHl6YTc4OTFzSGQ4NDdVeEI0cG54WjMwT2hRRXFNZXQ6SXdYNEg4bmRDbmE0R1RpRDhMVFkyT3hqSDJncG5uYkt6cTRCaHFkL250RQ== reveals xyza7891sHd847UxB4pnxZ30OhQEqMet:IwX4H8ndCna4GTiD8LTY2OxjH2gpnnbKzq4Bhqd/ntE, where xyza7891sHd847UxB4pnxZ30OhQEqMet is the client ID and IwX4H8ndCna4GTiD8LTY2OxjH2gpnnbKzq4Bhqd/ntE is the client secret.

    Request Headers:

    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic eHl6YTc4OTFzSGQ4NDdVeEI0cG54WjMwT2hRRXFNZXQ6SXdYNEg4bmRDbmE0R1RpRDhMVFkyT3hqSDJncG5uYkt6cTRCaHFkL250RQ==

    Request Body:

    grant_type=client_credentials

    If the request is successful, then the response will have the following structure:

    {
    "access_token": string,
    "token_type": "bearer",
    "expires_at": string,
    "features": [
    "Achievements",
    "AntiCheat",
    "Ecom",
    "Matchmaking",
    "Metrics",
    "Sanctions",
    "Stats"
    ],
    "organization_id": "o-2ctdycbd3jxm6a26vpz5d4xv872smu",
    "product_id": "2b2299be8ae84d679d4dc57c55af1510",
    "expires_in": 3599
    }
    Key Type Description
    access_token String The OAuth 2.0 access token, which grants temporary access to the application's protected resources.
    token_type String Indicates the type of token issued.
    expires_at String The expiration timestamp of the access token, formatted in ISO 8601.
    features Array A list of features that are enabled for the access token.
    organization_id String A unique identifier for the organization linked to the token.
    product_id String The unique identifier of the product linked to the token.
    expires_in Number The duration (in seconds) until the access token expires.

    Exchange Code Grant

    This grant allows clients to exchange a short-lived authorization code for an access token. Since Epic has removed the endpoint that previously allowed obtaining an exchange code through a browser, the only way to acquire one now is by launching the selected game via the Epic Games Launcher. However, you can still retrieve the access token by capturing the game's network traffic as it launches. Specifically, by inspecting the request sent to https://api.epicgames.dev/epic/oauth/v2/token after launching the game, you will find a response structured as follows:

    {
    "scope": string,
    "token_type": string,
    "access_token": string,
    "refresh_token": string,
    "id_token": string,
    "expires_in": number,
    "expires_at": string,
    "refresh_expires_in": number,
    "refresh_expires_at": string,
    "account_id": string,
    "client_id": string,
    "application_id": string,
    "selected_account_id": string,
    "merged_accounts": [],
    "acr": string,
    "auth_time": string
    }
    Key Type Description
    scope String The permissions granted by the token, specifying the resources the client can access.
    token_type String Indicates the type of token issued.
    access_token String The OAuth 2.0 access token, which grants temporary access to the application's protected resources.
    refresh_token String The token that can be used to request a new access token after the current one expires.
    id_token String A token that contains user-related information in the form of claims.
    expires_in Number The duration (in seconds) until the access token expires.
    expires_at String The expiration timestamp of the access token, formatted in ISO 8601.
    refresh_expires_in Number The duration (in seconds) before the token used to obtain a new access token expires.
    refresh_expires_at String The expiration timestamp of the refresh token, formatted in ISO 8601.
    account_id String The unique identifier for the user's account within Epic Games services.
    client_id String The unique identifier of the client making the request, typically representing the application.
    application_id String The unique identifier of the application requesting the token. This may differ from client_id when multiple applications share the same client.
    selected_account_id String The selected account ID when a user has multiple accounts linked to the service.
    merged_accounts Array An array of account IDs that have been merged into the primary account.
    acr String The level of security or strength of the authentication method used.
    auth_time String The timestamp, representing the moment when authentication took place, formatted in ISO 8601.
    Example: Authenticating to the Dead by Daylight Client

    Request Headers:

    Host: api.epicgames.dev
    Accept-Encoding: identity
    Content-Type: application/x-www-form-urlencoded
    Accept: application/json
    Authorization: Basic eHl6YTc4OTFzSGQ4NDdVeEI0cG54WjMwT2hRRXFNZXQ6SXdYNEg4bmRDbmE0R1RpRDhMVFkyT3hqSDJncG5uYkt6cTRCaHFkL250RQ==
    X-Epic-Correlation-ID: {X-Epic-Correlation-ID}
    User-Agent: EOS-SDK/{X-EOS-Version} ({os_name}/{os_version}.{os_build}.{architecture}) DeadByDaylight/{version}
    X-EOS-Version: {sdk_version}-{build_number}
    Content-Length: {Content-Length}

    , where X-Epic-Correlation-ID is a unique identifier for tracking requests across Epic's services, X-EOS-Version is the EOS SDK version followed by the build number, os_name is the operating system name, os_version is the operating system version, os_build is the specific build of the operating system, architecture is the system's architecture, version is the game's version, sdk_version is the EOS SDK version, build_number is the EOS SDK build number, and Content-Length is the size of the request body in bytes.

    Request Body:

    grant_type=exchange_code&scope=basic_profile+friends_list+presence+openid&exchange_code={exchange_code}&deployment_id={deployment_id}

    , where exchange_code is the exchange code, and deployment_id is a unique identifier for a specific game deployment integrated with EOS.

    {
    "scope": "basic_profile friends_list openid presence",
    "token_type": "bearer",
    "access_token": string,
    "refresh_token": string,
    "id_token": string,
    "expires_in": 7200,
    "expires_at": string,
    "refresh_expires_in": 28800,
    "refresh_expires_at": string,
    "account_id": string,
    "client_id": "xyza7891sHd847UxB4pnxZ30OhQEqMet",
    "application_id": string,
    "selected_account_id": string,
    "merged_accounts": [],
    "acr": "AAL1",
    "auth_time": string
    }

    Refresh Token Grant

    This grant allows clients to exchange a refresh token for a new access token when the current one expires, enabling continuous access without requiring further user interaction. You can learn about its flow here.

    Method for Authenticating to the Dead by Daylight Client

    1. Identify the client for which you need to obtain a refresh token.

    2. Typically, a refresh_token is provided at the final step of the authorization code grant. However, since Dead by Daylight does not support authentication via this grant, you will instead receive a refresh_token at the final step of the exchange code grant. This token remains valid for 8 hours and allows the client to obtain a new access token without requiring the user's consent again.

    3. Launch Dead by Daylight from the Epic Games Launcher while your network traffic capture application is running.

    4. When you reach the title screen (where Dead by Daylight prompts you to "PRESS SPACE TO CONTINUE"), switch back to your network traffic capture application.

    5. Locate the session that uses the exchange_code grant_type. This will be the request sent to https://api.epicgames.dev/epic/oauth/v2/token.

    6. In the response body, locate the refresh_token key and its corresponding value. Right-click on the value and select "Copy".

    7. Send a POST request to https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token:

    Request Headers:

    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic eHl6YTc4OTFzSGQ4NDdVeEI0cG54WjMwT2hRRXFNZXQ6SXdYNEg4bmRDbmE0R1RpRDhMVFkyT3hqSDJncG5uYkt6cTRCaHFkL250RQ==

    Request Body:

    grant_type=refresh_token&refresh_token={refresh_token}

    Note that refresh_token is obtained from the response in step 6.

    8. If the request is successful, then you will receive a response with the following structure:

    {
    "access_token": string,
    "expires_in": 7200,
    "expires_at": string,
    "token_type": "bearer",
    "refresh_token": string,
    "refresh_expires": 28800,
    "refresh_expires_at": string,
    "account_id": string,
    "client_id": "xyza7891sHd847UxB4pnxZ30OhQEqMet",
    "internal_client": false,
    "client_service": "2b2299be8ae84d679d4dc57c55af1510",
    "scope": [
    "basic_profile",
    "friends_list",
    "openid",
    "presence"
    ],
    "displayName": string,
    "app": "2b2299be8ae84d679d4dc57c55af1510",
    "in_app_id": string,
    "device_id": string,
    "product_id": "2b2299be8ae84d679d4dc57c55af1510",
    "sandbox_id": "611482b8586142cda48a0786eb8a127c",
    "deployment_id": string,
    "application_id": string,
    "acr": "urn:epic:loa:aal1",
    "auth_time": string
    }
    Key Type Description
    access_token String The OAuth 2.0 access token, which grants temporary access to the application's protected resources.
    expires_in Number The duration (in seconds) until the access token expires.
    expires_at String The expiration timestamp of the access token, formatted in ISO 8601.
    token_type String Indicates the type of token issued.
    refresh_token String The token that can be used to request a new access token after the current one expires.
    refresh_expires Number The duration (in seconds) before the token used to obtain a new access token expires.
    refresh_expires_at String The expiration timestamp of the refresh token, formatted in ISO 8601.
    account_id String The unique identifier for the user's account within Epic Games services.
    client_id String The unique identifier of the client making the request, typically representing the application.
    internal_client Boolean Indicates whether the client is part of Epic's internal systems.
    client_service String The service associated with the client.
    scope Array The permissions granted by the token, specifying the resources the client can access.
    displayName String The user's display name associated with the account.
    app String The application that is requesting the token.
    in_app_id String The unique ID assigned to the user within the application.
    device_id String The unique identifier of the device making the request.
    product_id String The unique identifier of the product linked to the token.
    sandbox_id String The environment to which the API requests and responses belong.
    deployment_id String A unique identifier for a specific game deployment integrated with EOS.
    application_id String The unique identifier of the application requesting the token. This may differ from client_id when multiple applications share the same client.
    acr String The level of security or strength of the authentication method used.
    auth_time String The timestamp, representing the moment when authentication took place, formatted in ISO 8601.