Members
Manage who has access to a project, and at what role — console session only, no API key path.
Members are the people with access to a project through the console. This is a session-only surface — there is no way to manage members with a project API key or a scoped key, even a read.
Authentication
Section titled “Authentication”Every endpoint below requires the trackly_session cookie from a logged-in console user. A project API key
(legacy pair or scoped) gets no access at all here, not even GET — this differs from
Projects, where the two read routes do accept a project key.
List members
Section titled “List members”GET https://retidal.com/api/projects/{projectId}/membersRequires any project role. Returns the member list and currentUserRole for the caller.
Add a member
Section titled “Add a member”POST /api/projects/{projectId}/membersRequires project ADMIN.
{ "email": "teammate@yourcompany.com", "role": "VIEWER" }emailstringrequiredMust belong to a user who already has an account in the same tenant. There is no “invite a brand-new person directly onto a project” path — a person outside the tenant has to be invited to the tenant first (a separate, tenant-level invitation flow, not covered by this project-scoped endpoint).
rolestringADMIN | EDITOR | VIEWER. Default VIEWER.
POST /api/projects/{projectId}/members returns 409 if the user is already a project member, 404 if
the user doesn’t exist, 400 if the user exists but isn’t in the project’s tenant.
Change a member’s role
Section titled “Change a member’s role”PUT /api/projects/{projectId}/members/{memberId}Requires project ADMIN. Body: { "role": "ADMIN" | "EDITOR" | "VIEWER" }.
The OWNER's role can't be changed here
PUT /api/projects/{projectId}/members/{memberId} can move anyone between ADMIN/EDITOR/VIEWER, but
the project’s OWNER is immutable through this route — attempting it returns 403. Ownership transfer is
a separate, tenant-level operation.
Remove a member
Section titled “Remove a member”DELETE /api/projects/{projectId}/members/{memberId}Requires project ADMIN. On DELETE /api/projects/{projectId}/members/{memberId}, the OWNER cannot be
removed (403).
Role reference
Section titled “Role reference”| Role | Can do |
|---|---|
VIEWER |
Read analytics, campaigns, links, project events — anything gated to VIEWER+. |
EDITOR |
Everything VIEWER can, plus create/update most resources (templates, triggers, links, platforms). |
ADMIN |
Everything EDITOR can, plus destructive operations (delete), member management, project settings, scoped API keys. |
OWNER |
Everything ADMIN can, plus delete the project and transfer ownership. Exactly one per project; immutable through the members endpoints above. |
Two resource groups deviate from the usual EDITOR-writes/ADMIN-deletes pattern, worth knowing if you’re handing out roles by task rather than by trust level:
- Custom domains (
/api/projects/{projectId}/domains) require EDITOR for every route, includingGET— it’s the one resource group with no VIEWER-readable path. - Derived rules (
/api/projects/{projectId}/derived-rules) require ADMIN for all writes, where most other resources only need EDITOR.
Next steps
Section titled “Next steps”Project details, the legacy key pair, and scoped API keys.
Analytics, funnels, retention, and the user/value-user directory.