Offer
The Offer object represents a purchasable pricing option for a product.
An Offer object represents a specific pricing configuration for a Product that customers can purchase. Offers define the price, currency, region availability, and subscription terms (if applicable).
A single Product can have multiple offers to support different regions, currencies, or pricing tiers. Offers can include product keys for digital goods that are automatically delivered upon purchase. Discounts can be applied to offers to reduce the price.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /v0/offers/list | List and filter offers |
POST | /v0/offers/create | Create a new offer |
GET | /v0/offers/{offerId} | Retrieve an offer |
PATCH | /v0/offers/{offerId}/update | Update an offer |
PATCH | /v0/offers/{offerId}/archive | Archive an offer |
POST | /v0/offers/{offerId}/keys/add | Add product keys |
DELETE | /v0/offers/{offerId}/keys/removeAllUnsold | Remove every unsold key |
DELETE | /v0/offers/{offerId}/keys/{keyId}/removeUnsold | Remove one unsold key |
Showing a price with tax
An offer's price is the pre-tax amount. To display a gross price on a product page, quote it with
POST /v0/tax/calculate — pass the offerId, a quantity, and the customer's country (plus
state for accurate US/CA rates). You get back amountSubtotal, amountTax, amountTotal and a
taxBreakdown, all in the smallest currency unit.
For business buyers, send customerType: "company" with taxId and taxNumber. The VAT-ID is
checked against the EU VIES registry and the quote matches what checkout will charge — a verified EU
VAT-ID returns 0% (reverse charge), anything else returns the standard destination rate.
vatVerification tells you which happened and why. Read amountTax to know what will be charged,
not reverseChargeEligible, which only says the destination offers reverse charge at all.
The result is a quote, not a settled charge — the authoritative tax is recomputed at checkout from full billing details.
Full reference: Calculate product price including tax.
The Offer object
objectstringObject type identifier. Always "offer" for Offer objects.
idstringrequiredUnique identifier (UUID) for this offer.
internalIdstring | nullYour custom identifier for this offer. Use to link to your own SKU system.
namestring | nullDisplay name of the offer (e.g., "Standard Edition", "Premium Bundle").
descriptionstring | nullDescription of what's included in this offer.
pricenumberrequiredPrice in the smallest currency unit — 5999 is $59.99, not 59.99. For
Subscriptions, this is the recurring price.
Responses return minor units, but create and update take the price as a decimal amount
(59.99). Divide by the currency's decimal places when reading, multiply when writing.
Zero-decimal currencies such as JPY have no conversion: 1999 is ¥1999 in both directions.
A non-free price below the currency's smallest unit — under 0.01 for USD/PLN, under 1 for
JPY, under 0.001 for three-decimal currencies — is rejected. Prices are stored in whole
minor units, so a smaller amount cannot be represented.
originalPricenumber | nullOriginal price before any discount, in the smallest currency unit. Used to show strikethrough
pricing. Same input/output asymmetry as price above: sent as a decimal amount, returned in
minor units. Subject to the same currency-minimum rejection described for price above.
currencystringrequiredThree-letter ISO 4217 currency code (e.g., "USD", "EUR", "GBP").
statusstringrequiredCurrent offer status. Possible values: DRAFT, OPEN, CLOSED, SOLD. An offer created
through the API is always OPEN — there is no publish step. DRAFT only comes from the
dashboard.
limitinteger | nullMaximum number of units that can be sold. null means unlimited.
soldItemsintegerUnits sold so far. Compare against limit to know what is left. Defaults to 0.
regionstring | nullGeographic region this offer is restricted to. Common values: Global, Europe, United States, United Kingdom, North America, Latin America, Asia, EMEA, Rest of the World. null means no restriction — the offer is sold in every region.
platformstring | nullPlatform for digital product activation. Common values: Steam, Xbox Live, PSN, Nintendo, Epic Games, GOG.com, Origin, Battle.net, Ubisoft Connect
gtinstring | nullGlobal Trade Item Number (barcode) for the product.
warningMessagestring | nullWarning or disclaimer message to display to customers.
recurringIntervalstring | nullBilling interval for Subscriptions. Possible values: day, week, month, year
recurringIntervalCountinteger | nullNumber of intervals between billings. For example, 3 with month interval means billing every 3 months.
trialIntervalstring | nullTrial period interval type. Possible values: day, week, month, year
trialIntervalCountinteger | nullNumber of intervals for the trial period. For example, 14 with day interval means a 14-day trial.
Example response
{
"status": "success",
"data": {
"offer": {
"object": "offer",
"id": "990e8400-e29b-41d4-a716-446655440004",
"internalId": "sku_standard_us",
"name": "Standard Edition",
"description": "Base game with all launch content",
"price": 5999,
"originalPrice": 6999,
"currency": "USD",
"status": "OPEN",
"limit": 500,
"soldItems": 137,
"region": "United States",
"platform": "Steam",
"gtin": "1234567890123",
"warningMessage": null,
"recurringInterval": null,
"recurringIntervalCount": null,
"trialInterval": null,
"trialIntervalCount": null
}
}
}Subscription offer example
{
"status": "success",
"data": {
"offer": {
"object": "offer",
"id": "aa0e8400-e29b-41d4-a716-446655440005",
"internalId": "plan_pro_monthly",
"name": "Pro Plan - Monthly",
"description": "Full access to all features",
"price": 2999,
"originalPrice": null,
"currency": "USD",
"status": "OPEN",
"limit": null,
"soldItems": 42,
"region": "Global",
"platform": null,
"gtin": null,
"warningMessage": null,
"recurringInterval": "month",
"recurringIntervalCount": 1,
"trialInterval": "day",
"trialIntervalCount": 14
}
}
}Related resources
Last updated