Projects & sources
A project is a namespace inside a tenant. A source is one thing that sends into it, with its own token.
Projects
GET /v1/projects lists every project the tenant owns, name-ordered, each with name, config_version, sources, rules, open_alerts and created_at. Paginate with limit and after, passing the last name on the previous page.
POST /v1/projects with {"name": "…"} creates one. Projects are explicit rows: a typo in a path is a 404, never a project created by accident.
POST /v1/projects/{id}/rename and DELETE /v1/projects/{id} are owner or admin only. Renaming does not break ingest tokens, which resolve through the source row. Deleting removes the project’s sources, rules, alerts and reports; a report’s public page stops resolving.
Sources
| Field | Meaning |
|---|---|
name | The source’s identity. Appears on every line and can be matched by rules. |
retain_logs | Keep raw lines for the log tail. Off by default. Required explicitly on update. |
created_at |
POST /v1/projects/{id}/sources creates one and returns its pti_ ingest token. The token is shown once; there is no route that reads it back.
POST /v1/projects/{id}/sources/{name}/rotate-token mints a new token and invalidates the old one immediately, with no overlap window, so deploy the new token to the sender first and rotate second if a gap matters. Owner or admin only.
DELETE /v1/projects/{id}/sources/{name} is refused with 409 while a rule’s match.sources still names it.
How to split things up
- One project per thing you would page separately. A service, an environment, a customer. Open-alert counts and the app’s project filter work at this level.
- One source per sender. Each app instance, host or probe gets its own token, so a leaked or retired one can be rotated without touching the rest, and rules can tell them apart.
- Tags for everything else. Region, tier, customer: put it in
tagson the line and match on it in the rule.
distinct_sources, or watch the agent’s heartbeat from something else.