Skip to content

Feedback

The feedback loop captures per-statement accuracy ratings and feeds a rolling template-accuracy aggregate. Use it to surface which templates ring true for your users and which need rewriting.

Submit — POST /v1/feedback

Required scope: feedback:write

Request

{
    "statement_id": "019e32cb-...",
    "verdict": "correct",
    "role": "subject",
    "confidence": 0.9,
    "comment": "Spot on — this is exactly how I deal with pressure."
}
Field Type Required Notes
statement_id string yes The specific statement being rated. The server derives its template, skill, and chart from this.
verdict enum yes correct, doubtful, or wrong.
role enum no, default "subject" Who is rating: subject, observer, or hr_admin.
user_id string no Optional rater id, for your own attribution.
organization_id string no Optional org id, for your own attribution.
confidence float, 0–1 no How sure the rater is.
comment string no, max 2 000 chars Free-text. Stored for review; not used in the aggregate.

Response — 201 Created

{
    "id": "019e32d2-...",
    "statement_id": "019e32cb-...",
    "chart_id": "019e32b5-...",
    "template_id": "resilience-strength-high-en",
    "skill_id": "resilience",
    "verdict": "correct",
    "role": "subject",
    "submitted_at": "2026-05-16T22:10:00Z",
    "user_id": null,
    "organization_id": null,
    "comment": "Spot on — this is exactly how I deal with pressure.",
    "confidence": 0.9
}

The template_id, skill_id, and chart_id are resolved server-side from the statement_id and returned for convenience.

Fetch — GET /v1/feedback/{feedback_id}

Required scope: feedback:read

Returns the same FeedbackEntry shape as the create response.

Template accuracy aggregate — GET /v1/feedback/templates/{template_id}

Required scope: feedback:read

Returns the rolling accuracy aggregate for a single template across the caller's tenant.

{
    "template_id": "resilience-strength-high-en",
    "sample_size": 142,
    "correct_count": 110,
    "doubtful_count": 22,
    "wrong_count": 10,
    "accuracy": 0.82,
    "deprecated": false,
    "updated_at": "2026-05-16T22:10:00Z"
}
Field Type Notes
sample_size int Total ratings in the window.
correct_count / doubtful_count / wrong_count int Raw counts per verdict.
accuracy float, 0–1 (correct + 0.5 × doubtful) / sample_size.
deprecated bool Whether the template has been flagged for retirement.
updated_at ISO 8601 When the aggregate was last recomputed.

The aggregate is recomputed asynchronously after each feedback submission (within ~60 s). Treat it as eventually-consistent.

Operational uses

  • Drop low-accuracy templates from the eligible set. If a template's rolling accuracy is below your threshold, exclude it from the interpretations:write path. The platform itself uses accuracy < 0.4 as a default suppression cutoff (configurable).
  • Compare tone variants. When use_llm_rewrite: true produces multiple phrasings of the same template, feedback on the resulting statement-id ties back to the template-id so you can compare across styles.
  • Surface in admin dashboards. The GET .../templates/{id} endpoint is the same data the platform exposes in its operator console.

Feedback is per-tenant — your aggregates do not mix with another tenant's. Cross-tenant rollups are an admin-only feature surfaced via a separate internal endpoint, not via this REST surface.