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 identifierurl(required): Full URL of the page being viewedreferrer(optional): Referrer URLuser_agent(optional): User agent string for device/browser detectionip_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 identifierevent_name(required): Name of the custom event (e.g., "signup", "purchase", "download")url(required): Full URL where the event occurredreferrer(optional): Referrer URLprops(optional): Custom event properties (max 10 key-value pairs)user_agent(optional): User agent stringip_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 parametersunauthorized: Invalid or missing API keyrate_limit_exceeded: Too many requests (see rate limits)invalid_site_id: Site ID not found or access deniedinvalid_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
- Privacy First: Never send PII (personally identifiable information) in event properties
- Use Meaningful Names: Event names should be clear and consistent (e.g., "signup", not "s" or "user_reg")
- Limit Properties: Only send necessary properties (max 10 per event)
- Handle Errors Gracefully: Don't let analytics failures break your application
- Respect Rate Limits: Implement backoff and retry logic
- Validate Data: Ensure URLs are well-formed and event names are valid
- Test in Development: Use a separate site_id for testing
- Monitor API Keys: Rotate keys regularly and revoke unused ones
SDK Libraries
Official SDKs coming soon:
@ovyxa/node- Node.js/JavaScriptovyxa-python- Pythonovyxa-ruby- Rubyovyxa-php- PHP
For now, use the HTTP API directly with your preferred HTTP client.