API reference / Feedback

Feedback

The Feedback endpoints of the Voiceland AI API, with parameters, schemas and curl examples.

Last updated:

GET /v1/feedback#

List answer feedback. One page of the raw feedback rows your visitors and reviewers left on individual answers, in key order (call, then turn, then author). This is also the export: follow the cursor to the end and you hold every row. **Paging.** Pass the next_cursor from the previous response back as ?cursor=. **An empty next_cursor is the only signal that you have seen everything**, a short page, including an empty one, is normal and means "ask again": the agent filter is applied after each read, so a page can match nothing and still have more behind it.

Parameters

Name In Type Required Description
call_id query string Only one call's feedback.
agent query string Only one agent's feedback. Applied after the read, short pages are normal.
limit query integer Rows per page, 1 to 100 (default 50). Larger values are capped rather than refused.
cursor query string The next_cursor from the previous page. Omit for the first page. A cursor belongs to the scope that issued it.

Responses

Code Description
200 Success.
400 limit is not a positive whole number (bad_request), or cursor was not issued by this listing for this scope (invalid_cursor), start again without it.
401 Missing or invalid API key.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl "https://api.voiceland.ai/v1/feedback" \
  -H "Authorization: Bearer VL_API_KEY"

A successful response returns a FeedbackListResponse.

Example response

{
  "items": [
    {
      "agent_name": "front-desk",
      "author_id": "widget-user-1a2b",
      "author_kind": "visitor",
      "call_id": "widget-8c2f1a7e-4b3d-4e21-9c0a-5f6d7e8a9b0c",
      "category": "inaccurate",
      "rating": "down",
      "rating_kind": "thumbs",
      "score": 1,
      "tenant_slug": "acme",
      "turn_id": "t3",
      "turn_role": "agent"
    }
  ],
  "next_cursor": ""
}

POST /v1/feedback#

Rate an answer. Records your review of one transcript turn. Send **either** rating (up/down) **or** score (1 to 5), a thumb is stored as 5/1 on the same scale, so both controls land in one shape. turn_id is t<index>, the zero-based position of the turn in GET /calls/{id}/transcript, or o<offset_ms>, the turn's offset_ms. The turn must exist on the persisted call. **One row per (turn, author): re-submitting replaces your previous rating, it is never counted twice.** Pass author to keep two reviewers' ratings distinct. A rating on a human reply (a representative's turn) is stored with its role and deliberately excluded from the agent satisfaction numbers, it is not an AI quality signal.

Request body

application/json Schema: FeedbackSubmitRequest

Field Type Required Description
agent string
author string
call_id string Yes
category string
comment string
rating string
score integer
turn_id string Yes

Responses

Code Description
200 The stored feedback row (replacing any earlier one by the same author on the same turn).
401 Missing or invalid API key.
404 No CDR for that call id (call_not_found), or the turn id names no turn of it (turn_not_found).
422 Neither a rating nor a score was sent, they contradict each other, or the category is not one of inaccurate/outdated/irrelevant/inappropriate/other (invalid_feedback).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl -X POST "https://api.voiceland.ai/v1/feedback" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "call_id": "widget-8c2f1a7e-4b3d-4e21-9c0a-5f6d7e8a9b0c",
  "category": "outdated",
  "comment": "Quotes the 2024 price list.",
  "score": 2,
  "turn_id": "t3"
}'

Example response

{
  "agent_name": "front-desk",
  "author_id": "operator",
  "author_kind": "operator",
  "call_id": "widget-8c2f1a7e-4b3d-4e21-9c0a-5f6d7e8a9b0c",
  "category": "outdated",
  "rating": "down",
  "rating_kind": "scale",
  "score": 2,
  "tenant_slug": "acme",
  "turn_id": "t3",
  "turn_role": "agent"
}

GET /v1/feedback/analytics#

Answer satisfaction analytics. Per-agent satisfaction over the stored feedback rows: rated count, up/down split, average score and the satisfaction rate (share of ratings with score ≥ 4), plus the worst-rated turns as a review feed. Only ratings on AI turns count; ratings on human replies are excluded and reported in human_turns_excluded. The fold reads a bounded number of rows and says so: when truncated is true the numbers cover scanned rows, not the whole history.

Parameters

Name In Type Required Description
agent query string Fold one agent only.

Responses

Code Description
200 Success.
401 Missing or invalid API key.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl "https://api.voiceland.ai/v1/feedback/analytics" \
  -H "Authorization: Bearer VL_API_KEY"

A successful response returns a FeedbackAnalyticsResponse.

Example response

{
  "human_turns_excluded": 2,
  "items": [
    {
      "agent": "front-desk",
      "average_score": 4.1,
      "down": 8,
      "rated": 41,
      "satisfaction_rate": 0.8,
      "up": 33
    }
  ],
  "scanned": 43,
  "truncated": false,
  "worst": [
    {
      "agent": "front-desk",
      "call_id": "widget-8c2f…",
      "category": "inaccurate",
      "rating": "down",
      "score": 1,
      "turn_id": "t3"
    }
  ]
}

GET /v1/feedback/regressions#

