# Projects & sources

Source: https://www.pingtower.com/docs/service/projects/

A project is a namespace inside a tenant. A source is one thing that sends into it, with its own token.

## Projects

<span class="pill get">GET</span> `/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.

<span class="pill post">POST</span> `/v1/projects` with `{"name": "…"}` creates one. Projects are explicit rows: a typo in a path is a `404`, never a project created by accident.

<span class="pill post">POST</span> `/v1/projects/{id}/rename` and <span class="pill del">DELETE</span> `/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](/docs/service/logtail/). Off by default. Required explicitly on update. |
| `created_at` | |

<span class="pill post">POST</span> `/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.

<span class="pill post">POST</span> `/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.

<span class="pill del">DELETE</span> `/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 `tags` on the line and match on it in the rule.

<div class="docs-callout note"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><circle cx="8" cy="8" r="6.5"/><path d="M8 7v4M8 5v.5"/></svg><div><span class="t">Sources that go quiet</span>Nothing in the service alerts on silence. A source that stops sending, including a dead addons agent, produces no lines and therefore no alert. If you need that, run a second agent and use <code>distinct_sources</code>, or watch the agent&rsquo;s heartbeat from something else.</div>
</div>
