Purpose: Field-by-field map of what the Seller API exposes for store sync and checkout. Use this when building a catalog mirror or asking “is field X on list, detail, or allocations?”
Related: Sellable SKU readiness, Pricing authority.
How to read this document#
| Column | Meaning |
|---|---|
| Seller API | Endpoint(s) that expose it (or — if not exposed) |
| Status | exposed · runtime-only (returned but not in OpenAPI) · console-only · webhook-only · intentionally omitted |
Three surfaces (by design)#
Integrators merge browse, rich metadata, and checkout authority:
| Surface | Endpoints | Role |
|---|---|---|
| Browse / mirror | GET /products, GET /catalog/snapshot, GET /catalog/changes | Fast sync; presentation-oriented (may include non-sellable products) |
| Rich metadata | GET /products/{id}, GET /products/{id}/pricing | Store copy, edition tree, list prices |
| Checkout authority | GET /allocations, GET /availability | sellable, wholesale price, stock headroom |
Merge catalog with allocations (paginated) so sellability comes from GET /allocations
(sellable: true), not from catalog lists alone. Use GET /catalog/changes?since= for
tombstones and GET /catalog/checksum for mirror drift detection. Echo
expectedUnitPriceCents from preview on every commercial commit. See
Client & helpers for optional typed-client generation.
Identity & taxonomy#
| Field | Seller API | Status | Notes |
|---|---|---|---|
id | List, detail, allocations | exposed | UUID |
readableId | List, detail | exposed | e.g. prd_… |
name, slug | List, detail, allocations (productName) | exposed | |
productType | List, detail | exposed | Closed set: game, dlc, expansion, bundle, edition, soundtrack, currency, other |
productCategory | — | intentionally omitted | Console / vendor only |
status (legacy rollup) | List, detail | exposed (deprecated) | Derived from the lifecycle dimensions; use launchPhase / tradingState / isArchived |
createdAt | List, detail | exposed | |
updatedAt | List, detail | exposed | Watermark for updatedSince |
developer, publisher (display strings) | — | intentionally omitted | Store credits |
relatedProducts[] (requires / includes / edition_of) | Detail + catalog snapshot | exposed | DLC→base (requires), bundle contents (includes), edition lineage (edition_of); only seller-visible targets listed. Preview adds advisory warnings: ["REQUIRES_BASE_GAME"] |
parentProductId, child products | Via relatedProducts (raw ids not exposed) | exposed | Superseded by relatedProducts[] |
Lifecycle#
| Field | Seller API | Status | Notes |
|---|---|---|---|
launchPhase | List, detail (product + per release), webhooks product.updated, product.announced, release.available | exposed | Product-level rollup; release-level effective (inheritance + date auto-advance) |
tradingState | List, detail (product + per release), webhook product.updated | exposed | |
isArchived | List, detail, webhook product.updated | exposed | Archived products are not listed; field is false on visible rows |
announceDate | — | intentionally omitted | |
allowedBusinessModels | — | intentionally omitted | Grant-level on allocations |
Transact paths reject non-live products (PRODUCT_NOT_SELLABLE). Catalog list may still show announced-only products.
Vendor / connection#
| Field | Seller API | Status | Notes |
|---|---|---|---|
publisherCompanyId, publisherCompanyName | List, detail, allocations, partners | exposed | |
publisherCompanyDescription | Detail, partners | exposed | Not store copy |
publisherWebsite, publisherCountry | List, detail, partners | exposed | |
publisherCompanyImageUrl | List, detail, partners | exposed | |
| BMA / share / contract summary | GET /partners contracts | exposed | Not per-product on list |
Store copy & media#
| Field | Seller API | Status | Notes |
|---|---|---|---|
shortDescription (preferred locale) | List, detail | exposed | locale / Accept-Language |
longDescription, keyFeatures, legalText | Detail localizedDescriptions, edition fields | exposed / runtime-only | |
localizedDescriptions[] | Detail | runtime-only | All locales |
settlementWarnings | POST /orders as warnings[] | exposed | Internal name on the pull result; the wire name is warnings, documented in OpenAPI. What the settlement noticed but did not refuse over (D15), so a store hears about a declared rate that disagreed with its own amounts at the moment of sale rather than from a statement. |
supportedLanguages | Detail | runtime-only | |
eula[] | Detail | runtime-only | |
coverUrl | List, detail | exposed | |
assets.screenshots/trailers/capsules | Detail | runtime-only | |
systemRequirements | Detail | runtime-only | min/recommended text |
| Release-level store copy | — | intentionally omitted | Platform-specific notes |
Taxonomy & age ratings#
| Field | Seller API | Status | Notes |
|---|---|---|---|
genres, tags, features | Detail | runtime-only | { code, name } |
| Release/platform taxonomy | — | intentionally omitted | Product-level only today |
ageRatings[] | Detail | runtime-only | authority, code, label, minAge |
| Age rating descriptors | — | intentionally omitted |
Edition / release / SKU tree#
| Field | Seller API | Status | Notes |
|---|---|---|---|
editions[] | Detail | exposed | Full tree default; expand=base strips |
| Edition copy | Detail edition fields | runtime-only | short/long/keyFeatures/differentiator |
inheritsProductDescription | Detail | runtime-only | |
releases[] platform/region | Detail | exposed | |
allowedCountries[] | Detail | exposed | ISO alpha-2 |
Preorder window / preorderUnlocked | Detail, preview preorder block | exposed | launchPhase (list/detail/snapshot) says a SKU is pre-order phase; GET /allocations sellable is the transact signal; the window dates decide acceptance on the enabled path |
skus[] | Detail | exposed | Shared SKUs only when BMA selected |
skuType, bundleItems | Detail, availability | exposed / runtime-only | |
activation | Detail, allocations, preview lines | exposed | Guaranteed activation set — { type: worldwide | region_locked, countries }; distinct from sale territory |
externalReferences (Steam app/package) | Detail SKU | runtime-only | |
externalSkuCode | — | intentionally omitted | ERP mapping |
keyTypeCode, keyTypeName | Detail | exposed | |
List aggregates: platformNames, platforms, regions, editionNamesShared | List, snapshot | exposed | |
List sharedSkus[] per-SKU detail | List, snapshot | exposed | platform, edition, SRP per SKU |
Pricing#
| Field | Seller API | Status | Notes |
|---|---|---|---|
listPriceFromCents / listPriceCurrencyCode (US band) | List, snapshot | exposed | Browse hint, not wholesale |
Per-SKU srpPriceCents / srpCurrencyCode | List sharedSkus | exposed | Seller-scoped |
Detail pricing[] per release | Detail, /pricing | exposed | Country × currency × cents |
wholesaleFromCents (list expand) | List expand=pricing | exposed | Advisory |
pricePerKeyCents, currencyCode | GET /allocations | exposed | Authoritative wholesale |
currencyExponent | Allocations, preview, refunds, finance CSV, catalog sharedSkus[] wholesale | exposed | ISO-4217 minor-unit digits |
initialUnitPriceCents, promo, promoResolution | Preview lines, POST /orders/hold | exposed | List price before a settlement promo, the share/deal that discounted unitPriceCents, and whether promotions were readable at quote time |
initialSalePriceCents, promo | GET /finance/api-sales, GET /finance/statements lines | exposed | Billed vs list price and promo attribution (sourceType, sourceId) per sale row |
customerRegionCode / salesCountryCode, detectedCountryCode, countryMismatch, warnings | GET /finance/api-sales, statements lines, GET /transactions, api-sales CSV | exposed | Declared vs IP-resolved buyer country with a COUNTRY_MISMATCH flag; raw IP never exposed |
Settlement entry (kind, stockMovement, counterparty, promo, economics, …) | GET /activity (+ format=csv) | exposed | One feed over sale / refund / chargeback / pull / reveal at sale grain |
| Tier IDs, pricing mode, effective dates | — | intentionally omitted |
Stock & sellability#
| Field | Seller API | Status | Notes |
|---|---|---|---|
expand=availability | List, snapshot | exposed | Advisory |
GET /availability | Availability routes | exposed | Commit-time |
sellable, readinessBlockers, recommendedAction | GET /allocations, catalog sharedSkus[] | exposed | Same predicate on list/snapshot SKUs; allocations remain checkout authority |
| Plaintext keys | Order response / pull only | intentionally omitted | Never in webhooks |
errorDetails (pull result) | — | intentionally omitted | Internal carrier for guard details on failed pulls; the route merges it into the error envelope details, it is never a success-body field |
activation (type, countries) | GET /allocations, detail SKUs, preview lines, POST /orders, POST /keys/pull, POST /orders/{id}/fulfill | exposed | Guaranteed activation intersection across batches; "activates in" at delivery without a second lookup |
Catalog sync helpers#
| Field | Seller API | Status | Notes |
|---|---|---|---|
Tombstones added/updated/removed | GET /catalog/changes | exposed | Prefer over updatedSince alone. removed on archive, full delist, and access-ending unshare; updated (availability) on partial delist / visible-but-unsellable unshare |
| Catalog integrity digest | GET /catalog/checksum | exposed | |
emptyReason | List meta, snapshot meta | exposed | noActiveBma, etc. |
Media download#
| Field | Seller API | Status | Notes |
|---|---|---|---|
| Product media binary | GET /products/{productId}/media/download | exposed | Download assets referenced from product detail; follow OpenAPI query params for asset selection |
Prefer caching downloaded media on your side. Do not scrape media URLs from undocumented CDN hosts.
Integrator quick reference#
Cold start: GET /catalog/snapshot → persist meta.maxUpdatedAt
Deltas: GET /products?updatedSince= + GET /catalog/changes?since=
Sellable: GET /allocations → filter sellable:true → syncSellableCatalog()
Store page: GET /products/{id} (rich copy + edition tree)
Checkout: GET /availability + POST /orders/preview (never charge if !canFulfill)
Error mapping#
| Field | Seller API | Status | Guidance |
|---|---|---|---|
errorDetails | — | intentionally omitted | Use the documented error.details object on failed requests. |