Skip to content

Create a new feedback record

POST
/v1/feedback-records
curl --request POST \
--url http://localhost:8080/v1/feedback-records \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "source_type": "survey", "field_id": "q1", "field_type": "rating", "field_label": "How satisfied are you?", "value_number": 9, "source_id": "survey-123", "source_name": "Q1 NPS Survey", "user_id": "user-abc-123", "tenant_id": "org-123", "submission_id": "550e8400-e29b-41d4-a716-446655440000", "language": "en" }'

Creates a new feedback record data point

Media typeapplication/json
object
collected_at

When the feedback was collected (defaults to now). Must be between 1970-01-01 and 2080-12-31.

string format: date-time
field_id
required

Identifier for the question/field. NULL bytes not allowed.

string
>= 1 characters <= 255 characters /^[^\x00]*$/
field_label

The actual question text

string | null
<= 2048 characters /^[^\x00]*$/
field_group_id

Stable identifier grouping related fields (for ranking, matrix, grid questions). NULL bytes not allowed.

string
<= 255 characters /^[^\x00]*$/
field_group_label

Human-readable question text for the group

string | null
<= 2048 characters /^[^\x00]*$/
field_type
required

Field type: text (enrichable), categorical, nps, csat, ces, rating, number, boolean, date

string
>= 1 characters <= 255 characters
Allowed values: text categorical nps csat ces rating number boolean date
language

ISO language code. NULL bytes not allowed.

string
<= 10 characters /^[^\x00]*$/
metadata

Arbitrary context for this record, stored as JSON and returned with equivalent values (key order and number formatting are normalized): the dimensions you want to slice a dashboard by, such as channel, device, browser, OS, country, referrer, campaign, plan or tags. Values may be strings, numbers, booleans, null, or nested objects and arrays. Use snake_case keys and keep them stable across records, since a key is what a dashboard groups by: customer_tier, not a mix of customerTier and tier. Numbers keep full precision in storage (unlike value_number, which is a float64), so a large integer id round-trips exactly through this API — though a JavaScript client will still lose precision above 2^53 when it parses the response. Nothing here is redacted. Metadata is not sent to the LLM or embedding enrichment providers, unlike value_text — but it is included in the feedback_record.created and feedback_record.updated webhook payloads, so it reaches whatever URL a tenant has configured. Erasure covers metadata, with one precondition worth knowing: DELETE /v1/feedback-records matches on user_id and hard-deletes the whole row, metadata included — so a record written without a user_id cannot be reached that way. Set user_id on anything you may later have to erase. Three kinds of content are rejected with 400, because none of them can be stored: invalid UTF-8; NULL bytes or unpaired UTF-16 surrogates, in keys or values; and numbers outside the storable numeric range.

object | null
source_id

Reference to survey/form/ticket ID

string | null
<= 255 characters /^[^\x00]*$/
source_name

Human-readable name

string | null
<= 255 characters /^[^\x00]*$/
source_type
required

Type of feedback source (e.g., survey, review, feedback_form). NULL bytes not allowed.

string
>= 1 characters <= 255 characters /^[^\x00]*$/
submission_id
required

Identifier for the logical submission this record belongs to (tenant-scoped). Required. Enables grouping multi-field submissions and idempotent ingestion. Unique per (tenant_id, submission_id, field_id). If a record has no logical submission, use e.g. field_id.

string
>= 1 characters <= 255 characters /^[^\x00]*$/
tenant_id
required

Tenant/organization identifier for multi-tenancy. Required. U+FFFD is not allowed (it stands in for invalid UTF-8 or an unpaired surrogate).

string
>= 1 characters <= 255 characters /^[^\x00\uFFFD]*$/
user_id

User ID (e.g., anonymous ID or email hash)

string
<= 255 characters /^[^\x00]*$/
value_boolean

For yes/no questions

boolean
value_date

For date responses. Must be between 1970-01-01 and 2080-12-31.

string format: date-time
value_number

For ratings, NPS scores, numeric responses. Must be between -1e15 and +1e15.

number format: double
>= -1000000000000000 <= 1000000000000000
value_text

For open-ended text responses. Omit or null if not applicable. NULL bytes not allowed when present.

string | null
<= 30000 characters /^[^\x00]*$/
value_id

