| ← Back to README | Documentation Index | API Docs | Developer Guide |
The Event Collection API allows you to track user interactions and analytics data from your websites. Events are collected through the /api/v1/events endpoints and stored in the database for later aggregation and analysis.
Base URL: http://localhost:3000/api/v1/events
trackingCode
trackingCode (format: pm-xxxx-timestamp)| Field | Type | Required | Description |
|---|---|---|---|
trackingCode |
string | ✅ Yes | Website tracking code (format: pm-*) |
eventType |
enum | ✅ Yes | Type of event: pageview, click, custom |
url |
string (URL) | ✅ Yes | The page URL where event occurred |
referrer |
string (URL) | ❌ No | Referrer URL (where visitor came from) |
sessionId |
string | ✅ Yes | Unique session identifier |
visitorId |
string | ✅ Yes | Unique visitor identifier |
deviceType |
enum | ❌ No | Device type: mobile, tablet, desktop |
browser |
string | ❌ No | Browser name (e.g., “Chrome”, “Firefox”) |
os |
string | ❌ No | Operating system (e.g., “Windows”, “macOS”) |
location |
string | ❌ No | Geographic location (e.g., “US”, “GB”) |
timestamp |
number | ❌ No | Event timestamp in milliseconds (server uses current time if omitted) |
properties |
object | ❌ No | Custom properties as key-value pairs |
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/blog/article",
"referrer": "https://google.com",
"sessionId": "sess-user-123-session-456",
"visitorId": "vis-user-unique-id-789",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US",
"timestamp": 1704067200000,
"properties": {
"articleId": "art-123",
"readingTime": 5
}
}
Endpoint: POST /api/v1/events
Purpose: Submit a single event to the tracking system
Request Body:
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/page",
"referrer": "https://google.com",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US"
}
Success Response (201 Created):
{
"id": "clv1234567890",
"websiteId": "web-123",
"eventType": "pageview",
"url": "https://example.com/page",
"referrer": "https://google.com",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US",
"createdAt": "2026-01-28T20:00:00.000Z"
}
Error Response (400 - Invalid Data):
{
"error": "VALIDATION_ERROR",
"message": "Invalid event data",
"details": {
"fieldErrors": {
"trackingCode": ["Invalid tracking code format"]
}
}
}
Error Response (404 - Website Not Found):
{
"error": "NOT_FOUND",
"message": "Website with this tracking code not found"
}
Endpoint: POST /api/v1/events/batch
Purpose: Submit multiple events in a single request (recommended for performance)
Request Body:
{
"events": [
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/page1",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome"
},
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "click",
"url": "https://example.com/page1",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"properties": {
"buttonId": "cta-button"
}
}
]
}
Success Response (201 Created):
{
"success": true,
"eventsCreated": 2,
"events": [
{
"id": "clv1234567890",
"websiteId": "web-123",
"eventType": "pageview",
"url": "https://example.com/page1",
"createdAt": "2026-01-28T20:00:00.000Z"
},
{
"id": "clv1234567891",
"websiteId": "web-123",
"eventType": "click",
"url": "https://example.com/page1",
"createdAt": "2026-01-28T20:00:00.001Z"
}
],
"message": "Successfully created 2 events"
}
Partial Success Response (207 Multi-Status):
{
"success": false,
"eventsCreated": 1,
"events": [
{
"id": "clv1234567890",
"websiteId": "web-123",
"eventType": "pageview",
"url": "https://example.com/page1",
"createdAt": "2026-01-28T20:00:00.000Z"
}
],
"errors": [
{
"index": 1,
"error": "NOT_FOUND",
"message": "Website with tracking code \"invalid\" not found"
}
],
"message": "Created 1 events with 1 errors"
}
Endpoint: GET /api/v1/events?trackingCode=pm-xxx&eventType=pageview&limit=100&offset=0
Purpose: Retrieve events for a website with optional filtering
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
trackingCode |
string | ✅ Yes | Website tracking code |
eventType |
string | ❌ No | Filter by event type (pageview, click, custom) |
limit |
number | ❌ No | Max results (default: 100, max: 1000) |
offset |
number | ❌ No | Pagination offset (default: 0) |
Success Response (200 OK):
{
"events": [
{
"id": "clv1234567890",
"eventType": "pageview",
"url": "https://example.com/page",
"referrer": "https://google.com",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US",
"createdAt": "2026-01-28T20:00:00.000Z"
}
],
"pagination": {
"total": 1,
"limit": 100,
"offset": 0
}
}
Endpoint: GET /api/v1/events/:id
Purpose: Retrieve a specific event by ID
Success Response (200 OK):
{
"id": "clv1234567890",
"websiteId": "web-123",
"eventType": "pageview",
"url": "https://example.com/page",
"referrer": "https://google.com",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US",
"properties": null,
"createdAt": "2026-01-28T20:00:00.000Z"
}
First, register a website to get the tracking code (see Website Management Guide):
curl -X POST http://localhost:3000/api/v1/websites \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"name": "My Website",
"domain": "example.com",
"description": "My example website"
}'
This returns:
{
"id": "web-123",
"trackingCode": "pm-abc123-1704067200000",
"name": "My Website",
"domain": "example.com"
}
curl -X POST http://localhost:3000/api/v1/events \
-H "Content-Type: application/json" \
-d '{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/blog/article-1",
"referrer": "https://google.com",
"sessionId": "sess-user123-session1",
"visitorId": "vis-user123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows",
"location": "US"
}'
curl -X POST http://localhost:3000/api/v1/events/batch \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/page1",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows"
},
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "pageview",
"url": "https://example.com/page2",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"os": "Windows"
},
{
"trackingCode": "pm-abc123-1704067200000",
"eventType": "click",
"url": "https://example.com/page2",
"sessionId": "sess-123",
"visitorId": "vis-123",
"deviceType": "desktop",
"browser": "Chrome",
"properties": {
"buttonId": "subscribe-btn"
}
}
]
}'
# Get all events for a website
curl http://localhost:3000/api/v1/events?trackingCode=pm-abc123-1704067200000
# Get only pageview events
curl http://localhost:3000/api/v1/events?trackingCode=pm-abc123-1704067200000&eventType=pageview
# Get with pagination
curl http://localhost:3000/api/v1/events?trackingCode=pm-abc123-1704067200000&limit=50&offset=0
# Get specific event
curl http://localhost:3000/api/v1/events/clv1234567890
Events are stored in the Event table in SQLite with the following structure:
model Event {
id String @id @default(cuid())
websiteId String
website Website @relation(fields: [websiteId], references: [id])
eventType String
url String
referrer String?
sessionId String
visitorId String
deviceType String?
browser String?
os String?
location String?
properties String? // JSON stringified
createdAt DateTime @default(now())
@@index([websiteId])
@@index([sessionId])
@@index([visitorId])
@@index([createdAt])
}
All events are validated using Zod schemas:
pm-*pageview, click, custommobile, tablet, desktopInstead of sending individual events:
# ❌ Slow - Multiple requests
curl -X POST http://localhost:3000/api/v1/events -d {...}
curl -X POST http://localhost:3000/api/v1/events -d {...}
curl -X POST http://localhost:3000/api/v1/events -d {...}
# ✅ Fast - Single batch request
curl -X POST http://localhost:3000/api/v1/events/batch -d {...}
Include device type, browser, and OS for better analytics:
{
"deviceType": "mobile",
"browser": "Safari",
"os": "iOS"
}
Use the same sessionId for events in the same session, and same visitorId for all events from a visitor:
{
"sessionId": "sess-[timestamp]-[random]",
"visitorId": "vis-[unique-user-id]"
}
Helps track traffic sources:
{
"referrer": "https://google.com/search?q=analytics"
}
Add custom data as needed:
{
"properties": {
"articleId": "art-123",
"author": "john-doe",
"category": "tech"
}
}
After implementing event collection:
trackingCode is validerrors array in the response| ← Back to README | Documentation Index | API Docs |