---
title: "Get a feedback record"
method: GET
path: "/api/v3/feedbackRecords/{id}"
tags: ["V3 Feedback Records"]
---

# Get a feedback record

`GET /api/v3/feedbackRecords/{id}`

## Request

- Base URL: `https://app.formbricks.com`
- URL: `https://app.formbricks.com/api/v3/feedbackRecords/{id}`
- Auth: API key in header `x-api-key`

Returns one feedback record by id, with its read-only assignment in the active directory
taxonomy. The assignment reflects the current visible path in the active run; editing a record
does not reclassify it until another run. `taxonomy` is null if its lookup is unavailable.
The gateway looks the record up to learn its dataset and
authorizes against that, so no `tenant_id` is sent. Requires an API key with **read**
permission (or higher) on a workspace the record's dataset is assigned to.

An unknown id, or one in a dataset you cannot read, answers **403** rather than 404, so ids
cannot be probed. The exception is the minute after a delete: the gateway still has the
record's dataset cached, authorizes the call, and the store answers **404**.

## Path parameters

- `id` string, uuid, required

## Response `200`

Feedback record retrieved

- FeedbackRecordDetail: One piece of feedback in the normalized Feedback Record shape. Field names are `snake_case`: the payload is the Hub's, passed through the API gateway unchanged. Optional members are **absent** (not `null`) when unset, except `taxonomy` on the get-one response, which is null if its lookup fails.
  - `taxonomy` FeedbackRecordTaxonomy, required: Read-time view of the record's membership in the active directory taxonomy.
    - `status` 'classified' | 'unclassified' | 'no_active_taxonomy', required
    - `run_id` string, uuid, nullable, required
    - `path` object[], required: Currently visible non-root nodes in root-to-leaf order; empty unless classified.
      - `id` string, uuid, required
      - `label` string, required
      - `level` integer, required
      - `node_type` 'branch' | 'leaf', required
  - `id` string, uuid, required: UUIDv7 primary key.
  - `tenant_id` string, cuid2, required: The feedback dataset this record belongs to (the dataset id, as shown by the MCP `list_feedback_datasets` tool).
  - `collected_at` string, date-time, required: When the feedback was given.
  - `created_at` string, date-time, required: When the record was stored. Diverges from `collected_at` on a historical re-import.
  - `updated_at` string, date-time, required: When the record was last changed.
  - `source_type` string, required: Type of feedback source, e.g. `survey`, `review`, `feedback_form`.
  - `source_id` string: Reference to the survey / form / ticket the record came from.
  - `source_name` string: Human-readable name of the source.
  - `submission_id` string, required: Identifier of the logical submission this record belongs to (e.g. a response id). Records are unique per (`tenant_id`, `submission_id`, `field_id`).
  - `field_id` string, required: Identifier of the question / field.
  - `field_label` string: The question text.
  - `field_group_id` string: Stable identifier grouping related fields (ranking, matrix and grid questions).
  - `field_group_label` string: Human-readable question text for the group.
  - `field_type` 'text' | 'categorical' | 'nps' | 'csat' | 'ces' | 'rating' | 'number' | 'boolean' | 'date', required: The type of a feedback field, which determines which `value_*` member carries the answer: `text` → `value_text` (the only enrichable type), `categorical` → `value_text` + `value_id`, `nps` / `csat` / `ces` / `rating` / `number` → `value_number`, `boolean` → `value_boolean`, `date` → `value_date`.
  - `language` string: ISO language code the feedback was given in.
  - `user_id` string: End-user identifier (e.g. an anonymous id or an email hash).
  - `value_text` string: Text answer.
  - `value_id` string: Stable id of the selected option in the source system (e.g. a survey choice id), stored alongside `value_text` so choice answers keep their identity across label edits and languages. Opaque. Absent for free-text and non-choice answers.
  - `value_number` number, double: Numeric answer (ratings, NPS scores, numbers).
  - `value_boolean` boolean: Yes / no answer.
  - `value_date` string, date-time: Date answer.
  - `metadata` union: Arbitrary context stored with the record and returned with equivalent values (key order and number formatting are normalized). Omitted when the record has no metadata; a record explicitly stored with a JSON `null` returns `null`. An object is the supported shape and the only one the write operations accept; the wider union exists so records written before that convention still deserialize.
    - object
    - unknown[]
      - unknown
    - string
    - number
    - boolean
  - `sentiment` 'very_negative' | 'negative' | 'neutral' | 'positive' | 'very_positive' | 'mixed': Sentiment polarity label inferred from `value_text` by the sentiment enrichment: five ordinal levels plus a distinct `mixed`. Server-generated and read-only.
  - `sentiment_score` number, double: Signed sentiment polarity from `-1.0` (very negative) to `1.0` (very positive). Read-only; absent until the record is enriched.
  - `emotions` FeedbackRecordEmotion[]: Emotions inferred from `value_text`; multi-label from a fixed set. Read-only, and **never an empty array** — the column is either absent or has at least one label. Absent covers two different states: not yet classified, and classified with no emotion detected. Do not read absence as "not enriched yet"; `has_emotions=false` selects both, and the enrichment-status endpoint is what distinguishes them.
  - `value_text_translated` string: `value_text` translated into the dataset's configured target language. Read-only; absent until the record is enriched.
  - `translation_lang_key` string: BCP-47 locale that `value_text_translated` was produced in. Read-only; absent until the record is enriched.

