Persisted model reference
Use this reference when designing request payloads, mapping Drift records into an application, or implementing a compatible storage adapter. It defines the API-facing model; the OpenAPI document remains canonical for HTTP validation, and src/interfaces/repository.ts is canonical for adapter method signatures.
Ownership and guarantees
Drift owns tenant IDs, record IDs, timestamps, versions, and deletion markers. Clients own domain fields and the meaning of flexible JSON. An adapter owns only the representation and persistence mechanics.
Guaranteed behavior across adapters includes tenant isolation, UUIDv7 record IDs, UTC date-time strings, optimistic versions, soft deletion, and lossless round trips for valid Drift JSON. SQLite's tables and validated JSON-text columns are adapter-specific and are not a client contract.
Common record fields
| Field | Input/default | Output and invariant |
|---|---|---|
id | Never accepted from graph clients. | UUIDv7 generated by Drift and stable for the record lifetime. |
tenantId | Never accepted from graph clients. | Derived from the authenticated key and immutable. |
version | Omitted on create; current value on mutation. | Starts at 1; each successful mutation increments it. |
createdAt | Never accepted. | UTC date-time set at creation and never changed. |
updatedAt | Never accepted. | UTC date-time refreshed by a successful mutation. |
deletedAt | Never accepted. | null while active; UTC soft-delete time while deleted. |
data | Optional; defaults to {}. | Any valid JSON value owned by the client application. |
metadata | Optional; defaults to {}. | Any valid JSON value for explicit source, sync, or control information. |
PATCH updates only supplied client-owned fields; it does not merge nested JSON objects. A caller that replaces data or metadata owns the complete replacement value. Invalid JSON or undeclared mutation fields fail request validation without a persisted change.
Vertex fields
| Field | Required on create | Default | Definition and ownership |
|---|---|---|---|
type | yes | none | Non-empty client-defined domain kind, such as device or service. |
slug | no | null | Client-defined human-readable identifier. |
externalId | no | null | Client-defined identifier from another system. |
title | no | null | Client-defined display label. |
status | no | active | Client-defined lifecycle state; Drift does not infer transitions. |
data | no | {} | Primary flexible payload. |
metadata | no | {} | Explicit system/control payload. |
Drift guarantees storage and exact-match filtering for top-level type and status; it does not assign business semantics to either value. Automation may copy or validate an explicitly supplied value but must not infer a status transition, record type, or identity match from content.
Edge fields
| Field | Required on create | Default | Definition and invariant |
|---|---|---|---|
fromVertexId | yes | none | Source vertex UUIDv7; must identify an active vertex in the tenant. |
toVertexId | yes | none | Destination vertex UUIDv7; must identify an active vertex in the tenant. |
type | yes | none | Non-empty client-defined relationship kind. |
status | no | active | Client-defined relationship lifecycle state. |
data | no | {} | Relationship-specific JSON, such as role, quantity, or order. |
metadata | no | {} | Explicit system/control JSON for the relationship. |
Both endpoints must be active and belong to the authenticated tenant when an edge is created or restored. A deleted vertex atomically soft-deletes its active incident edges. Restoring a vertex never restores edges automatically. A missing, inactive, or foreign endpoint fails without creating or restoring the edge.
Tenant fields
Operators create tenants through the bootstrap CLI, not through the v1 HTTP API.
| Field | Input/default | Output and invariant |
|---|---|---|
slug | Required and unique. | Stable operator-facing tenant identifier. |
name | Required. | Operator-defined display name. |
status | Defaults to active. | Tenant lifecycle value; no public v1 mutation route. |
id | Generated by Drift. | Internal tenant identifier bound to keys and graph data. |
createdAt, updatedAt | Generated by Drift. | UTC audit timestamps. |
Bootstrap with an existing slug fails and does not issue another key. Tenant deletion, rename, export, and cross-tenant reassignment are not public v1 capabilities.
API-key fields
| Field | Input/default | Output and invariant |
|---|---|---|
label | Required, non-empty. | Operator-owned purpose label. |
scopes | At least one explicit scope required. | Array containing read, write, and/or admin. |
id | Generated by Drift. | Stable key-record identifier used for rotation or revocation. |
tenantId | Derived from the admin key. | Immutable owning tenant. |
prefix | Generated by Drift. | Non-secret lookup component of the raw credential. |
createdAt | Generated by Drift. | UTC creation time. |
lastUsedAt | Defaults to null. | Most recently recorded successful credential verification. |
revokedAt | Defaults to null. | UTC revocation time; non-null keys cannot authenticate. |
The complete raw secret is returned only at creation or rotation. Drift persists a cryptographic hash and cannot recover the secret. A client or operator owns secure distribution and storage. See tenants, bootstrap, and API keys for the security model and Architecture for the complete persistence boundary.