> ## Documentation Index
> Fetch the complete documentation index at: https://docs.digiflecttech.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics API: Group Dashboard, Summary, and Reports

> Query high-level group metrics, personal savings summaries, financial reports over a date range, credit scores, and the admin audit trail.

The Save App analytics API gives you programmatic access to the numbers that matter most: total group balances, pending approvals, per-member savings, financial period reports, individual credit scores, and a full audit trail of every admin action. Dashboard and report endpoints are restricted to admins; the summary endpoint is available to all authenticated users.

***

## GET /api/analytics/dashboard

Returns high-level counts for the group. Requires an **admin** JWT.

### Response

<ResponseField name="total_members" type="integer">
  Total number of users with the `member` role in the group.
</ResponseField>

<ResponseField name="active_members" type="integer">
  Number of members whose accounts are currently active (`is_active = true`).
</ResponseField>

<ResponseField name="total_balance" type="float">
  Current total balance of the group fund, in UGX.
</ResponseField>

<ResponseField name="pending_loans" type="integer">
  Number of loan requests currently in `PENDING` status awaiting admin approval.
</ResponseField>

<ResponseField name="pending_transactions" type="integer">
  Number of transactions currently in `PENDING` status awaiting admin approval.
</ResponseField>

<ResponseField name="pending_payouts" type="integer">
  Number of payouts currently in `PENDING` status awaiting execution.
</ResponseField>

<CodeGroup>
  ```bash Dashboard theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/analytics/dashboard" \
    --header "Authorization: Bearer <admin_token>"
  ```
</CodeGroup>

```json Sample response theme={null}
{
  "total_members": 24,
  "active_members": 22,
  "total_balance": 12450000.0,
  "pending_loans": 3,
  "pending_transactions": 1,
  "pending_payouts": 0
}
```

***

## GET /api/analytics/summary

Returns a personalised summary for the authenticated user. Available to **all authenticated users** — both admins and members.

### Response

<ResponseField name="total_members" type="integer">
  Total number of members in the group.
</ResponseField>

<ResponseField name="active_members" type="integer">
  Number of currently active members.
</ResponseField>

<ResponseField name="total_balance" type="float">
  Current total balance of the group fund, in UGX.
</ResponseField>

<ResponseField name="personal_savings" type="float">
  The authenticated user's total contribution amount (`contribution_paid`), in UGX.
</ResponseField>

<ResponseField name="pending_approvals_count" type="integer">
  Combined count of pending loans and pending transactions across the group.
</ResponseField>

<ResponseField name="group_name" type="string">
  Name of the savings group the authenticated user belongs to.
</ResponseField>

<ResponseField name="admin_name" type="string">
  Display name of the authenticated user making the request.
</ResponseField>

<ResponseField name="monthly_contributions" type="float">
  Sum of all approved contribution transactions for the current calendar month, in UGX.
</ResponseField>

<ResponseField name="interest_earned" type="float">
  Total interest amount accrued from loans in `APPROVED`, `ACTIVE`, or `COMPLETED` status, in UGX.
</ResponseField>

<ResponseField name="group_id" type="string | null">
  Unique identifier of the group, if available. May be `null`.
</ResponseField>

<CodeGroup>
  ```bash Summary theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/analytics/summary" \
    --header "Authorization: Bearer <token>"
  ```
</CodeGroup>

```json Sample response theme={null}
{
  "total_members": 24,
  "active_members": 22,
  "total_balance": 12450000.0,
  "personal_savings": 750000.0,
  "pending_approvals_count": 4,
  "group_name": "Kampala Savers",
  "admin_name": "Aisha Nakato",
  "monthly_contributions": 480000.0,
  "interest_earned": 135000.0,
  "group_id": null
}
```

***

## GET /api/analytics/reports

Returns a financial summary for a given date range. Requires an **admin** JWT.

### Query parameters

<ParamField query="startDate" type="integer">
  Start of the report period as a Unix millisecond timestamp. Defaults to 30 days before the current time if omitted.
</ParamField>

<ParamField query="endDate" type="integer">
  End of the report period as a Unix millisecond timestamp. Defaults to the current time if omitted.
</ParamField>

### Response

<ResponseField name="start_date" type="datetime">
  ISO 8601 datetime derived from the resolved `startDate` value.
</ResponseField>

<ResponseField name="end_date" type="datetime">
  ISO 8601 datetime derived from the resolved `endDate` value.
</ResponseField>

<ResponseField name="total_contributions" type="float">
  Sum of all approved contribution transactions within the period, in UGX.
</ResponseField>

<ResponseField name="total_payouts" type="float">
  Sum of all approved payouts executed within the period, in UGX.
</ResponseField>

<ResponseField name="total_loans" type="float">
  Sum of all approved, active, or completed loan principal amounts requested within the period, in UGX.
</ResponseField>

<ResponseField name="total_repayments" type="float">
  Sum of all loan repayment amounts recorded within the period, in UGX.
</ResponseField>

