Skip to content

Offers API ​

The Offers API provides access to active promotional offers including percentage discounts, fixed amount discounts, and buy-one-get-one (BOGO) deals.

Do Not Cache Locally

Offers have time-sensitive validity rules (expiration dates, usage limits). The CDN always serves fresh data and is automatically invalidated when offers change, but you should not cache offer data in your application for extended periods.

Endpoints ​

MethodEndpointDescription
GET/api/v1/public/offersList active offers
GET/api/v1/public/offers/{id}Get offer details

List Offers ​

Retrieve a paginated list of currently active and valid offers.

http
GET /api/v1/public/offers

Query Parameters ​

ParameterTypeDefaultDescription
per_pageinteger20Number of items per page (1-50)
pageinteger1Page number
typestring-Filter by offer type

Offer Types ​

TypeDescription
percentagePercentage discount (e.g., 10% off)
fixedFixed amount discount (e.g., $5 off)
bogoBuy-one-get-one offers

Validity Rules ​

Only offers meeting ALL conditions are returned:

  1. Status is active
  2. Current time >= valid_from (if set)
  3. Current time < valid_until (if set)
  4. usage_count < usage_limit (if limit set)

Example Request ​

javascript
const response = await fetch(
  'https://cdn.engagehq.retailsuccessplatform.com/api/v1/public/offers?type=percentage',
  {
    headers: {
      'Authorization': `Bearer ${token}`,
    },
  }
);

Response ​

