API reference
API objects
The shape of every object the GameCoin API returns, with its fields, its possible values and a real example.
On this page
This page describes the objects that the operations of the API reference return. Every example below is a real response from the test environment.
Conventions. Field names are in camelCase. A type written string or null is always present and is null when there is no value: a field is never missing. Dates are ISO 8601 strings in UTC, with milliseconds. Amounts are integers: virtual currencies in their smallest unit, euro prices in cents. Ids are 24 hexadecimal characters. Unknown fields may be added to a response in the future: ignore the ones you do not know.
Player
A person who plays your game.
| Field | Type | Description |
|---|---|---|
id | string | The GameCoin player id. |
externalId | string or null | Your own id for the player, without the ext: prefix. null for an anonymous player. |
kind | string | external for a player created by your backend, hosted for an anonymous player created by the client API. |
displayName | string or null | The name shown in your game. |
country | string or null | The ISO 3166-1 alpha-2 country, such as BE. |
blocked | boolean | true when the player is blocked: they are refused on every client route and on wallet and inventory writes. |
createdAt | string | When the player was created. |
The e-mail address and the birth year you may store with Create or update a player are never returned.
{
"id": "665f1c2e8a3b4d5e6f708192",
"externalId": "user-42",
"kind": "external",
"displayName": "Alice",
"country": "BE",
"blocked": false,
"createdAt": "2026-10-05T22:14:34.808Z"
}Balance
The balance of a player in one currency, split in two parts.
| Field | Type | Description |
|---|---|---|
currency | string | The currency code. |
paid | integer | Units bought with real money. This is the part a refund takes back. |
bonus | integer | Units granted or earned for free. |
total | integer | paid plus bonus. |
paid and total can be negative after a refund of coins that were already spent: see Refund an order.
{ "currency": "gems", "paid": 0, "bonus": 100, "total": 100 }Wallet
All the balances of a player.
| Field | Type | Description |
|---|---|---|
playerId | string | The player's id. |
balances | array of Balance | One balance per active currency, zeros included. |
{
"playerId": "665f1c2e8a3b4d5e6f708192",
"balances": [
{ "currency": "gems", "paid": 0, "bonus": 70, "total": 70 },
{ "currency": "gold", "paid": 0, "bonus": 0, "total": 0 }
]
}LedgerEntry
One immutable line of a player's ledger: what changed a balance, and the balance right after.
| Field | Type | Description |
|---|---|---|
id | string | The entry id. Ids sort by creation time. |
type | string | What produced the entry: see Ledger entry types. |
currency | string | The currency code. |
paidDelta | integer | The change of the paid part: negative when coins are taken. |
bonusDelta | integer | The change of the bonus part: negative when coins are taken. |
balanceAfter | object | The balance right after the entry: paid, bonus and total. |
reason | string or null | The reason you gave, if any. |
metadata | object | The metadata you gave: string to string pairs, {} when none. A paid order sets pack, the sku of the pack. |
ref | object | What the entry relates to: orderId for an entry caused by an order, itemSku for the purchase of an item. {} when it relates to nothing. |
createdAt | string | When the entry was written. |
A grant, with its reason and metadata:
{
"id": "6ac4214bae33663917ec0ca6",
"type": "grant",
"currency": "gems",
"paidDelta": 0,
"bonusDelta": 100,
"balanceAfter": { "paid": 0, "bonus": 100, "total": 100 },
"reason": "level_up",
"metadata": { "level": "5" },
"ref": {},
"createdAt": "2026-10-05T22:14:35.965Z"
}The delivery of a pack, written when the order was paid:
{
"id": "6ac4214aad31ce32f56b16e4",
"type": "purchase_credit",
"currency": "gems",
"paidDelta": 500,
"bonusDelta": 50,
"balanceAfter": { "paid": 500, "bonus": 50, "total": 550 },
"reason": null,
"metadata": { "pack": "gems-500" },
"ref": { "orderId": "665f1c2e8a3b4d5e6f7081b4" },
"createdAt": "2026-10-05T22:14:34.070Z"
}Ledger entry types
type | Written when | paidDelta / bonusDelta |
|---|---|---|
grant | Your backend grants currency | bonusDelta positive (a debt is repaid first) |
spend | Currency is spent, or an item is bought (ref.itemSku) | Negative |
purchase_credit | An order is paid and its pack delivered (ref.orderId) | paidDelta is the pack's amount, bonusDelta its bonus |
refund_clawback | An order is refunded (ref.orderId) | Negative |
chargeback_clawback | The cardholder disputes the payment of an order (ref.orderId) | Negative |
adjustment | A manual correction made by the studio | Either sign |
gift_code | A player redeems a gift code (metadata.code is the code) | bonusDelta positive: gift codes only give free coins |
InventoryItem
A quantity of an item that a player owns.
| Field | Type | Description |
|---|---|---|
sku | string | The sku of the item. |
quantity | integer | Units owned. 0 is possible right after a consumption, never in an inventory list. |
updatedAt | string | When the quantity last changed. |
{ "sku": "potion", "quantity": 3, "updatedAt": "2026-10-05T22:14:37.251Z" }Currency
A currency of the game.
| Field | Type | Description |
|---|---|---|
code | string | The currency code: lowercase letters, digits and _, such as gems. |
name | string | The display name. |
purchasable | boolean | true when packs can sell this currency for real money. Its balances then have a paid part. |
{ "code": "gems", "name": "Gems", "purchasable": true }Item
An item of the game: something a player can own.
| Field | Type | Description |
|---|---|---|
sku | string | The sku of the item. |
name | string | The display name. |
description | string or null | The display description. |
type | string | consumable (can be consumed) or durable (cannot). |
price | object or null | The price in a currency: currency and amount. null when the item cannot be bought with currency. |
maxOwned | integer or null | The most units a player can own. null for no limit. |
clientPurchasable | boolean | true when the client API may sell the item. |
metadata | object | Free string to string pairs set on the item in the dashboard. |
{
"sku": "potion",
"name": "Potion",
"description": null,
"type": "consumable",
"price": { "currency": "gems", "amount": 20 },
"maxOwned": null,
"clientPurchasable": true,
"metadata": {}
}Pack
A bundle of currency and items sold for real money.
| Field | Type | Description |
|---|---|---|
sku | string | The sku of the pack. |
name | string | The display name. |
description | string or null | The display description. |
priceCents | integer | The price in euro cents, VAT included. |
currency | string | Always EUR. |
grants | array | The currency delivered: currency, amount (credited to paid) and bonus (credited to bonus). |
items | array | The items delivered: sku and quantity. |
badge | string or null | A short label such as "Best value". |
maxPerPlayer | integer or null | The most paid orders a player can have for this pack. null for no limit. |
availability | PackAvailability or null | The sale window, the stock left and the founder flag. null for an ordinary pack, always on sale without limit. |
{
"sku": "starter",
"name": "Starter pack",
"description": null,
"priceCents": 99,
"currency": "EUR",
"grants": [{ "currency": "gems", "amount": 100, "bonus": 20 }],
"items": [{ "sku": "potion", "quantity": 1 }],
"badge": null,
"maxPerPlayer": 1,
"availability": null
}PackAvailability
When a pack is sold during a window, in limited quantity, or as a founder pack. See Founder packs.
| Field | Type | Description |
|---|---|---|
startsAt | string or null | When the sale starts (included), an ISO 8601 date in UTC. null when the pack is on sale from the start. |
endsAt | string or null | When the sale ends (excluded). null when it has no end. |
remaining | integer or null | The units still on sale in the environment of your key: the total stock minus the orders that are delivered, paid or pending. Never below 0. null for an unlimited stock. |
founder | boolean | true for a founder pack: sold before the launch of the game, shown with a badge and a public counter. |
{ "startsAt": "2026-10-01T00:00:00.000Z", "endsAt": "2026-12-01T00:00:00.000Z", "remaining": 312, "founder": true }Catalog
The active currencies, items and packs of the game. Archived and draft entries are left out.
| Field | Type | Description |
|---|---|---|
currencies | array of Currency | The currencies. |
items | array of Item | The items. |
packs | array of Pack | The packs. |
prelaunch | boolean | true while the game is not launched: a shop presents purchases as pre-orders. |
launchAt | string or null | The announced launch date of the game, an ISO 8601 date in UTC. null when it is not announced. |
A complete catalog is shown in Get the catalog.
Order
The purchase of a pack with real money, created by a checkout.
| Field | Type | Description |
|---|---|---|
id | string | The order id. |
playerId | string | The player who ordered. |
status | string | Where the order stands: see Order statuses. |
pack | object | The pack as it was sold: sku and name at the time of the order. |
amountCents | integer | The amount in euro cents, VAT included. |
currency | string | Always EUR. |
country | string | The buyer's country (ISO 3166-1 alpha-2), which decided the VAT. |
vatRateBp | integer | The VAT rate in basis points: 2100 is 21 %. |
vatCents | integer | The VAT included in amountCents. |
netCents | integer | amountCents minus vatCents. |
createdAt | string | When the order was created. |
paidAt | string or null | When the payment succeeded. |
fulfilledAt | string or null | When the coins and items were delivered. |
refundedAt | string or null | When the order was refunded. |
creatorCode | object or null | The creator code the buyer used: code and creatorName. The bonus and commission rates are never shown. null when no code was used. |
{
"id": "665f1c2e8a3b4d5e6f7081b4",
"playerId": "665f1c2e8a3b4d5e6f708192",
"status": "fulfilled",
"pack": { "sku": "gems-500", "name": "Bag of gems" },
"amountCents": 499,
"currency": "EUR",
"country": "BE",
"vatRateBp": 2100,
"vatCents": 87,
"netCents": 412,
"createdAt": "2026-10-05T22:14:32.995Z",
"paidAt": "2026-10-05T22:14:34.054Z",
"fulfilledAt": "2026-10-05T22:14:34.054Z",
"refundedAt": null,
"creatorCode": null
}pending → paid → fulfilled → refunded
→ chargeback
pending → failed | canceled | expiredstatus | Meaning | Final |
|---|---|---|
pending | The order is created and waits for the payment. It becomes expired after one hour. | No |
paid | The payment is confirmed and the delivery is under way. It is a step of a moment, not a state you wait in. | No |
fulfilled | The payment succeeded and the coins and items are delivered. | Until a refund |
refunded | The order was refunded and the coins and items were taken back. | Yes |
chargeback | The cardholder disputed the payment. | Yes |
failed | The payment was refused. | Yes |
canceled | The order was canceled before payment. | Yes |
expired | The order was not paid within one hour. | Yes |
Player token
A short-lived credential that lets one player act on their own wallet and inventory through the client API. Returned by Issue a player token and Get a new player token.
| Field | Type | Description |
|---|---|---|
token | string | The token, gc_pt_…, sent as Authorization: Bearer. An opaque string: do not parse it. |
expiresAt | string | When it stops working: one hour after it was issued. |
{ "token": "gc_pt_…", "expiresAt": "2026-10-05T23:14:35.000Z" }Create an anonymous player returns a token with the new player and their playerSecret:
{
"player": {
"id": "665f1c2e8a3b4d5e6f7081c6",
"externalId": null,
"kind": "hosted",
"displayName": "Guest",
"country": null,
"blocked": false,
"createdAt": "2026-10-05T22:14:41.141Z"
},
"playerSecret": "bD7QMp…",
"token": "gc_pt_…",
"expiresAt": "2026-10-05T23:14:41.000Z"
}Responses that combine objects
| Name | Returned by | Fields |
|---|---|---|
| Movement | Grant currency, Spend currency | entry (LedgerEntry), balance (Balance) |
| Purchase | Buy an item with currency | entry, balance, item (InventoryItem) |
| Checkout | Order a currency pack | order (Order), checkoutUrl (string) |
| Redemption | Redeem a gift code | grants (array of currency, amount, balance), items (array of sku, quantity), skipped (array of sku, quantity) |
| Ledger page | List ledger entries | entries (array of LedgerEntry), nextCursor (string or null) |
| Inventory | List the inventory | items (array of InventoryItem) |
| Inventory change | Grant an item, Consume an item | item (InventoryItem) |
| Me | Get the token player | player, wallet, inventory (array of InventoryItem) |
| Anonymous player | Create an anonymous player | player, playerSecret, token, expiresAt |
Error
Every response that is not a success has this body, with the HTTP status of the error.
| Field | Type | Description |
|---|---|---|
error.code | string | The stable code of the error: test this one. The codes are listed in Errors. |
error.message | string | An English message for developers, not for your players. |
error.details | object | Optional. required and available for INSUFFICIENT_FUNDS; fieldErrors for VALIDATION_FAILED: a field name (or _ for the whole body) mapped to messages or codes such as COUNTRY_NOT_SELLABLE, CURSOR_INVALID, PLAYER_REF_INVALID, URL_INVALID, URL_SCHEME_NOT_ALLOWED or ORIGIN_MISMATCH. Meant to be read, not parsed. |
{
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "Insufficient funds",
"details": { "required": 5000, "available": 70 }
}
}