Skip to main content

Events API

The Events API allows you to send pageviews and custom events to Ovyxa programmatically. This is useful for server-side tracking, mobile applications, backend processes, and scenarios where the JavaScript snippet cannot be used.

Base URL

All Events API requests are sent to:

https://api.ovyxa.com/api/v1/events

Authentication

Events API requires authentication via API keys or JWT tokens in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Generate API keys in your Ovyxa dashboard under Settings → API Keys.


POST /events/pageview

Track manual pageviews from server-side code or applications.

Endpoint: POST /api/v1/events/pageview

Request Body:

{
"site_id": "your-site-id",
"url": "https://example.com/page",
"referrer": "https://google.com",
"user_agent": "Mozilla/5.0...",
"ip_address": "192.168.1.1"
}

Parameters:

  • site_id (required): Your site identifier
  • url (required): Full URL of the page being viewed
  • referrer (optional): Referrer URL
  • user_agent (optional): User agent string for device/browser detection
  • ip_address (optional): IP address for geo-location (not stored, only used for country detection)

Response (201 Created):

{
"success": true,
"event_id": "evt_1234567890"
}

Example (cURL):

curl -X POST https://api.ovyxa.com/api/v1/events/pageview \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"site_id": "site_abc123",
"url": "https://example.com/pricing",
"referrer": "https://google.com/search",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"ip_address": "203.0.113.42"
}'

Example (JavaScript/Node.js):

const response = await fetch('https://api.ovyxa.com/api/v1/events/pageview', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
site_id: 'site_abc123',
url: 'https://example.com/pricing',
referrer: 'https://google.com/search',
user_agent: req.headers['user-agent'],
ip_address: req.ip
})
});

const data = await response.json();
console.log(data); // { success: true, event_id: "evt_..." }

Example (Python):

import requests

response = requests.post(
'https://api.ovyxa.com/api/v1/events/pageview',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'site_id': 'site_abc123',
'url': 'https://example.com/pricing',
'referrer': 'https://google.com/search',
'user_agent': request.headers.get('User-Agent'),
'ip_address': request.remote_addr
}
)

data = response.json()
print(data) # {'success': True, 'event_id': 'evt_...'}

POST /events/custom

Track custom events with optional properties for conversion tracking and advanced analytics.

Endpoint: POST /api/v1/events/custom

Request Body:

{
"site_id": "your-site-id",
"event_name": "signup",
"url": "https://example.com/signup/complete",
"referrer": "https://example.com/pricing",
"props": {
"plan": "pro",
"source": "landing-page",
"trial_days": 14
},
"user_agent": "Mozilla/5.0...",
"ip_address": "192.168.1.1"
}

Parameters:

  • site_id (required): Your site identifier
  • event_name (required): Name of the custom event (e.g., "signup", "purchase", "download")
  • url (required): Full URL where the event occurred
  • referrer (optional): Referrer URL
  • props (optional): Custom event properties (max 10 key-value pairs)
  • user_agent (optional): User agent string
  • ip_address (optional): IP address for geo-location

Event Properties (props):

  • Maximum 10 properties per event
  • Keys must be strings (max 50 characters)
  • Values can be strings, numbers, or booleans
  • Avoid including PII (names, emails, etc.)

Response (201 Created):

{
"success": true,
"event_id": "evt_1234567890"
}

Example (cURL):

curl -X POST https://api.ovyxa.com/api/v1/events/custom \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"site_id": "site_abc123",
"event_name": "signup",
"url": "https://example.com/signup/complete",
"props": {
"plan": "pro",
"source": "landing-page",
"trial_days": 14
}
}'

Example (JavaScript/Node.js):

async function trackSignup(userId, plan) {
const response = await fetch('https://api.ovyxa.com/api/v1/events/custom', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
site_id: 'site_abc123',
event_name: 'signup',
url: 'https://example.com/signup/complete',
props: {
plan: plan,
source: 'api',
timestamp: new Date().toISOString()
}
})
});

if (!response.ok) {
console.error('Failed to track signup:', await response.text());
}
}

// Usage
await trackSignup('user_123', 'pro');

Example (Python):

import requests

def track_event(event_name, url, props=None):
response = requests.post(
'https://api.ovyxa.com/api/v1/events/custom',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'site_id': 'site_abc123',
'event_name': event_name,
'url': url,
'props': props or {}
}
)

