Events & Analytics API Reference | Lynes Loyalty API

Events & Analytics API

Use these endpoints to log user events and query analytics data such as streak performance and event statistics.

  • Authentication: All endpoints require a valid JWT Bearer token.
  • Versioning: Paths support /v0, /v1, /v2, /v3. The version prefix is stripped internally.

See JWT Authentication for details on obtaining and using tokens.

Endpoints Overview

  • POST /event – Log event
  • GET /event – List events
  • GET /event/{eventId} – Get event by ID
  • GET /analytics/streak – Streak analytics
  • GET /stats/event – Event stats

POST /event – Log Event

Log a user event that can award points, update challenges, streaks, and leaderboards.

  • Method: POST
  • Path: /v1/event
  • Auth: Authorization: Bearer <JWT_TOKEN> (or API key for selected events)

Request Body

{
  "eventId": "purchase_completed",
  "userId": "user-123",
  "metadata": {
    "amount": 49.99,
    "currency": "EUR",
    "usergroup": ["default"],
    "source": "web"
  }
}
  • eventId string (required): Identifier of the configured event in the dashboard.
  • userId string (required): User identifier used across the loyalty system.
  • metadata object (optional):
    • Arbitrary key/value pairs used for conditions, transaction rewards (e.g. amount), usergroups, or analytics.

If the event is configured as transactional, the reward is calculated based on a configured rewardValueField in the event definition that is read from metadata.

If the event requires an API key, the system will:

  • Inspect the host and event configuration.
  • Return 403 if the request is not authenticated via API key.

Responses

  • 200 OK

    {
      "statusCode": 200,
      "message": "Event erfolgreich geloggt",
      "data": {
        "userId": "user-123",
        "eventId": "purchase_completed",
        "points": 50,
        "type": "TRANSACTION",
        "title": "Purchase completed",
        "limit": 10,
        "maximumReward": 1000,
        "metadata": {
          "amount": 49.99,
          "currency": "EUR",
          "usergroup": ["default"],
          "source": "web"
        },
        "conditionReached": true,
        "limitReached": false,
        "userGroupId": "default"
      }
    }
    • message can be "Event erfolgreich geloggt" or "Event Limit erreicht" depending on the configured limit.
  • 400 Bad Request

    • Missing or invalid eventId
    • Missing or invalid userId
    • Invalid JSON body
    • Event is not active
  • 401 / 403 Unauthorized / Forbidden

    • User is not authenticated or is not allowed to act on the given userId.
    • API key required for specific events but not provided.
  • 404 Not Found

    • User could not be found in the project.
    • Event does not exist.
  • 500 Internal Server Error

    • Unexpected DynamoDB or internal processing error.

GET /event – List Events

Retrieve a list of configured events for the current project.

  • Method: GET
  • Path: /v1/event
  • Auth: Authorization: Bearer <JWT_TOKEN>

Query Parameters

NameTypeRequiredDefaultDescription
showAllstringno"true""true" returns all events, "false" only returns events with ACTIVE status.

Response

  • 200 OK

    [
      {
        "eventId": "purchase_completed",
        "title": "Purchase completed",
        "description": "Tracks completed purchases",
        "status": "ACTIVE",
        "limit": 10,
        "maximumReward": 1000,
        "reward": {
          "default": 2
        },
        "conditions": {
          "type": "AND",
          "conditions": [
            {
              "field": "amount",
              "operator": "greater_than",
              "value": 0
            }
          ]
        },
        "metadataFields": [
          {
            "key": "amount",
            "type": "number",
            "required": true
          }
        ],
        "type": "TRANSACTION"
      }
    ]
  • 204 No Content

    • No events are configured for the project.
  • 500 Internal Server Error

    • Error querying events.

GET /event/{eventId} – Get Event by ID

Retrieve the full configuration of a single event.

  • Method: GET
  • Path: /v1/event/{eventId}
  • Auth: Authorization: Bearer <JWT_TOKEN>

