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

# Identity

> The identity module is Voyant's shared contact-point, address, and named-contact primitive: low-level records that any entity can attach, reused across relationships, suppliers, facilities, and distribution.

The identity module is a low-level shared primitive, not a CRM. It owns three generic records, contact points, addresses, and named contacts, that any entity in the system can attach by reference. A Person, an organization, a supplier, or a facility does not store its own phone columns and address columns. It points at identity records instead, so contact data stays canonical and consistent across every consumer.

It ships as `@voyant-travel/identity` with Drizzle schema, Zod validation, a sync and hydration service, and Hono routes.

```bash theme={null}
pnpm add @voyant-travel/identity
```

## Key concepts

* **Generic attachment.** Every identity record carries an `entityType` and `entityId` pair, not a typed foreign key. A contact point belongs to whatever entity those two columns name, so identity never depends on its consumers and any module can attach to it.
* **Contact points.** A contact point is one reachable channel for an entity: an `email`, `phone`, `mobile`, `whatsapp`, `website`, `sms`, `fax`, `social`, or `other` value, with an optional label, a normalized value for matching, and an `isPrimary` flag.
* **Addresses.** A structured postal address with `line1`, `line2`, `city`, `region`, `postalCode`, and `country`, plus optional `latitude`, `longitude`, and `timezone`. Each address carries a label such as `primary`, `billing`, `shipping`, `mailing`, `meeting`, `service`, or `legal`.
* **Named contacts.** A person of contact attached to an entity, such as a reservations or accounting contact at a supplier, with a `name`, optional `title`, inline `email` and `phone`, and a role such as `reservations`, `operations`, `front_desk`, `sales`, `accounting`, or `emergency`.

<Note>
  Identity is contact data, not relationship history. It owns reachable channels, postal addresses, and named points of contact. Customer records, pipelines, and timelines belong to the relationships module, which is a consumer of identity, not the other way around.
</Note>

## What it owns

The module owns three Drizzle tables, each with a TypeID prefix:

| Table                     | TypeID prefix | Holds                                        |
| ------------------------- | ------------- | -------------------------------------------- |
| `identity_contact_points` | `idcp`        | Reachable channels (email, phone, and so on) |
| `identity_addresses`      | `idad`        | Structured postal addresses                  |
| `identity_named_contacts` | `idnc`        | Named points of contact on an entity         |

All three share the same shape: an `entityType` and `entityId` pair, an `isPrimary` flag, free-form `notes`, a `metadata` JSON column, and timestamps. The tables are indexed by `(entityType, entityId)` so listing an entity's contact data is a single fast lookup.

## Working with it

Standard modules are not registered by hand. `@voyant-travel/identity` is part of the standard product graph, so its routes, services, subscribers, and jobs are resolved into the application at build time. See [Configuration](/docs/platform/fundamentals/configuration).

Call the service directly to attach a contact point to any entity by its type and id:

```ts theme={null}
import { identityService } from "@voyant-travel/identity/service"

await identityService.createContactPoint(db, {
  entityType: "supplier",
  entityId: "sup_01h...",
  kind: "email",
  value: "reservations@hotel.example",
  isPrimary: true,
})
```

Read every contact point, address, or named contact for an entity in one call:

```ts theme={null}
const contactPoints = await identityService.listContactPointsForEntity(
  db,
  "supplier",
  "sup_01h...",
)
```

The schema and validation surfaces are available on their own subpaths for consumers that need the tables (`@voyant-travel/identity/schema`) or the Zod insert and update schemas (`@voyant-travel/identity/validation`).

## Links to other modules

* **Relationships.** A Person create or update syncs inline contact fields (email, phone, website, address, city, country) into identity records, keeping the relationships module's contact data canonical here rather than duplicated on its own tables.
* **Distribution.** Suppliers attach contact points, addresses, and named contacts (reservations, operations, accounting) by reference rather than carrying their own contact columns.
* **Operations.** Facilities and venues use identity addresses and named contacts for their physical location and on-site points of contact.

## Next steps

<CardGroup cols={2}>
  <Card title="Relationships" icon="users" href="/docs/platform/modules/relationships">
    The People and organizations that sync inline contact data into identity.
  </Card>

  <Card title="Distribution" icon="truck" href="/docs/platform/modules/distribution">
    Suppliers that attach contact points and named contacts by reference.
  </Card>

  <Card title="Links" icon="link" href="/docs/concepts/how-it-is-built">
    How modules associate records without hard foreign keys.
  </Card>

  <Card title="Glossary" icon="book-open" href="/docs/concepts/glossary">
    The canonical vocabulary for entities and contact data.
  </Card>
</CardGroup>
