Egress Endpoints Full Closed Beta
Complete reference for the loyalty egress REST API endpoints. For a guided introduction, see the REST API guide.
Closed Beta
These endpoints are in Closed Beta and subject to change. Contact us for access.
Base URL
https://api.fanfest.vip/egress/loyaltyAuthentication
All endpoints require an API key with the loyalty:read permission, passed via the x-api-key header.
x-api-key: your_api_key_hereRate Limits
100 requests per minute per API key. Exceeding this limit returns 429 Too Many Requests with a Retry-After: 60 header.
GET /egress/loyalty/actions
Query loyalty actions for the channel associated with your API key. Response format depends on the channel's resolution mode.
Request
GET /egress/loyalty/actions?user_id=usr_xyz789&app_action_name=quiz_answer&page=0&limit=20
x-api-key: your_api_key_hereParameters
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
user_id | string | No | — | — | Filter by user ID |
app_action_name | string | No | — | — | Filter by action type |
from_date | string | No | — | ISO 8601 datetime | Start of date range (inclusive) |
to_date | string | No | — | ISO 8601 datetime | End of date range (inclusive) |
page | integer | No | 0 | Min: 0 | Zero-indexed page number |
limit | integer | No | 50 | Min: 1, Max: 100 | Results per page |
Response — Aggregated Mode
HTTP/1.1 200 OK
Content-Type: application/json{
"data": [
{
"resolution": "aggregated",
"channel_id": "ch_abc123",
"user_id": "usr_xyz789",
"app_action_name": "quiz_answer",
"total_points": 1250,
"total_occurrences": 47,
"community_ids": [],
"timestamp": "2025-06-15T14:32:00.000Z"
}
],
"total": 1
}Response — Day Aggregated Mode
{
"data": [
{
"resolution": "day_aggregated",
"channel_id": "ch_abc123",
"user_id": "usr_xyz789",
"app_action_name": "quiz_answer",
"date": "2025-06-15",
"points": 75,
"occurrences": 3,
"community_ids": []
}
],
"total": 1
}Response — High Fidelity Mode
{
"data": [
{
"resolution": "high_fidelity",
"channel_id": "ch_abc123",
"user_id": "usr_xyz789",
"user_action_id": "ua_def456",
"app_action_name": "quiz_answer",
"points": 25,
"occurrences": 1,
"community_ids": ["com_111", "com_222"],
"created_at": "2025-06-15T14:32:00.000Z"
}
],
"total": 1
}Notes
- In aggregated and day aggregated modes, results are grouped by
user_id+app_action_name. Each group appears as one entry indata. community_idsis an empty array in aggregated and day aggregated modes. It is only populated in high fidelity mode.- Only settled transactions are included in point totals. On-hold transactions are excluded.
- When no resolution mode is configured for the channel, the default is aggregated.
GET /egress/loyalty/points
Get the total settled loyalty points for a specific user in your channel.
Request
GET /egress/loyalty/points?user_id=usr_xyz789
x-api-key: your_api_key_hereParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | Yes | The user ID to query points for |
Response
HTTP/1.1 200 OK
Content-Type: application/json{
"user_id": "usr_xyz789",
"channel_id": "ch_abc123",
"total_points": 1550
}Notes
total_pointsis the sum of allUserWalletTransactionrecords withstatus: "settled"for the given user and channel.- Returns
total_points: 0if the user has no settled transactions. - The
user_idparameter is required. Omitting it returns a400 Bad Requesterror.
GET /egress/loyalty/config
Check the egress configuration status for the channel associated with your API key.
Request
GET /egress/loyalty/config
x-api-key: your_api_key_hereParameters
None.
Response — Configured
HTTP/1.1 200 OK
Content-Type: application/json{
"configured": true,
"resolution_mode": "aggregated",
"is_enabled": true,
"active_webhook_count": 2
}Response — Not Configured
{
"configured": false
}Response Fields
| Field | Type | Present When | Description |
|---|---|---|---|
configured | boolean | Always | Whether an egress configuration exists for this channel |
resolution_mode | string | configured: true | The channel's resolution mode: "aggregated", "day_aggregated", or "high_fidelity" |
is_enabled | boolean | configured: true | Whether the egress configuration is currently active |
active_webhook_count | number | configured: true | Number of active (non-disabled) webhook endpoints |
Notes
- This endpoint never exposes webhook secrets or URLs.
active_webhook_countonly counts webhooks withis_active: true.
Error Responses
All endpoints return errors with a consistent JSON body:
{
"error": "Description of the error"
}Status Codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid query parameters or missing required parameters |
401 | Unauthorized | Missing or invalid x-api-key header |
403 | Forbidden | API key is valid but lacks loyalty:read permission |
429 | Too Many Requests | Rate limit exceeded — check Retry-After header |
500 | Internal Server Error | Unexpected server error |
429 Response
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{
"error": "Rate limit exceeded"
}The Retry-After header indicates the number of seconds to wait before retrying. The rate limit window resets every 60 seconds.
