The pieces
Zend identity. One account per person across Zend and every ZApp. Every app gets the user’sappUserId, username, name and avatar. Email, wallet address and contacts need the user’s consent.
ZApp. Your web app, hosted on your own HTTPS origins and registered with a manifest.
Bridge. @zendfi/appkit talks to Zend with JSON messages. In the mobile app it uses a WebView bridge; on the web it uses postMessage to the app.usezend.app frame. Zend checks that every message comes from one of your registered origins.
Interaction. A stateful object with an ID: a challenge, a round, a booking. Your manifest defines its states and allowed moves; Zend stores it and enforces them. See Interactions.
Card. A chat or feed item that Zend draws from a template you fill in. Cards show the live state of their interaction. See Cards.
Who owns what
Rule of thumb: Zend enforces anything that involves money, identity, or what other people see.
Lifecycle of a chat ZApp
1
The user starts it
Tunde taps + → Apps → Challenge in a chat with Danny.
2
Zend creates the interaction
Zend creates a
challenge interaction with both people and opens your sheet path with ?interaction=int_....3
Consent, once
The first time, Zend shows “Continue to Accident as Tunde?”.
4
Your page runs
Your page reads
zend.launch.interaction, runs the game, and calls zend.interaction.update(...) and zend.postCard(...).5
The other person joins
Danny sees a card in the chat. Its button opens your app on the same interaction.
6
Your server follows along
Your server receives
interaction.updated webhooks and can make moves only it is allowed to make.Private and public apps
Anyone with the link
app.usezend.app/apps/<slug> can open a private app. See Public apps.
Custody
Custody decides where money from groups, events and prizes sits before it’s paid out. Set it withcustody in the manifest.
Trust boundaries
- Your page can propose money actions. Only the user can approve them, in Zend’s sheet.
- A resolved promise in the browser is not proof of payment. Confirm with the
payment.completedwebhook or the server API. See Verifying payments. appSessiontokens last 10 minutes. Exchange them on your server and start your own session; don’t use them as your session.- Moves that decide outcomes, such as declaring a winner, belong on your server. Mark them
serverOnlyin the manifest so a page can’t make them.