Stable id of the selected option in the source system (e.g. a survey choice id or matrix column id), stored alongside value_text so selected-choice answers keep a durable identity across label edits and languages. Opaque to Hub (not validated). Null for free-text/“other” answers, non-choice fields, and sources without option ids. NULL bytes not allowed when present.

string | null
<= 255 characters /^[^\x00]*$/

Examples

Rating feedback

{
"source_type": "survey",
"field_id": "q1",
"field_type": "rating",
"field_label": "How satisfied are you?",
"value_number": 9,
"source_id": "survey-123",
"source_name": "Q1 NPS Survey",
"user_id": "user-abc-123",
"tenant_id": "org-123",
"submission_id": "550e8400-e29b-41d4-a716-446655440000",
"language": "en"
}

Created

Media typeapplication/json
object
collected_at
required

When the feedback was collected

string format: date-time
created_at
required

When this record was created

string format: date-time
field_id
required

Identifier for the question/field

string
field_label

The actual question text

string
field_group_id

Stable identifier grouping related fields (for ranking, matrix, grid questions)

string
field_group_label

Human-readable question text for the group

string
field_type
required

Type of field

string
Allowed values: text categorical nps csat ces rating number boolean date
id
required

UUIDv7 primary key

string format: uuid
language

ISO language code. NULL bytes not allowed.

string
/^[^\x00]*$/
metadata

Arbitrary context stored with this record, returned with equivalent values (key order is normalized, and so are number exponents — 1e2 reads back as 100). 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 request schemas accept. The wider union is for reading: the column stores whatever JSON was written, so a record created before that convention can return an array or a scalar, and an object-only response schema would make a generated client reject it.

Array | object | string | number | boolean | null
sentiment

Sentiment polarity inferred from value_text (sentiment enrichment). Read-only; absent until the record is enriched.

string
Allowed values: very_negative negative neutral positive very_positive mixed
sentiment_score

Signed sentiment polarity from -1.0 (very negative) to 1.0 (very positive) (sentiment enrichment). Read-only; absent until the record is enriched.

number format: double
>= -1 <= 1
taxonomy
Any of:
object
status
required
string
Allowed values: classified unclassified no_active_taxonomy
run_id
required
One of:
string format: uuid
path
required

Current visible non-root nodes in root-to-leaf order; empty unless classified.

Array<object>
object
id
required
string format: uuid
label
required
string
level
required
integer format: int64
node_type
required
string
Allowed values: branch leaf
emotions

Emotions inferred from value_text (emotion enrichment); multi-label from a fixed set. Read-only; absent until the record is enriched, and never an empty array.

Array<string>
>= 1 items
Allowed values: joy anger sadness fear surprise disgust
source_id

Reference to survey/form/ticket ID

string
source_name

Human-readable name

string
source_type
required

Type of feedback source

string
submission_id
required

Identifier for the logical submission this record belongs to (required).

string
/^[^\x00]*$/
tenant_id
required

Tenant/organization identifier. NULL bytes not allowed.

string
/^[^\x00]*$/
translation_lang_key

BCP-47 target locale that value_text_translated was produced in (language enrichment). Read-only; absent until the record is enriched.

string
<= 35 characters
updated_at
required

When this record was last updated

string format: date-time
user_id

User ID (e.g., anonymous ID or email hash)

string
value_boolean

Boolean response

boolean
value_date

Date response

string format: date-time
value_number

Numeric response

number format: double
value_text

Text response. NULL bytes not allowed.

string
/^[^\x00]*$/
value_id

Stable id of the selected option in the source system (e.g. a survey choice id), stored alongside value_text for durable option identity. Opaque to Hub. Absent for free-text/non-choice answers. NULL bytes not allowed.

string
/^[^\x00]*$/
value_text_translated

Value_text translated into the tenant’s configured target language (language enrichment). Read-only; absent until the record is enriched.

string
/^[^\x00]*$/

Examples

Examplecreated

Created feedback record

{
"id": "018e1234-5678-9abc-def0-123456789abc",
"collected_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"source_type": "survey",
"field_id": "q1",
"field_type": "rating",
"field_label": "How satisfied are you?",
"value_number": 9,
"source_id": "survey-123",
"source_name": "Q1 NPS Survey",
"user_id": "user-abc-123",
"tenant_id": "org-123",
"submission_id": "550e8400-e29b-41d4-a716-446655440000",
"language": "en"
}

