Feedback
Set feedback on <ChatWidget> to show thumbs up/down under completed assistant
messages. The client always fires its local onFeedback callback and makes a
best-effort POST to ${apiBase}/v1/feedback.
<ChatWidget
apiBase="/api/chat"
config={{
schemaVersion: 1,
runtime: { model: 'anthropic/claude-sonnet-4-5' },
client: { feedback: true },
}}
onFeedback={(event) => analytics.track('chat_feedback', event)}
/>Persist on the server
The mounted handler validates the payload, resolves the user again through
getUserId, and calls its server-side onFeedback seam. Browser identity is
never authoritative.
import { createHostedFeedback }
from '@mordn/chat-widget/server/hosted';
createChatHandler({
getUserId: getChatUserId,
model,
store,
onFeedback: createHostedFeedback({
apiKey: process.env.MORDN_CHAT_KEY!,
}),
});Without a server onFeedback, the handler acknowledges valid submissions but
does not persist them. Recording failures are logged and still return { ok: true }; feedback must not break chat.
The submitted shape is:
interface FeedbackEvent {
userId: string; // added by the verified server handler
conversationId?: string;
messageId: string;
rating: 'up' | 'down';
reason?: string;
}Hosted summary
curl "https://api.mordn.com/v1/feedback/summary?from=2026-07-01" \
-H "Authorization: Bearer $MORDN_CHAT_KEY"The current response is the aggregate count only:
{
"up": 1601,
"down": 239,
"total": 1840
}from and to are optional. The endpoint does not currently return upRate or
recent reason text; compute the rate client-side and use a separate authorized
surface if reason inspection is required.