Products

The Products API allows you to create and manage products that users can redeem with their loyalty points, coins, or other currencies. Products can be badges, unique code pools, merchandise, tickets, or competition entries.

Overview

Product Types:

  • badge: Digital badges/achievements

  • unique_code_pool: Unique promo codes (one per user)

  • merchandise: Physical merchandise

  • ticket: Event tickets

  • entry: Competition entries

Key Features:

  • Stock management with reserved and available tracking

  • Automatic metadata extraction from product names/descriptions

  • SKU-based inventory tracking

  • Points/coins/XP cost configuration


Endpoints

List Products

Get a paginated list of products for your organization.

GET /v1/products

Query Parameters:

Parameter
Type
Required
Description

status

string

No

Filter by status: active, inactive, draft

type

string

No

Filter by type: badge, unique_code_pool, merchandise, ticket, entry

limit

number

No

Number of results (default: 50)

cursor

string

No

Pagination cursor from previous response

Example Request:

curl -X GET "https://api.monterosa.cloud/loyalty/v1/products?type=badge&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID"

Example Response:

{
  "success": true,
  "data": {
    "products": [
      {
        "orgId": "550e8400-e29b-41d4-a716-446655440000",
        "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "Gold Member Badge",
        "description": "Exclusive badge for Gold tier members",
        "sku": "BADGE-GOLD-001",
        "type": "badge",
        "status": "active",
        "pointsCost": 1000,
        "coinsCost": 0,
        "xpCost": 0,
        "allocatedStock": 150,
        "redeemedStock": 75,
        "metadata": {
          "category": "achievement",
          "rarity": "rare",
          "imageUrl": "https://cdn.monterosa.cloud/badges/gold.png"
        },
        "createdAt": "2025-10-01T10:00:00.000Z",
        "updatedAt": "2025-10-05T14:30:00.000Z",
        "createdBy": "[email protected]"
      }
    ],
    "cursor": "eyJwcm9kdWN0SWQiOiJwcm9kXzEyMyJ9"
  }
}

Create Product

Create a new product.

POST /v1/products

Request Body:

Field
Type
Required
Description

name

string

Yes

Product name

sku

string

Yes

Stock Keeping Unit (unique identifier)

description

string

No

Product description

type

string

Yes

Product type: badge, unique_code_pool, merchandise, ticket, entry

status

string

No

Status: active, inactive, draft (default: active)

pointsCost

number

No

Cost in points (default: 0)

coinsCost

number

No

Cost in coins (default: 0)

xpCost

number

No

Cost in XP (default: 0)

metadata

object

No

Additional metadata

extractMetadata

boolean

No

Auto-extract metadata from name/description (default: false)

Example Request:

curl -X POST "https://api.monterosa.cloud/loyalty/v1/products" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VIP Access Badge",
    "sku": "BADGE-VIP-001",
    "description": "Exclusive VIP access badge for premium members",
    "type": "badge",
    "status": "active",
    "pointsCost": 5000,
    "metadata": {
      "imageUrl": "https://cdn.monterosa.cloud/vip-badge.png",
      "category": "premium"
    },
    "extractMetadata": true
  }'

Example Response:

{
  "success": true,
  "data": {
    "orgId": "550e8400-e29b-41d4-a716-446655440000",
    "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "VIP Access Badge",
    "sku": "BADGE-VIP-001",
    "description": "Exclusive VIP access badge for premium members",
    "type": "badge",
    "status": "active",
    "pointsCost": 5000,
    "coinsCost": 0,
    "xpCost": 0,
    "allocatedStock": 0,
    "redeemedStock": 0,
    "metadata": {
      "imageUrl": "https://cdn.monterosa.cloud/vip-badge.png",
      "category": "premium",
      "extractionMethod": "ai",
      "confidence": 0.95
    },
    "createdAt": "2025-10-11T10:00:00.000Z",
    "updatedAt": "2025-10-11T10:00:00.000Z",
    "createdBy": "[email protected]"
  }
}

