Ecom Web APIs

RESTful endpoints to perform verification of ownership without using the SDK.

Epic Games Store
10 mins to read

Epic Online Services (EOS) provides multiple ways to verify an account's ownership of catalog items. The preferred method is to use the EOS SDK APIs through the Ecom Interface. This document is provided for titles and services that prefer to access ownership information via RESTful endpoints. EOS has RESTful service endpoints for direct online ownership verification, creating and validating an ownership token that can be passed between clients and services, and entitlements services for querying, enumerating and consuming entitlement records.

The method used for ownership verification depends on the use case. The online method can be used by your game client or your game server by integrating with our endpoints directly. The ownership verification token method provides a token that includes information about the game client, user, and entitlement as well as a signature that can be verified by your game client or any other service. If integrating with a third-party service that performs ownership verification, it is preferred to use the ownership verification token check to avoid granting them access to a user's data.

Ownership checks walk the full tree to determine whether a user has access to a given catalogItemId. Entitlements are useful for validating specific transactions have taken place. For example, in the case of a user that purchases a Deluxe Edition of a game, which includes a Season Pass, which itself includes access to DLC1, the ownership check will return TRUE for DLC1, versus an entitlement check that will not include DLC1.

Before getting started, you must integrate with the Authentication Service to obtain an access token. Review Getting started with Epic Account Services for more information about authentication.

Direct Ownership Verification

The endpoint to check if a user owns an item, or a list of items.

https://api.epicgames.dev/epic/ecom/v1/platforms/EPIC/identities/{{currentAccountId}}/ownership?nsCatalogItemId={{sandboxId:catalogItemId}}

This endpoint applies to auth tokens obtained via SDK 1.5+ or via OAuth OpenID Connect exchange implemented using configuration 'https://api.epicgames.dev/epic/oauth/v1/.well-known/openid-configuration'

You need to pass an access token in the Authorization header using Bearer authorization.

This endpoint supports the following query parameters:

ParameterDescription
nsCatalogItemIdIn the format of {{sandboxId:catalogItemId}}, This parameter can be repeated to check multiple sandboxId and catalogItem combinations.
sandboxIdThis parameter can be used to obtain the full list of owned catalogItemIds in a given sandbox.

The following snippet shows a sample request to get the ownership information:

GET /epic/ecom/v1/platforms/EPIC/identities/12abc3de456f78901a2bc345dd6789e0/ownership HTTP/1.1
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e
nsCatalogItemId=fn:ff150af93c9a4fb99fee12f5db49fa5b&nsCatalogItemId=fn:94egdb6df476d45199f6be940aa1337c0
[
{
"namespace": "fn",
"itemId": "94egdb6df476d45199f6be940aa1337c0",
"owned": false
},
{
"namespace": "fn",
"itemId": "ff150af93c9a4fb99fee12f5db49fa5b",
"owned": true
}
]

Token-based Ownership Verification

