Messaging and rooms
Sollar is a messenger first. A mini app can be launched from inside a room, can know which room, and can send a message on the user’s behalf. What it cannot do is post from a server into an encrypted room — and that constraint should shape your design from the first sketch.
Room context
Section titled “Room context”const room = await sollar.room.current() // requires room.context
if (room === null) { // Launched from the home grid, not from a room. This is the common case. renderStandalone()} else { renderForRoom(room)}interface Room { room_id: string name?: string is_encrypted: boolean member_count: number}null is normal, not an error. Most launches come from the home grid.
Check is_encrypted early — it decides what your backend can do, and the answer should shape the
UI, not surface as a failure later.
Sending as the user
Section titled “Sending as the user”await sollar.message.send({ room_id: room.room_id, body: 'Purchase order 4471 approved — €12,400 to Nordwerk GmbH.',}) // requires room.sendThe message leaves from the user’s own client, under the user’s identity, and the user confirms each send. A mini app cannot post silently under someone’s name, and there is no scope that enables it.
Rate limit: 10 per minute, each confirmed.
await sollar.message.send({ room_id: room.room_id, body: 'Purchase order 4471 approved', // plain-text fallback card: { title: 'Purchase order 4471 approved', body: '€12,400 · Vendor: Nordwerk GmbH', actions: [{ label: 'Open', deep_link: '/orders/4471' }], },})body is required even when you send a card. It is what appears in notifications, in search, in
accessibility tooling, and in any client that cannot render your card. A card with a body of
“Update” is a card nobody can find again.
deep_link resolves against the routes in your manifest’s pages. A link to an undeclared route
does not open.
The encryption constraint
Section titled “The encryption constraint”Two paths that work:
1. Send from the user’s client.
// Runs in the mini app, in the user's session, with the user's keys.await sollar.message.send({ room_id, body })Works in any room the user is in, encrypted or not. Requires the mini app to be open, and requires the user to confirm.
2. An agent that is a member of the room.
An AI agent admitted to a room as a verified, cross-signed device can post under its own identity.
It sees the room’s content exactly as an invited human member would — visible and auditable, not
confidential during processing. Your mini app’s actions[] are what the agent calls; the agent
posts the result.
Designing around it
Section titled “Designing around it”The pattern that does not work:
order approved on your server → your server posts to the room → ✗ encrypted roomThe patterns that do:
order approved → push notification to the user → user opens the mini app → mini app posts with sollar.message.send()order approved → your server tells the agent → the agent, a room member, postsorder approved → your server posts to a NON-encrypted room → worksThe third is real: not every room is encrypted, and a tenant may designate an unencrypted channel for system notifications precisely so that integrations can reach it. That is a tenant decision, not one your mini app can make.
Decide this before you build. Discovering during integration that the notification feature is impossible as designed is the expensive way to learn it.
Notifications instead
Section titled “Notifications instead”When you cannot post to the room, notify the user directly:
POST /v1/users/{app_user_id}/notificationsRequires the notifications scope from that user. It reaches the person rather than the channel —
which is often what was actually wanted, and is what makes the encrypted-room limit less painful
than it first sounds.
See Server API.
Deep links
Section titled “Deep links”Every route in pages is deep-linkable:
https://sollar.com/app/com.acme.erp/orders/4471Opens Sollar, launches the mini app, and routes to /orders/4471. Parameters arrive at
sollar.app.launchParams.
Public universal links for store-channel mini apps also satisfy Apple’s Guideline 4.7.4, which requires an index of the software available in the app, with universal links to all of it. That index is the public catalogue.
What a mini app cannot do
Section titled “What a mini app cannot do”| Why | |
|---|---|
| Read a room’s message history | No scope grants it. A mini app is not a client. |
| Post without the user confirming | Structural: sends are per-message confirmed. |
| Post as another user or as the system | The message carries the user’s identity. |
| Create, join or leave a room | Room membership is the messenger’s job. |
| Message a user who has not installed the app | No installation, no channel. |
| Navigate to another mini app | Cross-promotion, ranking and inter-app navigation are prohibited. |
The last row is a store policy borrowed verbatim from WeChat’s rejection criteria, and the reason is sound: a store where mini apps promote each other becomes an attention marketplace rather than a tool directory.