Skip to main content

Fetching Promotional Content for Loyalty Members

This guide shows how client applications and Point of Sale (PoS) systems can fetch personalized promotional content for loyalty members using the Loyalty Integration API.

The Endpoint

The Loyalty Integration API provides a member-specific endpoint that automatically filters content based on the member's profile, tier, audiences, and current date.

Base URL:

  • Production: https://api.qurable.io/v2
  • Sandbox: https://api.sandbox.qurable.io/v2

Path: GET /members/{loyaltyMemberId}/content/collections/{collectionKeyOrSlug}/documents

Path Parameters

ParameterRequiredDescription
loyaltyMemberIdYesThe authenticated member's ID
collectionKeyOrSlugYesCollection UUID or slug (e.g., welcome-offers, home-banners)

Query Parameters

All parameters are optional:

ParameterTypeDefaultDescription
pagenumber0Page number (0-indexed)
limitnumber20Results per page (1-200)
sortstring-Sort field and direction (e.g., displayOrder:asc, createdAt:desc)

Automatic Server-Side Filtering

The endpoint handles all filtering automatically, so you don't need client-side logic:

  • Published documents only: Only returns documents with status: published
  • Date validation: Filters by fromDate and toDate against current time
  • Audience filtering: Validates member's tier, segment, and other audience keys
  • Caching: Results are cached for 15 minutes for performance
  • Authorization: Only returns documents the member is authorized to see

Sample Request

Here's how a PoS system would fetch welcome offers for a newly registered customer:

curl -X 'GET' \
'https://api.sandbox.qurable.io/v2/members/11111111/content/collections/welcome-offers/documents?sort=displayOrder:asc' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {YOUR_TOKEN}'

Authentication: Use a JWT token obtained through the member authentication flow. See Authentication for details.

Sample Response

The API returns a collection object with filtered documents:

{
"collection": {
"collectionKey": "coll_01JSG2C0V4AJHVZ6P3E0PQH9EV",
"name": "Welcome Offers"
},
"query": {
"sort": "displayOrder:asc",
"page": 0,
"limit": 20
},
"totalCount": 2,
"items": [
{
"documentKey": "doc_01JSG9YM0YZHBS9X3G0VMVMAW6",
"slug": "first-purchase-discount",
"attrs": {
"name": "20% Off Your First Purchase",
"description": "Welcome to our loyalty program! Enjoy 20% off your first purchase.",
"pictureUrl": "https://example.com/welcome-banner.png",
"buttonName": "Shop Now",
"link": "https://example.com/shop"
},
"status": "published",
"fromDate": "2024-06-01T00:00:00Z",
"toDate": "2024-06-30T23:59:59Z",
"createdAt": "2024-05-15T10:00:00Z",
"updatedAt": "2024-05-20T14:30:00Z"
}
]
}

Response Fields

  • collection: Metadata about the collection being queried
  • query: Echo of the query parameters used
  • totalCount: Total number of documents matching the filter
  • items: Array of document objects with:
    • documentKey: Unique identifier for the document
    • slug: Human-readable identifier
    • attrs: Custom attributes defined in the collection schema (e.g., name, description, images, links)
    • status: Publication status (always published in filtered results)
    • fromDate/toDate: Date range when the document is visible (already validated)

Integration Notes

Ready to display: Documents in the response are pre-filtered and validated, so you can display them directly in your UI without additional client-side filtering.

Member authentication required: This endpoint requires a valid JWT token for the member. Ensure your authentication flow is implemented before calling this endpoint.

Performance optimization: Results are cached server-side for 15 minutes, so repeated requests for the same member and collection will be fast.

Error handling: If the collection doesn't exist or the member doesn't have access, you'll receive a 404 or 403 error respectively. Handle these gracefully in your UI.