Code Pools

Code Pools allow you to manage unique coupon/promo codes for products. Codes can be generated algorithmically or uploaded from external systems, then automatically allocated to users when they earn rewards.

Overview

  • Automatic Generation: Generate unique codes with configurable prefixes and lengths

  • Bulk Import: Upload up to 10,000 codes at a time via paste or file upload

  • Automatic Allocation: Codes are automatically assigned when products are awarded

  • Status Tracking: Track codes through available → allocated → redeemed lifecycle

  • Third-Party Integration: Webhook endpoint for external systems to confirm redemption

Creating a Code Pool

Create a pool to hold codes for a specific product.

POST /v1/code-pools

Request Body

{
  "productId": "prod_abc123",
  "name": "Summer 2025 Discount Codes",
  "description": "10% off discount codes for summer campaign",
  "prefix": "SUMMER",
  "expiresAt": "2025-09-01T00:00:00Z"
}

Parameters

Field
Type
Required
Description

productId

string

Product ID this pool is associated with

name

string

Name for this code pool

description

string

No

Description of the pool

prefix

string

No

Prefix for generated codes (e.g., "SUMMER")

expiresAt

string

No

ISO8601 timestamp when codes expire

Response

{
  "orgId": "550e8400-e29b-41d4-a716-446655440000",
  "poolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "productId": "prod_abc123",
  "name": "Summer 2025 Discount Codes",
  "description": "10% off discount codes for summer campaign",
  "prefix": "SUMMER",
  "totalCodes": 0,
  "availableCodes": 0,
  "allocatedCodes": 0,
  "redeemedCodes": 0,
  "expiredCodes": 0,
  "expiresAt": "2025-09-01T00:00:00Z",
  "status": "active",
  "createdAt": "2025-10-06T16:00:00Z",
  "updatedAt": "2025-10-06T16:00:00Z"
}

Generating Codes

Generate codes algorithmically for a pool.

POST /v1/code-pools/{poolId}/generate

Request Body

{
  "quantity": 1000,
  "codeLength": 12
}

Parameters

Field
Type
Required
Description

quantity

number

Number of codes to generate (max 100,000)

codeLength

number

No

Length of each code excluding prefix (default 12, range 6-32)

Response

{
  "poolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "requested": 1000,
  "generated": 1000,
  "duplicates": 0,
  "failed": 0
}

Generated Code Format

  • Prefix (if configured) + Random alphanumeric characters

  • Character set: ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (no ambiguous characters: 0, O, I, 1)

  • Example: SUMMER4K7P9N2X8Q

Adding Codes (Paste/Upload)

Import codes from an external source.

POST /v1/code-pools/{poolId}/codes

Request Body

{
  "codes": [
    "EXTERNAL-ABC123",
    "EXTERNAL-DEF456",
    "EXTERNAL-GHI789"
  ]
}

Parameters

Field
Type
Required
Description

codes

array

Array of code strings (max 10,000 per request)

Response

{
  "poolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "imported": 3,
  "duplicates": 0,
  "failed": 0,
  "errors": []
}

Notes

  • Codes are automatically converted to uppercase

  • Duplicate codes within the pool are rejected

  • Whitespace is trimmed from each code

  • For large imports (>10k codes), split into multiple requests

Code Lifecycle

┌──────────┐    Award Product    ┌───────────┐    Third-Party    ┌──────────┐
│Available │ ──────────────────> │ Allocated │ ───────────────> │ Redeemed │
└──────────┘                     └───────────┘     Confirms      └──────────┘
     │                                                                 │
     │                           ┌─────────┐                          │
     └──────────────────────────>│ Expired │<─────────────────────────┘
              Time-based          └─────────┘      Time-based

Status Definitions

  • available: Code exists in pool, not yet assigned to a user

  • allocated: Code has been awarded to a user

  • redeemed: Third-party has confirmed the code was used

  • expired: Code has passed its expiration date

Marking Codes as Redeemed

Third-party systems call this endpoint to confirm a code has been used.

POST /v1/code-pools/redeem

Request Body

{
  "poolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "code": "SUMMER4K7P9N2X8Q",
  "redeemedAt": "2025-10-06T16:30:00Z",
  "metadata": {
    "orderId": "ORD-12345",
    "discountAmount": 10.00,
    "currency": "USD"
  }
}

Parameters

Field
Type
Required
Description

poolId

string

Pool ID containing the code

code

string

The code that was redeemed

redeemedAt

string

No

ISO8601 timestamp of redemption (defaults to now)

metadata

object

No

Additional redemption data

Response

{
  "code": "SUMMER4K7P9N2X8Q",
  "poolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "status": "redeemed",
  "redeemedAt": "2025-10-06T16:30:00Z"
}

Authentication

This endpoint requires API authentication. Provide your organization's API credentials:

POST /v1/code-pools/redeem
Authorization: Bearer YOUR_API_TOKEN
X-Monterosa-Org-ID: YOUR_ORG_ID