if response.status_code == 201:
print(f"Event '{event_name}' tracked successfully")
else:
print(f"Error: {response.text}")

# Usage
track_event('purchase', 'https://example.com/checkout/success', {
'amount': 99.99,
'currency': 'USD',
'product': 'Pro Plan Annual'
})

Use Cases

The Events API enables powerful server-side tracking scenarios:

1. Server-Side Tracking

Track actions that happen on your backend:

// After successful payment processing
await fetch('https://api.ovyxa.com/api/v1/events/custom', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
site_id: 'site_abc123',
event_name: 'payment_successful',
url: 'https://example.com/checkout/success',
props: {
plan: 'enterprise',
amount: 999,
currency: 'USD'
}
})
});

2. Mobile App Events

Track events from native mobile applications:

// iOS Swift
func trackAppEvent(eventName: String, props: [String: Any]) {
let url = URL(string: "https://api.ovyxa.com/api/v1/events/custom")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer YOUR_API_KEY", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

let payload: [String: Any] = [
"site_id": "site_abc123",
"event_name": eventName,
"url": "app://example/\(eventName)",
"props": props
]

request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

URLSession.shared.dataTask(with: request).resume()
}

// Usage
trackAppEvent(eventName: "feature_used", props: [
"feature": "export_data",
"format": "csv"
])

3. Batch Imports

Import historical events from other analytics platforms:

async function importEvents(events) {
for (const event of events) {
await fetch('https://api.ovyxa.com/api/v1/events/custom', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
site_id: 'site_abc123',
event_name: event.name,
url: event.url,
props: event.properties
})
});

// Rate limiting: wait 10ms between requests
await new Promise(resolve => setTimeout(resolve, 10));
}
}

4. Backend Process Tracking

Track automated processes and cron jobs:

# Daily report generation
def generate_report():
# ... report generation logic ...

# Track completion
requests.post(
'https://api.ovyxa.com/api/v1/events/custom',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'site_id': 'site_abc123',
'event_name': 'report_generated',
'url': 'https://example.com/reports/daily',
'props': {
'report_type': 'daily',
'records_processed': 15000,
'duration_seconds': 42
}
}
)

Error Handling

Error Response (400 Bad Request):

{
"error": {
"code": "invalid_request",
"message": "Missing required field: event_name",
"field": "event_name"
}
}

Common Error Codes:

  • invalid_request: Missing or invalid parameters
  • unauthorized: Invalid or missing API key
  • rate_limit_exceeded: Too many requests (see rate limits)
  • invalid_site_id: Site ID not found or access denied
  • invalid_props: Event properties exceed limits (max 10 keys)

Error Handling Example:

try {
const response = await fetch('https://api.ovyxa.com/api/v1/events/custom', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(eventData)
});

if (!response.ok) {
const error = await response.json();
console.error(`Error ${error.error.code}: ${error.error.message}`);
return;
}

const data = await response.json();
console.log('Event tracked:', data.event_id);
} catch (err) {
console.error('Network error:', err);
}

Rate Limits

Events API has the following rate limits per API key:

  • Free tier: 1,000 events/hour
  • Pro tier: 10,000 events/hour
  • Enterprise tier: Custom limits

When rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.

Rate Limit Handling:

async function trackEventWithRetry(eventData, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch('https://api.ovyxa.com/api/v1/events/custom', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(eventData)
});

if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
console.log(`Rate limited. Retrying after ${retryAfter}s...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}

return response;
}

throw new Error('Max retries exceeded');
}

Best Practices

  1. Privacy First: Never send PII (personally identifiable information) in event properties
  2. Use Meaningful Names: Event names should be clear and consistent (e.g., "signup", not "s" or "user_reg")
  3. Limit Properties: Only send necessary properties (max 10 per event)
  4. Handle Errors Gracefully: Don't let analytics failures break your application
  5. Respect Rate Limits: Implement backoff and retry logic
  6. Validate Data: Ensure URLs are well-formed and event names are valid
  7. Test in Development: Use a separate site_id for testing
  8. Monitor API Keys: Rotate keys regularly and revoke unused ones

SDK Libraries

Official SDKs coming soon:

  • @ovyxa/node - Node.js/JavaScript
  • ovyxa-python - Python
  • ovyxa-ruby - Ruby
  • ovyxa-php - PHP

For now, use the HTTP API directly with your preferred HTTP client.