Skip to main content

Overview

Consistent naming makes your data easier to understand, query, and maintain. This guide covers recommended conventions for events, properties, and user attributes in AI, agentic, and SaaS products.

Event naming

Use snake_case

// ✅ Correct
Trodo.track('agent_run_completed');
Trodo.track('integration_connected');
Trodo.track('workflow_published');

// ❌ Avoid
Trodo.track('AgentRunCompleted');
Trodo.track('agent-run-completed');
Trodo.track('Agent Run Completed');

Use action verbs

Events should describe what happened:
// ✅ Clear actions
'button_clicked'
'form_submitted'
'prompt_submitted'
'agent_run_started'
'export_generated'

// ❌ Unclear
'button'
'agent'
'user_data'
'page'

Object and action

Pattern: {object}_{action} or {action}_{object}
'workflow_published'
'template_selected'
'integration_connected'
'notification_dismissed'

Tense

// ✅ Past tense — completed
'agent_run_completed'
'onboarding_finished'

// ✅ Present flow — initiated
'agent_run_started'
'checkout_started'
// Onboarding
'onboarding_started'
'onboarding_step_completed'
'onboarding_finished'

// Agent run
'agent_run_started'
'tool_call_completed'
'agent_run_completed'
'agent_run_failed'

Property naming

Use snake_case

// ✅ Correct
{
  workflow_id: 'weekly_report',
  duration_seconds: 36,
  outcome: 'success'
}

// ❌ Avoid
{
  workflowId: 'x',
  'workflow-id': 'x',
  WorkflowId: 'x'
}

Be specific

// ✅ Specific
{
  workflow_id: 'weekly_report',
  surface: 'in_app',
  model: 'gpt-4o'
}

// ❌ Vague
{
  id: 'weekly_report',
  type: 'in_app'
}

Include units

// ✅ Clear units
{
  amount_usd: 49.99,
  duration_seconds: 180,
  seat_count: 12
}

// ❌ Ambiguous
{
  amount: 49.99,
  duration: 180
}

Boolean prefixes

// ✅ Clear booleans
{
  is_paid: true,
  has_workspace: false,
  was_referred: true
}

// ❌ Unclear
{
  paid: true,
  workspace: false
}

Consistent prefixes

user_count: 150
active_user_count: 75
total_runs: 500
created_at: '2024-01-15T10:30:00Z'
updated_at: '2024-01-16T14:20:00Z'

User profile properties

Identity

Trodo.identify('user_12345');

Trodo.people.set({
  email: '[email protected]',
  name: 'Alex Builder'
});

Lifecycle

Trodo.people.set({
  signup_date: '2024-01-01',
  account_status: 'active',
  subscription_tier: 'pro'
});

Product context

Trodo.people.set({
  primary_workspace_id: 'ws_abc',
  agent_beta_opt_in: true,
  integrations_connected_count: 4,
  favorite_template_id: 'weekly_digest'
});

Anti-patterns

High-cardinality event names

// ❌ Don't embed raw IDs in event names
'viewed_workflow_wf_123'

// ✅ Use properties
Trodo.track('workflow_viewed', { workflow_id: 'wf_123' });

Dynamic event names

// ❌ Unbounded event names
Trodo.track(`${action}_${object}`);

// ✅ Stable name + properties
Trodo.track('user_action', {
  action_type: action,
  target: object
});

PII in event names

// ❌ Never put PII in the event key
'[email protected]_logged_in'

// ✅ Use opaque IDs in properties
Trodo.track('user_logged_in', { user_id: '12345' });

Naming checklist

1

snake_case

Event and property keys use snake_case
2

Clear action

Event names describe a specific action
3

Specific properties

Properties are specific (not just value or data)
4

Units included

Numeric properties include units where helpful (_usd, _seconds)
5

Boolean prefixes

Booleans use is_, has_, was_, can_ where appropriate
6

No PII in names

Sensitive values live in controlled properties, not event keys

Examples by category

Agent / automation

'prompt_submitted'
'agent_run_started'
'tool_call_completed'
'agent_run_completed'
'workflow_published'
'schedule_created'

User lifecycle

'signup_started'
'signup_completed'
'email_verified'
'activation_milestone_hit'
'subscription_upgraded'

Engagement

'feature_discovered'
'tutorial_completed'
'integration_connected'
'export_generated'

Next steps

Implementation guide

Patterns and examples

Track events

track() reference