Integration with Products

To use code pools with products, set the product type to unique_code_pool and link it to a pool.

Creating a Code Pool Product

{
  "sku": "DISCOUNT-10",
  "name": "10% Off Discount Code",
  "type": "unique_code_pool",
  "codePoolId": "pool_7f9e2c8a-1234-5678-90ab-cdef12345678",
  "infiniteAvailability": false,
  "totalStock": 1000,
  "isFree": true,
  "tags": ["discount", "reward"]
}

When this product is awarded via a campaign, the system automatically:

  1. Allocates an available code from the pool

  2. Creates a transaction record

  3. Returns the code to the user

  4. Updates pool statistics

Integration with Campaigns

Use the award_product effect to give products (including codes) as rewards.

Campaign Effect Example

{
  "type": "award_product",
  "config": {
    "productId": "prod_abc123",
    "reason": "Completed summer challenge",
    "tags": ["challenge", "summer"]
  }
}

When the effect triggers:

  • Product is awarded to the user

  • Stock is decremented

  • For code pool products, a unique code is allocated

  • Transaction is created with the code details

Best Practices

Code Generation

  • Use prefixes to identify campaigns/batches (e.g., "SUMMER2025")

  • Generate in batches rather than all at once for better control

  • Monitor availability and generate more codes before running out

Code Import

  • Validate externally before uploading to avoid duplicates

  • Keep records of which external system generated which codes

  • Use metadata to track code sources

Expiration

  • Set expiration dates for time-limited campaigns

  • Monitor expired codes to understand redemption rates

  • Plan buffer time between allocation and expiration

Third-Party Integration

  • Implement webhooks to confirm redemptions in real-time

  • Handle retries for webhook delivery failures

  • Store order IDs in metadata for reconciliation

Error Handling

Common Errors

Pool not found (404)

{
  "error": "Code pool not found"
}

No codes available (500)

{
  "error": "No codes available in pool"
}

Code not allocated (404)

{
  "error": "Code not found or not in allocated status"
}

Duplicate code (409)

{
  "error": "Code already exists in pool"
}

Monitoring

Pool Statistics

Track these metrics for each pool:

  • totalCodes - Total codes added to pool

  • availableCodes - Codes ready to be allocated

  • allocatedCodes - Codes given to users

  • redeemedCodes - Codes confirmed as used

  • expiredCodes - Codes past expiration date

Alerts

Set up alerts for:

  • Low availability: When available codes < 10% of total

  • High allocation rate: Unusually fast code allocation

  • Low redemption rate: Few allocated codes being redeemed

  • Expired codes: Track unused codes that expire

Example Workflow

Complete Integration Example

  1. Create a campaign product

POST /v1/products
{
  "sku": "VIP-ACCESS",
  "name": "VIP Event Access Code",
  "type": "unique_code_pool",
  "infiniteAvailability": false,
  "totalStock": 500
}
# Response: { "productId": "prod_abc123", ... }
  1. Create code pool

POST /v1/code-pools
{
  "productId": "prod_abc123",
  "name": "VIP Event Codes",
  "prefix": "VIP2025",
  "expiresAt": "2025-12-31T23:59:59Z"
}
# Response: { "poolId": "pool_xyz789", ... }
  1. Generate codes

POST /v1/code-pools/pool_xyz789/generate
{
  "quantity": 500,
  "codeLength": 10
}
# Response: { "generated": 500, ... }
  1. Update product with pool

PATCH /v1/products/prod_abc123
{
  "codePoolId": "pool_xyz789"
}
  1. Create campaign with effect

POST /v1/campaigns
{
  "name": "VIP Access Challenge",
  "effects": [
    {
      "type": "award_product",
      "config": {
        "productId": "prod_abc123",
        "reason": "Completed VIP challenge"
      }
    }
  ]
}
  1. User earns reward

  • Campaign triggers when user completes challenge

  • Code is automatically allocated: VIP2025K7P9N2X8Q

  • User receives code in their transaction history

  1. User redeems at event

  • Your event system validates the code

  • Call redemption endpoint to mark as used

POST /v1/code-pools/redeem
{
  "poolId": "pool_xyz789",
  "code": "VIP2025K7P9N2X8Q",
  "metadata": { "eventId": "EVT-001", "scanTime": "2025-11-15T19:00:00Z" }
}

FAQ

Q: What happens if codes run out? A: The award fails with an error. Monitor availableCodes and generate more before running out.

Q: Can codes be reused? A: No, each code can only be allocated once and redeemed once.

Q: Can I delete codes from a pool? A: Not currently supported. Create a new pool if you need to change codes.

Q: How are codes allocated? A: First available code is selected. Codes are not allocated in any specific order.

Q: Can I see which user has which code? A: Yes, query transactions with type=product_award and filter by productId.

Q: What if redemption webhook fails? A: The code remains in allocated status. Retry the redemption call when your system is back online.

Last updated