An Ownership Verification Token is a signed JWT with a five-minute expiration. It is signed using RS512 (RSA PKCS#1 signature with SHA-512, RSA key size 2048).

There are two steps to perform the token baesd ownership verification:

  1. Request an ownership verification token

  2. Use the public key to verify the token is genuine

Once the game client/server obtains the Ownership Verification Token, it can be passed to any integration that needs to perform ownership verification. The integration verifying the token will need to unpack the JWT to extract the kid (Key ID), then fetch the public key for that Key ID to verify the signature.

The token contains the following claims:

ClaimDescription
jtiA unique identifier for this token.
subThe account ID for the account that was used to request the token.
clidThe client ID for the client that was used to request the token.
entAn array of entitlements ownership that were verified for this token. If this value is empty, the account is not entitled to the requested entitlements
iatTime when the token was issued as a Unix timestamp.
expTime when the token expires as a Unix timestamp.

Requesting an Ownership Verification Token

To request an ownership verification token, the client will make an HTTP POST request to the ownership token endpoint.

The endpoint to request an ownership verification token is:

https://api.epicgames.dev/epic/ecom/v1/platforms/{platform}/identities/{identityId}/ownershipToken

You will need to pass an access token in the Authorization header using Bearer authorization.

This endpoint supports the following request body parameters:

Note: The Content-Type needs to be "application/x-www-form-urlencoded" and the parameter needs to be in the request body.

ParameterDescription
nsCatalogItemIdIn the format of {{sandboxId:catalogItemId}}, This parameter can be repeated to check multiple sandboxId and catalogItem combinations.

The following snippet shows a sample request to get a verification token:

POST /epic/ecom/v1/platforms/EPIC/identities/{{currentAccountId}}/ownershipToken HTTP/1.1
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e
nsCatalogItemId=fn:c204662afac64acd8a2117590be477da
{
"token": "egoc1~eyJraWQiOiJWbWdpMDFoQ2V2dXVEbUtWZFZubXphWnhpT2lBa0dEZWdRQmdDdWc4dkRZIiwiYWxnIjoiUlM1MTIifQ.eyJzdWIiOiI5NGVkYjZkZjQ3NmQ0NTE5OWY2YmU5NDBhYTEzMzdjMCIsImlwIjoiNTAuOTguMjI2LjEwIiwiY2xpZCI6IjI5Y2VlNDJlNzExNzQ2ZTFiYmNhZmI2MjkyOWU0OGZkIiwiZW50IjpbeyJjYXRhbG9nSXRlbUlkIjoiYzIwNDY2MmFmYWM2NGFjZDhhMjExNzU5MGJlNDc3ZGEiLCJvd25lZCI6dHJ1ZSwibmFtZXNwYWNlIjoiY2F0bmlwIn1dLCJleHAiOjE1Njk5Nzg1NjUsImlhdCI6MTU2OTk3ODI2NSwianRpIjoiMzgzN2FjODhlNDJjNDE1OTlmMzI5OTNjMmViYzBhOWQifQ.CX4yEEsZph9qPaVvtpnS0sLe_9YGLic5jIOQhhk3tG88GfNLp10w5y9DbYXocDlMXdEoAsAt-33G1JOPIFzrktrOxpR_FNdQ_ozCbBCF1aTQFTYKtvrbYkpA5AIGHmy_J9jSKMq-jN4TQxoSbR0LnowiWoKp_ntibmx0titFQ0kOYBQMvwwTlLgTzUv55I6VlFl8gMBSEw1_oRIUbdNbdHJO4UwnHTeUbcUUvuAWm13BpI2P39vRjU1xx4t51kUj_yY9ISWFBSGsLgEAhH13Mm1CilaeiPsLanE1sA5B3mRMjq8KcLtkkp8JvlIrgD4e-xo_tnRSLkRyKuU0GoqNKw"
}

egoc1~ is the prefix to represent Epic Games Ownership Check. Please strip it when decoding the token.

The token includes three base64 encoded JSON objects that correspond to the JWT header, payload, and signature. Please refer to the JWT documentation for more information.

The following is a sample of the JWT header:

{
"kid": "tFC2UIhFpTM_Ea3qcOd_MqQT1cBBm9kFLSDfeJhsRG8",
"alg": "RS512"
}

The following is a sample of the JWT body:

{
"jti" : "a19c3f03edf84c0a9621ee44ff36566f",
"sub" : "d144285abee343df98c4e84572c576bb",
"clid": "44c39619da304266855c9646e1081ab5",
"iat" : 1547675438,
"exp" : 1547704238,
"ent" : [{
"catalogItemId": "c204662afac64acd8a2117590be477da",
"owned": true,
"namespace": "catnip"
}]
}

Verifying the Ownership Verification Token

To verify the signature in the token, you will need to fetch a public key. To fetch the key, you will need the Key ID (kid claim in the JWT). The response will include a JSON Web Key (JWK) that can be used to verify the signature in the JWT.

To request the Public Key, your client/service will make an HTTP request to the public keys endpoint.

The public keys endpoint is:

https://ecommerceintegration-public-service-ecomprod02.ol.epicgames.com/ecommerceintegration/api/public/publickeys/{kid}.

The following snippet shows a sample request to get a public key:

GET /ecommerceintegration/api/public/publickeys/Vmgi01hCevuuDmKVdVnmzaZxiOiAkGDegQBgCug8vDY HTTP/1.1
Host: ecommerceintegration-public-service-ecomprod02.ol.epicgames.com
{
"kty": "RSA",
"e": "AQAB",
"kid": "Vmgi01hCevuuDmKVdVnmzaZxiOiAkGDegQBgCug8vDY",
"n": "k-LHmLHW5bbiqYLmPxC77ciG4N7IuF1SUOSsnDBLneKH3ZAU9kXRkq5MYjmRjxt8g3HpXmmhi_sHe4_g-VnSrM7jP6ntMiJ5t0d5J9ERkSEUSY4w_LS_YECavTr76GiutV_xPT-9jpHJWdVYqk68tiqR42xPFHEFUkYYsb_t6gONhth85ICnVY8Mjg6F0hFvvaMvOJcDVYfQbdjWY8-mzvIF9DmvyVkWaZSQYBaVuNCNKkSiSnkyCtbrynneayugwW0R-rNP5lEcp8UwXpBnep6sRf8nQEsByCnR91RdRXjuvrCSl7fOxpFX82t2WjWTYEOkOgb6yGc_ft-sJidSIQ"
}

Direct Entitlement Enumeration

The endpoint to check in cases where you need to get a list of direct entitlements for accounts.

https://api.epicgames.dev/epic/ecom/v1/identities/{identityId}/entitlements

If you just need to check the ownership, please use the ownership check APIs above which is recommended by Epic.)