Get Product

Retrieve a specific product by ID.

GET /v1/products/{productId}

Path Parameters:

Parameter
Type
Required
Description

productId

string

Yes

Product ID

Example Request:

curl -X GET "https://api.monterosa.cloud/loyalty/v1/products/prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID"

Example Response:

{
  "success": true,
  "data": {
    "orgId": "550e8400-e29b-41d4-a716-446655440000",
    "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "VIP Access Badge",
    "sku": "BADGE-VIP-001",
    "type": "badge",
    "status": "active",
    "pointsCost": 5000,
    "allocatedStock": 100,
    "redeemedStock": 45,
    "createdAt": "2025-10-01T10:00:00.000Z",
    "updatedAt": "2025-10-05T14:30:00.000Z"
  }
}

Update Product

Update an existing product. Note: SKU cannot be changed after creation.

PUT /v1/products/{productId}

Path Parameters:

Parameter
Type
Required
Description

productId

string

Yes

Product ID

Request Body: Any fields from Create Product (except sku)

Example Request:

curl -X PUT "https://api.monterosa.cloud/loyalty/v1/products/prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium VIP Badge",
    "pointsCost": 6000,
    "status": "active"
  }'

Example Response:

{
  "success": true,
  "data": {
    "orgId": "550e8400-e29b-41d4-a716-446655440000",
    "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "Premium VIP Badge",
    "sku": "BADGE-VIP-001",
    "type": "badge",
    "status": "active",
    "pointsCost": 6000,
    "updatedAt": "2025-10-11T11:30:00.000Z",
    "updatedBy": "[email protected]"
  }
}

List Badges

Get all products of type badge. This is a convenience endpoint that filters products by type.

GET /v1/badges

Query Parameters: Same as List Products (type filter is automatically set to badge)

Example Request:

curl -X GET "https://api.monterosa.cloud/loyalty/v1/badges?status=active" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID"

Example Response:

{
  "success": true,
  "data": {
    "products": [
      {
        "productId": "prod_badge_001",
        "name": "First Login Badge",
        "type": "badge",
        "status": "active",
        "pointsCost": 0,
        "metadata": {
          "imageUrl": "https://cdn.monterosa.cloud/first-login.png"
        }
      }
    ],
    "cursor": null
  }
}

Extract Metadata

Manually trigger metadata extraction for a product. This uses AI/ML to extract relevant information from the product name and description.

POST /v1/products/extract-metadata

Request Body:

Field
Type
Required
Description

productId

string

Yes

Product ID to extract metadata for

Example Request:

curl -X POST "https://api.monterosa.cloud/loyalty/v1/products/extract-metadata" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }'

Example Response:

{
  "success": true,
  "data": {
    "productId": "prod_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "extractedMetadata": {
      "category": "premium",
      "sentiment": "positive",
      "keywords": ["vip", "exclusive", "premium", "badge"],
      "extractionMethod": "ai",
      "confidence": 0.92
    },
    "message": "Metadata extraction complete"
  }
}

Stock Management

Get Stock Level

Get the current stock level for a SKU.

GET /v1/stock/{sku}

Path Parameters:

Parameter
Type
Required
Description

sku

string

Yes

Stock Keeping Unit

Example Request:

curl -X GET "https://api.monterosa.cloud/loyalty/v1/stock/BADGE-VIP-001" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID"

Example Response:

{
  "success": true,
  "data": {
    "orgId": "550e8400-e29b-41d4-a716-446655440000",
    "sku": "BADGE-VIP-001",
    "available": 55,
    "reserved": 10,
    "total": 100,
    "updatedAt": "2025-10-11T10:00:00.000Z",
    "updatedBy": "system"
  }
}

If the SKU doesn't exist, returns:

{
  "success": true,
  "data": {
    "sku": "BADGE-VIP-001",
    "available": 0,
    "reserved": 0,
    "total": 0
  }
}

Update Stock Level