Bad Request (e.g. validation error)

Media typeapplication/problem+json

RFC 9457 problem details (application/problem+json). Branch on the stable code member rather than on title or type.

object
code
required

Stable, machine-readable error code; the primary value to branch on. service_unavailable indicates a feature or dependency is temporarily unavailable and the request may be retried later. tenant_write_conflict indicates the write conflicted with an in-progress tenant data purge (or vice versa) and may be retried later unchanged. All other codes are terminal until the request itself is changed.

string
Allowed values: validation bad_request unauthorized forbidden not_found conflict tenant_write_conflict method_not_allowed content_too_large service_unavailable internal_server_error
detail

A human-readable explanation specific to this occurrence of the problem.

string
details

Optional structured context for this problem, e.g. resource_type on a 404.

object
key
additional properties
any
instance

A URI reference (typically the request path) identifying the specific occurrence of the problem.

string
invalid_params

Field-level validation failures (RFC 9457 “invalid_params” extension). Present on validation errors.

Array<object>
<= 100 items

A single invalid request parameter (RFC 9457 “invalid_params” extension member).

object
name
required

Dotted path to the offending request field, e.g. ‘field_type’ or ‘items[0].field_type’.

string
reason
required

Human- and agent-readable explanation of why the value is invalid, naming allowed values or constraints where applicable so the request can be corrected without guessing.

string
request_id
required

Identifier for this request, also returned in the X-Request-ID response header; include it when reporting a problem.

string
status
required

HTTP status code

integer format: int64
title
required

A short, human-readable summary of the problem type. This value should not change between occurrences of the error.

string
type

A URI reference identifying the problem type.

string format: uri

Examples

Exampleinvalid_field_type

Invalid field_type enum

{
"type": "https://hub.formbricks.com/problems/validation",
"title": "Validation Error",
"status": 400,
"code": "validation",
"detail": "One or more request parameters are invalid",
"instance": "/v1/feedback-records",
"request_id": "0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"invalid_params": [
{
"name": "field_type",
"reason": "has invalid value \"textt\"; must be one of: text, categorical, nps, csat, ces, rating, number, boolean, date"
}
]
}

Conflict. Either a duplicate tenant_id/submission_id/field_id (code conflict, terminal), or a tenant data purge is in progress for this tenant (code tenant_write_conflict, retryable – retry after the purge completes).

Media typeapplication/problem+json

RFC 9457 problem details (application/problem+json). Branch on the stable code member rather than on title or type.

object
code
required

Stable, machine-readable error code; the primary value to branch on. service_unavailable indicates a feature or dependency is temporarily unavailable and the request may be retried later. tenant_write_conflict indicates the write conflicted with an in-progress tenant data purge (or vice versa) and may be retried later unchanged. All other codes are terminal until the request itself is changed.

string
Allowed values: validation bad_request unauthorized forbidden not_found conflict tenant_write_conflict method_not_allowed content_too_large service_unavailable internal_server_error
detail

A human-readable explanation specific to this occurrence of the problem.

string
details

Optional structured context for this problem, e.g. resource_type on a 404.

object
key
additional properties
any
instance

A URI reference (typically the request path) identifying the specific occurrence of the problem.

string
invalid_params

Field-level validation failures (RFC 9457 “invalid_params” extension). Present on validation errors.

Array<object>
<= 100 items

A single invalid request parameter (RFC 9457 “invalid_params” extension member).

object
name
required

Dotted path to the offending request field, e.g. ‘field_type’ or ‘items[0].field_type’.

string
reason
required

Human- and agent-readable explanation of why the value is invalid, naming allowed values or constraints where applicable so the request can be corrected without guessing.

string
request_id
required

Identifier for this request, also returned in the X-Request-ID response header; include it when reporting a problem.

string
status
required

HTTP status code

integer format: int64
title
required

A short, human-readable summary of the problem type. This value should not change between occurrences of the error.

string
type

A URI reference identifying the problem type.

string format: uri

Example

{
"code": "validation",
"detail": "One or more request parameters are invalid",
"instance": "/v1/feedback-records",
"invalid_params": [
{
"name": "field_type",
"reason": "must be one of: text, categorical, nps, csat, ces, rating, number, boolean, date"
}
],
"request_id": "0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"status": 400,
"title": "Bad Request",
"type": "https://hub.formbricks.com/problems/bad-request"
}

