Documentation

Core concepts

How users, wallets, cards, organizations, and profiles fit together on Davi.

Davi cleanly separates what a thing is from who holds it right now. Once you have this mental model, the API surface makes sense.

The picture

The four nouns

  • A User owns one or more wallets — a personal primary wallet, plus a membership wallet for each organization they join.
  • A Wallet is a points/rewards ledger account. One or more cards can tap into it.
  • A Card is a tap-able credential (NFC, QR, or virtual). It points at exactly one wallet, and whoever owns that wallet owns the card. Issuing a card is separate from owning it.
  • An Organization issues cards (branding, membership tier, freeze) and can run its own treasury wallet.

A Profile is a public identity page. It is owned by the user (a sibling of their wallets), and a card routes to one when tapped — profiles are not attached to wallets.

Registry vs. assignment

The most important idea in Davi is that a card has two layers:

  • The registry — the stable set of valid, registered cards and their issuance configuration: identifier, card type, issuing organization, the membership tier granted on claim, and design. This never gets personalized and never moves.
  • The assignment layer — where a card is held right now: which wallet owns it, its custom name and image, its profile route, and holder-level freeze. Transferring a card only re-points this layer; the registry entry is untouched.

Because of this split, ownership is always derived through the wallet:

card → connection.wallet → wallet's owner (user)

There are deliberately no duplicated owner fields on the assignment layer, so nothing can drift out of sync.

Wallet kinds

A wallet's kind is determined by its owner, not a type field:

| Kind | Meaning | |---|---| | personal | the user's own wallet (one is primary) | | membership | the user's wallet inside a specific organization | | treasury | an organization's own funds (no user owner) | | bearer | a wallet with no owner yet — e.g. a card preloaded with rewards, waiting to be claimed |

How things resolve

  • Card ownercard → connection.wallet → wallet's user. Empty for unclaimed inventory or bearer wallets.
  • Effective frozen — a card is frozen if either the registry (org) freeze or the holder-level freeze is set. The registry freeze is dominant and can't be cleared by the holder.
  • Profile shown on tap — the card's profile-route override if set, otherwise the owner's primary profile.

Card lifecycle

Each step is a distinct operation:

  • Mint (fulfillment) — create the registry entry for a manufactured card. A physical card's identifier is burned into hardware before Davi hears about it, so only fulfillment can mint; nothing else in the system creates an identifier. That's what makes an unknown identifier refusable.
  • Assign (organization) — take an already-minted card into the org's inventory, setting its issuance config. Release is the reverse, and is refused once someone holds the card.
  • Provision (user/virtual) — create a virtual card plus its wallet binding. This happens automatically at signup.
  • Claim — bind the card to a wallet the user owns, keyed on the identifier (all a caller has after a tap). If the card carries a membership tier, claiming it also creates an organization membership; if its card model has a profile template, a profile is generated.
  • Unclaim — unbind the wallet. For a physical or org-issued card the registry entry is kept — the identifier belongs to the object, so the card becomes claimable again. A self-provisioned virtual card, which nobody else can hold, is destroyed.
  • Freeze — two independent flags: the issuer's and the holder's. The effective state is the OR of the two, so a holder cannot clear an issuer's freeze.

Transfer is not an operation. The model supports it — re-pointing the assignment layer moves a card without touching the registry — but no endpoint exposes it. Handing a card to someone else today is unclaim, then claim.

Organizations and the "org-scoped" model

Most resources belong to an organization: memberships, activities, rewards, reward triggers, and webhooks. An entity with no organization is platform-owned (for example, a freely-claimable platform card).

To act on an organization's resources, your app uses an org-scoped token — a token that carries the organization's context and the user's role within it (owner, manager, or member). This is how the reference's "Requires an org-scoped token" endpoints are gated. See Org-scoped tokens.

Keep going