# Event Types

This guide explains how **event types** work in EventSourcingDB, how they should be structured, and what naming conventions to follow. Event types are a required part of every event and play a central role in **filtering**, **processing**, and **understanding domain behavior** over time.

You'll learn how to name event types in a way that is clear, meaningful, and consistent – and how to avoid common mistakes.

## Required Field

Event types are **mandatory** in EventSourcingDB. Since the system is based on the CloudEvents specification, each event must include a **`type` field**. This field is used to describe what happened in the domain, and it forms the basis for **filtering**, **versioning**, **routing**, and **other processing tasks**.

## Format and Structure

Event types must follow the **CloudEvents naming convention**, which uses a **reversed domain name as a namespace**, followed by a domain-specific event name. For example:

```
io.eventsourcingdb.library.book-acquired
```

EventSourcingDB **enforces this format when writing events**: an event type must consist of **at least three dot-separated segments**, each containing only **letters, digits, underscores, and hyphens** (`0-9`, `A-Za-z`, `_`, `-`), and the first segment must be **at least two characters long**. A two-segment type such as `io.book-acquired` is rejected, as are types that contain spaces or other special characters.

This structure ensures that types are **globally unique and consistently scoped**. The namespace (`io.eventsourcingdb.library`) should reflect a domain or organization under your control – even if the domain is not resolvable. The event name itself (`book-acquired`) should be **lowercase and use hyphens for clarity**.

**Avoid camel case, underscores, or ambiguous separators** such as slashes or dots within the event name. Stick to lowercase letters and hyphens to maximize readability and consistency across tooling.

## Verbs and Domain Semantics

Each event type should include a **verb in past tense**, because **events represent something that has already happened**. Examples include `book-acquired`, `user-added-to-group`, or `order-cancelled`. This **clearly distinguishes events from commands**, which typically use imperative forms such as `add-user` or `cancel-order`.

It is important that the verb **does not appear at the beginning of the name**. Starting with a verb is common in command naming, and doing the same for events can lead to confusion. Instead, **structure your event names so that the action is embedded naturally** within the domain concept. For example:

- `user-added-to-group` instead of `add-user-to-group`
- `order-payment-declined` instead of `cancel-order`

Also, **avoid overly generic or technical verbs** like `created` or `changed`, unless those terms are meaningful in the domain language. An event should communicate not just what changed, but why the change happened – what business decision or external condition led to the event.

## Versioning

Because **events are immutable** and designed to live indefinitely, it's often necessary to evolve their structure over time. EventSourcingDB does not provide a dedicated field for versioning, but you can **encode the version directly in the event type**. For example:

```
io.eventsourcingdb.library.book-acquired.v1
```

This allows **multiple versions of the same conceptual event to coexist**, and gives consumers a clear way to distinguish between them. You can increment the version as needed (`v2`, `v3`, etc.), keeping your system **adaptable without breaking compatibility**.

## Filtering by Event Type

Event types can be used for **filtering in EventQL queries**. For example, you can select only certain kinds of events when building projections or exporting data.

When **[reading events](/learn/tutorials/first-steps-with-eventsourcingdb/reading-events)** or **[observing events](/learn/tutorials/first-steps-with-eventsourcingdb/observing-events)**, filtering by event type is not directly supported – except in the special case of using `fromLatestEvent`, which supports type-based constraints. For full filtering support, **use EventQL instead**.

## Common Pitfalls

- **Missing verb**: An event must describe something that happened – always include a verb.
- **Verb in the wrong form**: Use past tense (e.g. `completed`, not `complete` or `completing`).
- **Command-style naming**: Avoid imperative forms like `create`, `add`, or `change`.
- **Generic terms**: Prefer expressive domain language over vague labels like `updated`.
- **Verb-first naming**: Avoid starting with the verb; it blurs the line between events and commands.

## Defining Good Event Types

The **`type` field** is more than just a label – it's a **central part of how your system communicates meaning**. A **well-designed event type** tells the story of what happened, what caused it, and what it means in the domain.

Following **consistent naming conventions** will help you build more readable, reliable, and maintainable event-sourced systems – and make your event logs truly expressive.