Path Parameters

NameTypeRequiredDescription
eventIdstringyesEvent identifier from dashboard.

Response

  • 200 OK

    {
      "eventId": "purchase_completed",
      "title": "Purchase completed",
      "description": "Tracks completed purchases",
      "status": "ACTIVE",
      "limit": 10,
      "maximumReward": 1000,
      "reward": {
        "default": 2
      },
      "conditions": {
        "type": "AND",
        "conditions": [
          {
            "field": "amount",
            "operator": "greater_than",
            "value": 0
          }
        ]
      },
      "metadataFields": [
        {
          "key": "amount",
          "type": "number",
          "required": true
        }
      ],
      "type": "TRANSACTION"
    }
  • 400 Bad Request

    • eventId is missing.
  • 404 Not Found

    • Event does not exist in the project.
  • 500 Internal Server Error

    • Error loading the event configuration.

GET /analytics/streak – Streak Analytics

Return aggregated analytics for a configured streak definition.

  • Method: GET
  • Path: /v1/analytics/streak
  • Auth: Authorization: Bearer <JWT_TOKEN>

Query Parameters

NameTypeRequiredDescription
streakIdstringyesIdentifier of the configured streak.

Response

  • 200 OK

    {
      "streakId": "daily_login",
      "totalParticipants": 1240,
      "activeParticipants": 830,
      "averageStreakLength": 6.2,
      "longestUserStreak": 45,
      "completionRate": 0.67
    }
  • 200 OK with null body

    • Streak analytics are not yet available for the given streakId.
  • 500 Internal Server Error

    • Error loading analytics from DynamoDB.

GET /stats/event – Event Stats

Return global or event-specific analytics for a given period.

  • Method: GET
  • Path: /v1/stats/event
  • Auth: Authorization: Bearer <JWT_TOKEN>

Query Parameters

NameTypeRequiredDefaultDescription
periodstringno7dTime window: 1d, 7d, 30d, 90d, current_month, ytd, or all.
eventIdstringnoIf provided, returns event-specific analytics; otherwise global.
timeframestringnoWhen set to month and month is provided, uses monthly aggregates.
monthstringnoIn YYYY-MM format, e.g. 2025-08. Used together with timeframe=month.

Response – Global Analytics Example

  • 200 OK

    {
      "period": "7d",
      "eventId": null,
      "startDate": "2025-08-01",
      "endDate": "2025-08-07",
      "data": {
        "totalEvents": 6120,
        "uniqueUsers": 1420,
        "totalPoints": 81230,
        "eventBreakdown": {
          "purchase_completed": {
            "count": 4210,
            "users": 980,
            "points": 71230
          },
          "login": {
            "count": 1910,
            "users": 1240,
            "points": 10000
          }
        },
        "topEvents": ["purchase_completed", "login"],
        "dailyData": {
          "2025-08-01": {
            "events": 900,
            "users": 320,
            "points": 11000,
            "hourlyDistribution": []
          }
        },
        "_metadata": {
          "uniqueUsersCalculationMethod": "daily_exact",
          "uniqueUsersNote": null
        }
      }
    }

Response – Event-Specific Analytics Example

{
  "period": "30d",
  "eventId": "purchase_completed",
  "startDate": "2025-08-01",
  "endDate": "2025-08-30",
  "data": {
    "totalCount": 4100,
    "uniqueUsers": 950,
    "pointsAwarded": 71000,
    "conditionMet": 4050,
    "conditionFailed": 50,
    "limitReached": 20,
    "dailyData": {
      "2025-08-01": {
        "count": 200,
        "users": 120,
        "points": 3400,
        "hourlyDistribution": []
      }
    }
  }
}

Error Responses

  • 400 Bad Request

    • Invalid month format (not YYYY-MM) when timeframe=month.
  • 500 Internal Server Error

    • Error retrieving analytics data or aggregations.