Skip to main content

Get product offers (list)

Returns a paginated list of products with their individual offers, including per-offer price and quantity. This endpoint is the primary way to discover which products are available and at what prices, and to poll for changes — by filtering on updatedAtFrom/updatedAtTo you receive only products whose offer data changed within a given time window.

Typical use cases:

  • Build or refresh a local product catalog with current pricing.
  • Monitor price or availability changes by polling with a sliding updatedAtFrom window.
  • Look up offer IDs to use as offerId when placing a manual order item.

Endpoint: GET /export/v1/product-offers

Headers

HeaderRequiredDescription
AuthorizationYesBearer token obtained from the OAuth2 token endpoint. Format: Bearer <access_token>. See Authentication.

Query parameters

updatedAtFrom and updatedAtTo are date-time bounds (RFC 3339 / ISO 8601 date-time), not plain calendar dates. Contrast with dateFrom / dateTo on Get orders history; see Date vs date-time filters.

ParameterTypeRequiredDescription
productIds[]array of stringsNoFilter by specific product IDs. Each value must be exactly 14 numeric digits (e.g. 10000004439009). Up to 20 IDs per request.
updatedAtFromstring (RFC 3339 date-time)NoInclusive lower bound on last offer update. Example: 2026-03-01T00:00:00Z. Must be a full date-time, not YYYY-MM-DD alone.
updatedAtTostring (RFC 3339 date-time)NoInclusive upper bound on last offer update. Example: 2026-03-31T23:59:59Z. When both bounds are set, updatedAtFrom must not be after updatedAtTo.
pagestringNoPage number, starting at 1. Defaults to 1. Maximum: 100000.
itemsPerPagestringNoNumber of results per page. Allowed values: 10, 20, 50, 100. Defaults to 20.

Sandbox

curl --location 'https://sandboxapi.g2a.com/export/v1/product-offers' \
--header 'Authorization: Bearer rfC3vIi6zoVqZSHAlhTXslTfvMZYwWPZ'

Result ordering

Results are returned in insertion order — the order in which products were first added to the offers cache. This is not the same as updatedAt.

Custom sorting is not supported.

Example requests

Paginated feed — all products, page 2

GET /export/v1/product-offers?page=2&itemsPerPage=50

Poll for recently updated products

GET /export/v1/product-offers?updatedAtFrom=2026-03-01T00:00:00Z&updatedAtTo=2026-03-31T23:59:59Z

Fetch specific products by ID

GET /export/v1/product-offers?productIds[]=10000004439009&productIds[]=10000004439010

Success response (200)

{
"data": [
{
"id": "10000004439009",
"name": "Grand Theft Auto San Andreas Steam Key GLOBAL",
"totalQuantity": 156,
"minPrice": "1.49",
"updatedAt": "2026-03-20T10:00:00Z",
"currency": "EUR",
"offers": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"price": "1.49",
"quantity": 50
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"price": "1.89",
"quantity": 106
}
]
}
],
"meta": {
"page": 2,
"itemsPerPage": 20,
"totalResults": 150,
"hasNext": true,
"hasPrevious": true
}
}

Response fields

FieldTypeDescription
dataarrayList of products on the current page
data[].idstringProduct identifier (e.g. 10000004439009)
data[].namestringProduct name
data[].totalQuantityintegerTotal number of available items across all offers for this product
data[].minPricestring (decimal)Lowest offer price across all offers (e.g. 9.99)
data[].updatedAtstring (ISO 8601)UTC timestamp of the last offer update for this product
data[].currencystringCurrency code for all prices in this product object. Always "EUR".
data[].offersarrayUp to 3 cheapest offers for this product, sorted by price ascending
data[].offers[].idstring (UUID)Offer identifier — use as offerId in a manual order item
data[].offers[].pricestring (decimal)Price per unit for this offer
data[].offers[].quantityintegerNumber of items available from this offer
meta.pageintegerCurrent page number
meta.itemsPerPageintegerNumber of items returned per page
meta.totalResultsintegerTotal number of products matching the query
meta.hasNextbooleanWhether a next page exists
meta.hasPreviousbooleanWhether a previous page exists

Error responses

StatusDescriptionPossible error codes
400Bad requestvalidation-error — one or more query parameters failed validation; see message for details
401Unauthorizedunauthorized — missing or invalid Bearer token
500Internal server errorinternal-server-error — unexpected server-side error; contact your Key Account Manager and include the traceId from the response

validation-error (400) — the message field identifies the specific parameter and problem. Possible causes:

  • productIds[] — any supplied identifier is not exactly 14 characters long
  • productIds[] — any supplied identifier is non-numeric
  • productIds[] — any supplied identifier is below the minimum value (10000000000000)
  • productIds[] — any supplied identifier is an empty string
  • page — value is not a valid integer, or outside the allowed range 1100000
  • itemsPerPage — value is not one of the allowed values: 10, 20, 50, 100
  • updatedAtFrom or updatedAtTo — value is not a valid RFC 3339 date-time (e.g. 2026-03-01T00:00:00Z)
  • updatedAtFrom is after updatedAtTo

Example — invalid itemsPerPage:

{
"error": {
"code": "validation-error",
"message": "invalid itemsPerPage value: 15, itemsPerPage must be one of: 10, 20, 50, 100",
"status": 400
}
}

Example — invalid date-time format:

{
"error": {
"code": "validation-error",
"message": "Validation errors: updatedAtFrom must be a valid RFC3339 date-time",
"status": 400
}
}

Example — date range conflict:

{
"error": {
"code": "validation-error",
"message": "Validation errors: updatedAtFrom cannot be greater than updatedAtTo",
"status": 400
}
}