Studies
The API is the same one the product uses. There is no second public API that drifts from an internal one, because there is no internal one — which is why an endpoint here cannot be behind what the dashboard does.
Endpoints
GET /api/v1/studies ?project=&status=&cursor= POST /api/v1/studies GET /api/v1/studies/:id PATCH /api/v1/studies/:id status, name — never definition POST /api/v1/studies/:id/publish POST /api/v1/studies/:id/duplicate DELETE /api/v1/studies/:id requires an explicit confirmation flag GET /api/v1/studies/:id/responses ?cursor=&since= GET /api/v1/studies/:id/export.csv GET /api/v1/studies/:id/analysis the analyse() output, per block
Pagination is cursor-based, everywhere
Offset pagination over a table that participants are writing to skips and repeats rows. For a research tool that means an export which silently omits responses, which is the one failure this product exists to avoid.
Scopes
A key’s effective permission is the intersection of its scopes and the role of whoever created it. A researcher’s key cannot delete a study, because the researcher cannot.
studies:read studies:write responses:read responses:write library:read library:write insights:read insights:write org:read
Errors
An expired token returns 401 token_expired, distinguishable from token_revoked and insufficient_scope — three different fixes deserve three different codes.