Documentation menu
Reference
API reference
Docs · markdown

Browser & feedback

Feedback is telemetry: it lands next to the session it grades, and the same loop that clusters failures clusters bad feedback — negative feedback becomes bug candidates; directional asks become idea candidates whose text IS the spec.

Your feedback_key (lk_feedback_*) is browser-safe — it can submit feedback and targeted events, plus read its own project's ingest health; nothing else (no telemetry reads).

Typed feedback

Target one of session_id / trace_id / span_id, plus at least one valence (score 0..1, polarity up|down, rating 1..5, comment, or expected — "what it should have said", a golden-answer seed):

POST /v1/feedback
Authorization: Bearer <feedback_key>
Content-Type: application/json

{ "session_id": "sess_abc", "polarity": "down", "labels": ["export"],
  "comment": "the export button does nothing on mobile" }

Spoken feedback

POST raw recording bytes (audio/*, ≤ 4 MiB); the worker transcribes at the edge and the transcript enters the same lane. Raw audio is not retained:

POST /v1/feedback/audio?session_id=sess_abc
Authorization: Bearer <feedback_key>
Content-Type: audio/webm

<recording bytes>

@getloopops/sdk ships feedback() / feedbackAudio() plus a drop-in widget (feedback-widget.js: thumbs, comment panel, mic).

Product / UX events

Standard OTLP logs with EventName — regenerations, retries, abandons, escalations, slow-UX markers. Actionable friction becomes a bug candidate; positive actions stay context:

POST /v1/logs
Authorization: Bearer <feedback_key>
Content-Type: application/json

{ "resourceLogs": [{ "scopeLogs": [{ "logRecords": [{
  "traceId": "tr_123",
  "eventName": "chat.response_regenerated",
  "body": { "stringValue": "user regenerated the response" },
  "attributes": [
    { "key": "session.id", "value": { "stringValue": "sess_abc" } },
    { "key": "loopops.event.action", "value": { "stringValue": "regenerated" } }
  ]
}] }] }] }

With the feedback_key, events must be targeted (carry session.id, trace_id, span_id, or a message id). Ordinary application logs use the producer key.

Evaluator results — the OTel standard just works

Automated evals instrumented to the OpenTelemetry GenAI semantic conventions need no LoopOps-specific shape: a gen_ai.evaluation.result log event (semconv v1.39) posted to /v1/logs is recognized at ingest and folds into this same feedback lane as agent feedback. gen_ai.evaluation.score.label (pass/fail-style verdicts) or score.value becomes the polarity, gen_ai.evaluation.explanation the comment, and gen_ai.response.id the join back to the evaluated call. The standard defines no human-feedback event — human 👍/👎 stays on /v1/feedback above, where the rater split (end user / reviewer / auto) already goes further than the spec.

Next: Run your first loop →