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

# Event Properties

> Structure and validate event data in the Permutive JavaScript SDK

Events in Permutive consist of a name and properties object. Properties provide the context and data that powers cohort building and insights.

<CardGroup cols={3}>
  <Card title="Property Types" href="#property-types" icon="shapes" />

  <Card title="Event Structure" href="#event-structure" icon="code" />

  <Card title="Best Practices" href="#best-practices" icon="check" />
</CardGroup>

## Event Structure

Every event has a name and properties:

```javascript theme={"dark"}
permutive.track('EventName', {
  property1: 'value',
  property2: 123,
  nested: {
    property3: true
  }
});
```

### Automatic Properties

The SDK automatically adds these properties to every event:

| Property            | Type      | Description                          |
| ------------------- | --------- | ------------------------------------ |
| `time`              | timestamp | When the event occurred              |
| `session_id`        | string    | Current session identifier           |
| `view_id`           | string    | Current pageview identifier          |
| `client.url`        | string    | Current page URL                     |
| `client.referrer`   | string    | Referring URL                        |
| `client.user_agent` | string    | Browser user agent                   |
| `client.viewport`   | object    | Browser viewport dimensions          |
| `geo_info`          | object    | Geographic information (server-side) |

## Property Types

Permutive supports several property types:

<Tabs>
  <Tab title="String">
    ```javascript theme={"dark"}
    permutive.track('Article', {
      title: 'Breaking News',
      category: 'technology',
      author: 'Jane Smith'
    });
    ```
  </Tab>

  <Tab title="Number">
    ```javascript theme={"dark"}
    permutive.track('Purchase', {
      price: 29.99,
      quantity: 2,
      discount_percentage: 10
    });
    ```
  </Tab>

  <Tab title="Boolean">
    ```javascript theme={"dark"}
    permutive.track('UserAction', {
      is_subscriber: true,
      has_ad_blocker: false,
      accepted_cookies: true
    });
    ```
  </Tab>

  <Tab title="Array">
    ```javascript theme={"dark"}
    permutive.track('Article', {
      categories: ['technology', 'business', 'startups'],
      tags: ['AI', 'funding', 'silicon-valley'],
      authors: ['Jane Smith', 'John Doe']
    });
    ```
  </Tab>

  <Tab title="Object">
    ```javascript theme={"dark"}
    permutive.track('Article', {
      article: {
        title: 'Breaking News',
        id: 'article-123',
        publishedAt: '2024-01-15T10:00:00Z'
      },
      author: {
        name: 'Jane Smith',
        id: 'author-456'
      }
    });
    ```
  </Tab>

  <Tab title="Date">
    ```javascript theme={"dark"}
    permutive.track('Subscription', {
      start_date: '2024-01-15',
      expiry_date: '2025-01-15',
      created_at: new Date().toISOString()
    });
    ```

    <Info>
      Dates should be passed as ISO 8601 strings for consistent parsing.
    </Info>
  </Tab>
</Tabs>

## Standard Events

The SDK defines standard event types with expected properties:

### Pageview

Tracked automatically by the web addon:

```javascript theme={"dark"}
// Automatic via web addon
permutive.addon('web', {
  page: {
    type: 'article',
    article: {
      title: 'Article Title',
      categories: ['news'],
      authors: ['Author Name'],
      publishedAt: '2024-01-15'
    }
  }
});
```

### Custom Event

For non-standard tracking:

```javascript theme={"dark"}
permutive.track('CustomEvent', {
  action: 'button_click',
  element_id: 'signup-button',
  page_section: 'header'
});
```

## Property Naming Conventions

Follow these conventions for consistent data:

| Convention  | Example         | Notes                           |
| ----------- | --------------- | ------------------------------- |
| snake\_case | `article_title` | Preferred for custom properties |
| camelCase   | `articleTitle`  | Also supported                  |
| Lowercase   | `category`      | Use for simple properties       |

<Warning>
  Property names are case-sensitive. `category` and `Category` are different properties. Be consistent across your implementation.
</Warning>

### Reserved Property Names

Avoid these reserved property names:

* `time` - Automatically set by SDK
* `session_id` - Automatically set
* `view_id` - Automatically set
* `client` - Reserved for client context
* `geo_info` - Reserved for geographic data

## Nested Properties

You can nest properties up to 3 levels deep:

```javascript theme={"dark"}
permutive.track('Article', {
  content: {
    article: {
      metadata: {
        word_count: 1500,
        read_time: 7
      }
    }
  }
});
```

<Info>
  Deeply nested properties work in cohort building, but keep structures simple when possible for easier querying.
</Info>

## Arrays

Arrays are useful for multi-value properties:

```javascript theme={"dark"}
permutive.track('Article', {
  // Array of strings
  categories: ['technology', 'business'],

  // Array of numbers
  related_article_ids: [123, 456, 789],

  // Array of objects
  authors: [
    { name: 'Jane Smith', id: 'author-1' },
    { name: 'John Doe', id: 'author-2' }
  ]
});
```

