> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datalyr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Properties and Metadata

> Add context and rich data to your events

Properties add context to events, turning simple actions into rich data points. Metadata captures technical details automatically. Together, they enable precise segmentation, attribution, and analysis.

## Event Properties

Properties are key-value pairs that describe what happened during an event.

**Basic Event:**

```javascript theme={null}
datalyr.track('button_clicked');
```

**Event with Properties:**

```javascript theme={null}
datalyr.track('button_clicked', {
  button_text: 'Sign Up Now',
  button_color: 'blue',
  location: 'hero_section',
  page_type: 'landing'
});
```

## Property Types

### Standard Properties

DATALYR recognizes common property names and handles them specially:

**Revenue Properties:**

* `revenue` or `amount`: Monetary value (number)
* `currency`: Three-letter currency code (USD, EUR, GBP)
* `order_id`: Unique order identifier (string)
* `transaction_id`: Transaction reference (string)

**Product Properties:**

* `product_id`: Product SKU or ID
* `product_name`: Product title
* `product_category`: Category or collection
* `product_price`: Unit price
* `quantity`: Number of items
* `variant_id`: Product variant identifier

**Page Properties:**

* `page_url`: Full page URL
* `page_path`: URL path only
* `page_title`: Document title
* `referrer`: Previous page URL

**User Properties:**

* `email`: User email address
* `name`: User full name
* `phone`: Phone number
* `user_id`: Internal user identifier

### Custom Properties

Add any properties relevant to your business:

**E-commerce:**

```javascript theme={null}
datalyr.track('product_viewed', {
  product_id: 'SKU-123',
  product_name: 'Wireless Headphones',
  product_category: 'Electronics',
  product_price: 99.99,
  product_vendor: 'TechBrand',
  in_stock: true,
  discount_applied: false,
  variant_options: ['Black', 'Medium']
});
```

**SaaS:**

```javascript theme={null}
datalyr.track('feature_used', {
  feature_name: 'Export to CSV',
  usage_count: 5,
  subscription_plan: 'pro',
  workspace_id: 'ws_123',
  team_size: 12,
  is_trial: false
});
```

**Media:**

```javascript theme={null}
datalyr.track('video_played', {
  video_id: 'vid_456',
  video_title: 'Product Demo',
  video_duration: 180,
  video_category: 'tutorials',
  playback_position: 0,
  quality: '1080p',
  autoplay: false
});
```

**Lead Generation:**

```javascript theme={null}
datalyr.track('form_submitted', {
  form_id: 'contact_form',
  form_intent: 'demo_request',
  fields_completed: 5,
  time_to_submit: 45,
  company_size: '50-100',
  industry: 'SaaS'
});
```

## Property Value Types

Properties support multiple value types:

**String:**

```javascript theme={null}
{
  product_name: 'Wireless Headphones',
  category: 'Electronics',
  status: 'active'
}
```

**Number:**

```javascript theme={null}
{
  price: 99.99,
  quantity: 2,
  discount_percent: 15
}
```

**Boolean:**

```javascript theme={null}
{
  in_stock: true,
  is_featured: false,
  autoplay: true
}
```

**Array:**

```javascript theme={null}
{
  colors: ['Black', 'White', 'Blue'],
  tags: ['electronics', 'wireless', 'audio'],
  variant_options: ['Medium', 'Black']
}
```

**Object (Nested):**

```javascript theme={null}
{
  product: {
    id: 'SKU-123',
    name: 'Wireless Headphones',
    price: 99.99
  },
  shipping: {
    method: 'express',
    cost: 9.99
  }
}
```

**Date/Timestamp:**

```javascript theme={null}
{
  signup_date: '2025-09-29T10:30:45.123Z',
  trial_end: '2025-10-29',
  last_login: new Date().toISOString()
}
```

## Automatic Metadata

DATALYR automatically captures metadata with every event:

### Page Context

**Automatically Captured:**

```json theme={null}
{
  "url": "https://example.com/products/headphones",
  "path": "/products/headphones",
  "search": "?utm_source=google",
  "title": "Wireless Headphones | Example Store",
  "referrer": "https://google.com/search?q=headphones"
}
```

**Referrer Enrichment:**

```json theme={null}
{
  "referrer": "https://google.com/search?q=headphones",
  "referrer_host": "google.com",
  "referrer_path": "/search",
  "referrer_search": "?q=headphones",
  "referrer_source": "google"
}
```

### Device Information

**Screen Dimensions:**

```json theme={null}
{
  "screen_width": 1920,
  "screen_height": 1080,
  "viewport_width": 1400,
  "viewport_height": 900
}
```

**Browser Capabilities:**

