AccoilAccoil Developer Docs
Best Practices

Naming Conventions

Standards for naming events, properties, and identifiers.

Consistent naming is the foundation of queryable, readable, and maintainable analytics. Without a naming strategy, the same action ends up tracked under multiple names, data fragments across dashboards, and nobody trusts the numbers.

The cost of fixing naming after the fact is enormous. You either migrate historical data (expensive, error-prone) or live with a permanent seam in your analytics. Get this right from the start.

Event names

The Accoil format: Object_Action

Accoil uses Title_Case with underscores for event names. The object comes first, followed by a past-tense verb, separated by underscores.

Report_Created
User_Invited
Search_Performed
Integration_Connected

This format:

  • Groups related events when sorted alphabetically (all Report_* events cluster together)
  • Reads naturally and is immediately understandable
  • Works cleanly in all databases and APIs without quoting issues

Core naming rules

Every event name must follow these rules:

RuleExplanation
Object firstName the thing that was acted upon. This groups related events in sorted lists.
Past-tense verbThe event describes something that already happened. Events are facts, not intentions.
Outcomes, not mechanismsTrack what the user accomplished, not how they accomplished it.
Title_Case with underscoresCapitalize each word, separate with underscores.

Multi-word objects

When the object or action is more than one word, keep the same pattern:

Advanced_Search_Performed
Bulk_Export_Generated
Setup_Wizard_Completed
User_Role_Changed

Multi-word objects are fine and often necessary. Clarity beats brevity. Do not abbreviate objects to avoid multi-word names.

Singular vs plural

Use singular for individual actions. Use plural only for genuine bulk operations:

Report_Exported        -- one report was exported
Reports_Bulk_Deleted   -- batch operation on many reports
Todo_Created           -- one todo was created
Todos_Cleared          -- all todos were removed at once

Do / Don't examples

DoDon'tWhy
Report_CreatedCreate_Report_Button_ClickedTrack the outcome, not the mechanism
Search_Performeduser_searched_somethingUse the standard format, not ad-hoc naming
Plan_UpgradedPerforming_UpgradePast tense, not present or future
Integration_Connectedapp.integration.connectedUse Accoil's Title_Case format
Report_CreatedCreated_ReportObject first, verb second
Export_GeneratedEXPORT_GENERATEDTitle_Case, not ALL_CAPS

Action vocabulary

Use past tense. The event already happened.

ActionMeaningNotes
CreatedNew thing made
UpdatedExisting thing modified
DeletedThing removed
ViewedThing displayed to userUse sparingly -- see below
StartedProcess began
CompletedProcess finished
FailedProcess errored
AbandonedProcess left incompleteUseful for workflows and wizards
SentMessage or notification dispatched
ConnectedIntegration or service linked
DisconnectedIntegration or service unlinked
ConfiguredSettings or setup established
InvitedUser invited someone
JoinedUser accepted invite
UpgradedPlan or tier increased
DowngradedPlan or tier decreased
GeneratedOutput produced (reports, exports)
AppliedFilter, template, or rule put into effect
PerformedAction executed (search, sync)

A note on Viewed and Clicked: These describe UI mechanics, not user intent. Prefer tracking the meaningful outcome. If you must track navigation, keep it sparse -- key pages only, not every screen. See Cost Optimization for why page views are almost never worth tracking.

Accoil track calls: event name only

No properties on track

Accoil's track call accepts only the event name. There are no event properties. This is by design -- it forces cleaner event taxonomy and pushes contextual data to user and account traits where it belongs.

Because track calls carry no properties, event naming carries more weight in Accoil than in other platforms. The event name alone must communicate what happened. Use identify and group traits to provide the context that other platforms carry as event properties.

When to create a new event vs use traits

Since Accoil events have no properties, the question of "new event vs property" becomes "new event vs trait":

Use separate events for fundamentally different actions:

Report_Created
Report_Shared
Report_Exported
Report_Archived

Use traits (via identify or group) for contextual metadata:

// Set via group() call -- not on the event
group("acc_456", { primary_report_type: "standard" })

// Then track the action
track("Report_Created")

The test: Can you write a single sentence that describes all variants? "A report was created" covers standard, custom, and template reports -- so use one event and let traits provide context. But "a report was created" and "a report was shared" are fundamentally different actions -- so use separate events.

Property and trait naming

Format: snake_case

Always use snake_case for property and trait names, regardless of event naming convention. This applies to all traits sent via identify and group calls.

{
  report_type: "standard",
  created_by: "usr_456",
  is_template: false,
  employee_count: 150
}

Consistent suffixes

Use consistent suffixes so properties are self-describing:

PatternTypeExamplesPurpose
*_idString (prefixed)report_id, task_idEntity references
*_typeEnum stringreport_type: "standard"Categorization
*_countIntegerrecipient_count: 3Quantities
is_*Booleanis_template: trueState flags
has_*Booleanhas_description: truePresence flags
*_atISO 8601 timestampcreated_at, expires_atPoints in time
*_sourceEnum stringsignup_source: "google_oauth"Origin and attribution
*_formatEnum stringexport_format: "pdf"Output format

When someone sees recipient_count they immediately know it is an integer. When they see is_template they know it is a boolean. Consistent suffixes eliminate guesswork in every query.

The same trait must always mean the same thing

If report_id appears on user traits and account traits, it must reference the same entity in the same format. Never reuse a trait name with a different meaning. This sounds obvious, but it drifts over time as different developers add traits independently.

ID format conventions

Use prefixed IDs so they are self-documenting in logs and queries:

EntityPrefixExample
Userusr_usr_abc123
Accountacc_acc_def456
Reportrpt_rpt_ghi789
Tasktsk_tsk_jkl012
Teamtem_tem_mno345
Sessionses_ses_pqr678
Workspacews_ws_abc123
Projectproj_proj_def456

When you see usr_abc123 in a raw event, you know instantly it is a user ID without checking the property name. This matters when debugging, reviewing logs, and joining data across systems.

Event naming checklist

Before adding a new event, verify:

  • Follows the Object_Action format with Title_Case underscores
  • Uses past tense verb (describes what happened, not what will happen)
  • Object comes first, verb comes last
  • Describes the outcome, not the UI mechanism
  • No redundant prefixes (e.g., "Event_", "Track_", "App_")
  • No implementation details (e.g., "Button1", "Div_Search")
  • No PII in the event name
  • Consistent with existing events for the same object
  • Added to the centralized event definition file
  • Would not be better served by an existing event

On this page