### Array Limitations

* Maximum 100 items per array
* Array items should be of consistent type
* Nested arrays are not recommended

## Page Properties vs Event Properties

<Tabs>
  <Tab title="Page Properties">
    Set via the web addon, applied to all events on the page:

    ```javascript theme={"dark"}
    permutive.addon('web', {
      page: {
        type: 'article',
        article: {
          title: 'Article Title',
          categories: ['news']
        }
      }
    });

    // These page properties are included in:
    // - Pageview event
    // - PageviewEngagement events
    // - PageviewComplete event
    ```
  </Tab>

  <Tab title="Event Properties">
    Set per-event, specific to that event:

    ```javascript theme={"dark"}
    permutive.track('VideoPlay', {
      video_id: 'video-123',
      video_title: 'Demo Video',
      autoplay: false
    });

    // These properties only apply to this event
    ```
  </Tab>
</Tabs>

## Best Practices

<AccordionGroup>
  <Accordion title="Use Descriptive Names">
    ```javascript theme={"dark"}
    // Good
    permutive.track('Article', {
      article_category: 'technology',
      article_author: 'Jane Smith',
      is_premium_content: true
    });

    // Avoid
    permutive.track('Article', {
      cat: 'tech',
      auth: 'JS',
      prem: 1
    });
    ```
  </Accordion>

  <Accordion title="Be Consistent">
    Use the same property names and types across all events:

    ```javascript theme={"dark"}
    // Consistent naming
    permutive.track('Article', { article_id: '123' });
    permutive.track('VideoPlay', { video_id: '456' });

    // Avoid mixing
    permutive.track('Article', { article_id: '123' });
    permutive.track('Article', { articleId: '456' }); // Different convention!
    ```
  </Accordion>

  <Accordion title="Avoid PII">
    Never include personally identifiable information:

    ```javascript theme={"dark"}
    // Good - use hashed or anonymized values
    permutive.track('Login', {
      user_type: 'subscriber',
      account_age_days: 365
    });

    // Never do this
    permutive.track('Login', {
      email: 'user@example.com',  // PII!
      name: 'John Smith'          // PII!
    });
    ```
  </Accordion>

  <Accordion title="Use Appropriate Types">
    ```javascript theme={"dark"}
    // Good - correct types
    permutive.track('Purchase', {
      price: 29.99,              // Number
      quantity: 2,               // Number
      product_name: 'Widget',    // String
      in_stock: true             // Boolean
    });

    // Avoid - incorrect types
    permutive.track('Purchase', {
      price: '29.99',            // Should be number
      quantity: '2',             // Should be number
      in_stock: 'true'           // Should be boolean
    });
    ```
  </Accordion>

  <Accordion title="Limit Property Count">
    Keep events focused with relevant properties only:

    ```javascript theme={"dark"}
    // Good - focused properties
    permutive.track('ArticleRead', {
      article_id: '123',
      category: 'technology',
      read_percentage: 75
    });

    // Avoid - too many properties
    permutive.track('ArticleRead', {
      article_id: '123',
      category: 'technology',
      // ... 50 more properties
    });
    ```
  </Accordion>
</AccordionGroup>

## Property Validation

The SDK validates properties before sending:

* Invalid property types are converted or dropped
* Very long strings may be truncated
* Invalid JSON structures are rejected

Enable debug mode to see validation messages:

```
?__permutive.loggingEnabled=true
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Properties not appearing in dashboard">
    **Problem:** Event tracked but properties missing in dashboard.

    **Solutions:**

    * Check property names match dashboard schema
    * Verify property types are correct
    * Enable debug mode to see what's sent
    * Allow time for data processing
  </Accordion>

  <Accordion title="Type conversion issues">
    **Problem:** Numbers stored as strings or vice versa.

    **Solutions:**

    * Explicitly cast types before tracking
    * Use `parseInt()` or `parseFloat()` for numbers
    * Avoid string representations of numbers
  </Accordion>

  <Accordion title="Nested properties not queryable">
    **Problem:** Can't build cohorts on deeply nested properties.

    **Solution:** Flatten structure or limit nesting to 2 levels:

    ```javascript theme={"dark"}
    // Instead of deep nesting
    { a: { b: { c: { d: 'value' } } } }

    // Use flatter structure
    { a_b_c_d: 'value' }
    ```
  </Accordion>
</AccordionGroup>

## Related Documentation

<CardGroup cols={2}>
  <Card title="Event Tracking" icon="bolt" href="/sdks/web/javascript-sdk/features/event-tracking">
    Track custom events
  </Card>

  <Card title="Pageview Tracking" icon="file" href="/sdks/web/javascript-sdk/features/pageview-tracking">
    Configure page properties
  </Card>

  <Card title="Cohorts" icon="users" href="/sdks/web/javascript-sdk/core-concepts/cohorts-and-activations">
    Build cohorts from properties
  </Card>

  <Card title="Connectivity Events" icon="plug" href="/products/connectivity/events">
    Event schema documentation
  </Card>
</CardGroup>
