Projects
The tenant boundary — project details, the legacy key pair, and scoped API keys.
A project is the isolation boundary for everything in Retidal: every event, campaign, short link, and
email lives under exactly one projectId, and every management path is scoped to
/api/projects/{projectId}/....
Authentication on this page
Section titled “Authentication on this page”Project management is mostly a console session (trackly_session cookie) surface. Two read routes are
the exception — they also accept the project’s own legacy API key:
| Route | Accepts a project API key? |
|---|---|
GET /api/projects |
Yes — returns only that key’s own project. |
GET /api/projects/{projectId} |
Yes — read-only. |
| Everything else on this page (update, regenerate keys, manage scoped keys) | No — session cookie only. |
See Authentication for the full model.
Get and update a project
Section titled “Get and update a project”GET https://retidal.com/api/projects/{projectId}PUT https://retidal.com/api/projects/{projectId}GET returns the safe project shape to VIEWER/EDITOR callers, and additionally includes the project’s
apiKey/apiSecret when the caller has role ADMIN or OWNER (or is that project’s own API key).
PUT (requires ADMIN) updates name, description, and domain — all optional, description/domain
nullable.
Creating and deleting a project aren't API-key operations at all
POST /api/projects requires a tenant ADMIN role (not a project role) and a name + slug — it’s how
a new project gets its apiKey/apiSecret minted in the first place, so naturally it can’t be
authenticated with a project key that doesn’t exist yet. DELETE /api/projects/{projectId} requires
project OWNER specifically — ADMIN is not enough. Both are console-only actions; there’s no
script-friendly path around them.
Regenerate the legacy key pair
Section titled “Regenerate the legacy key pair”POST /api/projects/{projectId}/regen-keyRequires ADMIN. Rotates the project’s apiKey/apiSecret — the pair used as X-API-Key on the
ingestion API and (where a project key is accepted) on read-only console routes.
The old pair is invalidated immediately with no overlap window; update every deployed integration before
you rotate, not after.
This is a distinct credential from the scoped API keys below.
Scoped API keys
Section titled “Scoped API keys”GET /api/projects/{projectId}/api-keysPOST /api/projects/{projectId}/api-keys (ADMIN)PATCH /api/projects/{projectId}/api-keys/{id} (ADMIN)DELETE /api/projects/{projectId}/api-keys/{id} (ADMIN)A scoped key is a second, independent kind of credential: it carries an explicit list of capability scopes
instead of a project role, and is used as X-API-Key (no secret) on the ingestion/decisioning surface and on
the MCP server.
{ "name": "Backend event forwarder", "scopes": ["ingest:write", "decision:call"] }namestringrequired1–120 characters.
scopesarrayrequiredAt least one of: ingest:write, tracking:ingest, decision:call, decision:read, profile:write,
coupon:redeem, coupon:read, metrics:read, metrics:write, mcp:events_read, mcp:events_write,
mcp:links_write, mcp:attribution_read.
The raw key is shown exactly once
POST returns the raw key string in the response body — that’s the only time it’s ever visible. GET
always returns keys masked. Store it in your secret manager immediately; there’s no recovery endpoint.
PATCH updates scopes and/or name (at least one required) and invalidates the credential cache
immediately, so a scope change takes effect on the next request rather than waiting out a TTL. DELETE /api/projects/{projectId}/api-keys/{id} revokes a key; it’s idempotent — revoking an already-revoked key
still returns 200.
Roles at a glance
Section titled “Roles at a glance”Project roles form a strict hierarchy: VIEWER < EDITOR < ADMIN < OWNER. A project API key (the legacy
pair, not a scoped key) authenticates the two read routes above as if it were the project itself — it never
satisfies an OWNER-only check (delete project, transfer ownership), which is why project deletion is
console-only.
Next steps
Section titled “Next steps”Who has which role on this project, and how to change it.
Analytics, funnels, retention, and the user/value-user directory.