You will need to pass an access token in the Authorization header using Bearer authorization.

This endpoint supports the following query parameters:

ParameterDescription
sandboxIdThe namespace for the game title.
entitlementNameOptional. The name of the entitlement. If not provided, all entitlements under the sandboxId will be returned. This parameter can be repeated to check multiple entitlements.
includeRedeemedOptional. This parameter specifies whether to include entitlements that have been redeemed. This defaults to false. If not set to true, the result will only include entitlements that have NOT been redeemed.

The following snippet shows a sample request to get all entitlements for user and sandbox:

GET /api.epicgames.dev/epic/ecom/v1/identities/12abc3de456f78901a2bc345dd6789e0/entitlements HTTP/1.1
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e
[{
"id": "8894469f1120432095eff043a4529433",
"entitlementName": "942e8a7133464f0ea83179030536505e",
"namespace": "buffalo",
"catalogItemId": "942e8a7133464f0ea83179030536505e",
"entitlementType": "AUDIENCE",
"grantDate": "2019-01-04T21:34:24.826Z",
"consumable": false,
"status": "ACTIVE",
"useCount": 0,
"entitlementSource": "AppEpicgamesCom"
},
{
"id": "e21aa0b339ae4e778971058c9395b2b7",
"entitlementName": "25ed76af7816430cbfc0f5e6d3195d56",
"namespace": "badger",
"catalogItemId": "25ed76af7816430cbfc0f5e6d3195d56",
"entitlementType": "AUDIENCE",
"grantDate": "2019-01-16T04:42:06.270Z",
"consumable": false,
"status": "ACTIVE",
"useCount": 0,
"entitlementSource": "LauncherWeb"
}]

Token-based Entitlement Verification