<CodeGroup>
  ```bash Reports (custom date range) theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/analytics/reports?startDate=1704067200000&endDate=1706745600000" \
    --header "Authorization: Bearer <admin_token>"
  ```

  ```bash Reports (last 30 days) theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/analytics/reports" \
    --header "Authorization: Bearer <admin_token>"
  ```
</CodeGroup>

```json Sample response theme={null}
{
  "start_date": "2024-01-01T00:00:00",
  "end_date": "2024-02-01T00:00:00",
  "total_contributions": 2400000.0,
  "total_payouts": 600000.0,
  "total_loans": 900000.0,
  "total_repayments": 315000.0
}
```

***

## GET /api/credit-scores/me

Returns the credit score record for the authenticated user. Available to all authenticated users.

### Response

<ResponseField name="member_id" type="string">
  UUID of the member whose score is returned.
</ResponseField>

<ResponseField name="member_name" type="string">
  Display name of the member.
</ResponseField>

<ResponseField name="score" type="float">
  Current credit score. The scale runs from `min_credit_score` (default 300) to `max_credit_score` (default 850), with new members starting at `starting_credit_score` (default 500).
</ResponseField>

<ResponseField name="on_time_payments" type="integer">
  Number of contribution payments made on time.
</ResponseField>

<ResponseField name="late_payments" type="integer">
  Number of contribution payments made after the due date.
</ResponseField>

<ResponseField name="missed_payments" type="integer">
  Number of contribution payments that were missed entirely.
</ResponseField>

<ResponseField name="loans_repaid_on_time" type="integer">
  Number of loans fully repaid before or on the due date.
</ResponseField>

<ResponseField name="loans_repaid_late" type="integer">
  Number of loans repaid after the due date.
</ResponseField>

<ResponseField name="loans_defaulted" type="integer">
  Number of loans that defaulted without repayment.
</ResponseField>

<ResponseField name="cycles_participated" type="integer">
  Number of complete group cycles the member has participated in.
</ResponseField>

<ResponseField name="cycles_completed" type="integer">
  Number of cycles successfully completed by the member.
</ResponseField>

<ResponseField name="last_updated" type="datetime">
  ISO 8601 timestamp of the most recent score recalculation.
</ResponseField>

***

## GET /api/audit-logs

Returns a paginated list of admin action records. Requires an **admin** JWT.

### Query parameters

<ParamField query="admin_id" type="string">
  Filter results to actions performed by a specific admin UUID.
</ParamField>

<ParamField query="entity_type" type="string">
  Filter by the type of entity that was acted on (e.g., `"loan"`, `"member"`, `"config"`).
</ParamField>

<ParamField query="action" type="string">
  Filter by the action string (e.g., `"approve"`, `"reject"`, `"update"`).
</ParamField>

<ParamField query="start_date" type="string">
  ISO 8601 datetime. Only return logs created at or after this time.
</ParamField>

<ParamField query="end_date" type="string">
  ISO 8601 datetime. Only return logs created at or before this time.
</ParamField>

<ParamField query="limit" type="integer" default="100">
  Maximum number of records to return. Upper bound is `500`.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Zero-based index of the first record to return. Use with `limit` for pagination.
</ParamField>

### Response

Returns an array of `AuditLogResponse` objects, ordered by `created_at` descending.

<ResponseField name="id" type="string">
  UUID of the audit log entry.
</ResponseField>

<ResponseField name="admin_id" type="string">
  UUID of the admin who performed the action.
</ResponseField>

<ResponseField name="admin_name" type="string">
  Display name of the admin who performed the action.
</ResponseField>

<ResponseField name="action" type="string">
  String describing what was done (e.g., `"approve"`, `"reject"`, `"update"`).
</ResponseField>

<ResponseField name="entity_type" type="string">
  The type of entity that was acted on (e.g., `"loan"`, `"member"`, `"config"`).
</ResponseField>

<ResponseField name="entity_id" type="string">
  UUID of the entity that was acted on.
</ResponseField>

<ResponseField name="previous_value" type="string | null">
  JSON-serialised representation of the entity's state before the action. May be `null` for creation events.
</ResponseField>

<ResponseField name="new_value" type="string | null">
  JSON-serialised representation of the entity's state after the action. May be `null` for deletion events.
</ResponseField>

<ResponseField name="created_at" type="datetime">
  ISO 8601 timestamp of when the action was recorded.
</ResponseField>

<CodeGroup>
  ```bash All audit logs theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/audit-logs?limit=50&offset=0" \
    --header "Authorization: Bearer <admin_token>"
  ```

  ```bash Filter by action theme={null}
  curl --request GET \
    --url "https://api.saveapp.io/api/audit-logs?action=approve&limit=20" \
    --header "Authorization: Bearer <admin_token>"
  ```
</CodeGroup>

```json Sample response theme={null}
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "admin_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "admin_name": "Aisha Nakato",
    "action": "approve",
    "entity_type": "loan",
    "entity_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "previous_value": "{\"status\": \"PENDING\"}",
    "new_value": "{\"status\": \"APPROVED\"}",
    "created_at": "2024-01-20T14:35:00Z"
  }
]
```