Export confirmed-wrong answers (regression cases). Every report resolved confirmed_wrong, as stable rows an evaluation harness can consume: the snapshotted answer, its sources, the linked knowledge document and the resolution trail. Rows whose call was erased under a data-subject request keep only the hashed call linkage (erased: true). **Paging.** Pass the next_cursor back as ?cursor=; **an empty next_cursor is the only signal that the export is complete**, the status filter runs after each read, so short pages with a cursor are normal. The row shape is additive-only: fields may be added, never renamed or removed.

Parameters

Name In Type Required Description
limit query integer Rows per page, 1 to 100 (default 50).
cursor query string The next_cursor from the previous page. Omit for the first page.

Responses

Code Description
200 Success.
400 limit is not a positive whole number (bad_request), or the cursor was not issued by this listing (invalid_cursor).
401 Missing or invalid API key.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl "https://api.voiceland.ai/v1/feedback/regressions" \
  -H "Authorization: Bearer VL_API_KEY"

A successful response returns a FeedbackRegressionsResponse.

Example response

{
  "items": [
    {
      "agent": "front-desk",
      "answer_text": "Our premium plan costs …",
      "call_id_hash": "b1946ac9…",
      "category": "inaccurate",
      "id": "fbr_9d8c7b6a",
      "kb_document_id": "doc_4b1e77a0",
      "resolved_by": "maria@acme.example",
      "turn_id": "t3"
    }
  ],
  "next_cursor": ""
}

GET /v1/feedback/reports#

List inaccuracy reports (review queue). One page of the reported answers, in report-id order. ?status=open is the review queue; the three resolved states are the history. Each report carries its own **snapshot** of the answer text and the sources that grounded it, taken when the report was filed, so the review works even after the call itself was erased. snapshot_source says whether the copy came from the stored transcript or was claimed by the reporter mid-session. **Paging.** Pass the next_cursor back as ?cursor=. **An empty next_cursor is the only signal that you have seen everything**, the status filter runs after each read, so short and empty pages with a cursor are normal.

Parameters

Name In Type Required Description
status query string Filter: open, confirmed_wrong, correct or fixed. Applied after the read.
limit query integer Rows per page, 1 to 100 (default 50).
cursor query string The next_cursor from the previous page. Omit for the first page.

Responses

Code Description
200 Success.
400 status is not one of the four states or limit is not a positive whole number (bad_request); or the cursor was not issued by this listing (invalid_cursor).
401 Missing or invalid API key.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl "https://api.voiceland.ai/v1/feedback/reports" \
  -H "Authorization: Bearer VL_API_KEY"

A successful response returns a FeedbackReportsResponse.

Example response

{
  "items": [
    {
      "answer_text": "Our premium plan costs …",
      "call_id": "widget-8c2f…",
      "category": "inaccurate",
      "id": "fbr_9d8c7b6a",
      "snapshot_source": "transcript",
      "sources": [
        {
          "chunk_id": "doc_4b1e77a0:0003",
          "document_id": "doc_4b1e77a0",
          "index": 1,
          "title": "Τιμολόγηση 2026"
        }
      ],
      "status": "open",
      "turn_id": "t3"
    }
  ],
  "next_cursor": ""
}

POST /v1/feedback/reports#

Report an inaccurate answer. Files one answer into the review queue. The answer text and the sources that grounded it are **copied from the stored transcript turn at this moment**, never recomputed later, so the report stays reviewable even if the call is erased afterwards. turn_id is t<index> (transcript item index) or o<offset_ms>, and must name a turn of the persisted call.

Request body

application/json Schema: FeedbackReportCreateRequest

Field Type Required Description
agent string
author string
call_id string Yes
category string
comment string
turn_id string Yes

Responses

Code Description
201 The report, open, with the snapshot attached.
401 Missing or invalid API key.
404 No CDR for that call id (call_not_found), or the turn id names no turn of it (turn_not_found).
422 The category is not one of inaccurate/outdated/irrelevant/inappropriate/other (invalid_feedback).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl -X POST "https://api.voiceland.ai/v1/feedback/reports" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "call_id": "widget-8c2f1a7e-4b3d-4e21-9c0a-5f6d7e8a9b0c",
  "category": "inaccurate",
  "comment": "The quoted price is last year'\''s.",
  "turn_id": "t3"
}'

Example response

{
  "answer_text": "Our premium plan costs …",
  "call_id": "widget-8c2f…",
  "category": "inaccurate",
  "id": "fbr_9d8c7b6a",
  "snapshot_source": "transcript",
  "status": "open",
  "turn_id": "t3"
}

GET /v1/feedback/reports/{id}#

Get an inaccuracy report. One report, snapshot included.

Parameters

Name In Type Required Description
id path string Yes Report id.

Responses

