API reference
API plan access: External personal/service tokens require the workspace’s configured api capability (Pro by default). New issuance and bearer requests return pro_required when it is unavailable. Roles, scopes and project restrictions still apply. Free browser authoring, public collection, documentation, token inventory and revocation remain available. Downgrade retains credentials; eligible recovery restores unexpired, unrevoked tokens without resetting usage.
Open the interactive OpenAPI reference to browse the public API routes and schemas, or download the OpenAPI JSON.
JSON request bodies
The API accepts JSON objects for survey creation, draft saving, project and workspace creation, profile updates, token issuance and invitations. Set Content-Type: application/json. Validation and publication are POST endpoints without bodies; they use the current saved draft. Google sign-in uses GET redirects, and sign-out is a bodyless POST.
Create and publish a survey in this order:
- Create:
POST /api/v1/projects/{projectId}/surveys. - Read the draft:
GET /api/v1/surveys/{surveyId}. - Save your changes:
PUT /api/v1/surveys/{surveyId}/draft. - Validate:
POST /api/v1/surveys/{surveyId}/validate. - Publish:
POST /api/v1/surveys/{surveyId}/publish.
See authentication for cookies, CSRF, token scopes, and roles. See creating surveys for complete examples.
Access and retry rules
OpenAPI describes supported contracts; schema validity does not replace graph validation, current permissions, live collection gates or optimistic revision checks. Error envelopes normally have error.code and error.message. Shared error responses list possible API failures, not a promise that every route emits every status.
| Operation family | Credential and permission | Retry or concurrency rule |
|---|---|---|
| Published content | Public reads; live gates still apply | Published definitions/pages are versioned; collection/protection remain live. |
| Project read | Session membership or projects:read | Workspace and optional project restriction apply on every request. |
| Survey create/read/save/validate/publish | Session editor or the respective survey scope | Draft revision protects saves. Create and publication do not promise universal idempotency. |
| Tracked link and QR reads | Session membership or surveys:read | Creation/rename and live collection/protection/embed updates are session-only. |
| Results, reports and CSV | Session membership or responses:read; report/brief writes also need reports:write and editor role | Snapshot/after cursors are actor-scoped. Report creation requires Idempotency-Key. Brief writes use revision. |
| Workspace/profile/token/team settings | Signed-in session, appropriate membership/role and write CSRF | Tokens cannot administer workspaces or create projects. Personal workspaces cannot invite teammates. |
| Research deletion | Workspace owner session and write CSRF | Request key plus explicit confirmation; advance resumes one bounded batch. |
| Billing | Owner/admin session for reads; owner session and CSRF for Checkout/portal | Request key identifies one intention; return URLs never grant Pro. |
Token scopes are independent: surveys:publish cannot validate without surveys:write, and surveys:* does not grant results access. Use authentication for the sorted scope list and wildcard rules.
Browser session writes require CSRF even on routes that also accept bearer tokens. Response collection is handled by the hosted survey or embed, not the developer integration API.
Endpoint inventory
The following inventory is kept in sync with the published OpenAPI contract. Request/response names refer to schemas in the interactive reference. — means no JSON body. Admin, HTML application pages, widget scripts, images and static assets are outside this API inventory.
| Method | Path | Access | Request | Success response | |
|---|---|---|---|---|---|
| GET | /api/docs | public | — | 200 Html | |
| GET | /api/health | public | — | 200 Health | |
| GET | /api/openapi.json | public | — | 200 OpenApi | |
| GET | /api/openapi.yaml | public | — | 200 OpenApi | |
| POST | /api/v1/invitations/accept | session | InvitationAccept | 200 InvitationAccepted | |
| GET | /api/v1/me | session | — | 200 Me | |
| PUT | /api/v1/me/avatar | session | AvatarInput | 200 AvatarResult | |
| PUT | /api/v1/me/profile | session | ProfileInput | 200 ProfileResult | |
| GET | /api/v1/projects | token | — | 200 Projects | |
| POST | /api/v1/projects | session | ProjectInput | 201 ProjectCreated | |
| PATCH | /api/v1/projects/{projectId} | session | ProjectUpdate | 200 ProjectResult | |
| GET | /api/v1/projects/{projectId} | token | — | 200 ProjectResult | |
| GET | /api/v1/projects/{projectId}/research-deletions | session | — | 200 DeletionPreview | |
| POST | /api/v1/projects/{projectId}/research-deletions | session | DeletionInput | 202 DeletionJob | |
| GET | /api/v1/projects/{projectId}/research-deletions/{deletionId} | session | — | 200 DeletionJob | |
| POST | /api/v1/projects/{projectId}/research-deletions/{deletionId}/advance | session | EmptyInput | 200 DeletionJob | |
| GET | /api/v1/projects/{projectId}/surveys | token | — | 200 Surveys | |
| POST | /api/v1/projects/{projectId}/surveys | token | SurveyCreate | 201 SurveyCreated | |
| GET | /api/v1/public/{workspace}/{project}/{survey} | public | — | 200 SurveyDefinition | |
| GET | /api/v1/public/{workspace}/{project}/{survey}/page | public | — | 200 SurveyPage | |
| PATCH | /api/v1/survey-links/{linkId} | session | SurveyLinkRename | 200 SurveyLink | |
| GET | /api/v1/survey-links/{linkId}/qr.png | token | — | 200 QrPng | |
| GET | /api/v1/survey-links/{linkId}/qr.svg | token | — | 200 QrSvg | |
| GET | /api/v1/surveys/{surveyId} | token | — | 200 SurveyDraft | |
| GET | /api/v1/surveys/{surveyId}/analysis-runs | token | — | 200 AnalysisRunList | |
| POST | /api/v1/surveys/{surveyId}/analysis-runs | token | AnalysisRunInput | 201 AnalysisRun | |
| GET | /api/v1/surveys/{surveyId}/analysis-runs/{runId} | token | — | 200 AnalysisRun | |
| PUT | /api/v1/surveys/{surveyId}/collection | session | CollectionInput | 200 CollectionWindow | |
| GET | /api/v1/surveys/{surveyId}/draft | token | — | 200 SurveyDraft | |
| PUT | /api/v1/surveys/{surveyId}/draft | token | DraftInput | 200 DraftSaved | |
| GET | /api/v1/surveys/{surveyId}/embeds | session | — | 200 EmbedSettings | |
| PUT | /api/v1/surveys/{surveyId}/embeds | session | EmbedInput | 200 EmbedSettings | |
| GET | /api/v1/surveys/{surveyId}/exports/aggregates.csv | token | — | 200 Csv | |
| GET | /api/v1/surveys/{surveyId}/exports/codebook.csv | token | — | 200 Csv | |
| GET | /api/v1/surveys/{surveyId}/exports/responses.csv | token | — | 200 Csv | |
| GET | /api/v1/surveys/{surveyId}/link-results | token | — | 200 LinkResults | |
| GET | /api/v1/surveys/{surveyId}/links | token | — | 200 SurveyLinks | |
| POST | /api/v1/surveys/{surveyId}/links | session | SurveyLinkInput | 201 SurveyLink | |
| GET | /api/v1/surveys/{surveyId}/protection | session | — | 200 ProtectionSettings | |
| PUT | /api/v1/surveys/{surveyId}/protection | session | ProtectionInput | 200 ProtectionSettings | |
| POST | /api/v1/surveys/{surveyId}/publish | token | — | 200 Published | |
| GET | /api/v1/surveys/{surveyId}/research-brief | token | — | 200 ResearchBriefResult | |
| PUT | /api/v1/surveys/{surveyId}/research-brief | token | ResearchBriefInput | 200 ResearchBriefResult | |
| GET | /api/v1/surveys/{surveyId}/research-deletions | session | — | 200 DeletionPreview | |
| POST | /api/v1/surveys/{surveyId}/research-deletions | session | DeletionInput | 202 DeletionJob | |
| GET | /api/v1/surveys/{surveyId}/research-deletions/{deletionId} | session | — | 200 DeletionJob | |
| POST | /api/v1/surveys/{surveyId}/research-deletions/{deletionId}/advance | session | EmptyInput | 200 DeletionJob | |
| GET | /api/v1/surveys/{surveyId}/results | token | — | 200 Results | |
| POST | /api/v1/surveys/{surveyId}/validate | token | — | 200 Validated | |
| GET | /api/v1/plans | public | — | 200 PublicPlans | |
| GET | /api/v1/workspaces | session | — | 200 WorkspaceList | |
| POST | /api/v1/workspaces/personal | session | WorkspaceCreate | 201 WorkspaceCreated | |
| POST | /api/v1/workspaces/team | session | TeamWorkspaceCreate | 201 WorkspaceCreated | |
| GET | /api/v1/workspaces/{id}/billing | session | — | 200 WorkspaceUsage | |
| POST | /api/v1/workspaces/{id}/billing/checkout | session | EmptyInput | 200 BillingRedirect | |
| POST | /api/v1/workspaces/{id}/billing/portal | session | EmptyInput | 200 BillingRedirect | |
| PATCH | /api/v1/workspaces/{workspaceId} | session | WorkspaceRename | 200 WorkspaceRenamed | |
| GET | /api/v1/workspaces/{workspaceId}/audit | session | — | 200 Audit | |
| GET | /api/v1/workspaces/{workspaceId}/invitations | session | — | 200 Invitations | |
| POST | /api/v1/workspaces/{workspaceId}/invitations | session | InvitationInput | 201 InvitationCreated | |
| GET | /api/v1/workspaces/{workspaceId}/members | session | — | 200 Members | |
| DELETE | /api/v1/workspaces/{workspaceId}/members/{userId} | session | — | 204 — | |
| PATCH | /api/v1/workspaces/{workspaceId}/members/{userId} | session | MemberRoleInput | 200 MemberRoleResult | |
| GET | /api/v1/workspaces/{workspaceId}/features | Read effective workspace capabilities | Browser session | — | WorkspaceFeatures |
| GET | /api/v1/workspaces/{workspaceId}/included-team | Read included-team selection | Browser session | — | IncludedTeamDetails |
| PUT | /api/v1/workspaces/{workspaceId}/included-team | Select the included team | Browser session | IncludedTeamSelection | IncludedTeamDetails |
| GET | /api/v1/workspaces/{workspaceId}/tokens | session | — | 200 Tokens | |
| POST | /api/v1/workspaces/{workspaceId}/tokens | session | TokenInput | 201 TokenCreated | |
| DELETE | /api/v1/workspaces/{workspaceId}/tokens/{tokenId} | session | — | 204 — |
Authentication routes, provider webhook receivers and platform administration are excluded from this public contract.