Request body exceeds the maximum allowed size.

Media typeapplication/problem+json

RFC 9457 problem details (application/problem+json). Branch on the stable code member rather than on title or type.

object
code
required

Stable, machine-readable error code; the primary value to branch on. service_unavailable indicates a feature or dependency is temporarily unavailable and the request may be retried later. tenant_write_conflict indicates the write conflicted with an in-progress tenant data purge (or vice versa) and may be retried later unchanged. All other codes are terminal until the request itself is changed.

string
Allowed values: validation bad_request unauthorized forbidden not_found conflict tenant_write_conflict method_not_allowed content_too_large service_unavailable internal_server_error
detail

A human-readable explanation specific to this occurrence of the problem.

string
details

Optional structured context for this problem, e.g. resource_type on a 404.

object
key
additional properties
any
instance

A URI reference (typically the request path) identifying the specific occurrence of the problem.

string
invalid_params

Field-level validation failures (RFC 9457 “invalid_params” extension). Present on validation errors.

Array<object>
<= 100 items

A single invalid request parameter (RFC 9457 “invalid_params” extension member).

object
name
required

Dotted path to the offending request field, e.g. ‘field_type’ or ‘items[0].field_type’.

string
reason
required

Human- and agent-readable explanation of why the value is invalid, naming allowed values or constraints where applicable so the request can be corrected without guessing.

string
request_id
required

Identifier for this request, also returned in the X-Request-ID response header; include it when reporting a problem.

string
status
required

HTTP status code

integer format: int64
title
required

A short, human-readable summary of the problem type. This value should not change between occurrences of the error.

string
type

A URI reference identifying the problem type.

string format: uri

Example

{
"code": "validation",
"detail": "One or more request parameters are invalid",
"instance": "/v1/feedback-records",
"invalid_params": [
{
"name": "field_type",
"reason": "must be one of: text, categorical, nps, csat, ces, rating, number, boolean, date"
}
],
"request_id": "0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"status": 400,
"title": "Bad Request",
"type": "https://hub.formbricks.com/problems/bad-request"
}

Error

Media typeapplication/problem+json

RFC 9457 problem details (application/problem+json). Branch on the stable code member rather than on title or type.

object
code
required

Stable, machine-readable error code; the primary value to branch on. service_unavailable indicates a feature or dependency is temporarily unavailable and the request may be retried later. tenant_write_conflict indicates the write conflicted with an in-progress tenant data purge (or vice versa) and may be retried later unchanged. All other codes are terminal until the request itself is changed.

string
Allowed values: validation bad_request unauthorized forbidden not_found conflict tenant_write_conflict method_not_allowed content_too_large service_unavailable internal_server_error
detail

A human-readable explanation specific to this occurrence of the problem.

string
details

Optional structured context for this problem, e.g. resource_type on a 404.

object
key
additional properties
any
instance

A URI reference (typically the request path) identifying the specific occurrence of the problem.

string
invalid_params

Field-level validation failures (RFC 9457 “invalid_params” extension). Present on validation errors.

Array<object>
<= 100 items

A single invalid request parameter (RFC 9457 “invalid_params” extension member).

object
name
required

Dotted path to the offending request field, e.g. ‘field_type’ or ‘items[0].field_type’.

string
reason
required

Human- and agent-readable explanation of why the value is invalid, naming allowed values or constraints where applicable so the request can be corrected without guessing.

string
request_id
required

Identifier for this request, also returned in the X-Request-ID response header; include it when reporting a problem.

string
status
required

HTTP status code

integer format: int64
title
required

A short, human-readable summary of the problem type. This value should not change between occurrences of the error.

string
type

A URI reference identifying the problem type.

string format: uri

Example

{
"code": "validation",
"detail": "One or more request parameters are invalid",
"instance": "/v1/feedback-records",
"invalid_params": [
{
"name": "field_type",
"reason": "must be one of: text, categorical, nps, csat, ces, rating, number, boolean, date"
}
],
"request_id": "0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b",
"status": 400,
"title": "Bad Request",
"type": "https://hub.formbricks.com/problems/bad-request"
}