DocumentationFeedback to SnakkbarMarkdown
Feedback to Snakkbar: from the panel to the developers and back
People working in the panel (the hosted one and every embedded admin) can tell Snakkbar about a bug, something unclear or a feature they miss. They draw on the screen to show what they mean and write a message; the report reaches the developers with a picture of the panel, and the developers' answer comes back to the person in the panel. The developers' tools (Claude Code, a script, CI) fetch what is open over the API, fix it, and answer.
In the panel
- The bug in Pixel's head (packages/admin/src/feedback/, as in Declarely) opens the drawing tool. On a phone Pixel's sheet closes first, so the panel is free to draw on.
- Answers show at the top of Pixel's chat (
FeedbackAnswers): what the person wrote, the status and Snakkbar's answer, until «Ok, takk». While Pixel is closed, a dot on its bubble says an answer has come. The person's reports are fetched when the panel loads, when the tab comes back into view, and every five minutes. - The drawing tool lies over the whole admin. Tools: freehand (H), line (L), rectangle (R), and the hand (M), which lets the panel be used under the drawing (open a menu, then mark it). Three colours, undo and redo (Ctrl+Z, Ctrl+Shift+Z or Ctrl+Y). Pictures can be pasted, dropped or picked (at most three, 8 MB each). Ctrl+Enter sends. On a phone the card folds to its toolbar, and «Skriv melding» opens the message (the panel is copied then, before the keyboard squeezes it).
- Sending closes the tool at once. The admin's frame is copied with modern-screenshot (without the tool and the tooltips), the drawing is laid on top, and it is posted as WebP (PNG where the browser cannot write WebP). A notice says «Takk! Tilbakemelding #N er sendt», or offers to try again.
- Pixel can do it too: when someone describes a problem with Snakkbar itself, Pixel offers to
send it, writes it up in their words and opens the drawing tool with it (
start_feedback); the person points and sends.my_feedbacklists their reports and answers.
With every report go: the message, the panel's address and open view (inbox, email,
settings/profile, …), the frame's size, the user agent, the build (VERCEL_GIT_COMMIT_SHA, short)
and what the browser says about itself: language, time zone, screen, pixel ratio, touch, colour
scheme, reduced motion, online, and the last ten script errors in the tab. Nothing else the person
did is recorded.
The developers' API
/api/v1/platform/feedback, authenticated with a platform key (Authorization: Bearer sk_platform_…) or a signed-in system owner. Make keys in the panel under
Systemeier → Tilbakemeldinger → API-nøkler for utviklere; the key is shown once and only its
hash is kept. A tenant's sk_snakkbar_… key never gets in, and a platform key opens nothing but
these routes. 120 requests a minute per key.
GET /platform/feedback
| Query | |
|---|---|
status | open (new and planned, the default in the panel), all, one status, or several separated by commas. Leaving it out means all |
tenantId | Only this customer's |
since | Created on or after this date (2026-11-01) |
before | Paging: numbers below this (nextBefore from the previous page) |
limit | 1–200, default 50 |
{
"items": [
{
"id": "6c1f…",
"number": 42,
"status": "new",
"message": "Lagre-knappen under Nettsted og chat er grå selv om jeg har endret noe.",
"tenant": { "id": "amatec", "name": "Amatec" },
"author": { "operatorId": "…", "userId": "…", "name": "Kari Nordmann", "email": "kari@amatec.no" },
"page": { "url": "https://snakkbar.app/panel?tenant=amatec&view=settings/site", "view": "settings/site", "viewport": "1440x900", "userAgent": "Mozilla/5.0 …" },
"appVersion": "fef8627",
"browser": { "language": "nb-NO", "timeZone": "Europe/Oslo", "screen": "1920x1080", "pixelRatio": 1, "errors": [{ "at": "…", "message": "TypeError: …", "source": "/admin.js:1:2345" }] },
"screenshotUrl": "https://…/feedback/amatec/….webp?token=…",
"attachmentUrls": [],
"response": null,
"respondedAt": null,
"responseSeenAt": null,
"createdAt": "2026-11-04T09:12:00Z",
"updatedAt": "2026-11-04T09:12:00Z"
}
],
"nextBefore": null
}Picture links work for ten minutes. Behind the key instead:
GET /platform/feedback/{id or number}/screenshot and /attachments/{1–3}.
GET /platform/feedback/{id or number}
One report, { "feedback": … }. 42 and #42 both work.
PATCH /platform/feedback/{id or number}
{ "status": "done", "response": "Takk! Det var en feil, og den er rettet nå." }status is new, planned (accepted, coming), declined (not now) or done. response (at most
4000 characters, Markdown) is shown to the person in the panel until they have read it; a changed
answer shows again, null or "" removes it. A status change alone is not announced. Send the body
as UTF-8 (a body with U+FFFD is refused: that is what a Windows shell makes of æ, ø and å). Every
answer is written to the audit log (feedback.respond).
A round with curl
KEY=sk_platform_…
curl -s -H "Authorization: Bearer $KEY" "https://snakkbar.app/api/v1/platform/feedback?status=open"
curl -s -H "Authorization: Bearer $KEY" -o 42.webp "https://snakkbar.app/api/v1/platform/feedback/42/screenshot"
curl -s -X PATCH -H "Authorization: Bearer $KEY" -H "Content-Type: application/json; charset=utf-8" \
--data '{"status":"done","response":"Rettet i dag. Takk for at du sa fra!"}' \
"https://snakkbar.app/api/v1/platform/feedback/42"The person's side of the API
For a custom panel built on the SDK (client.feedback):
| Call | |
|---|---|
POST /operator/feedback | multipart: message (required), screenshot, attachments (≤ 3), pageUrl, view, viewport, context (JSON, ≤ 12 kB). Images are PNG, JPEG, WebP or GIF, checked by their bytes, ≤ 8 MB. 30 an hour per person. Answers 201 { "feedback": { "id", "number" } } |
GET /operator/feedback | { items, unseen }: the person's own reports (across their tenants when signed in to the hosted panel), newest first |
POST /operator/feedback/seen | { ids? }: the answers have been read (all when ids is left out). A system owner acting as someone reads without marking |
Storage
feedback and platform_api_keys (supabase/migrations/20261104140000_feedback.sql), read and
written by the server only; pictures in the private feedback bucket under <tenant>/<uuid>.<ext>.
Reports are numbered across all tenants. A report outlives the operator who sent it (their name and
e-mail are kept on it); deleting a tenant keeps its reports without the link.