Send Events
Send events to Hardal with an HTTP POST to the /collect endpoint.
curl -X POST "https://analytics.yourdomain.com/collect" \
-H "Content-Type: application/json" \
-H "x-hrd-session-id: 123e4567-e89b-12d3-a456-426614174000" \
-H "x-hrd-consent: granted" \
-d '{
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"title": "Request a Quote",
"hostname": "www.yourdomain.com",
"url": "https://www.yourdomain.com/quote",
"timestamp": 1773914400000,
"data": {
"plan": "enterprise",
"seats": 250,
"region": "EMEA"
}
}
}'
import requests
import json
url = "https://analytics.yourdomain.com/collect"
headers = {
"Content-Type": "application/json",
"x-hrd-session-id": "123e4567-e89b-12d3-a456-426614174000",
"x-hrd-consent": "granted"
}
data = {
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"title": "Request a Quote",
"hostname": "www.yourdomain.com",
"url": "https://www.yourdomain.com/quote",
"timestamp": 1773914400000,
"data": {
"plan": "enterprise",
"seats": 250,
"region": "EMEA"
}
}
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://analytics.yourdomain.com/collect", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-hrd-session-id": "123e4567-e89b-12d3-a456-426614174000",
"x-hrd-consent": "granted"
},
body: JSON.stringify({
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"title": "Request a Quote",
"hostname": "www.yourdomain.com",
"url": "https://www.yourdomain.com/quote",
"timestamp": 1773914400000,
"data": {
"plan": "enterprise",
"seats": 250,
"region": "EMEA"
}
}
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"title": "Request a Quote",
"hostname": "www.yourdomain.com",
"url": "https://www.yourdomain.com/quote",
"timestamp": 1773914400000,
"data": {
"plan": "enterprise",
"seats": 250,
"region": "EMEA"
}
}
}`)
req, err := http.NewRequest("POST", "https://analytics.yourdomain.com/collect", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-hrd-session-id", "123e4567-e89b-12d3-a456-426614174000")
req.Header.Set("x-hrd-consent", "granted")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://analytics.yourdomain.com/collect')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['x-hrd-session-id'] = '123e4567-e89b-12d3-a456-426614174000'
request['x-hrd-consent'] = 'granted'
request.body = '{
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"title": "Request a Quote",
"hostname": "www.yourdomain.com",
"url": "https://www.yourdomain.com/quote",
"timestamp": 1773914400000,
"data": {
"plan": "enterprise",
"seats": 250,
"region": "EMEA"
}
}
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"accepted": 1,
"events": [
{
"eventId": "123e4567-e89b-12d3-a456-426614174000",
"sourceId": "your-source-id"
}
],
"consentStatus": "granted"
},
"timestamp": "2024-12-25T10:00:00Z",
"path": "/collect",
"requestId": "example_string"
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
/collect
Target server for requests. Edit to use your own host.
The media type of the request body
Optional UUID shared by events in the same session.
Consent state: granted or denied. See Consent Signals before sending user identity.
Your Tenant ID from Setup in the Dashboard. Send it in the JSON body.
Optional session UUID. You can use x-hrd-session-id instead.
Consent state: granted or denied. You can use x-hrd-consent instead.
Use event for standard and custom actions, or page_view for a page visit.
The action name, such as purchase, quote_requested or page_view.
Send multiple events in this array instead of the single-event fields.
Request Preview
Response
Response will appear here after sending the request
Headers
Optional UUID shared by events in the same session.
Consent state: granted or denied. See Consent Signals before sending user identity.
granteddeniedBody
Your Tenant ID from Setup in the Dashboard. Send it in the JSON body.
11111111-1111-4111-8111-111111111111Optional session UUID. You can use x-hrd-session-id instead.
33333333-3333-4333-8333-333333333333Consent state: granted or denied. You can use x-hrd-consent instead.
granteddeniedSend multiple events in this array instead of the single-event fields.
Responses
Send an event
Use your first-party URL, Tenant ID, and Source ID from Setup in the Dashboard.
curl -X POST "https://analytics.yourdomain.com/collect" \
-H "Content-Type: application/json" \
-d '{
"tenantId": "11111111-1111-4111-8111-111111111111",
"type": "event",
"eventName": "quote_requested",
"payload": {
"sourceId": "22222222-2222-4222-8222-222222222222",
"timestamp": 1792659600000,
"data": {
"plan": "enterprise"
}
}
}'
Replace the example IDs and timestamp with your own values. Send the event time in milliseconds, for example Date.now() in JavaScript.
Build the body
| Field | Required | What to send |
|---|---|---|
tenantId | Yes | Your Tenant ID (UUID), in the JSON body. |
type | Yes | Use event for standard and custom actions. For a page visit, use page_view. |
eventName | Yes | The action name, such as purchase, quote_requested, or page_view. |
payload.sourceId | Yes | Your Source ID (UUID). |
payload.timestamp | Yes | Event time as a Unix timestamp in milliseconds. |
payload.data | No | Parameters for the event, such as plan, value, or items. |
type describes the kind of event; eventName describes the action. Keep event parameters inside payload.data.
For page visits, include payload.url with its query parameters and payload.referrer when available. For purchases and other standard events, use the parameters in Standard Events. You can also send Custom Events.
To send several events together, use an events array with type, eventName, and payload in each entry. Keep tenantId at the top level.
Optional headers
x-hrd-session-id: a UUID shared by events in the same session.x-hrd-consent:grantedordenied. See Consent Signals before sending user identity.
To link events to a known user, follow Identify Visitors.
Check the result
202 Accepted means Hardal accepted the request for processing. Check the Events report to confirm your event appears.
For 400 Bad Request, check the required fields, UUIDs, and JSON format. The response includes error details.