EZ Loyalty Reporting API

An OData-enabled C# .NET 9.0 API for querying tracking, rewards, and partner data from the EZ Loyalty database. Tracking data (logins and activities) is backed by Elasticsearch for high-volume query performance.

📚 Documentation Navigation

Features

  • OData Support: Full OData query capabilities including $filter, $select, $expand, $orderby, $top, $skip, and $count
  • Dual Authentication: API Key + Bearer Token authentication
  • Elasticsearch-backed tracking: TrackingLogins and TrackingActivities are served from Elasticsearch with deep pagination via search_after
  • Entity Categories:
    • Partners: Partner data and partner categories
    • Rewards: Rewards, brands, and countries
    • Tracking: Activities, logins (Elasticsearch), and impressions (database)
    • Users: User accounts, churn metrics, cohort analysis, and segments

Authentication

The API uses a two-step authentication process:

  1. Obtain a JWT token by calling the authentication endpoint with your API key:

    GET /api/authentication/getauthtoken
    Headers:
      apikey: your-partner-api-key
    

    The token is valid for 24 hours.

  2. Use the JWT token in the Authorization header for all other requests:

    Authorization: Bearer your-jwt-token-here
    

Example Request Headers (after obtaining token):

Authorization: Bearer your-jwt-token-here

Authentication Endpoints

  • GET /api/authentication/getauthtoken - Exchange API key for JWT token
  • GET /api/authentication/partners - List partners for API key verification (testing only)

OData Endpoints

All OData endpoints are prefixed with /odata/

Partner Endpoints

  • GET /odata/Partners - Get authenticated partner's information → See available fields
  • GET /odata/Partners({id}) - Get partner by ID
  • GET /odata/PartnerCategories - Get all partner categories → See available fields
  • GET /odata/PartnerCategories({id}) - Get partner category by ID

Reward Endpoints

  • GET /odata/Rewards - Get all rewards → See available fields
  • GET /odata/Rewards({id}) - Get reward by ID
  • GET /odata/RewardCountries - Get all reward countries → See available fields
  • GET /odata/RewardCountries({id}) - Get reward country by ID
  • GET /odata/RewardBrands - Get all reward brands → See available fields
  • GET /odata/RewardBrands({id}) - Get reward brand by ID

Tracking Endpoints (Elasticsearch-backed)

  • GET /odata/TrackingActivities - Get tracking activities → See available fields
  • GET /odata/TrackingActivities({id}) - Get tracking activity by ID
  • GET /odata/TrackingLogins - Get tracking logins → See available fields
  • GET /odata/TrackingLogins({id}) - Get tracking login by ID

Tracking Endpoints (Database-backed)

  • GET /odata/TrackingImpressions - Get all tracking impressions → See available fields
  • GET /odata/TrackingImpressions({id}) - Get tracking impression by ID

User Endpoints

  • GET /odata/Users - Get all users → See available fields
  • GET /odata/Users({id}) - Get user by ID
  • GET /odata/UsersElastic - Get users with login data from Elasticsearch (OData, paged)

REST Endpoints

User Analytics

  • GET /api/users/counts - Aggregated user counts for churn metrics (total, active, churned, renewed, cancelled, expired). Supports joinedBefore and joinedAfter query params.
  • GET /api/users/cohorts - User cohort retention data grouped by join month (last 24 months)
  • GET /api/users/segments - User churn rates segmented by country and member level (top 5 each)
  • GET /api/users/elastic - Bulk user list with login data from Elasticsearch. Supports maxUsers (default 50000) and joinedBefore query params.

Cache Management

  • DELETE /api/cache/clear - Clear all cached data for the authenticated partner
  • DELETE /api/cache/clear/{cacheType} - Clear a specific cache type (users, logins, activities, impressions, orgunits, all)
  • DELETE /api/cache/clear-all - Returns information about system-wide cache clearing (restart required)

Deep Pagination for Tracking Endpoints

TrackingLogins and TrackingActivities use Elasticsearch's search_after mechanism for pages beyond 10,000 records. The @odata.nextLink in the response automatically switches from $skip to a searchAfter token when needed. Follow the @odata.nextLink URL to retrieve subsequent pages without any manual handling.

For the UsersElastic endpoint, when $skip >= 10000, a searchAfter query parameter (a numeric user ID) is required. This value is included in the @odata.nextLink automatically.

OData Query Examples

Filtering

Get tracking activities by type:

GET /odata/TrackingActivities?$filter=Type eq 'click'

Get activities created after a date:

GET /odata/TrackingActivities?$filter=CreatedAt gt 2024-01-01T00:00:00Z

Get active rewards:

GET /odata/Rewards?$filter=IsActive eq true

Selecting Specific Fields

Get only user names and IDs:

GET /odata/Users?$select=Id,Email,FirstName,LastName

Ordering

Get rewards ordered by title:

GET /odata/Rewards?$orderby=Title asc

Pagination

Get first 100 users:

GET /odata/Users?$top=100

Skip first 100 and get next 100:

GET /odata/Users?$top=100&$skip=100

Get tracking impressions with user details:

GET /odata/TrackingImpressions?$expand=User

Get users with org unit details:

GET /odata/Users?$expand=AccountsUsersOrgUnits

Get tracking activities with user and reward:

GET /odata/TrackingActivities?$expand=User,Reward

Complex Queries

Get active rewards with filtering, ordering, and pagination:

GET /odata/Rewards?$filter=IsActive eq true&$orderby=DateAdded desc&$top=50&$select=Id,Title,DiscountString

User Analytics

Get churn metrics:

GET /api/users/counts
GET /api/users/counts?joinedAfter=2024-01-01&joinedBefore=2024-12-31
GET /api/users/cohorts
GET /api/users/segments

Swagger Documentation

When running in Development mode, Swagger UI is available at:

https://reporting.api.myezrewards.com/swagger

This provides interactive API documentation and testing capabilities.

Notes

  • All endpoints require Bearer token authentication (obtain via /api/authentication/getauthtoken)
  • Maximum $top value is 1000 items
  • TrackingLogins and TrackingActivities are served from Elasticsearch; deep pagination uses search_after tokens automatically
  • TrackingImpressions are served from the database; check the CachedAt field on each record for cache age
  • Cached data can be invalidated via DELETE /api/cache/clear (or DELETE /api/cache/clear-all)
  • JSON responses use reference handling to prevent circular references
  • CORS is enabled for all origins (configure as needed for production)

Support

For issues or questions, contact the EZ Loyalty development team.