Limits
TL;DR
- Files are served only to authenticated members of the chat space. A forwarded URL does not open for someone who is not in the space.
- Files cannot be deleted from storage. Deleting the message hides them in the chat.
- Actor answers arrive complete, not token by token.
- Actors have no per-person memory in chat.
- Signing out does not cut a key off the relay. Remove, suspend or rotate the key.
- Messages are readable by Orkestia as the operator of the relay.
Files
Chat files require a chat-member credential. GET /media/{sha256} on the space relay checks a Blossom t=get token signed by a current member of that chat space (NIP-43). An unauthenticated request is refused. A URL sent outside the space does not work.
Reads are not additionally gated to the private-channel or DM roster. Any member of the same chat space who obtains the URL can open the file. If that is too wide for a given room, set media.allow_in_private_channels to false in the theme so the chat page does not offer attachments in private channels and DMs. That flag is enforced by the chat page, not by the relay: a member using a separate relay client could still upload.
Files cannot be deleted from storage. Deleting the message (the author's delete, or buzz.message.moderate-delete) hides the file in every chat client, but the bytes stay in the space's MinIO until you delete the whole chat space with buzz.space.delete. Unauthenticated GETs still fail. buzz.media.list reports deletion_supported: false.
That is not the Identity app Files tab. Org-member app files (apphost.file.*) can be deleted by an organization admin — see Files.
Allowed file types are a short list of images, PDF, CSV and plain text. SVG, archives and executables are not allowed: blobs are never scanned, and there is no per-file delete.
Actors
- Answers arrive complete. The actor's answer is posted once it is finished. Progress lines show what it is doing in the meantime, but there is no token-by-token streaming.
- No per-person memory. An actor in the chat does not remember earlier conversations with a person. Within one conversation it sees the recent messages of the thread or DM (up to 20).
- Answers usually take fifteen to thirty seconds. A run that has not answered after ten minutes gives up and posts a short failure line with the option to reach a person.
- Seat mode tools are your app's end-user workflows only. For organization tools, use internal mode, which is enabled per organization.
- Every reply spends your organization's model budget. Bound it with
max_replies_per_hourand the actor's own budget. - Structured chat is Alpha. DGI responders, cards and the wire contract are part of DGI. New card keys are added over time; clients must ignore keys they do not know. Calling DGI directly over an API, outside the chat, is not available yet.
- Files reach actors as URLs plus a short-lived Blossom GET header. An actor gets the attachment URLs of the message it answers, with
authorizationminted from its own chat key. It does not receive a copy in Orkestia storage.
Members and access
- Sign-out is record-level. A key already in a browser keeps working until you run
buzz.member.remove,buzz.member.set-status(suspended),buzz.member.banorbuzz.member.rotate-key. - Lapsed seats leave at reconcile. Disabling an end user or removing their seat takes effect on the relay when
buzz.member.reconcileruns, not instantly. After that, their media GET tokens stop working too. - Policy flags stop the platform path, not the relay.
member_channel_createandmember_channel_joinoff means the chat page and entry points refuse. Members hold their own chat key and a separate relay client could still send channel commands. - Theme limits are client-side.
max_bytes,max_per_messageandallowed_typesare enforced by the chat page before upload. The relay also enforces its own global size and type ceilings. - Private channels a member created are not visible to admin reads such as
data.buzz.member.channelsunless the space owner key is in them.
Notifications
- Missed-message email is available per space, and the scheduled scan that sends it is being enabled. Until it runs for your space, no email goes out.
- The email has counts and places only. It never contains message text.
Privacy
Messages are stored by the relay in your app's own App Data Postgres, and they are not end-to-end encrypted. Orkestia runs the relay, so messages are readable by Orkestia as the operator. Retention settings per space and deleting one person's messages on request are not available yet. Moderator delete and author delete hide messages in chat clients.
Ask your AI assistant
Is it safe to share contracts as files in a private channel of my Orkestia chat? Read https://docs.orkestia.dev/raw/chat/limits.md and answer plainly.
Turn off attachments in private channels and DMs for my chat space. Update media.allow_in_private_channels in a draft theme and publish after I confirm.
Someone's chat access was compromised. Walk me through removing them and rotating their key with the right workflows.
For AI agents
| Rule | Detail |
|---|---|
| Be honest | Files require a current chat-space member credential. They are not public URLs. They are also not gated to the private-channel roster. State both. Do not claim end-to-end encryption or per-file deletion |
| No deletion path | There is no workflow that deletes a stored chat file short of buzz.space.delete. App files on the Files tab are apphost.file.delete (admin) — different prefix. |
| Access removal | Recommend buzz.member.remove or buzz.member.set-status, and buzz.member.rotate-key after a leak, not sign-out |
API and console
Every chat workflow you can call from the API, the console or an assistant, who may call it, the end-user entry points, and the console Chat tab
Structured chat with DGI
Let DGI answer for a chat actor, or for any app over an API, with forms, confirm cards, tables with row actions, charts, KPI tiles, data grids, diagrams, live cards, quick replies and a / command palette, built on your organization's own workflows. Part of DGI (Alpha)
