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
- Quick Start Guide - Get up and running quickly
- API Documentation & Testing Tools - Swagger, Postman, and testing tools
- Field Query Guide - Detailed field-level query examples
- Testing Examples - Practical code examples for testing
- Churn Metrics Guide - Using the API for member churn analysis
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:
Obtain a JWT token by calling the authentication endpoint with your API key:
GET /api/authentication/getauthtoken Headers: apikey: your-partner-api-keyThe token is valid for 24 hours.
Use the JWT token in the
Authorizationheader 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 tokenGET /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 fieldsGET /odata/Partners({id})- Get partner by IDGET /odata/PartnerCategories- Get all partner categories → See available fieldsGET /odata/PartnerCategories({id})- Get partner category by ID
Reward Endpoints
GET /odata/Rewards- Get all rewards → See available fieldsGET /odata/Rewards({id})- Get reward by IDGET /odata/RewardCountries- Get all reward countries → See available fieldsGET /odata/RewardCountries({id})- Get reward country by IDGET /odata/RewardBrands- Get all reward brands → See available fieldsGET /odata/RewardBrands({id})- Get reward brand by ID
Tracking Endpoints (Elasticsearch-backed)
GET /odata/TrackingActivities- Get tracking activities → See available fieldsGET /odata/TrackingActivities({id})- Get tracking activity by IDGET /odata/TrackingLogins- Get tracking logins → See available fieldsGET /odata/TrackingLogins({id})- Get tracking login by ID
Tracking Endpoints (Database-backed)
GET /odata/TrackingImpressions- Get all tracking impressions → See available fieldsGET /odata/TrackingImpressions({id})- Get tracking impression by ID
User Endpoints
GET /odata/Users- Get all users → See available fieldsGET /odata/Users({id})- Get user by IDGET /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). SupportsjoinedBeforeandjoinedAfterquery 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. SupportsmaxUsers(default 50000) andjoinedBeforequery params.
Cache Management
DELETE /api/cache/clear- Clear all cached data for the authenticated partnerDELETE /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
Expanding Related Entities
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
$topvalue is 1000 items - TrackingLogins and TrackingActivities are served from Elasticsearch; deep pagination uses
search_aftertokens automatically - TrackingImpressions are served from the database; check the
CachedAtfield on each record for cache age - Cached data can be invalidated via
DELETE /api/cache/clear(orDELETE /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.