Code Description
200 Success.
401 Missing or invalid API key.
404 No report with that id (report_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl "https://api.voiceland.ai/v1/feedback/reports/{id}" \
  -H "Authorization: Bearer VL_API_KEY"

Example response

{
  "category": "inaccurate",
  "id": "fbr_9d8c7b6a",
  "status": "open",
  "turn_id": "t3"
}

POST /v1/feedback/reports/{id}/resolve#

Resolve an inaccuracy report. Records the review decision: confirmed_wrong (the answer is wrong and becomes a regression case, see GET /feedback/regressions), correct (the answer was fine), or fixed (you corrected the knowledge content, so the expected answer changed). Optionally link the knowledge document that caused it with kb_document_id. **confirmed_wrong with a kb_document_id flags that document for review**: it appears in GET /kb/review-flags with a pointer back to this report, and its cited_wrong_count goes up. kb_document_flagged in the response says whether that happened. It is false when no document was named or the document no longer exists, and the decision itself is recorded either way. **A decision is one-shot**: resolving an already-resolved report answers 409.

Parameters

Name In Type Required Description
id path string Yes Report id.

Request body

application/json Schema: FeedbackResolveRequest

Field Type Required Description
kb_document_id string
note string
resolution string Yes
resolved_by string

Responses

Code Description
200 The resolved report.
401 Missing or invalid API key.
404 No report with that id (report_not_found).
409 The report is already resolved (already_resolved).
422 resolution is not confirmed_wrong, correct or fixed (invalid_resolution).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Example request

curl -X POST "https://api.voiceland.ai/v1/feedback/reports/{id}/resolve" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "kb_document_id": "doc_4b1e77a0",
  "note": "Doc quotes the 2024 price list.",
  "resolution": "confirmed_wrong",
  "resolved_by": "maria@acme.example"
}'

A successful response returns a FeedbackResolveResponse.

Example response

{
  "id": "fbr_9d8c7b6a",
  "kb_document_flagged": true,
  "kb_document_id": "doc_4b1e77a0",
  "status": "confirmed_wrong"
}

Schemas#

AnswerFeedback#

Field Type Required Description
agent_name string
author_id string Yes
author_kind string Yes
call_id string Yes
category string
comment string
created_at string (date-time)
rating string Yes
rating_kind string Yes
score integer Yes
tenant_slug string Yes
turn_id string Yes
turn_role string Yes
updated_at string (date-time)

AnswerFeedbackReport#

Field Type Required Description
agent_name string
answer_text string
call_id string
call_id_hash string Yes
category string Yes
comment string
created_at string (date-time)
erased boolean
id string Yes
kb_document_id string
reporter_id string
reporter_kind string Yes
resolution_note string
resolved_at string (date-time)
resolved_by string
snapshot_source string Yes
sources array of TranscriptSource
status string Yes
tenant_slug string Yes
turn_id string Yes
turn_role string
updated_at string (date-time)

Error#

Error envelope returned for non-2xx responses.

Field Type Required Description
error object Yes

FeedbackAgentAnalytics#

Field Type Required Description
agent string Yes
average_score number Yes
down integer Yes
rated integer Yes
satisfaction_rate number Yes
up integer Yes

FeedbackAnalyticsResponse#

Field Type Required Description
human_turns_excluded integer Yes
items array of FeedbackAgentAnalytics Yes
scanned integer Yes
truncated boolean Yes
worst array of FeedbackWorstItem Yes

FeedbackListResponse#

Field Type Required Description
items array of AnswerFeedback Yes
next_cursor string Yes

FeedbackRegressionCase#

Field Type Required Description
agent string
answer_text string
call_id string
call_id_hash string Yes
category string Yes
erased boolean
id string Yes
kb_document_id string
note string
reported_at string (date-time) Yes
resolved_at string (date-time) Yes
resolved_by string
sources array of TranscriptSource
turn_id string Yes

FeedbackRegressionsResponse#

Field Type Required Description
items array of FeedbackRegressionCase Yes
next_cursor string Yes

FeedbackReportCreateRequest#

Field Type Required Description
agent string
author string
call_id string Yes
category string
comment string
turn_id string Yes

FeedbackReportsResponse#

Field Type Required Description
items array of AnswerFeedbackReport Yes
next_cursor string Yes

FeedbackResolveRequest#

Field Type Required Description
kb_document_id string
note string
resolution string Yes
resolved_by string

FeedbackResolveResponse#

Field Type Required Description
agent_name string
answer_text string
call_id string
call_id_hash string Yes
category string Yes
comment string
created_at string (date-time)
erased boolean
id string Yes
kb_document_flagged boolean Yes
kb_document_id string
reporter_id string
reporter_kind string Yes
resolution_note string
resolved_at string (date-time)
resolved_by string
snapshot_source string Yes
sources array of TranscriptSource
status string Yes
tenant_slug string Yes
turn_id string Yes
turn_role string
updated_at string (date-time)

FeedbackSubmitRequest#

Field Type Required Description
agent string
author string
call_id string Yes
category string
comment string
rating string
score integer
turn_id string Yes

FeedbackWorstItem#

Field Type Required Description
agent string
call_id string Yes
category string
comment string
rating string Yes
score integer Yes
turn_id string Yes

TranscriptSource#

Field Type Required Description
chunk_id string Yes
document_id string Yes
index integer Yes
title string
url string

The console

These pages are read only. The test call, the API keys and the live API reference are in the console, where your account is signed in.

Open the console