Hopp til innholdet

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_feedback lists 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
statusopen (new and planned, the default in the panel), all, one status, or several separated by commas. Leaving it out means all
tenantIdOnly this customer's
sinceCreated on or after this date (2026-11-01)
beforePaging: numbers below this (nextBefore from the previous page)
limit1–200, default 50
json
{
  "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}

json
{ "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

sh
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/feedbackmultipart: 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.