Creator Traffic Sources
Top 15 referrer domains for the authenticated creator's bio page, with visit counts and percentage share. Direct visits show up as "direct".
GET /api/v1/creators/analytics/traffic โ ๐ Bearer ยท Rate limit: 60 req / minute
Returns the top 15 referrer domains driving traffic to the creator's bio page, plus each one's share of total visits. referrerDomain was extracted at session-create time (URL.hostname.replace('www.', '')); sessions with no referrer or an unparseable one show up under 'direct'.
direct is the catch-all. Any session with referrer === null or a referrer that didn't parse as a URL became 'direct' at write-time. You'll always see it as a row when there's any direct traffic โ there's no separate "unknown" bucket.
percentage is rounded to whole integers. Math.round((visits / total) * 100) โ no decimals. The sum across rows can drift a percent or two from 100 due to rounding; don't render it as "100% pie" without normalizing client-side.
Request
Query parameters
| Param | Type | Default | Notes |
|---|---|---|---|
days | integer | 30 | Lookback window. Capped at 365. |
Headers
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | โ | JwtAuthGuard. |
Response
200 OK โ ApiResponseOf<CreatorTrafficDto>
{
"success": true,
"data": {
"sources": [
{ "source": "instagram.com", "visits": 600, "percentage": 35 },
{ "source": "direct", "visits": 280, "percentage": 16 },
{ "source": "youtube.com", "visits": 150, "percentage": 9 }
]
}
}Item fields (sources[])
| Field | Type | Notes |
|---|---|---|
source | string | Referrer domain (e.g. "instagram.com") or "direct". |
visits | number | Session count where referrerDomain matched (or was null/unparseable, mapped to "direct"). |
percentage | number | Whole-number percentage of total visits. Rows are sorted by visits DESC. |
Errors
Same as overview โ 401 / 404 error.creator.not_found / 404 error.creator.bio_not_found / 429.
Side effects
JwtAuthGuard+ThrottleGuard.getBioPageId(userId)(main DB โ 404 if missing creator/bio page).analyticsDb.$queryRaw(Analytics DB):SELECT COALESCE("referrerDomain", 'direct') as source, COUNT(*)::int as visits FROM "AnalyticsSession" WHERE "bioPageId" = $bioPageId::uuid AND "startedAt" >= $since GROUP BY "referrerDomain" ORDER BY visits DESC LIMIT 15- Compute
total = sum(visits), then map each row to addpercentage = Math.round((visits / total) * 100).0when total is zero.
Code samples
curl 'https://api.bio.re/api/v1/creators/analytics/traffic?days=30' \
-H "Authorization: Bearer $ACCESS_TOKEN"type TrafficSource = { source: string; visits: number; percentage: number };
async function getTraffic(
accessToken: string,
days = 30,
): Promise<{ sources: TrafficSource[] }> {
const res = await fetch(
`https://api.bio.re/api/v1/creators/analytics/traffic?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
Authorization
bearer In: header
Query Parameters
Response Body
application/json
application/json
application/json
curl -X GET "https://loading/api/v1/creators/analytics/traffic"{
"success": true,
"data": {
"sources": [
{
"source": "instagram",
"visits": 600
}
]
}
}{
"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
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/analytics/creator-analytics.controller.ts | 64โ80 (traffic) |
| DTO (response) | apps/api-core/src/modules/analytics/dto/analytics-client-response.dto.ts | 89โ92 (CreatorTrafficDto), 76โ85 (item shape) |
| Prisma model | packages/prisma-analytics/prisma/schema.prisma | AnalyticsSession.referrerDomain (line 59), index @@index([referrerDomain, startedAt]) (91) |
Creator Analytics Overview
Top-line counters for the authenticated creator's bio page โ total views, unique visitors (by hashed visitorId), total link clicks, CTR. Scoped to the caller's own bio page; foreign access is impossible.
Creator Geo Distribution
Top 20 visitor countries for the authenticated creator's bio page. Country names from GeoIP at session-create; sessions with unknown country fall under "Unknown".