An Entitlement Verification Token is a JWT signed using RS512 (RSA PKCS#1 signature with SHA-512, RSA key size 2048), which expires 5 minutes after it is created.

There are two steps to perform token-based entitlement verification:

  1. Request an entitlement verification token

  2. Use the public key to verify the token is genuine

Once the game client/server obtains the Entitlement Verification Token, it can be passed to any integration that needs to perform ownership verification. The integration verifying the token will need to unpack the JWT to extract the kid (Key ID), then fetch the public key for that Key ID to verify the signature.

The token contains the following claims:

Entitlement Verification Token Claims
jtiA unique identifier for this token.
subThe account ID for the account that was used to request the token.
clidThe client ID for the client that was used to request the token.
entAn array of entitlements that were verified for this token. If this value is empty, the account is not entitled to the requested entitlement or any entitlement for the sandboxId.
iatTime when the token was issued as a Unix timestamp.
expTime when the token expires as a Unix timestamp.

Requesting an Entitlement Verification Token

To request an entitlement verification token, the client will make an HTTP POST request to the entitlement token endpoint.

The endpoint to request an entitlement verification token is https://api.epicgames.dev/epic/ecom/v1/platforms/{platform}/identities/{identityId}/entitlementToken

You will need to pass an access token in the Authorization header using Bearer authorization.

This endpoint supports the following request parameters:

Request Parameters
sandboxIdThe namespace for the game title.
entitlementName(Optional) The name of the entitlement. If not provided, all entitlements under the sandboxId will be returned. This parameter can be repeated to check multiple entitlements.

The following snippet shows a sample request to get a verification token:

POST
/epic/ecom/v1/platforms/EPIC/identities/12abc3de456f78901a2bc345dd6789e0/entitlementToken HTTP/1.1
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e
sandboxId=2bd59d629cda497b9f65dbdbee7d443s
{
"token": "egoc1~eyJraWQiOiJ0RkMyVUloRnBUTV9FYTNxY09kX01xUVQxY0JCbTlrRkxTRGZlSmhzUkc4IiwiYWxnIjoiUlM1MTIifQ. eyJqdGkiOiJhMTljM2YwM2VkZjg0YzBhOTYyMWVlNDRmZjM2NTY2ZiIsInN1YiI6ImQxNDQyODVhYmVlMzQzZGY5OGM0ZTg0NTcyYzU3NmJiIiwiY2xpZCI6IjQ0YzM5NjE5ZGEzMDQyNjY4NTVjOTY0NmUxMDgxYWI1IiwiaWF0IjoxNTQ3Njc1NDM4LCJleHAiOjE1NDc3MDQyMzgsImVudCI6W3siaWF0IjoxNTQ3Njc1MDAwLCJuYmYiOjE1NDc2NzkwMDAsInNyYyI6IkVQSUMiLCJucyI6InNuYXBkcmFnb24iLCJpdGVtIjoiMTJmYjdkNTBiYmJhNGQwNTlkNWJhYzJlOGUyNzZkMmYiLCJ0eXBlIjoiRU5USVRMRU1FTlQiLCJuYW1lIjoiNDNlZDI4ZTU3N2FiNGMyYThjZWEyN2Q2YjQ0YmJhMTgiLCJjb25zIjoxLCJ1c2NudCI6MH1dfQ.JHFFCjxmcKQDBGWaas53PsvaqeobK_kLZDgw3Je9Btwx5AzmmnW8TGUQGgr-FdZEkpdP2N_TMYV2UBO91QG1ApvwCYrvW3IYBwtl3_9e3NA1QrNLqw2qxG9X8LPiowh0gRO7rpJJ4BwbrYBwImcyf0KPhmCEKkHI9XiDsZDkoD8"
}

Note: egoc1~ is the prefix to represent Epic Games Ownership Check. Please strip it when decoding the token

The token includes three base64 encoded JSON objects that correspond to the JWT header, payload, and signature. Please refer to the JWT documentation for more information.

The following is a sample of the JWT header:

{
"kid": "tFC2UIhFpTM_Ea3qcOd_MqQT1cBBm9kFLSDfeJhsRG8",
"alg": "RS512"
}

The following is a sample of the JWT body:

{
"jti" : "a19c3f03edf84c0a9621ee44ff36566f",
"sub" : "d144285abee343df98c4e84572c576bb",
"clid": "44c39619da304266855c9646e1081ab5",
"iat" : 1547675438,
"exp" : 1547704238,
"ent" : [{
"grantDate" : 1547375000,
"startDate" : 1547375000,
"endDate" : (timestamp, optional),
"platformType" : "EPIC",
"namespace" : "tbd",
"catalogItemId" : "tbd",
"entitlementType" : "AUDIENCE",
"entitlementName" : "43ed28e577ab4c2a8cea27d6b44bba18",
"consumable" : false,
"useCount" : 0
}]
}

Verifying the Entitlement Verification Token

To verify the signature in the token, you will need to fetch a public key. To fetch the key, you will need the Key ID (kid claim in the JWT). The response will include a JSON Web Key (JWK) that can be used to verify the signature in the JWT.

To request the Public Key, your client/service will make an HTTP request to the public keys endpoint.

The public keys endpoint is https://ecommerceintegration-public-service-ecomprod02.ol.epicgames.com/ecommerceintegration/api/public/publickeys/{kid}

The following snippet shows a sample request to get a public key:

GET /ecommerceintegration/api/public/publickeys/Vmgi01hCevuuDmKVdVnmzaZxiOiAkGDegQBgCug8vDY HTTP/1.1
Host: ecommerceintegration-public-service-ecomprod02.ol.epicgames.com
{
"kty": "RSA",
"e": "AQAB",
"kid": "Vmgi01hCevuuDmKVdVnmzaZxiOiAkGDegQBgCug8vDY",
"n": "k-LHmLHW5bbiqYLmPxC77ciG4N7IuF1SUOSsnDBLneKH3ZAU9kXRkq5MYjmRjxt8g3HpXmmhi_sHe4_g-VnSrM7jP6ntMiJ5t0d5J9ERkSEUSY4w_LS_YECavTr76GiutV_xPT-9jpHJWdVYqk68tiqR42xPFHEFUkYYsb_t6gONhth85ICnVY8Mjg6F0hFvvaMvOJcDVYfQbdjWY8-mzvIF9DmvyVkWaZSQYBaVuNCNKkSiSnkyCtbrynneayugwW0R-rNP5lEcp8UwXpBnep6sRf8nQEsByCnR91RdRXjuvrCSl7fOxpFX82t2WjWTYEOkOgb6yGc_ft-sJidSIQ"
}

Query Offers

To request the list of available catalog offers for a user, the client makes an HTTP GET request to the offers endpoint.

The endpoint to request a list of catalog offers defined with Epic Online Services is shown below:

https://api.epicgames.dev/epic/ecom/v1/identities/{identityId}/namespaces/{sandboxID}/offers/

This API provides the same data as the SDK API EOS_Ecom_QueryOffers. See the EOS API Reference documentation for more information on using the SDK API.

You need to pass an access token in the Authorization header using Bearer authorization.

The following snippet shows a sample request to request offers for a user and sandbox:

GET
/ecom/v1/identities/12abc3de456f78901a2bc345dd6789e0/namespaces/8894469f1120432095eff043a4529433/offers/
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e

The following is a sample response from the server for a virtual currency offer:

{
"elements": [
{
"id": "123ca45c67a8487895811a1234567890",
"namespace": "tbd",
"title": "1500 Coins",
"description": "1500 Coins",
"longDescription": "",
"availableForPurchase": true,
"purchaseLimit": 1,
"purchasedCount": 0,
"priceInfo": {
"currencyCode": "USD",
"discountPrice": 0,
"originalPrice": 0,
"discountPercentage": 0,
"decimals": 2
},
"releaseDate": "2099-02-01T08:00:00.000Z",
"effectiveDate": "2099-02-01T08:00:00.000Z",
"keyImages": [
{
"type": "OfferImage",
"url": "https://offer/image/url",
"md5": "tbd",
"width": 1200,
"height": 1600,
"size": 651591,
"uploadedDate": "2022-05-12T22:29:48.971Z"
},
{
"type": "ProductLogo",
"url": "https://product/logo/url",
"md5": "tbd",
"width": 400,
"height": 400,
"size": 42030,
"uploadedDate": "2022-06-07T19:48:31.668Z"
}
],
"items": [
{
"id": "12c3f456f7bf89e0bbc1234c567d890d",
"namespace": "tbd",
"title": "1500 Coins Audience",
"itemType": "CONSUMABLE",
"entitlementName": "12c3f456f7bf89e0bbc1234c567d890d",
"description": "1500 Coins Audience",
"developer": "Epic Games",
"keyImages": [],
"releaseInfo": []
}
],
"offerType": "VIRTUAL_CURRENCY"
}
],
"paging": {
"count": 100,
"start": 0,
"total": 17
}
}

How you read the currency values in the priceInfo struct depends on the value of the decimals field. If decimals has a value of 2 (USD, CAD, Euro, etc.), then the value of the discountPrice and originalPrice fields is given in cents. So, to convert the value to whole dollar amounts, divide the amount by 100 (e.g. 350 equals 3.50 USD).

If the decimals field has a value of 0 (JPY, KRW, etc.), then the values for the other fields are exactly what they say for the specified currency. No conversion is required.

Redeem/Consume Entitlements

The endpoint to redeem/consume an entitlement. Once an entitlement is redeemed, the entitlement's status will be changed to inactive.

https://api.epicgames.dev/epic/ecom/v1/identities/{identityId}/entitlements/redeem

You need to pass an access token in the Authorization header using Bearer authorization.

This endpoint supports the following request body:

{
"entitlementIds": [
"8894469f1134432095eff043a4529433",
"25ed76af9816430cbfc0f5e6d3195d56"
],
"sandboxId": "8894469f1120432095eff043a4529433"
}

The following snippet shows a sample request to redeem multiple entitlements for a user and sandbox:

PUT
/ecom/v1/identities/12abc3de456f78901a2bc345dd6789e0/entitlements/redeem
Host: api.epicgames.dev
Authorization: Bearer 1fe59d629cda497b9f65dbdbee7d468e
Content-Type: application/json
Request body:
{
"entitlementIds": [
"8894469f1134432095eff043a4529433",
"25ed76af9816430cbfc0f5e6d3195d56"
],
"sandboxId": "8894469f1120432095eff043a4529433"
}