API reference
Rate limit: API is limited to 30 requests per second (30 req/s).
Production URL
https://api.g2a.com/export/
Sandbox
The sandbox is a test environment for the API, configured in read-only mode: use it to verify integration and endpoint behaviour without live state progression on the backend. After you create an order, its state does not change — there are no further status updates as in production. The product and offer catalog is limited to sample datasets, not the full production catalog.
https://sandboxapi.g2a.com/export/
Sandbox authentication follows the same rules as production: OAuth2 client credentials, token lifetime (expires_in), and obtaining a new access token when the previous one expires (there is no separate long-lived refresh step — you call the token endpoint again, as in Authentication). The Authorization: Bearer … values in the examples are sample tokens only
| Test Client Id | Test Api Key |
|---|---|
| qdaiciDiyMaTjxMt | 74026b3dc2c6db6a30a73e71cdb138b1e1b5eb7a97ced46689e2d28db1050875 |
Date vs date-time filters
Some list endpoints accept time bounds as query parameters. The name and value format tell you which kind of bound it is:
- Calendar date (no clock time) — parameters are named like
dateFromanddateTo. Values are an ISO 8601 date only:YYYY-MM-DD(year, month, day;MMis two-digit month). Example:2026-01-15. Used on Get orders history for filtering by order creation day. - Date-time (instant in time) — parameters carry an “updated at” / timestamp style name and values are an ISO 8601 date-time (RFC 3339), e.g.
2026-03-01T00:00:00Z. OpenAPI represents these asformat: date-time. Used on Get product offers (list) asupdatedAtFromandupdatedAtTofor filtering by last offer update time.
In the published OpenAPI components, reusable string schemas are named Date (calendar day only, format: date) and DateTime (instant in time, format: date-time). Query parameters and response fields that use those semantics reference these schemas.
Do not send a time-of-day component to dateFrom / dateTo; do not send a bare YYYY-MM-DD to updatedAtFrom / updatedAtTo unless your client serializes it as a full RFC 3339 date-time the API accepts.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /export/v1/product-offers | Get product offers (list) — paginated list of products with individual offers, filterable by update time or product ID |
| GET | /export/v1/product-offers/{productId} | Get product offers (single) — fetch a single product with its available offers, filterable by price and quantity |
| GET | /export/v1/products | Get products — fetch rich catalog metadata, media, and offer summary for one or more products |
| POST | /export/v1/orders | Create order — create an order with one or more products |
| GET | /export/v1/orders/{orderId}/keys | Get order keys — retrieve keys for an order |
| GET | /export/v1/orders | Get orders history — retrieve orders history |
Error response format
Errors are returned as JSON with an error object:
- code — string error code (e.g.
validation-error,order-not-found) - message — human-readable message
- status — HTTP status code
- traceId — optional; OpenTelemetry trace ID for debugging
- errors — optional array of sub-errors with
code,message, and optionalfield
Additionally, each response includes a traceId header.
When contacting support about any issue, include this traceId so the request can be quickly located in logs.
HTTP status codes
| Code | Meaning | Typical error codes |
|---|---|---|
| 200 | OK | — |
| 400 | Bad request | Depends on endpoint. Examples: validation-error; for create order also cart-validation-error, offer-not-available, max-price-exceeded, product-excluded; for Get order keys also order-not-complete, order-expired. |
| 401 | Unauthorized | unauthorized |
| 402 | Payment required | insufficient-funds, payment-went-wrong, payment-not-configured, order-not-paid |
| 400 | Not found | order-not-found |
| 409 | Conflict | idempotency-key-processing |
| 410 | Gone | order-auto-refund-image-keys |
| 422 | Unprocessable entity | idempotency-key-already-used |
| 500 | Internal server error | internal-server-error |