LiveUniqueUsers.md
Live Unique Users — Frontend Integration
Returns the distinct logged-in users who watched a video while it was live, with their name/email when known. Paginated. Intended for the admin analytics dashboard.
Endpoint
GET /admin/v1/video-analytics/live-unique-users/{videoId}?page=1&pageSize=15
- Method:
GET - Auth: Admin only — same authorization as the other
/admin/v1/video-analytics/*endpoints (e.g.live-viewers,totals,graph). Send the same admin credentials/headers you already use for those. A non-admin / unauthenticated call returns 401. - Base URL: same host you already use for the admin API (per environment).
Path parameters
| Name | Type | Description |
|---|---|---|
videoId |
string | The video id. |
Query parameters
| Name | Type | Default | Notes |
|---|---|---|---|
page |
number | 1 |
1-based page number. Values <= 0 are treated as 1. |
pageSize |
number | 15 |
Items per page. Max 50 (larger values are clamped to 50; <= 0 becomes 1). |
Response 200 OK
Standard pagination envelope ({ items, totalCount }):
{
"items": [
{
"userId": "14a29c05-1983-4b14-ba98-a88202bd9493",
"name": "Riad Asllani",
"email": "[email protected]",
"portaLink": null
},
{
"userId": "2f59d36d-e479-40bc-bc29-e6e398c40bd3",
"name": null,
"email": null,
"portaLink": "https://porta-gjirafainc-admin.gjirafa.com/users/2f59d36d-e479-40bc-bc29-e6e398c40bd3/user-details"
}
],
"totalCount": 30
}
Top-level fields
| Field | Type | Notes |
|---|---|---|
totalCount |
number | Total distinct logged-in users who watched while live (the full count, not just this page). Use it to compute the number of pages: Math.ceil(totalCount / pageSize). |
items |
array | Users for the requested page only. |
items[] fields
| Field | Type | Notes |
|---|---|---|
userId |
string | The user's id (Porta/account id). Always present. |
name |
string | null | Full name. null when the user was not found in the internal users DB. |
email |
string | null | Email. null when not found internally. |
portaLink |
string | null | Set only when name/email are null. Link to look the user up manually in the Porta admin portal. |
How the frontend should render a row
For each item in items:
- If
name/emailare present → show them normally. - If they're
nullandportaLinkis set → the user isn't in our DB. Render theuserIdand make it (or a "View in Porta" button) link toportaLink(open in a new tab) so an admin can look up the details manually.
items.map(u =>
u.email
? <Row name={u.name} email={u.email} />
: <Row id={u.userId} link={u.portaLink} label="View in Porta" />
)
// pages
const totalPages = Math.ceil(totalCount / pageSize);
Behavior notes
- Caching: results are cached server-side for ~2 minutes, per
(videoId, page, pageSize). Numbers refresh at most every couple of minutes (consistent across requests in that window). The metric is cumulative for the broadcast, sototalCountonly grows. - Invalid or unknown
videoId: returns200with{ "items": [], "totalCount": 0 }(not a 404). - Page out of range: returns
200withitems: []and the realtotalCount. - Errors: unexpected failures return
400with an error body (same shape as other admin analytics endpoints).
Examples
# first page (default page=1, pageSize=15)
curl -X GET "{BASE_URL}/admin/v1/video-analytics/live-unique-users/aZjMMPomjV" \
-H "Authorization: <same admin auth as other admin analytics calls>"
# page 2, 25 per page
curl -X GET "{BASE_URL}/admin/v1/video-analytics/live-unique-users/aZjMMPomjV?page=2&pageSize=25" \
-H "Authorization: <same admin auth as other admin analytics calls>"