Files
openapi/analytics/openapi.yaml
T
zeekay 97d8813b0b chore: rebrand all 27 specs to Hanzo, fix contacts, rewrite nexus
- Remove all upstream project references from descriptions
  (Casdoor, Casvisor, Casibase, Infisical, LiteLLM, Langfuse,
  LibreChat, ActivePieces, Umami, Meilisearch, Qdrant, Harbor,
  Neon, Valkey, CoreDNS, OpenZiti, KubeRay, KubeFlow, Agnost)
- Add email: [email protected] to all 27 contact blocks
- Rewrite nexus/openapi.yaml from Swagger 2.0 to OpenAPI 3.1.0
  (was still raw Casibase spec with [email protected])
- Fix IAM: [email protected] → [email protected], Casdoor → Hanzo IAM
- Fix Cloud: "Swagger Docs" → proper Hanzo Cloud API description
- Fix O11y: Loki/Prometheus refs → LogQL/PromQL
- 28 files, 64,266 total lines, all valid YAML
2026-02-21 16:40:59 -08:00

2722 lines
71 KiB
YAML

openapi: 3.1.0
info:
title: Hanzo Analytics API
version: 1.0.0
description: Web analytics API for tracking website traffic, events, sessions, and generating reports.
contact:
name: Hanzo AI
url: https://hanzo.ai
email: [email protected]
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://analytics.hanzo.ai
description: Production
tags:
- name: Auth
description: Authentication and session management
- name: Websites
description: Website CRUD and data retrieval
- name: Events
description: Event collection and querying
- name: Sessions
description: Session tracking and analytics
- name: Pageviews
description: Pageview statistics
- name: Stats
description: Aggregate website statistics
- name: Reports
description: Report creation, management, and execution
- name: Teams
description: Team management and membership
- name: Users
description: User management
- name: Admin
description: Admin-only endpoints
- name: Me
description: Current user endpoints
- name: Share
description: Public share links
- name: Realtime
description: Realtime visitor data
- name: Collect
description: Data collection (tracker)
security:
- BearerAuth: []
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
websiteId:
name: websiteId
in: path
required: true
schema:
type: string
format: uuid
sessionId:
name: sessionId
in: path
required: true
schema:
type: string
format: uuid
userId:
name: userId
in: path
required: true
schema:
type: string
format: uuid
teamId:
name: teamId
in: path
required: true
schema:
type: string
format: uuid
reportId:
name: reportId
in: path
required: true
schema:
type: string
format: uuid
shareId:
name: shareId
in: path
required: true
schema:
type: string
startAt:
name: startAt
in: query
required: true
description: Start timestamp in milliseconds
schema:
type: integer
format: int64
endAt:
name: endAt
in: query
required: true
description: End timestamp in milliseconds
schema:
type: integer
format: int64
page:
name: page
in: query
schema:
type: integer
minimum: 1
pageSize:
name: pageSize
in: query
schema:
type: integer
minimum: 1
orderBy:
name: orderBy
in: query
schema:
type: string
search:
name: search
in: query
schema:
type: string
timezone:
name: timezone
in: query
schema:
type: string
example: America/Los_Angeles
unit:
name: unit
in: query
schema:
type: string
enum: [minute, hour, day, week, month, year]
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
username:
type: string
role:
type: string
enum: [admin, user, view-only]
logoUrl:
type: string
nullable: true
displayName:
type: string
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
nullable: true
deletedAt:
type: string
format: date-time
nullable: true
Website:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
domain:
type: string
nullable: true
shareId:
type: string
nullable: true
resetAt:
type: string
format: date-time
nullable: true
userId:
type: string
format: uuid
nullable: true
teamId:
type: string
format: uuid
nullable: true
createdBy:
type: string
format: uuid
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
nullable: true
deletedAt:
type: string
format: date-time
nullable: true
Session:
type: object
properties:
id:
type: string
format: uuid
websiteId:
type: string
format: uuid
browser:
type: string
nullable: true
os:
type: string
nullable: true
device:
type: string
nullable: true
screen:
type: string
nullable: true
language:
type: string
nullable: true
country:
type: string
nullable: true
region:
type: string
nullable: true
city:
type: string
nullable: true
distinctId:
type: string
nullable: true
createdAt:
type: string
format: date-time
Team:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
accessCode:
type: string
nullable: true
logoUrl:
type: string
nullable: true
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
nullable: true
deletedAt:
type: string
format: date-time
nullable: true
TeamUser:
type: object
properties:
id:
type: string
format: uuid
teamId:
type: string
format: uuid
userId:
type: string
format: uuid
role:
type: string
enum: [team-member, team-view-only, team-manager, team-owner]
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
nullable: true
user:
$ref: '#/components/schemas/User'
Report:
type: object
properties:
id:
type: string
format: uuid
userId:
type: string
format: uuid
websiteId:
type: string
format: uuid
type:
type: string
enum: [funnel, insights, retention, utm, goals, journey, revenue, attribution]
name:
type: string
description:
type: string
parameters:
type: object
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
nullable: true
Metric:
type: object
properties:
x:
type: string
y:
type: number
StatValue:
type: object
properties:
value:
type: number
prev:
type: number
PageviewSeries:
type: object
properties:
t:
type: string
y:
type: number
PaginatedResponse:
type: object
properties:
data:
type: array
items: {}
count:
type: integer
page:
type: integer
pageSize:
type: integer
DateRange:
type: object
required: [startDate, endDate]
properties:
startDate:
type: string
format: date-time
endDate:
type: string
format: date-time
num:
type: number
offset:
type: number
unit:
type: string
value:
type: string
ReportParams:
type: object
required: [websiteId, dateRange]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
FilterParams:
type: object
description: Optional filter parameters for narrowing query results
properties:
url:
type: string
referrer:
type: string
title:
type: string
query:
type: string
os:
type: string
browser:
type: string
device:
type: string
country:
type: string
region:
type: string
city:
type: string
tag:
type: string
host:
type: string
language:
type: string
event:
type: string
SendPayload:
type: object
required: [type, payload]
properties:
type:
type: string
enum: [event, identify]
payload:
type: object
required: [website]
properties:
website:
type: string
format: uuid
data:
type: object
hostname:
type: string
maxLength: 100
language:
type: string
maxLength: 35
referrer:
type: string
screen:
type: string
maxLength: 11
title:
type: string
url:
type: string
name:
type: string
maxLength: 50
tag:
type: string
maxLength: 50
ip:
type: string
format: ipv4
userAgent:
type: string
timestamp:
type: integer
description: Unix timestamp in seconds
id:
type: string
description: Distinct user identifier
Error:
type: object
properties:
error:
type: string
paths:
# ---------- Auth ----------
/api/auth/login:
post:
operationId: login
tags: [Auth]
summary: Log in with username and password
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username, password]
properties:
username:
type: string
password:
type: string
responses:
'200':
description: Login successful
content:
application/json:
schema:
type: object
properties:
token:
type: string
user:
type: object
properties:
id:
type: string
format: uuid
username:
type: string
role:
type: string
createdAt:
type: string
format: date-time
isAdmin:
type: boolean
'401':
description: Incorrect username or password
/api/auth/logout:
post:
operationId: logout
tags: [Auth]
summary: Log out and invalidate token
responses:
'200':
description: Logged out
/api/auth/verify:
post:
operationId: verifyAuth
tags: [Auth]
summary: Verify current auth token
responses:
'200':
description: Token is valid
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'401':
description: Invalid token
/api/auth/sso:
post:
operationId: ssoAuth
tags: [Auth]
summary: Exchange SSO credentials for a session token
responses:
'200':
description: SSO token issued
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
token:
type: string
# ---------- Collect ----------
/api/send:
post:
operationId: send
tags: [Collect]
summary: Send a single event or identify payload
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SendPayload'
responses:
'200':
description: Event accepted
content:
application/json:
schema:
type: object
properties:
cache:
type: string
description: Opaque cache token for subsequent requests
sessionId:
type: string
format: uuid
visitId:
type: string
format: uuid
/api/batch:
post:
operationId: batch
tags: [Collect]
summary: Send a batch of events
security: []
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SendPayload'
responses:
'200':
description: Batch processed
content:
application/json:
schema:
type: object
properties:
size:
type: integer
processed:
type: integer
errors:
type: integer
details:
type: array
items:
type: object
properties:
index:
type: integer
response:
type: object
/api/heartbeat:
get:
operationId: heartbeat
tags: [Auth]
summary: Health check
security: []
responses:
'200':
description: Service is running
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
# ---------- Me ----------
/api/me:
get:
operationId: getMe
tags: [Me]
summary: Get current authenticated user info
responses:
'200':
description: Current user auth context
content:
application/json:
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
/api/me/password:
post:
operationId: changeMyPassword
tags: [Me]
summary: Change current user password
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [currentPassword, newPassword]
properties:
currentPassword:
type: string
newPassword:
type: string
minLength: 8
responses:
'200':
description: Password updated
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Current password is incorrect
/api/me/teams:
get:
operationId: getMyTeams
tags: [Me]
summary: List teams for the current user
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated list of teams
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Team'
/api/me/websites:
get:
operationId: getMyWebsites
tags: [Me]
summary: List websites for the current user
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated list of websites
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Website'
# ---------- Websites ----------
/api/websites:
get:
operationId: listWebsites
tags: [Websites]
summary: List websites owned by current user
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated list of websites
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Website'
post:
operationId: createWebsite
tags: [Websites]
summary: Create a new website
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, domain]
properties:
name:
type: string
maxLength: 100
domain:
type: string
maxLength: 500
shareId:
type: string
maxLength: 50
nullable: true
teamId:
type: string
format: uuid
nullable: true
responses:
'200':
description: Website created
content:
application/json:
schema:
$ref: '#/components/schemas/Website'
/api/websites/{websiteId}:
get:
operationId: getWebsite
tags: [Websites]
summary: Get website by ID
parameters:
- $ref: '#/components/parameters/websiteId'
responses:
'200':
description: Website details
content:
application/json:
schema:
$ref: '#/components/schemas/Website'
post:
operationId: updateWebsite
tags: [Websites]
summary: Update website
parameters:
- $ref: '#/components/parameters/websiteId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name, domain]
properties:
name:
type: string
domain:
type: string
shareId:
type: string
nullable: true
responses:
'200':
description: Website updated
content:
application/json:
schema:
$ref: '#/components/schemas/Website'
delete:
operationId: deleteWebsite
tags: [Websites]
summary: Delete website
parameters:
- $ref: '#/components/parameters/websiteId'
responses:
'200':
description: Website deleted
/api/websites/{websiteId}/active:
get:
operationId: getActiveVisitors
tags: [Websites]
summary: Get count of active visitors
parameters:
- $ref: '#/components/parameters/websiteId'
responses:
'200':
description: Active visitor count
content:
application/json:
schema:
type: object
properties:
x:
type: integer
description: Number of active visitors
/api/websites/{websiteId}/daterange:
get:
operationId: getWebsiteDateRange
tags: [Websites]
summary: Get the date range of data available for a website
parameters:
- $ref: '#/components/parameters/websiteId'
responses:
'200':
description: Date range
content:
application/json:
schema:
type: object
properties:
minDate:
type: string
format: date-time
maxDate:
type: string
format: date-time
/api/websites/{websiteId}/reset:
post:
operationId: resetWebsite
tags: [Websites]
summary: Reset all data for a website
parameters:
- $ref: '#/components/parameters/websiteId'
responses:
'200':
description: Website data reset
/api/websites/{websiteId}/transfer:
post:
operationId: transferWebsite
tags: [Websites]
summary: Transfer website ownership to another user or team
parameters:
- $ref: '#/components/parameters/websiteId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
userId:
type: string
format: uuid
description: Transfer to this user (mutually exclusive with teamId)
teamId:
type: string
format: uuid
description: Transfer to this team (mutually exclusive with userId)
responses:
'200':
description: Website transferred
content:
application/json:
schema:
$ref: '#/components/schemas/Website'
/api/websites/{websiteId}/values:
get:
operationId: getWebsiteValues
tags: [Websites]
summary: Get distinct values for a given column type
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: type
in: query
required: true
description: Column type (e.g. browser, os, device, country, url, referrer, title, event, tag, language, region, city, host)
schema:
type: string
- name: search
in: query
schema:
type: string
responses:
'200':
description: Sorted list of distinct values
content:
application/json:
schema:
type: array
items:
type: string
# ---------- Stats ----------
/api/websites/{websiteId}/stats:
get:
operationId: getWebsiteStats
tags: [Stats]
summary: Get aggregate statistics for a website
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: compare
in: query
description: Compare period (e.g. "previous_period")
schema:
type: string
- name: url
in: query
schema:
type: string
- name: referrer
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
- name: os
in: query
schema:
type: string
- name: browser
in: query
schema:
type: string
- name: device
in: query
schema:
type: string
- name: country
in: query
schema:
type: string
- name: region
in: query
schema:
type: string
- name: city
in: query
schema:
type: string
- name: tag
in: query
schema:
type: string
- name: host
in: query
schema:
type: string
- name: language
in: query
schema:
type: string
- name: event
in: query
schema:
type: string
responses:
'200':
description: Stats with current and previous period values
content:
application/json:
schema:
type: object
properties:
pageviews:
$ref: '#/components/schemas/StatValue'
visitors:
$ref: '#/components/schemas/StatValue'
visits:
$ref: '#/components/schemas/StatValue'
bounces:
$ref: '#/components/schemas/StatValue'
totalTime:
$ref: '#/components/schemas/StatValue'
/api/websites/{websiteId}/metrics:
get:
operationId: getWebsiteMetrics
tags: [Stats]
summary: Get breakdown metrics by type (url, referrer, browser, os, device, country, event, channel, etc.)
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: type
in: query
required: true
description: Metric type to break down by
schema:
type: string
enum: [url, referrer, title, browser, os, device, country, region, city, language, event, tag, host, query, channel]
- name: limit
in: query
schema:
type: integer
- name: offset
in: query
schema:
type: integer
- name: search
in: query
schema:
type: string
- name: url
in: query
schema:
type: string
- name: referrer
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
- name: os
in: query
schema:
type: string
- name: browser
in: query
schema:
type: string
- name: device
in: query
schema:
type: string
- name: country
in: query
schema:
type: string
- name: region
in: query
schema:
type: string
- name: city
in: query
schema:
type: string
- name: tag
in: query
schema:
type: string
- name: host
in: query
schema:
type: string
- name: language
in: query
schema:
type: string
- name: event
in: query
schema:
type: string
responses:
'200':
description: Metric breakdown
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Metric'
# ---------- Pageviews ----------
/api/websites/{websiteId}/pageviews:
get:
operationId: getPageviews
tags: [Pageviews]
summary: Get pageview and session time series
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- $ref: '#/components/parameters/unit'
- $ref: '#/components/parameters/timezone'
- name: compare
in: query
schema:
type: string
- name: url
in: query
schema:
type: string
- name: referrer
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
- name: os
in: query
schema:
type: string
- name: browser
in: query
schema:
type: string
- name: device
in: query
schema:
type: string
- name: country
in: query
schema:
type: string
- name: region
in: query
schema:
type: string
- name: city
in: query
schema:
type: string
- name: tag
in: query
schema:
type: string
- name: host
in: query
schema:
type: string
- name: language
in: query
schema:
type: string
- name: event
in: query
schema:
type: string
responses:
'200':
description: Pageview and session series data
content:
application/json:
schema:
type: object
properties:
pageviews:
type: array
items:
$ref: '#/components/schemas/PageviewSeries'
sessions:
type: array
items:
$ref: '#/components/schemas/PageviewSeries'
startDate:
type: string
format: date-time
endDate:
type: string
format: date-time
compare:
type: object
properties:
pageviews:
type: array
items:
$ref: '#/components/schemas/PageviewSeries'
sessions:
type: array
items:
$ref: '#/components/schemas/PageviewSeries'
startDate:
type: string
format: date-time
endDate:
type: string
format: date-time
# ---------- Events ----------
/api/websites/{websiteId}/events:
get:
operationId: getEvents
tags: [Events]
summary: Get paginated list of events
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated event list
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/events/series:
get:
operationId: getEventSeries
tags: [Events]
summary: Get event metrics as a time series
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- $ref: '#/components/parameters/unit'
- $ref: '#/components/parameters/timezone'
- name: url
in: query
schema:
type: string
- name: referrer
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
- name: os
in: query
schema:
type: string
- name: browser
in: query
schema:
type: string
- name: device
in: query
schema:
type: string
- name: country
in: query
schema:
type: string
- name: region
in: query
schema:
type: string
- name: city
in: query
schema:
type: string
- name: tag
in: query
schema:
type: string
- name: host
in: query
schema:
type: string
- name: language
in: query
schema:
type: string
- name: event
in: query
schema:
type: string
responses:
'200':
description: Event time series
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PageviewSeries'
# ---------- Event Data ----------
/api/websites/{websiteId}/event-data/events:
get:
operationId: getEventDataEvents
tags: [Events]
summary: Get event data grouped by event name
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: event
in: query
schema:
type: string
responses:
'200':
description: Event data events
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/event-data/fields:
get:
operationId: getEventDataFields
tags: [Events]
summary: Get event data fields
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
responses:
'200':
description: Event data fields
content:
application/json:
schema:
type: array
items:
type: object
properties:
propertyName:
type: string
dataType:
type: integer
total:
type: integer
/api/websites/{websiteId}/event-data/properties:
get:
operationId: getEventDataProperties
tags: [Events]
summary: Get event data properties
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: propertyName
in: query
schema:
type: string
responses:
'200':
description: Event data properties
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/event-data/values:
get:
operationId: getEventDataValues
tags: [Events]
summary: Get event data values for a property
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: eventName
in: query
schema:
type: string
- name: propertyName
in: query
schema:
type: string
responses:
'200':
description: Event data values
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/event-data/stats:
get:
operationId: getEventDataStats
tags: [Events]
summary: Get event data aggregate stats
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: propertyName
in: query
schema:
type: string
responses:
'200':
description: Event data stats
content:
application/json:
schema:
type: array
items:
type: object
# ---------- Sessions ----------
/api/websites/{websiteId}/sessions:
get:
operationId: getSessions
tags: [Sessions]
summary: Get paginated list of sessions
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated session list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
/api/websites/{websiteId}/sessions/stats:
get:
operationId: getSessionStats
tags: [Sessions]
summary: Get aggregate session statistics
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: url
in: query
schema:
type: string
- name: referrer
in: query
schema:
type: string
- name: title
in: query
schema:
type: string
- name: os
in: query
schema:
type: string
- name: browser
in: query
schema:
type: string
- name: device
in: query
schema:
type: string
- name: country
in: query
schema:
type: string
- name: region
in: query
schema:
type: string
- name: city
in: query
schema:
type: string
- name: tag
in: query
schema:
type: string
- name: host
in: query
schema:
type: string
- name: language
in: query
schema:
type: string
- name: event
in: query
schema:
type: string
responses:
'200':
description: Session stats
content:
application/json:
schema:
type: object
additionalProperties:
type: object
properties:
value:
type: number
/api/websites/{websiteId}/sessions/weekly:
get:
operationId: getSessionsWeekly
tags: [Sessions]
summary: Get weekly session breakdown
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- $ref: '#/components/parameters/timezone'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Weekly session data
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/sessions/{sessionId}:
get:
operationId: getSession
tags: [Sessions]
summary: Get a single session by ID
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/sessionId'
responses:
'200':
description: Session details
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
/api/websites/{websiteId}/sessions/{sessionId}/activity:
get:
operationId: getSessionActivity
tags: [Sessions]
summary: Get activity log for a session
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/sessionId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
responses:
'200':
description: Session activity entries
content:
application/json:
schema:
type: array
items:
type: object
properties:
eventName:
type: string
nullable: true
urlPath:
type: string
createdAt:
type: string
format: date-time
/api/websites/{websiteId}/sessions/{sessionId}/properties:
get:
operationId: getSessionProperties
tags: [Sessions]
summary: Get custom session data properties
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/sessionId'
responses:
'200':
description: Session data key-value pairs
content:
application/json:
schema:
type: array
items:
type: object
# ---------- Session Data ----------
/api/websites/{websiteId}/session-data/properties:
get:
operationId: getSessionDataProperties
tags: [Sessions]
summary: Get distinct session data property names
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: propertyName
in: query
schema:
type: string
responses:
'200':
description: Session data properties
content:
application/json:
schema:
type: array
items:
type: object
/api/websites/{websiteId}/session-data/values:
get:
operationId: getSessionDataValues
tags: [Sessions]
summary: Get session data values for a property
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
- name: propertyName
in: query
schema:
type: string
responses:
'200':
description: Session data values
content:
application/json:
schema:
type: array
items:
type: object
# ---------- Reports (CRUD) ----------
/api/reports:
get:
operationId: listReports
tags: [Reports]
summary: List reports, optionally filtered by website or team
parameters:
- name: websiteId
in: query
schema:
type: string
format: uuid
- name: teamId
in: query
schema:
type: string
format: uuid
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated list of reports
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Report'
post:
operationId: createReport
tags: [Reports]
summary: Create a new report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, name, type, description, parameters]
properties:
websiteId:
type: string
format: uuid
name:
type: string
maxLength: 200
type:
type: string
enum: [funnel, insights, retention, utm, goals, journey, revenue, attribution]
description:
type: string
maxLength: 500
parameters:
type: object
responses:
'200':
description: Report created
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
/api/reports/{reportId}:
get:
operationId: getReport
tags: [Reports]
summary: Get a report by ID
parameters:
- $ref: '#/components/parameters/reportId'
responses:
'200':
description: Report details
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
'404':
description: Report not found
post:
operationId: updateReport
tags: [Reports]
summary: Update a report
parameters:
- $ref: '#/components/parameters/reportId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, type, name, description, parameters]
properties:
websiteId:
type: string
format: uuid
type:
type: string
enum: [funnel, insights, retention, utm, goals, journey, revenue, attribution]
name:
type: string
maxLength: 200
description:
type: string
maxLength: 500
parameters:
type: object
responses:
'200':
description: Report updated
content:
application/json:
schema:
$ref: '#/components/schemas/Report'
delete:
operationId: deleteReport
tags: [Reports]
summary: Delete a report
parameters:
- $ref: '#/components/parameters/reportId'
responses:
'200':
description: Report deleted
/api/websites/{websiteId}/reports:
get:
operationId: getWebsiteReports
tags: [Reports]
summary: List reports for a specific website
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated report list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Report'
# ---------- Report Execution ----------
/api/reports/funnel:
post:
operationId: runFunnelReport
tags: [Reports]
summary: Run a funnel report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, window, steps]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
window:
type: number
description: Funnel window in minutes
minimum: 1
steps:
type: array
minItems: 2
items:
type: object
required: [type, value]
properties:
type:
type: string
value:
type: string
responses:
'200':
description: Funnel results
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/insights:
post:
operationId: runInsightsReport
tags: [Reports]
summary: Run an insights report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, fields, filters]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
fields:
type: array
minItems: 1
items:
type: object
required: [name, type, label]
properties:
name:
type: string
type:
type: string
label:
type: string
filters:
type: array
items:
type: object
required: [name, type, operator, value]
properties:
name:
type: string
type:
type: string
operator:
type: string
value:
type: string
responses:
'200':
description: Insights results
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/retention:
post:
operationId: runRetentionReport
tags: [Reports]
summary: Run a retention report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, timezone]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
timezone:
type: string
responses:
'200':
description: Retention cohort data
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/goals:
post:
operationId: runGoalsReport
tags: [Reports]
summary: Run a goals report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, goals]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
goals:
type: array
minItems: 1
items:
type: object
required: [type, value, goal]
properties:
type:
type: string
enum: [url, event, event-data]
value:
type: string
goal:
type: number
operator:
type: string
enum: [count, sum, average]
description: Required when type is event-data
property:
type: string
description: Required when type is event-data
responses:
'200':
description: Goals results
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/journey:
post:
operationId: runJourneyReport
tags: [Reports]
summary: Run a user journey report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, steps]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
steps:
type: integer
minimum: 3
maximum: 7
startStep:
type: string
endStep:
type: string
responses:
'200':
description: Journey flow data
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/utm:
post:
operationId: runUtmReport
tags: [Reports]
summary: Run a UTM report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
responses:
'200':
description: UTM breakdown data
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/revenue:
get:
operationId: getRevenueValues
tags: [Reports]
summary: Get available revenue values for a website
parameters:
- name: websiteId
in: query
required: true
schema:
type: string
format: uuid
- name: startDate
in: query
required: true
schema:
type: string
format: date-time
- name: endDate
in: query
required: true
schema:
type: string
format: date-time
responses:
'200':
description: Revenue values
content:
application/json:
schema:
type: array
items:
type: object
post:
operationId: runRevenueReport
tags: [Reports]
summary: Run a revenue report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, currency, timezone]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
currency:
type: string
timezone:
type: string
responses:
'200':
description: Revenue time series
content:
application/json:
schema:
type: array
items:
type: object
/api/reports/attribution:
post:
operationId: runAttributionReport
tags: [Reports]
summary: Run an attribution report
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [websiteId, dateRange, model, steps]
properties:
websiteId:
type: string
format: uuid
dateRange:
$ref: '#/components/schemas/DateRange'
model:
type: string
enum: [firstClick, lastClick]
steps:
type: array
minItems: 1
items:
type: object
required: [type, value]
properties:
type:
type: string
value:
type: string
currency:
type: string
responses:
'200':
description: Attribution data
content:
application/json:
schema:
type: array
items:
type: object
# ---------- Users ----------
/api/users:
post:
operationId: createUser
tags: [Users]
summary: Create a new user (admin only)
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username, password, role]
properties:
id:
type: string
format: uuid
username:
type: string
maxLength: 255
password:
type: string
role:
type: string
enum: [admin, user, view-only]
responses:
'200':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: User already exists
/api/users/{userId}:
get:
operationId: getUser
tags: [Users]
summary: Get user by ID
parameters:
- $ref: '#/components/parameters/userId'
responses:
'200':
description: User details
content:
application/json:
schema:
$ref: '#/components/schemas/User'
post:
operationId: updateUser
tags: [Users]
summary: Update user
parameters:
- $ref: '#/components/parameters/userId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username]
properties:
username:
type: string
maxLength: 255
password:
type: string
maxLength: 255
role:
type: string
enum: [admin, user, view-only]
responses:
'200':
description: User updated
content:
application/json:
schema:
$ref: '#/components/schemas/User'
delete:
operationId: deleteUser
tags: [Users]
summary: Delete user (admin only)
parameters:
- $ref: '#/components/parameters/userId'
responses:
'200':
description: User deleted
'400':
description: Cannot delete yourself
/api/users/{userId}/teams:
get:
operationId: getUserTeams
tags: [Users]
summary: List teams a user belongs to
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated team list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Team'
/api/users/{userId}/websites:
get:
operationId: getUserWebsites
tags: [Users]
summary: List websites owned by a user
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated website list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Website'
/api/users/{userId}/usage:
get:
operationId: getUserUsage
tags: [Users]
summary: Get event usage breakdown for a user (admin only)
parameters:
- $ref: '#/components/parameters/userId'
- $ref: '#/components/parameters/startAt'
- $ref: '#/components/parameters/endAt'
responses:
'200':
description: Usage data
content:
application/json:
schema:
type: object
properties:
websiteEventUsage:
type: integer
eventDataUsage:
type: integer
websites:
type: array
items:
type: object
properties:
websiteId:
type: string
format: uuid
websiteName:
type: string
websiteEventUsage:
type: integer
eventDataUsage:
type: integer
# ---------- Teams ----------
/api/teams:
post:
operationId: createTeam
tags: [Teams]
summary: Create a new team
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
properties:
name:
type: string
maxLength: 50
responses:
'200':
description: Team created
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
/api/teams/join:
post:
operationId: joinTeam
tags: [Teams]
summary: Join a team using an access code
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [accessCode]
properties:
accessCode:
type: string
maxLength: 50
responses:
'200':
description: Joined team
content:
application/json:
schema:
$ref: '#/components/schemas/TeamUser'
'400':
description: Already a team member
'404':
description: Team not found
/api/teams/{teamId}:
get:
operationId: getTeam
tags: [Teams]
summary: Get team by ID (includes members)
parameters:
- $ref: '#/components/parameters/teamId'
responses:
'200':
description: Team details with members
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
'404':
description: Team not found
post:
operationId: updateTeam
tags: [Teams]
summary: Update team (owner only)
parameters:
- $ref: '#/components/parameters/teamId'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
maxLength: 50
accessCode:
type: string
maxLength: 50
responses:
'200':
description: Team updated
content:
application/json:
schema:
$ref: '#/components/schemas/Team'
delete:
operationId: deleteTeam
tags: [Teams]
summary: Delete team (owner only)
parameters:
- $ref: '#/components/parameters/teamId'
responses:
'200':
description: Team deleted
/api/teams/{teamId}/users:
get:
operationId: getTeamUsers
tags: [Teams]
summary: List team members
parameters:
- $ref: '#/components/parameters/teamId'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated team member list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TeamUser'
post:
operationId: addTeamUser
tags: [Teams]
summary: Add a user to a team
parameters:
- $ref: '#/components/parameters/teamId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [userId, role]
properties:
userId:
type: string
format: uuid
role:
type: string
enum: [team-member, team-view-only, team-manager]
responses:
'200':
description: User added to team
content:
application/json:
schema:
$ref: '#/components/schemas/TeamUser'
'400':
description: User is already a member
/api/teams/{teamId}/users/{userId}:
get:
operationId: getTeamUser
tags: [Teams]
summary: Get a team member
parameters:
- $ref: '#/components/parameters/teamId'
- $ref: '#/components/parameters/userId'
responses:
'200':
description: Team user details
content:
application/json:
schema:
$ref: '#/components/schemas/TeamUser'
post:
operationId: updateTeamUser
tags: [Teams]
summary: Update team member role (owner only)
parameters:
- $ref: '#/components/parameters/teamId'
- $ref: '#/components/parameters/userId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [role]
properties:
role:
type: string
enum: [team-member, team-view-only, team-manager]
responses:
'200':
description: Team user updated
content:
application/json:
schema:
$ref: '#/components/schemas/TeamUser'
delete:
operationId: removeTeamUser
tags: [Teams]
summary: Remove user from team
parameters:
- $ref: '#/components/parameters/teamId'
- $ref: '#/components/parameters/userId'
responses:
'200':
description: User removed from team
/api/teams/{teamId}/websites:
get:
operationId: getTeamWebsites
tags: [Teams]
summary: List websites belonging to a team
parameters:
- $ref: '#/components/parameters/teamId'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated website list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Website'
# ---------- Admin ----------
/api/admin/users:
get:
operationId: adminListUsers
tags: [Admin]
summary: List all users (admin only)
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated user list with website counts
content:
application/json:
schema:
type: array
items:
allOf:
- $ref: '#/components/schemas/User'
- type: object
properties:
_count:
type: object
properties:
websiteUser:
type: integer
/api/admin/websites:
get:
operationId: adminListWebsites
tags: [Admin]
summary: List all websites for a user (admin only)
parameters:
- name: userId
in: query
required: true
schema:
type: string
format: uuid
- name: includeOwnedTeams
in: query
schema:
type: string
- name: includeAllTeams
in: query
schema:
type: string
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/pageSize'
- $ref: '#/components/parameters/orderBy'
- $ref: '#/components/parameters/search'
responses:
'200':
description: Paginated website list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Website'
# ---------- Realtime ----------
/api/realtime/{websiteId}:
get:
operationId: getRealtimeData
tags: [Realtime]
summary: Get realtime visitor data for the last 30 minutes
parameters:
- $ref: '#/components/parameters/websiteId'
- $ref: '#/components/parameters/timezone'
responses:
'200':
description: Realtime data
content:
application/json:
schema:
type: object
# ---------- Share ----------
/api/share/{shareId}:
get:
operationId: getSharedWebsite
tags: [Share]
summary: Get a shared website by share ID (no auth required)
security: []
parameters:
- $ref: '#/components/parameters/shareId'
responses:
'200':
description: Shared website token
content:
application/json:
schema:
type: object
properties:
websiteId:
type: string
format: uuid
token:
type: string
'404':
description: Share not found
# ---------- Telemetry ----------
/api/scripts/telemetry:
get:
operationId: getTelemetryScript
tags: [Auth]
summary: Get telemetry pixel script
security: []
responses:
'200':
description: JavaScript telemetry snippet
content:
text/javascript:
schema:
type: string