Update stock levels for a SKU. Supports three operations: set, add, and subtract.

PUT /v1/stock/{sku}

Path Parameters:

Parameter
Type
Required
Description

sku

string

Yes

Stock Keeping Unit

Request Body:

Field
Type
Required
Description

quantity

number

Yes

Quantity to set/add/subtract

operation

string

No

Operation type: set, add, subtract (default: set)

Example Request (Set Stock):

curl -X PUT "https://api.monterosa.cloud/loyalty/v1/stock/BADGE-VIP-001" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 100,
    "operation": "set"
  }'

Example Request (Add Stock):

curl -X PUT "https://api.monterosa.cloud/loyalty/v1/stock/BADGE-VIP-001" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Monterosa-Org-ID: YOUR_ORG_UUID" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 50,
    "operation": "add"
  }'

Example Response:

{
  "success": true,
  "data": {
    "orgId": "550e8400-e29b-41d4-a716-446655440000",
    "sku": "BADGE-VIP-001",
    "available": 150,
    "reserved": 0,
    "total": 150,
    "updatedAt": "2025-10-11T11:00:00.000Z",
    "updatedBy": "[email protected]"
  }
}

Product Types

Badge

Digital achievements or status symbols that users can collect.

Example:

{
  "name": "First Win Badge",
  "sku": "BADGE-FIRST-WIN",
  "type": "badge",
  "pointsCost": 0,
  "metadata": {
    "imageUrl": "https://cdn.monterosa.cloud/first-win.png",
    "rarity": "common"
  }
}

Unique Code Pool

Products that grant unique promo codes from a pool. Each user receives a different code.

Example:

{
  "name": "10% Discount Code",
  "sku": "PROMO-10PCT",
  "type": "unique_code_pool",
  "pointsCost": 500,
  "metadata": {
    "codePoolId": "pool_abc123",
    "discountType": "percentage",
    "discountValue": 10
  }
}

Merchandise

Physical products that require shipping.

Example:

{
  "name": "Team Jersey",
  "sku": "MERCH-JERSEY-001",
  "type": "merchandise",
  "pointsCost": 10000,
  "metadata": {
    "size": "M",
    "color": "blue",
    "requiresShipping": true
  }
}

Ticket

Event tickets or access passes.

Example:

{
  "name": "VIP Match Ticket",
  "sku": "TICKET-VIP-001",
  "type": "ticket",
  "pointsCost": 50000,
  "metadata": {
    "eventDate": "2025-11-20T19:00:00Z",
    "venue": "Stadium Arena",
    "section": "VIP"
  }
}

Entry

Competition or sweepstakes entries.

Example:

{
  "name": "Grand Prize Draw Entry",
  "sku": "ENTRY-GRAND-001",
  "type": "entry",
  "pointsCost": 100,
  "metadata": {
    "competitionId": "comp_abc123",
    "drawDate": "2025-12-01T00:00:00Z"
  }
}

Error Responses

400 Bad Request

{
  "success": false,
  "error": {
    "message": "Validation failed",
    "details": {
      "errors": [
        "name is required and must be a string",
        "sku is required and must be a string",
        "type must be one of: badge, unique_code_pool, merchandise, ticket, entry"
      ]
    }
  }
}

404 Not Found

{
  "success": false,
  "error": {
    "message": "Product not found"
  }
}

409 Conflict

{
  "success": false,
  "error": {
    "message": "Product with this SKU already exists"
  }
}

500 Internal Server Error

{
  "success": false,
  "error": {
    "message": "Failed to create product"
  }
}

Best Practices

  1. Unique SKUs: Always use unique, descriptive SKU values

  2. Stock Management: Set initial stock levels before making products available

  3. Metadata Extraction: Use extractMetadata: true for consistent categorization

  4. Product Status: Start with draft status for testing before setting to active

  5. Cost Configuration: Set at least one cost type (points, coins, or XP)

  6. Type Selection: Choose the correct product type for proper inventory tracking



Support

For questions about the Products API:

Last updated