> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bryel.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Feedback

> Record 👍/👎, scores, comments, and corrections against a generation with @bryel/feedback.

Record user feedback against a generation or session — the substrate for evals and fine-tuning datasets. `@bryel/feedback` runs server-side with zero dependencies.

<CodeGroup>
  ```bash bun theme={"theme":{"light":"github-light","dark":"github-dark"}}
  bun add @bryel/feedback
  ```

  ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}}
  npm i @bryel/feedback
  ```

  ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark"}}
  pnpm add @bryel/feedback
  ```

  ```bash yarn theme={"theme":{"light":"github-light","dark":"github-dark"}}
  yarn add @bryel/feedback
  ```
</CodeGroup>

## Record feedback

Call `recordFeedback` with the target you're scoring and the kind of signal you captured.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { recordFeedback, thumbsUp } from "@bryel/feedback";

await recordFeedback({
  apiKey: process.env.BRYEL_KEY!,
  target: { type: "message", id: messageId }, // or { type: "session", id: sessionId }
  kind: "thumb",      // thumb | score | comment | correction | label
  score: 1,           // 👍=1 / 👎=0, or a scalar
  userId,             // → annotator
  source: "end_user", // end_user | labeler | model_judge | code
});

// shorthands
await thumbsUp({ apiKey, target: { type: "message", id: messageId } });
```

See the [feedback API reference](/guides/feedback) for every field and shorthand.

## The messageId handshake

Feedback arrives *after* the answer, so the client needs a handle that also exists on the trace. Mint a `messageId` per turn, pass it into telemetry `metadata` (bryel stamps it as `bryel.interaction.id`), and return it to the client.

<Steps>
  <Step title="Mint, stamp, and return on the server">
    ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
    const messageId = crypto.randomUUID();
    streamText({ /* … */ experimental_telemetry: { isEnabled: true, metadata: { sessionId, userId, messageId } } });
    return result.toTextStreamResponse({ headers: { "x-bryel-message-id": messageId } });
    ```
  </Step>

  <Step title="Hold the id on the client">
    The browser keeps `messageId` (from the header) and POSTs a 👍/👎 to your backend.
  </Step>

  <Step title="Proxy to bryel from your backend">
    ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
    await recordFeedback({ apiKey: process.env.BRYEL_KEY!, target: { type: "message", id: messageId }, kind: "thumb", score: 1, userId, source: "end_user" });
    ```
  </Step>
</Steps>

<Warning>Keep your API key server-side. Proxy browser clicks through your backend — never ship `BRYEL_KEY` to the client.</Warning>

To capture the `messageId` upstream in the first place, see the [Vercel instrumentation](/sdk/typescript) guide.
