API Reference

Event Tracking

Track custom events programmatically using the Basket API. This is useful for server-side tracking, mobile apps, or custom integrations.

Base URL

https://basket.databuddy.cc

Authentication

You can authenticate requests using either:

  1. API Key (recommended for server-side): pass in the x-api-key header or as a Bearer token in the Authorization header
  2. Client ID — Pass as the website_id query parameter or as websiteId in the event body
http
# With API Key
POST /track
x-api-key: your_api_key

# Or as a Bearer token
POST /track
Authorization: Bearer your_api_key

# With Client ID
POST /track?website_id={website_id}

API keys require the track:events scope to send events.


Track Events

The primary endpoint for sending custom events.

http
POST /track

Single Event

json
{
"name": "purchase",
"properties": {
  "value": 99.99,
  "currency": "USD",
  "product_id": "prod_123"
},
"anonymousId": "anon_user_123",
"sessionId": "session_456",
"timestamp": 1704067200000
}

Batch Events

Send an array of events in a single request:

json
[
{
  "name": "page_view",
  "properties": { "page": "/pricing" },
  "timestamp": 1704067200000
},
{
  "name": "purchase",
  "properties": { "value": 99.99 },
  "timestamp": 1704067260000
}
]

Response

json
{
"status": "success",
"type": "custom_event",
"count": 1
}

Event Fields

FieldTypeRequiredDescription
namestringYesEvent name (1-256 characters)
propertiesobjectNoCustom event properties (max 50 keys, 32KB serialized)
eventIdstringNoClient-supplied event ID used for deduplication (max 512 chars)
pathstringNoPage path or URL associated with the event (max 2048 chars)
anonymousIdstringNoAnonymous user identifier (max 256 chars)
profileIdstringNoYour own user identifier for identity stitching
anonymizeVisitorIdsboolean | "auto"NoControls visitor ID anonymization
sessionIdstringNoSession identifier (max 256 chars)
timestampnumber | string | DateNoEvent timestamp (defaults to now)
namespacestringNoEvent namespace for grouping (max 64 chars)
sourcestringNoEvent source identifier (max 64 chars)
websiteIdstringNoPublic Databuddy Client ID (same value as data-client-id in the tracker; string id from the dashboard, not necessarily a UUID). Alternative to ?website_id=

Payload Limits

LimitValue
Properties per event50 keys
Serialized properties size32KB
Request body size2MB

Server-Side Examples

Node.js / TypeScript

typescript
async function trackEvent(
name: string,
properties?: Record<string, unknown>
) {
const response = await fetch('https://basket.databuddy.cc/track', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_api_key'
  },
  body: JSON.stringify({
    name,
    properties,
    timestamp: Date.now()
  })
});
return response.json();
}

// Usage
await trackEvent('purchase', {
value: 99.99,
currency: 'USD',
product_id: 'prod_123'
});

Python

python
import requests
import time

def track_event(name: str, properties: dict = None):
  response = requests.post(
      "https://basket.databuddy.cc/track",
      headers={
          "Content-Type": "application/json",
          "Authorization": "Bearer your_api_key"
      },
      json={
          "name": name,
          "properties": properties or {},
          "timestamp": int(time.time() * 1000)
      }
  )
  return response.json()

# Usage
track_event("purchase", {
  "value": 99.99,
  "currency": "USD",
  "product_id": "prod_123"
})

cURL

bash
curl -X POST https://basket.databuddy.cc/track \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key" \
-d '{
  "name": "purchase",
  "properties": {
    "value": 99.99,
    "currency": "USD"
  }
}'

Common Event Examples

E-commerce Purchase

json
{
"name": "purchase",
"properties": {
  "order_id": "order_123",
  "value": 149.99,
  "currency": "USD",
  "items": [
    {"sku": "SKU-001", "name": "Product A", "quantity": 2, "price": 49.99},
    {"sku": "SKU-002", "name": "Product B", "quantity": 1, "price": 50.01}
  ]
}
}

User Signup

json
{
"name": "signup",
"properties": {
  "method": "email",
  "plan": "free",
  "referrer": "google"
}
}

Feature Usage

json
{
"name": "feature_used",
"namespace": "dashboard",
"properties": {
  "feature": "export_csv",
  "format": "xlsx"
}
}

Subscription Event

json
{
"name": "subscription_started",
"properties": {
  "plan": "pro",
  "billing_cycle": "annual",
  "mrr": 99
}
}

Additional Endpoints

These endpoints are used by the JavaScript tracker SDK and are documented here for completeness. The client_id query value is your Databuddy Client ID.

Web Vitals

Track Core Web Vitals metrics.

http
POST /vitals?client_id={client_id}
json
[
{
  "timestamp": 1704067200000,
  "path": "https://example.com/page",
  "metricName": "LCP",
  "metricValue": 2500
}
]
FieldTypeRequiredDescription
timestampnumberYesUnix timestamp in milliseconds
pathstringYesPage URL
metricNamestringYesOne of: FCP, LCP, CLS, INP, TTFB, FPS
metricValuenumberYesMetric value
anonymousIdstringNoAnonymous user identifier
sessionIdstringNoSession identifier

Error Tracking

Track JavaScript errors.

http
POST /errors?client_id={client_id}
json
[
{
  "timestamp": 1704067200000,
  "path": "https://example.com/app",
  "message": "Cannot read property 'id' of undefined",
  "filename": "https://example.com/app.js",
  "lineno": 42,
  "colno": 15,
  "stack": "TypeError: ...",
  "errorType": "TypeError"
}
]
FieldTypeRequiredDescription
timestampnumberYesUnix timestamp in milliseconds
pathstringYesPage URL
messagestringYesError message
filenamestringNoSource file
linenonumberNoLine number
colnonumberNoColumn number
stackstringNoStack trace
errorTypestringNoError type (e.g. TypeError)
anonymousIdstringNoAnonymous user identifier
sessionIdstringNoSession identifier

Error Responses

json
{
"success": false,
"status": "error",
"error": "Description of the error",
"message": "Description of the error",
"code": "ERROR_CODE",
"retryable": false,
"requestId": "req_abc123def456"
}
StatusMessageDescription
400Invalid request bodyRequest body failed validation
400Website missing organizationWebsite not properly configured
401API key or website_id requiredNo authentication provided
402Event quota exceededThe plan's event quota was denied by the billing check
403API key missing track:events scopeAPI key lacks required scope
403Origin not authorizedRequest origin is not allowed for this website
403IP address not authorizedRequest IP is not allowed for this website
404Website not foundInvalid website_id
413Payload too largeBody or properties exceed the payload limits
429Rate limit exceeded600 requests per 60 seconds per API key or website+IP
500Internal server errorServer error
503Billing check unavailableEvent quota could not be verified; retry later

Best Practices

  1. Use consistent event names — Use snake_case and be descriptive (button_click not click)
  2. Use namespaces — Group related events with the namespace field
  3. Include context — Add properties that help segment and analyze later
  4. Batch when possible — Send arrays of events to reduce HTTP overhead
  5. Do not track PII — Avoid personally identifiable information in properties
  6. Use server-side for sensitive events — Track purchases and signups server-side with API keys

Event properties are stored as JSON. Keep values simple (strings, numbers, booleans) for best query performance.

How is this guide?