Event Ingestion API
Track events from your server or application with the PRIV Protocol Events API.
Track events from your server or application. The events API supports both single events and batch ingestion.
Track Events
/api/v1/eventsTrack one or more events. Supports two formats: the events array format and the SDK batch format.
Events Array Format
Use this format for server-side event tracking:
{
"events": [
{
"event_type": "track",
"event_name": "purchase_completed",
"user_id": "user_123",
"anonymous_id": "anon_456",
"session_id": "sess_789",
"properties": {
"product_id": "prod_abc",
"price": 99.99,
"currency": "USD"
},
"page_url": "https://example.com/checkout",
"page_title": "Checkout",
"referrer": "https://example.com/cart",
"timestamp": "2024-01-15T10:30:00Z",
"consent_given": true
}
]
}SDK Batch Format
The @priv/sdk uses this format for automatic batching:
{
"batch": [
{
"type": "track",
"id": "evt_unique_id",
"timestamp": "2024-01-15T10:30:00.000Z",
"anonymousId": "anon_456",
"sessionId": "sess_789",
"event": "button_click",
"properties": {
"button": "cta_signup",
"page": "/pricing"
},
"userId": "user_123"
},
{
"type": "page",
"id": "evt_page_id",
"timestamp": "2024-01-15T10:29:00.000Z",
"anonymousId": "anon_456",
"sessionId": "sess_789",
"name": "Pricing Page",
"properties": {
"url": "https://example.com/pricing",
"title": "Pricing - Example"
}
},
{
"type": "identify",
"id": "evt_identify_id",
"timestamp": "2024-01-15T10:28:00.000Z",
"anonymousId": "anon_456",
"sessionId": "sess_789",
"userId": "user_123",
"traits": {
"email": "user@example.com",
"plan": "pro"
}
}
]
}Event Types
| Type | Description |
|---|---|
track | Custom event tracking |
page_view / page | Page view event |
identify | User identification |
Request Fields (Events Format)
| Field | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | One of: track, page_view, identify |
event_name | string | Yes | Name of the event |
user_id | string | No | Authenticated user identifier |
anonymous_id | string | No | Anonymous identifier |
session_id | string | No | Session identifier |
properties | object | No | Event properties/metadata |
page_url | string | No | URL where event occurred |
page_title | string | No | Page title |
referrer | string | No | Referring URL |
timestamp | string | No | ISO 8601 timestamp |
consent_given | boolean | No | Whether user consented |
One of user_id or anonymous_id is required to identify the event source.
Response
{
"success": true,
"data": {
"received": 3,
"stored": 3
}
}Limits
- Maximum 100 events per batch request
- Maximum 1MB payload size
- Events older than 7 days may be rejected
Example: cURL
curl -X POST https://api.priv.io/v1/events \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"event_type": "track",
"event_name": "swap_completed",
"user_id": "user_123",
"properties": {
"token_in": "ETH",
"token_out": "USDC",
"amount": "1.5"
},
"consent_given": true
}
]
}'Example: JavaScript
const response = await fetch('https://api.priv.io/v1/events', {
method: 'POST',
headers: {
'Authorization': 'Bearer pk_live_xxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
events: [
{
event_type: 'track',
event_name: 'purchase_completed',
user_id: 'user_123',
properties: {
product_id: 'prod_abc',
price: 99.99,
},
consent_given: true,
},
],
}),
});
const data = await response.json();
console.log(`Stored ${data.data.stored} events`);Identify User
/api/v1/identifyAssociate traits with a user. This creates or updates the user profile.
Request
{
"userId": "user_123",
"anonymousId": "anon_456",
"traits": {
"email": "user@example.com",
"name": "John Doe",
"plan": "pro",
"created_at": "2024-01-01"
}
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | User identifier |
anonymousId | string | No | Previous anonymous ID to merge |
traits | object | No | User traits/properties |
Response
{
"success": true,
"data": {
"userId": "user_123"
}
}Track Page View
/api/v1/pageTrack a page view event with URL and referrer information.
Request
{
"userId": "user_123",
"name": "Pricing Page",
"properties": {
"url": "https://example.com/pricing",
"title": "Pricing - Example",
"referrer": "https://google.com"
}
}Response
{
"success": true,
"data": {
"eventId": "evt_page_123"
}
}Best Practices
Event Naming
Use snake_case and be descriptive:
// Good
purchase_completed
button_clicked
form_submitted
swap_executed
// Bad
Purchase
click
submitProperties
Include relevant context without sensitive data:
{
"event": "swap_completed",
"properties": {
"token_in": "ETH",
"token_out": "USDC",
"amount_in": "1.5",
"amount_out": "2500",
"slippage": "0.5%",
"dex": "uniswap"
}
}Timestamps
Always include accurate timestamps for historical data:
{
"event_name": "order_completed",
"timestamp": "2024-01-15T10:30:00.000Z"
}Consent
Always track user consent status:
{
"event_name": "page_view",
"consent_given": true
}Events without consent_given: true may be filtered out depending on your compliance settings.
Batching
For high-volume applications, batch events:
// Collect events
const eventQueue: Event[] = [];
// Send in batches of 50
if (eventQueue.length >= 50) {
await sendEvents(eventQueue);
eventQueue.length = 0;
}