API Reference
Server API

Server API

Track events server-side for maximum reliability and privacy.

Overview

The Server API allows you to send events directly from your backend, bypassing client-side limitations entirely.

Use cases:

  • Backend order confirmations
  • Webhook integrations
  • High-security environments
  • Hybrid tracking (client + server)

Authentication

All server API requests require your Server API Key.

๐Ÿšซ

Keep your Server Key secret! Never expose it in client-side code.

Include in headers:

Authorization: Bearer YOUR_SERVER_API_KEY

Or as query parameter:

?api_key=YOUR_SERVER_API_KEY

Track Event

Endpoint

POST https://your-endpoint.com/v1/track

Request

curl -X POST https://your-endpoint.com/v1/track \
  -H "Authorization: Bearer YOUR_SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "purchase",
    "timestamp": "2024-01-15T14:30:45Z",
    "session_id": "sess_abc123",
    "user_id": "user_12345",
    "properties": {
      "order_id": "ORD-12345",
      "value": 99.99,
      "currency": "USD"
    },
    "user_data": {
      "email": "customer@example.com",
      "phone": "+1234567890"
    },
    "context": {
      "ip": "203.0.113.0",
      "user_agent": "Mozilla/5.0...",
      "page_url": "https://yoursite.com/checkout"
    }
  }'

Request Body

FieldTypeRequiredDescription
event_typestringYesEvent name
timestampstringNoISO 8601 timestamp (default: now)
session_idstringNoSession ID from client
user_idstringNoYour user identifier
propertiesobjectNoEvent properties
user_dataobjectNoEnhanced Conversions data
contextobjectNoRequest context

Properties

PropertyTypeDescription
order_idstringOrder/transaction ID
valuenumberEvent value
currencystringISO currency code
itemsarrayProduct items

User Data

All fields are automatically hashed before sending to ad platforms.

FieldTypeDescription
emailstringCustomer email
phonestringPhone (E.164 format)
first_namestringFirst name
last_namestringLast name
citystringCity
statestringState/region
postal_codestringZIP/postal code
countrystringCountry code

Context

FieldTypeDescription
ipstringClient IP address
user_agentstringBrowser user agent
page_urlstringPage URL
referrerstringReferrer URL
gclidstringGoogle Click ID
fbclidstringFacebook Click ID
msclkidstringMicrosoft Click ID

Response

Success (200)

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

Error (4xx/5xx)

{
  "success": false,
  "error": "Invalid API key"
}

Batch Track

Send multiple events in one request.

Endpoint

POST https://your-endpoint.com/v1/track/batch

Request

curl -X POST https://your-endpoint.com/v1/track/batch \
  -H "Authorization: Bearer YOUR_SERVER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "event_type": "purchase",
        "properties": { "order_id": "ORD-001", "value": 99.99 }
      },
      {
        "event_type": "purchase",
        "properties": { "order_id": "ORD-002", "value": 149.99 }
      }
    ]
  }'

Limits

LimitValue
Max events per batch100
Max request size1 MB
Rate limit1000 req/min

Code Examples

const axios = require('axios')
 
async function trackPurchase(order) {
  await axios.post('https://your-endpoint.com/v1/track', {
    event_type: 'purchase',
    properties: {
      order_id: order.id,
      value: order.total,
      currency: 'USD'
    },
    user_data: {
      email: order.customer.email,
      phone: order.customer.phone
    },
    context: {
      session_id: order.session_id,
      ip: order.ip_address
    }
  }, {
    headers: {
      'Authorization': `Bearer ${process.env.CONVULTRA_SERVER_KEY}`,
      'Content-Type': 'application/json'
    }
  })
}

Linking Client and Server

Pass the client session to your server for unified tracking:

Client Side

// Get session ID
const sessionId = Convultra.getSessionId()
 
// Include in form/checkout
<input type="hidden" name="session_id" value={sessionId} />

Server Side

// Use same session for server events
await axios.post('https://your-endpoint.com/v1/track', {
  event_type: 'purchase',
  session_id: req.body.session_id, // From client
  properties: { ... }
})

Error Handling

StatusMeaningAction
200SuccessEvent tracked
400Bad requestCheck request format
401UnauthorizedCheck API key
429Rate limitedBack off, retry later
500Server errorRetry with backoff

Retry Strategy

async function trackWithRetry(event, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await track(event)
    } catch (error) {
      if (error.response?.status === 429 || error.response?.status >= 500) {
        await sleep(1000 * Math.pow(2, i)) // Exponential backoff
        continue
      }
      throw error
    }
  }
}

Next Steps