Products
POST /products
Creates a new product within the context of a given establishment.
The current handler requires only establishmentId and stock.
Localized content should be sent in translations; top-level fields such as
name, description, extendedDescription, and additionalDetails are not
consumed by this lambda.
Endpoint
Request Body
{
"productId": "string",
"establishmentId": "string",
"stock": 0,
"establishmentValueInEuros": 0,
"valueInEuros": 0,
"value": 0,
"height": 0,
"weight": 0,
"status": "available",
"verificationDate": "2025-06-20 09:30:00",
"verifiedBy": "string",
"providerId": "string",
"provider": "string",
"dateOfObject": "string",
"reference": "string",
"gameCatalog": "string",
"category": {
"categoryId": "string"
},
"type": "string",
"certificate": false,
"isAdmin": false,
"helpLink": "string",
"prizeCategory": "legendary",
"imageUrl": "string",
"featuredImageUrl": "string",
"featured": false,
"digital": false,
"isImport": false,
"medias": [
{
"example_key": "string"
}
],
"year": 0,
"order": 0,
"translations": {
"example_key": {
"name": "string",
"description": "string",
"extendedDescription": "string",
"additionalDetails": "string"
}
},
"currency": "string"
}| Attribute | Type | Required | Description |
|---|---|---|---|
| productId | string | No | Optional explicit product ID. Required when isImport is true. |
| establishmentId | string | Yes | Establishment identifier. If isAdmin is true, the product is stored under global. |
| stock | integer | Yes | |
| establishmentValueInEuros | number | No | Establishment-facing price in euros. The handler stores this as cents. |
| valueInEuros | number | No | Product value in euros. The handler stores this as cents. |
| value | number | No | Legacy alias for valueInEuros. When present, it takes precedence over valueInEuros. |
| height | number | No | |
| weight | number | No | |
| status | string [available, unavailable, booked, hidden, sold] | No | |
| verificationDate | string | No | Datetime in YYYY-MM-DD HH:mm:ss format. |
| verifiedBy | string | No | |
| providerId | string | No | |
| provider | string | No | |
| dateOfObject | string | No | Legacy pass-through field currently stored without additional validation. |
| reference | string | No | Legacy pass-through field currently stored without additional validation. |
| gameCatalog | string | No | Legacy pass-through field currently stored without additional validation. |
| category | object | No | Only categoryId is used during creation. If omitted, the product is stored with categoryId set to none. |
| category.categoryId | string | No | |
| type | string | No | |
| certificate | boolean | No | |
| isAdmin | boolean | No | |
| helpLink | string | No | |
| prizeCategory | string [legendary, epic, rare, uncommon, common, virtual] | No | |
| imageUrl | string | No | |
| featuredImageUrl | string | No | |
| featured | boolean | No | |
| digital | boolean | No | |
| isImport | boolean | No | |
| medias | array<object<{key}: object>> | No | Media entries are stored as provided. |
| medias[] | object<{key}: object> | No | |
| medias[].{key} | object | No | |
| year | integer | No | |
| order | number | No | |
| translations | object<{key}: object> | No | Locale-keyed content used by product listing and search. |
| translations.{key} | object | No | |
| translations.{key}.name | string | No | |
| translations.{key}.description | string | No | |
| translations.{key}.extendedDescription | string | No | |
| translations.{key}.additionalDetails | string | No | |
| currency | string | No |
Responses
200
Product created successfully.
{
"message": "Product created successfully",
"productId": "string"
}| Attribute | Type | Required | Description |
|---|---|---|---|
| message | string | No | |
| productId | string | No |
400
Bad request for create flows that require an explicit productId, such as isImport: true.
{
"message": "NULL_PRODUCT_ID"
}| Attribute | Type | Required | Description |
|---|---|---|---|
| message | string | No |
422
Invalid product payload.
{
"example_key": [
"string"
]
}| Attribute | Type | Required | Description |
|---|---|---|---|
| {key} | array<string> | No | |
| {key}[] | string | No |
500
Failed to create product.
POST /products/search
Searches products for the authenticated establishment with pagination,
sorting, optional text query, and filter metadata.
This endpoint is handled by /code/productListFilter.js.
Endpoint
Request Body
{
"query": "string",
"pagination": {
"page": 1,
"limit": 25,
"cursor": "string"
},
"sort": {
"field": "string",
"order": "asc"
},
"filters": {
"types": [
"string"
],
"categories": [
"string"
],
"status": [
"string"
],
"priceRange": {
"min": 0,
"max": 0
},
"stock": {
"min": 0
},
"catalogId": "string",
"locale": "string"
}
}| Attribute | Type | Required | Description |
|---|---|---|---|
| query | string | No | |
| pagination | object | No | |
| pagination.page | integer | No | |
| pagination.limit | integer | No | |
| pagination.cursor | string | No | |
| sort | object | No | |
| sort.field | string | No | |
| sort.order | string [asc, desc] | No | |
| filters | object | No | |
| filters.types | array<string> | No | |
| filters.types[] | string | No | |
| filters.categories | array<string> | No | |
| filters.categories[] | string | No | |
| filters.status | array<string> | No | |
| filters.status[] | string | No | |
| filters.priceRange | object | No | |
| filters.priceRange.min | number | No | |
| filters.priceRange.max | number | No | |
| filters.stock | object | No | |
| filters.stock.min | integer | No | |
| filters.catalogId | string | No | |
| filters.locale | string | No |
Responses
200
Products search result.
{
"data": [
{
"productId": "00000000-0000-0000-0000-000000000000",
"establishmentId": "string",
"name": "string",
"provider": "string",
"status": "string",
"type": "string",
"stock": 0,
"reserved": 0,
"price": 0,
"establishmentValueInEuros": 0,
"priceSource": "string",
"ruleName": "string",
"verificationDate": "2026-01-01T00:00:00.000Z",
"imageUrl": "string",
"translations": {
"example_key": {
"name": "string",
"description": "string",
"extendedDescription": "string",
"additionalDetails": "string"
}
},
"category": {
"categoryId": "string",
"name": "string",
"translations": {}
},
"catalogs": [
{
"catalogId": "string",
"name": "string",
"category": "string"
}
]
}
],
"pagination": {
"page": 0,
"limit": 0,
"total": 0,
"hasMore": false,
"nextCursor": "string"
},
"metadata": {
"categories": [
"string"
],
"types": [
"string"
],
"statuses": [
"string"
],
"filters": {
"categories": [
{
"categoryId": "string",
"name": "string",
"translations": {}
}
]
}
}
}| Attribute | Type | Required | Description |
|---|---|---|---|
| data | array<object> | No | |
| data[] | object | No | |
| data[].productId | string(uuid) | No | |
| data[].establishmentId | string | No | |
| data[].name | string | No | |
| data[].provider | string | No | |
| data[].status | string | No | |
| data[].type | string | No | |
| data[].stock | integer | No | |
| data[].reserved | integer | No | |
| data[].price | number | No | |
| data[].establishmentValueInEuros | number | No | |
| data[].priceSource | string | No | |
| data[].ruleName | string | No | |
| data[].verificationDate | string(date-time) | No | |
| data[].imageUrl | string | No | |
| data[].translations | object<{key}: object> | No | |
| data[].translations.{key} | object | No | |
| data[].translations.{key}.name | string | No | |
| data[].translations.{key}.description | string | No | |
| data[].translations.{key}.extendedDescription | string | No | |
| data[].translations.{key}.additionalDetails | string | No | |
| data[].category | object | No | |
| data[].category.categoryId | string | No | |
| data[].category.name | string | No | |
| data[].category.translations | object | No | |
| data[].catalogs | array<object> | No | |
| data[].catalogs[] | object | No | |
| data[].catalogs[].catalogId | string | No | |
| data[].catalogs[].name | string | No | |
| data[].catalogs[].category | string | No | |
| pagination | object | No | |
| pagination.page | integer | No | |
| pagination.limit | integer | No | |
| pagination.total | integer | No | |
| pagination.hasMore | boolean | No | |
| pagination.nextCursor | string | No | |
| metadata | object | No | |
| metadata.categories | array<string> | No | |
| metadata.categories[] | string | No | |
| metadata.types | array<string> | No | |
| metadata.types[] | string | No | |
| metadata.statuses | array<string> | No | |
| metadata.statuses[] | string | No | |
| metadata.filters | object | No | |
| metadata.filters.categories | array<object> | No | |
| metadata.filters.categories[] | object | No | |
| metadata.filters.categories[].categoryId | string | No | |
| metadata.filters.categories[].name | string | No | |
| metadata.filters.categories[].translations | object | No |
422
Invalid search payload.
500
Failed to list products.
GET /products/[productId]
Retrieves the details of a specific product by its ID. Returns complete metadata, including category, availability, and configuration.
Endpoint
Parameters
| Attribute | Description | Type | Location | Required |
|---|---|---|---|---|
| productId | string | path | Yes |
Responses
200
Product retrieved successfully.
{
"catalogs": {},
"internalPrice": 0,
"status": "string",
"reserved": 0,
"stock": 0,
"establishmentId": "string",
"weight": 0,
"probability": 0,
"valueInEuros": 0,
"provider": "string",
"verificationDate": "2026-01-01T00:00:00.000Z",
"featured": false,
"productId": "00000000-0000-0000-0000-000000000000",
"visible": false,
"certificate": false,
"order": 0,
"isAdmin": false,
"digital": false,
"helpLink": "string",
"providerId": "string",
"medias": [
"string"
],
"height": 0,
"year": 0,
"verifiedBy": "string",
"category": "string",
"prizeCategory": "string",
"price": 0,
"type": "string",
"translations": {
"example_key": {
"name": "string",
"description": "string",
"extendedDescription": "string",
"additionalDetails": "string"
}
}
}| Attribute | Type | Required | Description |
|---|---|---|---|
| catalogs | object | No | |
| internalPrice | number | No | |
| status | string | No | |
| reserved | integer | No | |
| stock | integer | No | |
| establishmentId | string | No | |
| weight | integer | No | |
| probability | number | No | |
| valueInEuros | number | No | |
| provider | string | No | |
| verificationDate | string(date-time) | No | |
| featured | boolean | No | |
| productId | string(uuid) | No | |
| visible | boolean | No | |
| certificate | boolean | No | |
| order | number | No | |
| isAdmin | boolean | No | |
| digital | boolean | No | |
| helpLink | string | No | |
| providerId | string | No | |
| medias | array<string> | No | |
| medias[] | string | No | |
| height | integer | No | |
| year | integer | No | |
| verifiedBy | string | No | |
| category | string | No | |
| prizeCategory | string | No | |
| price | number | No | |
| type | string | No | |
| translations | object<{key}: object> | No | Per-locale translations; keys are language codes (e.g., 'en', 'es'). |
| translations.{key} | object | No | |
| translations.{key}.name | string | No | |
| translations.{key}.description | string | No | |
| translations.{key}.extendedDescription | string | No | |
| translations.{key}.additionalDetails | string | No |
400
Invalid product ID.
404
Product not found.
500
Error retrieving product details.
PUT /products/[productId]
Updates a product by ID. Fields such as price, stock, translations, and metadata can be modified. Only valid product data should be submitted to avoid data integrity issues.
Endpoint
Request Body
{
"stock": 0,
"price": 0,
"internalPrice": 0,
"valueInEuros": 0,
"height": 0,
"weight": 0,
"status": "available",
"verificationDate": "2026-01-01T00:00:00.000Z",
"verifiedBy": "string",
"providerId": "string",
"provider": "string",
"category": "string",
"type": "string",
"certificate": false,
"isAdmin": false,
"helpLink": "string",
"prizeCategory": "legendary",
"imageUrl": "string",
"featuredImageUrl": "string",
"featured": false,
"digital": false,
"medias": [
"string"
],
"year": 0,
"translations": {
"example_key": {
"name": "string",
"description": "string",
"extendedDescription": "string",
"additionalDetails": "string"
}
}
}| Attribute | Type | Required | Description |
|---|---|---|---|
| stock | integer | No | |
| price | integer | No | |
| internalPrice | integer | No | |
| valueInEuros | number | No | |
| height | integer | No | |
| weight | integer | No | |
| status | string [available, unavailable, booked, hidden, sold] | No | |
| verificationDate | string(date-time) | No | |
| verifiedBy | string | No | |
| providerId | string | No | |
| provider | string | No | |
| category | string | No | |
| type | string | No | |
| certificate | boolean | No | |
| isAdmin | boolean | No | |
| helpLink | string | No | |
| prizeCategory | string [legendary, epic, rare, uncommon, common, virtual] | No | |
| imageUrl | string | No | |
| featuredImageUrl | string | No | |
| featured | boolean | No | |
| digital | boolean | No | |
| medias | array<string> | No | |
| medias[] | string | No | |
| year | integer | No | |
| translations | object<{key}: object> | No | Per-locale translations; keys are language codes (e.g., 'en', 'es'). |
| translations.{key} | object | No | |
| translations.{key}.name | string | No | |
| translations.{key}.description | string | No | |
| translations.{key}.extendedDescription | string | No | |
| translations.{key}.additionalDetails | string | No |
Parameters
| Attribute | Description | Type | Location | Required |
|---|---|---|---|---|
| productId | string | path | Yes |
Responses
200
Product updated successfully.
404
Product not found.
500
Failed to update product.
DELETE /products/[productId]
Deletes a product by its ID. This operation is irreversible and will remove the product from all associated catalogs and listings.
Endpoint
Parameters
| Attribute | Description | Type | Location | Required |
|---|---|---|---|---|
| productId | string | path | Yes |
Responses
200
Product deleted successfully.
400
Invalid product ID.
404
Product not found.
500
Server error during deletion.
POST /exclusive
Requests an exclusive product lock or reservation for a limited time period. This may be used to provide VIP-only availability or time-sensitive rewards.
Endpoint
Request Body
{
"days": 0
}| Attribute | Type | Required | Description |
|---|---|---|---|
| days | number | Yes |
Responses
200
Exclusive access granted or acknowledged.
400
Invalid exclusivity request.
500
Failed to process exclusivity request.
POST /admin/exclusive
Creates or updates a product exclusivity rule for the administrator establishment.
This endpoint always stores an infinite duration using requestedDurationDays = -1.
Endpoint
Request Body
{
"productId": "00000000-0000-0000-0000-000000000000"
}| Attribute | Type | Required | Description |
|---|---|---|---|
| productId | string(uuid) | Yes |
Responses
200
Exclusive product stored successfully.
403
Admin access required.
404
Product not found.
500
Failed to upsert exclusive product.