```json theme={null}
{
  "user_agent": "Mozilla/5.0...",
  "browser": "Chrome",
  "browser_version": "120.0",
  "os": "macOS",
  "os_version": "14.0",
  "device_type": "desktop"
}
```

### Session Context

**Session Data:**

```json theme={null}
{
  "session_id": "sess_1727634645123_a1b2c3d4",
  "session_duration": 45000,
  "session_page_views": 5,
  "session_events": 23,
  "session_start": 1727634645123,
  "time_since_session_start": 45000
}
```

### Attribution Data

**Marketing Attribution:**

```json theme={null}
{
  "utm_source": "facebook",
  "utm_medium": "cpc",
  "utm_campaign": "summer_sale",
  "utm_term": "wireless headphones",
  "utm_content": "carousel_ad",
  "fbclid": "IwAR...",
  "source": "facebook",
  "medium": "cpc"
}
```

**Landing Page:**

```json theme={null}
{
  "landing_page": "https://example.com/sale",
  "landing_path": "/sale"
}
```

### Performance Metrics

**Page Load Performance (pageview events):**

```json theme={null}
{
  "performance": {
    "dom_ready_time": 1200,
    "load_time": 2500,
    "first_contentful_paint": 800,
    "largest_contentful_paint": 1500
  }
}
```

**Scroll Depth (scroll events):**

```json theme={null}
{
  "scroll_depth": 75
}
```

### Fingerprinting Data

**Device Fingerprint:**

```json theme={null}
{
  "fingerprint": "a1b2c3d4e5f6",
  "device_fingerprint": "a1b2c3d4e5f6"
}
```

## Property Naming Conventions

Follow these conventions for consistent tracking:

### Use snake\_case

```javascript theme={null}
// Good
{
  product_name: 'Headphones',
  user_email: 'user@example.com',
  order_total: 99.99
}

// Bad
{
  productName: 'Headphones',      // camelCase
  'user-email': 'user@example.com', // kebab-case
  OrderTotal: 99.99                // PascalCase
}
```

### Be Descriptive

```javascript theme={null}
// Good
{
  button_text: 'Add to Cart',
  button_location: 'product_page',
  button_color: 'blue'
}

// Bad
{
  text: 'Add to Cart',  // Too vague
  loc: 'product_page',  // Abbreviated
  color: 'blue'         // Ambiguous context
}
```

### Use Consistent Names

```javascript theme={null}
// Good - Consistent across events
datalyr.track('product_viewed', {
  product_id: 'SKU-123',
  product_name: 'Headphones'
});

datalyr.track('product_added', {
  product_id: 'SKU-123',
  product_name: 'Headphones'
});

// Bad - Inconsistent naming
datalyr.track('product_viewed', {
  product_id: 'SKU-123',
  product_name: 'Headphones'
});

datalyr.track('product_added', {
  id: 'SKU-123',        // Different key name
  name: 'Headphones'    // Different key name
});
```

### Avoid Reserved Keys

Don't use these reserved property names:

* `user_id`
* `userId`
* `anonymous_id`
* `anonymousId`
* `visitor_id`
* `session_id`
* `event_id`
* `timestamp`
* `workspace_id`

## Property Limits

DATALYR enforces limits for performance and storage:

**Per Event:**

* Max 50 properties per event
* Property names: 255 characters max
* Property values: 10KB max
* Total event size: 50KB max

**Best Practices:**

* Keep property counts reasonable (10-20 is ideal)
* Avoid deeply nested objects (max 3 levels)
* Don't include large text blocks in properties
* Use arrays sparingly (max 100 items)

## Sensitive Data Handling

**Never send sensitive data:**

```javascript theme={null}
// BAD - Don't do this!
datalyr.track('checkout_completed', {
  credit_card_number: '1234-5678-9012-3456', // NO!
  cvv: '123',                                 // NO!
  ssn: '123-45-6789',                        // NO!
  password: 'user_password'                   // NO!
});
```

**Hash sensitive identifiers:**

```javascript theme={null}
// Good - Hash or tokenize sensitive data
import crypto from 'crypto';

const emailHash = crypto.createHash('sha256')
  .update('user@example.com')
  .digest('hex');

datalyr.track('user_registered', {
  email_hash: emailHash,  // Hashed
  phone_hash: phoneHash   // Hashed
});
```

**Safe user identification:**

```javascript theme={null}
// Good - Safe properties only
datalyr.identify('user_123', {
  email: 'user@example.com',  // Safe
  name: 'John Doe',           // Safe
  plan: 'pro',                // Safe
  company: 'Acme Inc'         // Safe
});
```

## Property Validation

DATALYR validates properties before sending:

**Valid Properties:**

