Send Agent Events
Send request metadata to Hardal so AI Visibility can analyze AI agent, crawler, and bot traffic.
curl -X POST "https://analytics.yourdomain.com/agent-events" \
-H "Content-Type: application/json" \
-H "tenant-id: 11111111-1111-4111-8111-111111111111" \
-d '{
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
}'
import requests
import json
url = "https://analytics.yourdomain.com/agent-events"
headers = {
"Content-Type": "application/json",
"tenant-id": "11111111-1111-4111-8111-111111111111"
}
data = {
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://analytics.yourdomain.com/agent-events", {
method: "POST",
headers: {
"Content-Type": "application/json",
"tenant-id": "11111111-1111-4111-8111-111111111111"
},
body: JSON.stringify({
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
}`)
req, err := http.NewRequest("POST", "https://analytics.yourdomain.com/agent-events", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("tenant-id", "11111111-1111-4111-8111-111111111111")
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/agent-events')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['tenant-id'] = '11111111-1111-4111-8111-111111111111'
request.body = '{
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
}'
response = http.request(request)
puts response.body
{
"success": true,
"data": {
"accepted": 1,
"events": [
{
"eventId": "44444444-4444-4444-8444-444444444444",
"sourceId": "22222222-2222-4222-8222-222222222222"
}
]
},
"timestamp": "2026-10-22T09:00:00.000Z",
"path": "/agent-events",
"requestId": "example-request-id"
}
{}
{
"success": false,
"error": {
"code": "invalid-tenant-id",
"message": "invalid-tenant-id",
"details": {
"tenantId": "invalid"
}
},
"timestamp": "2026-10-22T09:00:00.000Z",
"path": "/agent-events",
"requestId": "example-request-id"
}
curl -i -X POST "https://analytics.yourdomain.com/agent-events" \
-H "Content-Type: application/json" \
-H "tenant-id: 11111111-1111-4111-8111-111111111111" \
-d '{
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
}'
import requests
response = requests.post(
"https://analytics.yourdomain.com/agent-events",
headers={
"Content-Type": "application/json",
"tenant-id": "11111111-1111-4111-8111-111111111111",
},
json={
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
},
timeout=10,
)
if response.status_code == 204:
print("Request filtered; no event recorded.")
else:
response.raise_for_status()
print(response.json())
const response = await fetch("https://analytics.yourdomain.com/agent-events", {
method: "POST",
headers: {
"Content-Type": "application/json",
"tenant-id": "11111111-1111-4111-8111-111111111111"
},
body: JSON.stringify({
"path": "/pricing",
"ip": "66.249.66.1",
"userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
"eventTime": "2026-04-29T15:12:17.836Z",
"sourceId": "22222222-2222-4222-8222-222222222222"
})
});
if (response.status === 204) {
console.log("Request filtered; no event recorded.");
} else {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(await response.json());
}
/agent-events
Target server for requests. Edit to use your own host.
The media type of the request body
Your Tenant ID (UUID) from Setup in the Dashboard.
Requested path on the website.
IP address from the original incoming request.
Raw User-Agent header from the request.
Request time in ISO 8601 format.
Your Source ID (UUID) from Setup in the Dashboard.
Request Preview
Response
Response will appear here after sending the request
Headers
Your Tenant ID (UUID) from Setup in the Dashboard.
11111111-1111-4111-8111-111111111111Body
Raw User-Agent header from the request.
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)Your Source ID (UUID) from Setup in the Dashboard.
22222222-2222-4222-8222-222222222222Responses
Send request metadata
Send the original request's metadata to your first-party /agent-events endpoint. Replace the sample Tenant ID and Source ID with the UUIDs from Setup in the Dashboard, and use the original request's path, IP address, User-Agent, and time.
Headers
Send Content-Type: application/json and your tenant-id. Session and consent headers from Send Events are not used by this endpoint.
Check the result
202 Accepted: one event accepted for processing (accepted: 1).204 No Content: request filtered; the body is empty. Do not parse it as JSON.400 Bad Request: check the required fields, UUIDs, and error details.