Support tickets
Give your app's users a way to reach you — a ticket flow the platform hosts, switched on per app, with no code in your app and no second login for your users.
Your users can already sign in to your app without you writing a login screen. Support tickets are the same trade for the other direction: they can tell you something, and you can answer, without you building a ticket system.
Switch it on per app. Your users get a way in from the app itself and a page where their conversations live; your team gets a triage queue in the console. Nothing to deploy, no widget account to create, no second identity for anyone.
Turn it on
Two ways, and they answer to each other — see Which one wins below.
From the console, on the app’s Tickets tab. If support is off you get a panel that explains what turns on and lets you pick who may read a ticket. One click and it is live: the affordance appears in your app, the pages start working, the queue is there. No redeploy, and the setting survives your next deploy.
From dibbla.yaml, if you would rather keep it with the rest of the app’s
configuration:
support:
enabled: true
visibility: app # app (default) | own
An explicit support: block in dibbla.yaml always wins while it is there
— the whole block, not field by field, and enabled: false counts as the
manifest speaking. Remove the block and the console setting takes over.
With neither, support is off. Both surfaces show you which one is in force,
and a deploy whose manifest overrides a console setting says so in its
output.
What your users get
In your app. One tag, anywhere in your HTML:
<script src="/_platform/support.js"></script>
It is served from your app’s own origin, so there is no CORS to configure and no key to embed. Someone who is signed in gets a compose form; someone who is not gets a sign-in prompt that brings them back where they were. The script is served only for apps that have support on — before then the path is a plain 404.
In the portal. Every user has /support on
app.<your-domain> — one place for their tickets across every app they use,
with the thread and the reply box. Opening Support from an app card uses
/support?app=<alias>: the new request is locked to that app while the full
cross-app ticket history stays beside it. Each app also keeps its own page at
/apps/<alias>/support, which is where the widget links.
It is a place to write, not a form to fill in: the request is a sheet with room for as much detail as someone wants to give, their other tickets stay beside it as a list, and Cmd/Ctrl + Enter sends. On a phone the writing surface comes first and the list moves below it.
Two things worth knowing because they save a user’s work:
- Every ticket has its own address. Opening one puts you at
/support/<ticket-id>, so a conversation can be bookmarked, linked, or sent to a colleague, and reloading keeps you in it. - A half-written request survives a reload. It is kept in that browser until it is sent — per app, so a draft about one app is never offered on another. It is a convenience, not storage: it does not follow the user to another device.
A user keeps access to their own conversations even if they later lose access to the app itself. What they lose is everyone else’s tickets on it, not their own correspondence.
What your team gets
The console’s per-app Tickets tab is the queue: filter by status, open a
thread, reply, assign, set status and priority, and leave internal notes
that the reporter never sees. Who counts as staff here is your organisation’s
role — owner, admin or developer — checked per request, never taken from
anything the browser sends.
Coding agents can work the same queue over MCP. See
MCP server for the /support toolset: the same six actions,
the same authorization, and ticket text marked as untrusted so an agent treats
it as data rather than instructions.
Who can read a ticket
The rule is deliberately one sentence: whoever may see the app may see that app’s tickets. No per-ticket permissions to manage, and no second access model to keep in step with the first.
That has one consequence worth being deliberate about. On an app that anyone
signed in can open, “whoever may see the app” is every signed-in user — so
every one of them can read every ticket on it. If tickets on your app may
carry anything private, set visibility: own (in the console panel: only the
person who filed it), and a reporter sees only their own while your team
still sees all of them.
Each ticket records the setting that was in force when it was created.
Widening own to app later does not re-open tickets that were filed under
the narrower rule — which is the safe direction, and the reason changing
your mind is not a data leak.
Files on a ticket
A reporter can attach a screenshot or a log to a ticket, and your team can attach one to a reply. Files are stored by the platform, not by your app — there is nothing to configure and no bucket of your own to run.
Three ways to attach, from the widget or the portal: choose a file, drag it
onto the request, or paste a screenshot straight into the message. The last
one is the one people actually use — take the screenshot, click into the
message, paste. A pasted image arrives from the clipboard without a useful
name, so it is filed as screenshot-<when-it-was-taken>.png rather than as yet
another image.png. Pasting text does what it has always done and attaches
nothing.
A file attached from inside your app appears on the same ticket in the portal, and the other way round — it is one conversation seen from two places.
What is accepted:
| Size | up to 10 MB per file |
| Types | PNG, JPEG, GIF, WebP, PDF, plain text, CSV, JSON, .docx, .xlsx |
The list is an allow-list rather than a block-list, which is why it is short. SVG and HTML are deliberately absent: both are documents a browser will run script from, and a support queue is exactly where someone would try that.
Everything else about a file follows its ticket. Whoever may read the ticket
may download its files; a ticket that is own keeps its files as private as
its text. Uploading and downloading both go through Dibbla, so a file is never
addressable by a link that escapes those checks — there is no URL to leak.
A file that is too big or of the wrong type is refused as soon as it is chosen, and says which file and why. A refused file never costs the request — the text is still there, still sendable, with any accepted files still attached.
Dibbla checks the size and the type, not the contents. Treat a file from a ticket the way you would treat any file a stranger sent you — which is the same care you would take with one emailed to your support address.
How long tickets are kept
A closed ticket, its replies and its files are deleted 24 months after it was handled. A ticket can also be deleted on request before then, by an owner or admin of the app’s organisation — the erasure path that a data-processing agreement will ask you about, since the people writing these tickets are your users, not ours.
Why not build it yourself
You can, and it is more work than it looks: a ticket store, an agent view, a notification path, and — the expensive part — an identity bridge, because a bolted-on helpdesk does not know who your signed-in user is. The platform already knows. That is the whole argument: this exists because the identity was already there, and everything else is small next to it.
dibbla feedback sends a note to the Dibbla
team about the platform. Support tickets are your users writing to you
about your app. Same service underneath, deliberately separate flows.