Purchasing keys through the API
This guide walks through buying wholesale keys end-to-end via the Eneba API: finding an auction, paying with your EUR wallet, waiting for the checkout to complete, exporting the purchased keys and downloading the resulting archive.
The API checkout flow currently supports wholesale auctions only — non-wholesale listings cannot be purchased through the API at this time.
This flow requires the wholesale buyer role on your account —
purchasing and key export will reject calls made without it. Contact Eneba
support if you receive a 403 or an access-denied error.
Requirements
- You have generated API credentials and obtained an
access_token— see the Getting Started guide for the OAuth flow, environment URLs and authentication header. - Your EUR wallet has enough balance to cover the purchase. Payment is always deducted from the EUR wallet regardless of the auction currency.
Sequence diagram
The following sequence shows the successful end-to-end flow between your client, the Eneba API and the S3 download endpoint that serves the keys archive.
1. Find the auction
Search for the product you want to buy and pick the auction whose id you
will purchase. Filter by merchant when several merchants list the same
product.
Use the
P_wholesaleAuctions query.
query getWholesaleAuctions($search: String, $merchantSearch: String) {
P_wholesaleAuctions(search: $search, merchantSearch: $merchantSearch) {
edges {
node {
id
product { name }
wholesalePrice { amount currency }
wholesaleStock
merchant { displayName slug }
}
}
}
}Variables:
{ "search": "call of duty modern warfare" }Note the id of the desired auction — that is the auctionId you will pass
to the next step. The wholesaleStock field tells you how many keys are
currently available.
Price amounts are returned in cents — divide by 100 to display
the value (e.g. 1500 → €15.00).
2. Submit the purchase
Submit the purchase using the
S_purchaseWholesaleAuctions mutation.
Each call initiates an asynchronous checkout and returns an actionId you can
poll, plus the orderId of the created order.
mutation PurchaseWholesaleAuctions($input: S_API_PurchaseWholesaleAuctionsInput!) {
S_purchaseWholesaleAuctions(input: $input) {
success
orderId
actionId
}
}Variables:
{
"input": {
"items": [
{
"auctionId": "<id from step 1>",
"quantity": 1
}
]
}
}A single request supports up to 10 auction items, with
quantity between 1 and 2000 per item. All
auctionId values within one request must be unique.
A success: true response only confirms the checkout was queued — it does
not mean the purchase has completed. Poll
A_action with the
returned actionId (step 3) to track the actual outcome.
If the auction does not have enough stock when the checkout is processed,
the action will end in FAILED state at step 3. Note that the wholesaleStock
value reported by
P_wholesaleAuctions
reflects stock at query time and can change before your purchase runs.
3. Poll the checkout status
The checkout runs in the background. Poll the
A_action query with
the actionId returned in step 2 until state reaches a terminal value.
query getAction($actionId: A_Uuid!) {
A_action(actionId: $actionId) {
id
state
}
}Variables:
{ "actionId": "<actionId from step 2>" }| State | Meaning |
|---|---|
NEW | Checkout is still being processed |
COMPLETED | Purchase succeeded |
FAILED | Purchase failed |
Poll every 2–3 seconds. The query returns null if the action has not
started yet, or if 24 hours have passed since it was initiated.
4. Get the order's entryToken
Once the action is COMPLETED, fetch the order to obtain the entryToken
required to export the keys, and to confirm the orderState is FULFILLED.
Use the O_orders query.
query getOrders($first: Int) {
O_orders(first: $first) {
totalCount
edges {
node {
number
entryToken
orderState
paymentState
totalPrice { amount currency }
createdAt
items {
sellableName
quantity
totalPrice { amount currency }
}
}
}
}
}Only orders placed via the API checkout flow are returned here — orders the same account placed through the Eneba storefront will not appear.
Store the entryToken of the order you just placed — you'll use it in the
next two steps.
5. Trigger the key export
Start the asynchronous key export with the
O_exportOrderKeys mutation.
A success: true response means the export has been queued; the file itself
is produced in the background.
mutation exportOrderKeys($input: O_API_ExportOrderKeysInput!) {
O_exportOrderKeys(input: $input) {
success
}
}Variables:
{
"input": {
"entryToken": "<entryToken from step 4>"
}
}6. Poll the export status
Poll the O_orderExport
query with the same entryToken until status reaches COMPLETED and
downloadUrl is populated.
query getOrderExport($entryToken: String!) {
O_orderExport(entryToken: $entryToken) {
id
status
downloadUrl
expired
}
}Variables:
{ "entryToken": "<entryToken from step 4>" }| Status | Meaning |
|---|---|
PENDING | Export is still being generated |
COMPLETED | Archive is ready and downloadUrl is populated |
FAILED | Export failed — call O_exportOrderKeys again |
Poll every 2–3 seconds.
The downloadUrl is a presigned S3 URL valid for
30 minutes. If the URL expires, or if expired: true
is returned, call O_exportOrderKeys
again with the same entryToken to produce a fresh export.
7. Download and extract the keys
Download the archive from the presigned URL and unzip it. The archive is password-protected with the email address of the Eneba account that placed the order.
curl -o export.zip "<downloadUrl>"
unzip -P "<your-account-email>" export.zipInside the archive, each item from the order lives in its own sub-folder
containing a keys.txt file with one key per line. The folder names are
generated by the server and are not exposed in the API response — list the
archive contents (unzip -l export.zip) to discover them.