Send server-side events
Track events from your backend services using the Umami API. This is useful for recording actions that happen outside the browser, such as webhook events, payment completions, or background job results.
When to use server-side tracking
- Payment webhooks: Record purchases confirmed by Stripe, PayPal, or other payment processors.
- API actions: Track when users perform actions through your API (e.g., mobile app events).
- Background jobs: Record events from cron jobs, email sends, or data processing pipelines.
- Importing historical data: Backfill events from another analytics platform.
Using the Node client
The simplest approach for Node.js backends is the Umami Node client:
npm install @umami/nodeimport umami from '@umami/node';
umami.init({
websiteId: 'your-website-id',
hostUrl: 'https://your-umami.example.com',
});
// Track a page view
await umami.track({ url: '/api/checkout', title: 'Checkout API' });
// Track a custom event
await umami.track({
name: 'payment-received',
data: {
revenue: 49.99,
currency: 'USD',
plan: 'pro',
},
});Using the API directly
Send a POST request to /api/send with the event payload:
curl -X POST https://your-umami.example.com/api/send \
-H "Content-Type: application/json" \
-H "User-Agent: Mozilla/5.0 (Server)" \
-d '{
"payload": {
"hostname": "example.com",
"language": "en-US",
"url": "/checkout",
"website": "your-website-id",
"name": "payment-received",
"data": {
"revenue": 49.99,
"currency": "USD"
}
},
"type": "event"
}'Important: A valid
User-Agentheader is required. Requests without one will be rejected.
Python example
import requests
requests.post('https://your-umami.example.com/api/send', json={
'payload': {
'hostname': 'example.com',
'language': 'en-US',
'url': '/checkout',
'website': 'your-website-id',
'name': 'payment-received',
'data': {
'revenue': 49.99,
'currency': 'USD',
},
},
'type': 'event',
}, headers={
'User-Agent': 'MyApp/1.0',
})Batch sending
To send multiple events in a single request, POST a JSON array to the /api/batch endpoint. Each element of the array has the same shape as an /api/send request body:
curl -X POST https://your-umami.example.com/api/batch \
-H "Content-Type: application/json" \
-H "User-Agent: Mozilla/5.0 (Server)" \
-d '[
{
"type": "event",
"payload": {
"website": "your-website-id",
"hostname": "example.com",
"url": "/page-1",
"name": "page-view"
}
},
{
"type": "event",
"payload": {
"website": "your-website-id",
"hostname": "example.com",
"url": "/page-2",
"name": "page-view"
}
}
]'Each item is forwarded to /api/send, so the same type values (event, identify, performance) and payload fields are supported. The response summarizes the batch:
{
"size": 2,
"processed": 2,
"errors": 0,
"details": [],
"cache": "..."
}If any items fail, errors is the failure count and details lists each failure by its index in the array.
Tips
- Server-side events appear in the same dashboard as client-side events. Use event names or properties to distinguish them if needed.
- When tracking revenue from payment webhooks, use the
revenueandcurrencyproperties so data appears in the Revenue insight. - For high-volume backends, consider queuing events and sending them with concurrency limits to avoid overwhelming your instance.