curl --request POST \
--url https://app.formbricks.com/api/v3/surveys/{surveyId}/visibility \
--header 'Content-Type: application/json' \
--cookie next-auth.session-token= \
--data '
{
"visibility": "workspace"
}
'{
"data": {
"id": "clsv2234567890123456789012",
"visibility": "workspace",
"owner": {
"name": "Bob Example"
},
"access": {
"via": "workspace",
"canManageVisibility": true
},
"version": 3,
"pending": null,
"changedAt": "2026-09-21T10:15:00.000Z",
"changedBy": {
"type": "user",
"id": "clus2234567890123456789012",
"name": "Bob Example"
}
}
}Change a survey's visibility
Sets the survey to restricted or workspace.
Restrictions take effect at once. A workspace → restricted request stores the flag, a new version and a pending marker in one transaction. From that instant the survey is restricted on every path — single reads, lists and counts, responses, exports — for everyone but the owner and the organisation’s owners and managers, whether or not the graph has caught up (fail closed). The owner keeps only the access their workspace role gives them — read to view, write to edit; an owner who loses workspace access loses the survey too. The relationships are then projected; the answer is 200 either way, with pending: null when the graph acknowledged this version inside the request and pending: "restricted" when the outbox will finish it.
Grants take effect when enforced. A restricted → workspace request answers 200 only once the graph has acknowledged this exact version; until then the survey stays restricted. If the in-request projection fails, the answer is 503 projection_pending: the change is stored and queued, GET …/visibility shows pending: "workspace", and retrying is safe.
Fencing. Every accepted change increments the survey’s version. Projection work carries the version it was issued for, and a projector holding an older version never writes, so a worker leased before a newer change cannot overtake it — including one that crashed before its verification pass. A 200 for a grant means the graph holds this exact version.
No-ops and cancellation. Requesting the value the survey already enforces, with nothing pending, is a 200 no-op: nothing is written or audited and changedAt / changedBy are unchanged. Requesting the enforced value while the opposite is pending cancels the pending change: a new version is stored, the queued work is superseded, and the answer is 200 with pending: null. Requesting the pending value again re-attempts the projection (200 or 503).
When restricted is refused for two reasons at once — no owner and outbound connections — the 422 wins: the missing owner cannot be fixed, so listing connections to remove would send the caller down a dead end.
Allowed for the survey’s owner (while they still hold read access to the workspace) and for the organisation’s owners and managers. Not for workspace members with write or team-level manage rights, and never for API keys. Every successful change is audit-logged with the actor.
Going workspace → restricted is refused with 409 while any outbound connection depends on the survey; resolve them first. It is refused with 422 when the survey has no owner, because “restricted” would then mean “administrators only” — duplicate the survey for a restricted copy. Going restricted → workspace has no preconditions.
This is the only way to change visibility: PATCH /api/v3/surveys/{surveyId} accepts visibility, owner and access only as the exact values GET returned (so a fetched survey round-trips), and rejects any other value as an unsupported field. Publishing does not change visibility; the publish dialogue chains this call before the status change.
curl --request POST \
--url https://app.formbricks.com/api/v3/surveys/{surveyId}/visibility \
--header 'Content-Type: application/json' \
--cookie next-auth.session-token= \
--data '
{
"visibility": "workspace"
}
'{
"data": {
"id": "clsv2234567890123456789012",
"visibility": "workspace",
"owner": {
"name": "Bob Example"
},
"access": {
"via": "workspace",
"canManageVisibility": true
},
"version": 3,
"pending": null,
"changedAt": "2026-09-21T10:15:00.000Z",
"changedBy": {
"type": "user",
"id": "clus2234567890123456789012",
"name": "Bob Example"
}
}
}Authorizations
NextAuth session JWT cookie. Development: often next-auth.session-token.
Production (HTTPS): often __Secure-next-auth.session-token. Send the cookie your browser receives after sign-in.
Path Parameters
Survey identifier.
Body
restricted: readable by the owner and the organisation's owners and managers only. The owner's access is conditional on their workspace access, level for level: they read the survey only while they can read the workspace, and edit it only while they can write to it — being the owner grants nothing the workspace does not. workspace: readable by everyone with access to the workspace — today's behaviour.
restricted, workspace Response
Visibility changed, or already at the requested value
The three fields every SurveyListItem and SurveyResource carries, merged into both via allOf. All required, always present.
Show child attributes
Show child attributes
Was this page helpful?