# Telemetry read API

Read-only keys grant access to one or more explicitly approved Updog projects.
They cannot ingest telemetry or access projects outside their grants.

## Browser login and project access

With CLI 0.7.0 or newer:

1. Run `updog login`.
2. Open the displayed Updog authorization page and sign in if needed.
3. Enter the displayed code and select one or more projects (up to 100).
4. Approve access. The CLI stores one read-only key granting exactly those projects.

No project-selection flag is needed at login. Plain commands automatically query
the projects granted to the current credential:

```sh
updog logs search --query timeout --since 1h
updog errors search --status unresolved --since 7d
updog --all-projects hosts list
```

`--all-projects` queries all saved credential profiles, or the projects granted to
`UPDOG_API_KEY` when supplied. Repeated `--project NAME` selectors still query
existing saved profiles; a profile may grant several projects. `--project` and
`--all-projects` cannot be combined. `--project` cannot use environment authentication.

Up to four requests run concurrently. Filters, sorting, limits, offsets, and
windows apply per project. Multi-project JSON contains `data` entries with
`project` (slug), `project_id`, `url`, and the original API envelope under
`response`; failed entries contain `error`. Top-level `meta` counts `projects`,
`succeeded`, and `failed`. Partial failures preserve successful results and exit
nonzero. Single-project credential output is unchanged.

## Discover and select projects over HTTP

```http
GET /api/v1/projects
X-API-Key: updog_...
```

Requires `logs:read`, which every CLI-issued credential includes. Returns
`data: [{id, name, slug}, ...]` and `meta: {total}` for that key's grants only.
Discovery is rate-limited under the key's shared `logs:read` bucket.

For a multi-project key, select a granted project on each telemetry request:

```http
GET /api/v1/logs?since=1h
X-API-Key: updog_...
X-Updog-Project-ID: 123
```

Omitting the selector for a multi-project telemetry query returns structured
`400 project_selection_required`. Selecting any ungranted or invalid ID returns
`403 project_not_allowed`. A single-project key may omit the header; specifying
another project never expands access. Ingestion keys remain single-project.

Existing keys and older CLIs keep working. Older CLI login requests retain the
single-project browser selector. New CLIs request multi-selection automatically;
the token response includes a `projects` array alongside the compatible primary
`project` field. Deploy the server first, then CLI 0.7.0. Log in again to issue
one credential for multiple projects; existing tokens are not silently expanded.

## Authentication

Send a read-only key in the request header:

```http
X-API-Key: updog_...
```

Create a single-project key from the project's **API Keys** section, or use browser CLI login to select multiple projects. The secret is shown once, so store it in a secret manager. For noninteractive tools, provide it through `UPDOG_API_KEY` rather than a command-line argument.

Every project member can authorize CLI login or create a manual read-only key for projects they belong to. Ingestion key creation and key listing/revocation remain restricted to owners and admins. A shared key appears to owners and admins in every selected project's **API Keys** section. An owner or admin of any selected project can revoke it; revocation removes all of the key's access. The lowest-ID selected project anchors the credential; deleting that project deletes the whole key, while deleting an additional project removes that grant.

Invalid or revoked credentials return `401`. A key without the required read scope returns `403`. Rate-limited requests return `429` with `Retry-After`.

Every successful response contains `data` and `meta`, uses UTC ISO-8601 timestamps, and includes `Cache-Control: no-store`.

## Search logs

```http
GET /api/v1/logs?q=timeout&level=error&since=1h&limit=50
```

Supported parameters are `q`, `level`, `hostname`, `trace_id`, `since`, `until`, `sort_by`, `sort_dir`, `limit`, and `offset`. The default window is one hour and the maximum window is the 14-day log retention period.

## Inspect hosts

```http
GET /api/v1/hosts
GET /api/v1/hosts?hostname=zone-1
```

Host snapshots contain machine identity, role, environment, agent version, last-seen time, CPU, load, memory, swap, file descriptors, filesystem capacity, disk activity, network interfaces, and the current top processes by CPU and memory. The optional `hostname` parameter selects one exact machine.

## Search errors

```http
GET /api/v1/errors?q=ArgumentError&status=unresolved&since=7d
```

Error search matches the error class, message, and fingerprint. Supported parameters are `q`, `status`, `since`, `until`, `limit`, and `offset`. Use `since=all` to search all retained error-group summaries.

## Fetch error details

```http
GET /api/v1/errors/123?since=24h&limit=20
```

The response contains the project-scoped error group and its occurrences, including stack traces, breadcrumbs, request data, and context. Occurrences default to the last 24 hours and are retained for at most 90 days.

## Time ranges and pagination

`since` accepts a relative duration such as `30m`, `6h`, or `7d`, an RFC3339 timestamp, or `all`. `until` accepts an RFC3339 timestamp and defaults to the current time.

List endpoints default to 50 results and allow at most 200. Error details default to 20 occurrences and allow at most 100. `offset` defaults to zero and is capped at 10,000. Invalid parameters return `400` with a JSON error response.

Every successful response includes normalized UTC bounds in `meta.window.since` and `meta.window.until`. When paging, reuse the first response's `meta.window.until` as the next request's `until` value so newly arriving telemetry does not shift the result window.

## Rate limits

Responses include `RateLimit-Limit`, `RateLimit-Remaining`, and the Unix timestamp `RateLimit-Reset`. A `429` response also includes `Retry-After`.