```javascript theme={null}
// All valid
datalyr.track('button_clicked', {
  button_text: 'Sign Up',           // String
  clicks_count: 5,                   // Number
  is_primary: true,                  // Boolean
  tags: ['cta', 'hero'],            // Array
  metadata: { color: 'blue' },      // Object
  clicked_at: new Date().toISOString() // Date string
});
```

**Invalid Properties (Dropped):**

```javascript theme={null}
// These will be dropped
datalyr.track('test_event', {
  valid_property: 'hello',
  undefined_prop: undefined,        // Dropped
  null_prop: null,                  // Dropped
  function_prop: () => {},          // Dropped
  symbol_prop: Symbol('test')       // Dropped
});
```

## Enrichment Best Practices

**Add Context to Every Event:**

```javascript theme={null}
// Good - Rich context
datalyr.track('video_played', {
  video_id: 'vid_123',
  video_title: 'Product Demo',
  video_duration: 180,
  video_category: 'tutorials',
  playback_position: 0,
  player_version: '2.0',
  quality: '1080p',
  autoplay: false,
  from_playlist: true,
  playlist_name: 'Getting Started'
});

// Bad - Minimal context
datalyr.track('video_played', {
  video_id: 'vid_123'
});
```

**Use Properties for Segmentation:**

```javascript theme={null}
// Properties enable filtering/segmentation
datalyr.track('purchase_completed', {
  order_id: 'ORDER_123',
  revenue: 299.99,
  currency: 'USD',

  // Segmentation properties
  customer_type: 'returning',      // Segment by customer type
  acquisition_channel: 'facebook', // Segment by channel
  device_type: 'mobile',           // Segment by device
  country: 'US',                   // Segment by location
  product_category: 'electronics'  // Segment by category
});
```

**Track User Intent:**

```javascript theme={null}
// Add intent signals
datalyr.track('form_submitted', {
  form_id: 'contact_form',
  form_intent: 'demo_request',     // User intent
  urgency: 'high',                 // Purchase readiness
  company_size: '50-100',          // Qualification
  industry: 'SaaS',                // Targeting
  fields_interacted: 8,            // Engagement level
  time_to_submit: 45               // Commitment level
});
```

## Server-Side Properties

When tracking server-side, include additional context:

```javascript theme={null}
// Node.js server-side tracking
await fetch('https://ingest.datalyr.com/events', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    workspaceId: 'ws_123',
    events: [{
      event_name: 'subscription_created',
      anonymous_id: 'anon_abc123',
      user_id: 'user_456',
      properties: {
        // Subscription details
        plan: 'pro',
        amount: 99,
        currency: 'USD',
        billing_cycle: 'monthly',
        trial_days: 14,

        // Server context
        server_timestamp: new Date().toISOString(),
        stripe_customer_id: 'cus_abc123',
        invoice_id: 'inv_456',

        // Additional metadata
        payment_method: 'card',
        referral_code: 'SUMMER2025',
        ip_address: req.ip // Optional for geo
      },
      timestamp: new Date().toISOString()
    }]
  })
});
```

## Automatic Property Enrichment

DATALYR automatically enriches certain events:

**Pageview Events:**

* Performance metrics (load time, FCP, LCP)
* Referrer data (domain, path, source)
* Browser capabilities (user agent parsing)

**Form Events:**

* Field interaction count
* Time to submit
* Form intent detection

**E-commerce Events:**

* Product data (from page context)
* Cart state (from DOM)
* Platform detection (Shopify, WooCommerce, etc.)

**Engagement Events:**

* Scroll depth (for scroll events)
* Time on page
* Click position

## Property Schema Evolution

Properties can evolve over time as your tracking needs change:

**Initial Implementation:**

```javascript theme={null}
datalyr.track('button_clicked', {
  button_text: 'Sign Up'
});
```

**Enhanced Version:**

```javascript theme={null}
datalyr.track('button_clicked', {
  button_text: 'Sign Up',
  button_id: 'cta-hero',       // New property
  button_location: 'hero',      // New property
  button_color: 'blue',         // New property
  variant: 'test_b'             // New property for A/B testing
});
```

DATALYR handles missing properties gracefully - old events remain queryable.

## Next Steps

<CardGroup cols={2}>
  <Card title="Events Overview" icon="bolt" href="/understanding-data/events-overview">
    Learn about event tracking
  </Card>

  <Card title="Identity Calls" icon="user" href="/understanding-data/identity-calls">
    Link users across devices
  </Card>

  <Card title="Attribution Models" icon="chart-network" href="/understanding-data/attribution-models">
    How conversions are attributed
  </Card>

  <Card title="Custom Events" icon="code" href="/sdks/web/custom-events">
    Track custom events with SDK
  </Card>
</CardGroup>

## Need Help?

Questions about properties? Check our [troubleshooting guide](/troubleshooting/tracking-not-working) or contact support.