## Other responses

- `400`: Bad Request. From the **gateway** (`text/plain`): a missing or malformed `tenant_id`; a request body that is not a single JSON object; a body whose top-level keys can be read more than one way (a repeated key, a key with non-ASCII characters, or a key that differs from `tenant_id` only in letter case); a `tenant_id` query parameter given more than once; or a path under `/api/v3/feedbackRecords` that is not one of the documented operations. A record id that is not a UUID and a path such as `/count` both fall in that last case and share the one `Unsupported FeedbackRecords route` body, so the two cannot be told apart from the response. From the **feedback store** (`application/problem+json`): schema validation failures — an unknown enum value, an inverted range, a malformed or re-ordered cursor, or a string with NULL bytes or invalid UTF-8.
- `401`: Unauthorized — no credentials, or an API key that does not exist or is revoked. Answered by the gateway as `text/plain`, before the request reaches the feedback store.
- `403`: Forbidden. Answered by the gateway as `text/plain` whenever the request cannot be authorized: the dataset does not exist, is archived, or is not assigned to a workspace the API key has the required permission on; the organization lacks the Unify Feedback entitlement; a mutation was attempted with an API key on a dataset shared by more than one workspace; or the record id does not exist. Existence is not leaked: an unknown dataset or record is refused here rather than with a 404. The single-record operations are the one exception, and only for a minute after a delete — see their `404`.
- `404`: Not Found from the feedback store (`application/problem+json`, `code: not_found`). The record was deleted after the gateway resolved its dataset: that lookup is cached for 60 seconds, so for up to a minute after a delete the call is still authorized and reaches the store, which no longer has the record. Once the cache entry expires the same id answers **403** instead. Treat both as "this record is not available to you".
- `500`: Internal Server Error from the feedback store (`application/problem+json`, `code: internal_server_error`).
- `503`: Service Unavailable. From the **gateway** (`text/plain`): the record's dataset could not be resolved because the feedback store did not answer, the authorization service itself was unreachable, or the record's stored `tenant_id` is not a dataset id this API can address. From the **feedback store** (`application/problem+json`, `code: service_unavailable`): the operation needs a capability that is not configured on this instance — semantic search and similar records require an embedding model.

## Changes

- **2026-10-01** `f917fab96782`: 10 breaking, 18 warning, 1 info
  - the response's body type changed from `object` to no type for status `200`
  - removed the required property `collected_at` from the response with the `200` status
  - removed the required property `created_at` from the response with the `200` status
  - removed the required property `field_id` from the response with the `200` status
  - …25 more
- **2026-09-09** `b127aa22f81c`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/formbricks/apis/formbricks-api-v3/changes/api/v3/feedbackRecords/:id/get.md)

---

[API](https://skmtc.dev/formbricks/apis/formbricks-api-v3.md) - [All operations](https://skmtc.dev/formbricks/apis/formbricks-api-v3/llms.txt) - [OpenAPI document](https://skmtc.dev/formbricks/apis/formbricks-api-v3/revisions/25335c959a13?raw)
