BIO.RE
Creator Analytics

Creator Session Metrics

Aggregate session metrics for the authenticated creator's bio page — total sessions, bounce rate, average session duration, average pages per session.

GET /api/v1/creators/analytics/sessions — 🔑 Bearer · Rate limit: 60 req / minute

Four headline session metrics. Use this for the dashboard "engagement" tile — bounces, attention time, and how many pages a typical visitor opens.

bounceRate is integer percentage. Math.round((bounced / total) * 100) — 0 decimals. A session is bounced until its second pageview lands (the POST /pageview atomic UPDATE flips the flag) — single-pageview visits are bounces.

avgDuration excludes zero-duration sessions. The aggregate filters where: { duration: { gt: 0 } } — sessions that never received a heartbeat or pageleave (so still have duration = 0) are dropped before averaging. This biases the number upward vs a naïve AVG(duration). Don't multiply avgDuration * totalSessions to get total time.

pagesPerSession is rounded to 1 decimal. Math.round(avg * 10) / 102.5, not 2.51. avgDuration is rounded to whole seconds (Math.round(avg)).

Request

Query parameters

ParamTypeDefaultNotes
daysinteger30Lookback window. Capped at 365.

Headers

HeaderRequiredNotes
Authorization: Bearer <accessToken>JwtAuthGuard.

Response

200 OKApiResponseOf<CreatorSessionsDto>

{
  "success": true,
  "data": {
    "totalSessions": 1800,
    "bounceRate": 42,
    "avgDuration": 145,
    "pagesPerSession": 1.8
  }
}
FieldTypeNotes
totalSessionsnumberAll sessions in the window for this bio page.
bounceRatenumberWhole-number percentage of totalSessions that ended with bounced = true (i.e. had only one pageview).
avgDurationnumberAverage session duration in seconds, rounded to integer, only over sessions with duration > 0. 0 when no qualifying sessions.
pagesPerSessionnumberAverage pageViews per session across all sessions, rounded to 1 decimal. 0 when no sessions.

Errors

Same as overview.

Side effects

  1. JwtAuthGuard + ThrottleGuard.
  2. getBioPageId(userId).
  3. Four parallel queries against the Analytics DB:
    • count({ where: { bioPageId, startedAt: { gte: since } } })total.
    • count({ where: { bioPageId, startedAt: { gte: since }, bounced: true } })bounced.
    • aggregate({ where: { bioPageId, startedAt: { gte: since }, duration: { gt: 0 } }, _avg: { duration } })avgDur.
    • aggregate({ where: { bioPageId, startedAt: { gte: since } }, _avg: { pageViews } })avgPv.
  4. Compute the four metrics, round per the rules above, return.

Code samples

curl 'https://api.bio.re/api/v1/creators/analytics/sessions?days=30' \
  -H "Authorization: Bearer $ACCESS_TOKEN"
type SessionMetrics = {
  totalSessions: number;
  bounceRate: number;
  avgDuration: number;
  pagesPerSession: number;
};

async function getSessions(accessToken: string, days = 30): Promise<SessionMetrics> {
  const res = await fetch(
    `https://api.bio.re/api/v1/creators/analytics/sessions?days=${days}`,
    { headers: { Authorization: `Bearer ${accessToken}` } },
  );
  const json = await res.json();
  if (!res.ok || !json.success) throw new Error(json?.error?.message ?? 'Failed');
  return json.data;
}

Try it

GET
/api/v1/creators/analytics/sessions
AuthorizationBearer <token>

In: header

Query Parameters

days?string

Response Body

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/creators/analytics/sessions"
{
  "success": true,
  "data": {
    "totalSessions": 1800,
    "bounceRate": 42.5,
    "avgDuration": 145,
    "pagesPerSession": 1.8
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/analytics/creator-analytics.controller.ts141–163 (sessions)
DTO (response)apps/api-core/src/modules/analytics/dto/analytics-client-response.dto.ts159–171 (CreatorSessionsDto)
Prisma modelpackages/prisma-analytics/prisma/schema.prismaAnalyticsSession.bounced / duration / pageViews (lines 54–57), index @@index([bounced, startedAt]) (92)

On this page