Server-side ingest code examples
Server-side ingest examples that send an event with curl, Node.js, Python, PHP, Go, Rails and Next.js, forwarding the visitor's User-Agent and IP.
All examples send one Signup event for the visitor who made the current
request. Keep the ingest key in PRIVATUS_INGEST_KEY.
curl#
curl -X POST https://privatusanalytics.com/api/events \
-H "Authorization: Bearer $PRIVATUS_INGEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [{
"type": "event",
"name": "Signup",
"url": "https://example.com/signup",
"props": { "plan": "pro" },
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0 Safari/537.36",
"ip": "203.0.113.7"
}]
}'
The user_agent must be a real browser's: curl's own User-Agent is only on
the request, not in the event, so it doesn't matter here.
Node.js (Express)#
app.post('/signup', async (req, res) => {
// … create the account …
const response = await fetch('https://privatusanalytics.com/api/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PRIVATUS_INGEST_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
events: [{
type: 'event',
name: 'Signup',
url: `https://example.com${req.originalUrl}`,
referrer: req.get('referer'),
props: { plan: req.body.plan },
user_agent: req.get('user-agent'),
ip: req.ip, // set app.set('trust proxy', …) behind a load balancer
}],
}),
})
const { data } = await response.json() // [{ index, status, reason }]
res.redirect('/welcome')
})
Python (Django or Flask)#
import os
import requests
def track_signup(request, plan):
requests.post(
"https://privatusanalytics.com/api/events",
headers={"Authorization": f"Bearer {os.environ['PRIVATUS_INGEST_KEY']}"},
json={"events": [{
"type": "event",
"name": "Signup",
"url": request.build_absolute_uri(), # Flask: request.url
"props": {"plan": plan},
"user_agent": request.headers.get("User-Agent"),
"ip": request.META.get("REMOTE_ADDR"), # Flask: request.remote_addr
}]},
timeout=5,
)
PHP#
<?php
$payload = ['events' => [[
'type' => 'event',
'name' => 'Signup',
'url' => 'https://example.com' . $_SERVER['REQUEST_URI'],
'props' => ['plan' => 'pro'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
'ip' => $_SERVER['REMOTE_ADDR'] ?? null,
]]];
$ch = curl_init('https://privatusanalytics.com/api/events');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PRIVATUS_INGEST_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
Go#
func trackSignup(r *http.Request, plan string) error {
body, _ := json.Marshal(map[string]any{
"events": []map[string]any{{
"type": "event",
"name": "Signup",
"url": "https://example.com" + r.URL.RequestURI(),
"props": map[string]any{"plan": plan},
"user_agent": r.UserAgent(),
"ip": clientIP(r), // your helper: RemoteAddr or X-Forwarded-For from a trusted proxy
}},
})
req, _ := http.NewRequestWithContext(r.Context(), http.MethodPost,
"https://privatusanalytics.com/api/events", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("PRIVATUS_INGEST_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
Ruby (Rails)#
require "net/http"
class PrivatusEvents
URL = URI("https://privatusanalytics.com/api/events")
def self.track(request, name, props = {})
Net::HTTP.post(
URL,
{ events: [{ type: "event", name:, url: request.original_url, props:,
user_agent: request.user_agent, ip: request.remote_ip }] }.to_json,
"Authorization" => "Bearer #{ENV.fetch('PRIVATUS_INGEST_KEY')}",
"Content-Type" => "application/json"
)
end
end
# In a controller:
PrivatusEvents.track(request, "Signup", plan: "pro")
Consider sending from a background job so a slow network never delays your
response, but don't put the IP or User-Agent in the job payload if your
job store is persistent. Send in the request, or drop ip.
Next.js middleware#
The @privatus/next package's
trackPageview() and trackEvent() read the IP and User-Agent from the
incoming request for you and run on the Edge runtime.
Warning: @privatus/next is not published on npm yet. Until it is,
don't install a package with this name from the public registry,
because anyone could have published it. Call the ingest API
directly, as in the examples above, instead.