json
{
  "success": true,
  "message": "Offers retrieved",
  "data": [
    {
      "id": "ofr_00000p1Q2r3S4t5",
      "name": "Summer Savings",
      "description": "10% off all summer essentials",
      "type": "percentage",
      "discount": {
        "type": "percentage",
        "value": 10,
        "display": "10% off"
      },
      "valid_from": "2024-06-01T00:00:00+00:00",
      "valid_until": "2024-08-31T23:59:59+00:00"
    },
    {
      "id": "ofr_00000x1Y2z3A4b5",
      "name": "Weekly Special",
      "description": "$5 off your purchase of $25 or more",
      "type": "fixed",
      "discount": {
        "type": "fixed",
        "value": 5,
        "display": "$5.00 off"
      },
      "valid_from": "2024-06-03T00:00:00+00:00",
      "valid_until": "2024-06-09T23:59:59+00:00"
    },
    {
      "id": "ofr_00000m1N2o3P4q5",
      "name": "Mix & Match",
      "description": "Buy 2 get 1 free on select items",
      "type": "bogo",
      "discount": {
        "type": "bogo",
        "buy": 2,
        "get": 1,
        "display": "Buy 2 Get 1 Free"
      },
      "valid_from": null,
      "valid_until": null
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 20,
    "total": 3
  }
}

Response Fields (List) ​

FieldTypeDescription
idstringUnique offer identifier (hashkey)
namestringOffer name
descriptionstringOffer description
typestringOffer type (percentage, fixed, bogo)
discountobjectFormatted discount information
valid_fromstring|nullStart date (ISO 8601) or null for no start date
valid_untilstring|nullEnd date (ISO 8601) or null for ongoing

Discount Object by Type ​

Percentage Discount ​

json
{
  "type": "percentage",
  "value": 10,
  "display": "10% off"
}
FieldTypeDescription
typestringAlways "percentage"
valuenumberPercentage value (e.g., 10 for 10%)
displaystringFormatted display string

Fixed Discount ​

json
{
  "type": "fixed",
  "value": 5.00,
  "display": "$5.00 off"
}
FieldTypeDescription
typestringAlways "fixed"
valuenumberDollar amount
displaystringFormatted display string

BOGO Discount ​

json
{
  "type": "bogo",
  "buy": 2,
  "get": 1,
  "display": "Buy 2 Get 1 Free"
}
FieldTypeDescription
typestringAlways "bogo"
buyintegerQuantity to purchase
getintegerQuantity received free
displaystringFormatted display string

Sort Order ​

Results are sorted by:

  1. Offers expiring soonest first (valid_until ascending, nulls last)
  2. Most recently created (created_at descending)

Caching ​

CacheTTL
Browser (max-age)0 seconds
CDN24 hours (invalidated on publish)
Stale-while-revalidate30 seconds

Do Not Cache Locally

Offers can become invalid at any time due to expiration or usage limits. Always fetch fresh data from the CDN when displaying offers.


Get Offer ​

Retrieve detailed information about a specific offer.

http
GET /api/v1/public/offers/{id}

Path Parameters ​

ParameterTypeDescription
idstringThe offer hashkey (e.g., ofr_00000p1Q2r3S4t5)

Example Request ​

javascript
const response = await fetch(
  'https://cdn.engagehq.retailsuccessplatform.com/api/v1/public/offers/ofr_00000p1Q2r3S4t5',
  {
    headers: {
      'Authorization': `Bearer ${token}`,
    },
  }
);

Response ​

json
{
  "success": true,
  "message": "Offer retrieved",
  "data": {
    "id": "ofr_00000p1Q2r3S4t5",
    "name": "Summer Savings",
    "description": "10% off all summer essentials",
    "type": "percentage",
    "discount": {
      "type": "percentage",
      "value": 10,
      "display": "10% off"
    },
    "valid_from": "2024-06-01T00:00:00+00:00",
    "valid_until": "2024-08-31T23:59:59+00:00",
    "configuration": {
      "percentage": 10,
      "minimum_purchase": 25.00,
      "maximum_discount": 50.00,
      "eligible_categories": ["summer", "outdoor"],
      "exclude_sale_items": true
    },
    "terms": "Valid on regular-priced summer items only. Cannot be combined with other offers. Maximum discount $50."
  }
}

Additional Response Fields (Detail) ​

The detail response includes all list fields plus:

FieldTypeDescription
configurationobjectOffer configuration (sanitized)
termsstringTerms and conditions text

Configuration Object ​

The configuration varies by offer type. Common fields include:

FieldTypeDescription
percentagenumberPercentage for percentage offers
amountnumberDollar amount for fixed offers
buy_quantityintegerBuy quantity for BOGO
get_quantityintegerGet quantity for BOGO
minimum_purchasenumberMinimum purchase required
maximum_discountnumberMaximum discount cap
eligible_categoriesarrayCategories offer applies to
exclude_sale_itemsbooleanWhether sale items are excluded

Sanitized Configuration

Internal fields like internal_notes, cost_center, and budget_code are removed from the public response.

Caching ​

CacheTTL
Browser (max-age)0 seconds
CDN24 hours (invalidated on publish)
Stale-while-revalidate30 seconds

Error Responses ​

400 Bad Request ​

json
{
  "success": false,
  "message": "Organization context required",
  "errors": null
}

404 Not Found ​

json
{
  "success": false,
  "message": "Offer not found",
  "errors": null
}

The offer either:

  • Doesn't exist
  • Is not currently active
  • Has expired
  • Has reached its usage limit
  • Belongs to a different organization

Usage Example: Displaying Offers ​

javascript
async function displayOffers() {
  const response = await fetch('/api/v1/public/offers', {
    headers: { 'Authorization': `Bearer ${token}` }
  });

  const { data: offers } = await response.json();

  offers.forEach(offer => {
    console.log(`${offer.name}: ${offer.discount.display}`);

    if (offer.valid_until) {
      const expiresIn = new Date(offer.valid_until) - new Date();
      const daysLeft = Math.ceil(expiresIn / (1000 * 60 * 60 * 24));
      console.log(`  Expires in ${daysLeft} days`);
    }
  });
}

Changelog
DateChange
2026-02-23Updated for CloudFront CDN delivery.
2026-01-28Expanded documentation.
2026-01-15Initial publication.

EngageHQ Public Content Delivery API