Skip to content

Purge all feedback records for a tenant

DELETE
/v1/tenants/{tenant_id}/feedback-records
curl --request DELETE \
--url http://localhost:8080/v1/tenants/org-123/feedback-records \
--header 'Authorization: Bearer <token>'

Permanently deletes every feedback record for the specified tenant_id, everything derived from those records — embeddings and the enrichment stored on each record (sentiment, emotions, translations) — and the taxonomy built on them: runs, clusters, nodes, cluster memberships, active-run pointers and node events.

This is intended for emptying a dataset that stays in use, so it removes the tenant’s DATA but never its CONFIGURATION: webhooks and tenant settings are left untouched. That is the difference from DELETE /v1/tenants/{tenant_id}/data, which additionally deletes both and is meant for offboarding a deprovisioned tenant.

The taxonomy is removed rather than preserved because it describes records that no longer exist: its per-node counts are derived from memberships and would all read zero, while a run’s own stored counters (record_count, cluster_count, a cluster’s size) are historical and would keep advertising the old numbers. A new taxonomy can be generated once the dataset has enough feedback again; manual node renames and removals are per-run and do not survive a regeneration in any case.

The tenant is a required path segment, so it cannot be omitted the way a filter on a collection delete could be — dropping it routes elsewhere rather than widening the operation to every tenant.

Asynchronous: the request schedules the purge and returns 202 immediately, because the deletion is unbounded and can outlive a request. There is therefore no deleted count in the response. Poll GET /v1/feedback-records/count?tenant_id=... to observe progress.

The purge removes only the records that existed when it started — it takes a high-water mark up front — so feedback ingested while it runs is never deleted. For a dataset that is no longer receiving feedback the count reaching zero means the purge is complete; for one still ingesting, a nonzero count is those newer records. Note this means the count alone cannot distinguish “finished” from “failed” on an active dataset.

Idempotent and safe to repeat. Requesting a purge while one is already running for the same tenant joins the running purge rather than queueing a second one, and still returns 202. A purge requested after an earlier one finished starts a new run.

Records are deleted in committed batches, so a purge interrupted by a restart or a timeout keeps the progress it made and resumes on retry; the taxonomy is removed in a final step once the records are gone. While each step runs, the tenant’s write lock is held exclusively and Hub-owned writes for that tenant are rejected with HTTP 409 (code tenant_write_conflict); the lock is released between steps, and writes for other tenants are never affected. This does not apply to the request below — scheduling a purge takes no lock, so this endpoint does not return 409. A batch that cannot acquire the lock is retried by the job queue without any caller action, up to a bounded number of attempts.

No webhook events are published for a purge, and no webhooks are deleted. Enrichment jobs already queued for purged records no-op when they run, since the record they reference is gone.

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

Example

org-123

Tenant ID whose feedback records should be purged. Empty strings and NULL bytes are not allowed.

Purge accepted and scheduled

Media typeapplication/json
object
tenant_id
required

Tenant ID whose feedback records are being purged

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

Always accepted. The purge runs in the background, so this reports that the work was scheduled, not that it finished — poll GET /v1/feedback-records/count for the tenant to observe completion.

string
Allowed values: accepted
message

Human-readable confirmation

string

Examples

Exampleaccepted

Purge accepted

{
"tenant_id": "org-123",
"status": "accepted",
"message": "Feedback records purge accepted for org-123"
}

Bad Request (e.g. missing or invalid tenant_id)

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"
}

Unauthorized (missing or invalid API key)

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"
}