Feedback runs inside your application
Reporters file and follow their reports inside your own product, with an identity your backend signs. Ingest keys scope to a project and rotate with a grace window, and the people who report are a surface you can filter, read and moderate.
React
npm install @myna-sh/react @myna-sh/sdk
@myna-sh/react/feedback is a new subpath: the board's intake form, the reports one person has filed, and the thread where they answer.
import { FeedbackProvider, ReportForm, MyReports, ReportThread } from "@myna-sh/react/feedback";
import "@myna-sh/react/feedback.css"; // optional
<FeedbackProvider
ingestKey="myna_ik_…"
board="bugs"
identify={{ id: user.id, email: user.email, signature }}
context={() => ({ appVersion: BUILD.version, route: location.pathname })}
>
<ReportForm onSubmitted={(r) => setOpen(r.number)} />
<MyReports onSelect={setOpen} />
{open ? <ReportThread number={open} /> : null}
</FeedbackProvider>;
Every question comes from the board, so rewording one in board settings rewords it here. Every element is unstyled and carries a data-myna attribute; the stylesheet is optional and driven by --myna-accent, --myna-radius and --myna-font.
useFeedback, useBoardSchema, useSubmitReport, useMyReports and useReport are exported for anyone rendering their own.
Reading a report back
A reporter reads the answer where they filed it. The same client does it:
const mine = await feedback.myReports();
const report = await feedback.report(42);
await feedback.reply(42, "Still happening on the latest build.");
await feedback.confirm(42); // it works now
await feedback.reopen(42); // still broken
What comes back is the title, the body, the status and the public conversation, with the team attributed as "team". No priority, no labels, no assignee, no internal notes. A report belonging to somebody else answers exactly as one that does not exist.
Set a board's --app-url and the notification emails link there:
myna feedback boards update qa --app-url https://app.example.com/support
Identity
@myna-sh/sdk/feedback/server is a Node-only subpath, kept apart from the browser entry so a bundler cannot pull node:crypto into your page:
import { signIdentity } from "@myna-sh/sdk/feedback/server";
const signature = signIdentity(process.env.MYNA_IDENTITY_SECRET, user.id);
A signed submission skips the spam queue, may carry properties — your own facts about your own user, at most 32 keys and 4 KB — and is the only thing that reads a report back. Read-back sends X-Myna-Identity: <yourUserId>.<hmacHex> alongside the key, verified by the same HMAC a submission carries.
myna feedback boards update qa --require-identity
turns a board into an authenticated surface: an unsigned submission answers IDENTITY_REQUIRED.
Ingest keys
myna feedback keys create --name "Web app" --signed-identity
myna feedback keys rotate ing_01k2…
myna feedback keys rotate ing_01k2… --identity-secret
Omit --board and a key files on any board on the project, with each submission naming which. Rotation mints a new secret and leaves the old one working for 24 hours, then a durable job revokes it; myna feedback keys revoke skips the window.
The dashboard's Feedback → Setup page lists the keys and shows the install snippet with the key already in it.
People
myna feedback people list
myna feedback people show usr_1042
myna feedback reports list --reporter usr_1042 --property plan:enterprise
myna feedback people block usr_1042
verified means a signature your backend produced. An email somebody typed is an address to reply to, and properties is what your system said about its own user. Blocking stops them filing, reading back and being emailed; it deletes nothing they filed.
Agents get myna_list_reporters, myna_get_reporter, myna_block_reporter, myna_merge_report and myna_move_report.
Upgrading
Myna serves no reporter-facing page. The hosted submission form, the public roadmap and the emailed reporter link are gone, along with myna feedback reports exposure, the board's visibility, votingEnabled and hostedSubmission fields, --visibility and --voting on myna feedback boards update, and votes.
- Render the form with
@myna-sh/react/feedback,mountFeedbackForm, or your own markup againstfeedback.schema(). - Set
--app-urlon every board that emails reporters, or the mail carries the update and the report number and no link. - Mint a key with
--signed-identityand sign your users to keep read-back working. myna feedback reports moveno longer takes--confirm. Every board is private to the project, so a move is filing.
GET /v1/meta reports apiVersion 2026-08-31 and a minClientVersion of 0.16.0.
Affects sdk · react · cli · mcp · api · dashboard · docs
