# Limits & ingest health

## Ingest caps

| Bound | Value |
|---|---|
| Request body | 1 MiB, enforced on the stream |
| Spans per trace batch / records per log batch / data points per metric batch | 1,000 |
| Requests per project | 300/min per location (abuse ceiling — batch spans, don't spray) |
| Feedback audio | 4 MiB per recording |
| Sandbox projects | free and unlimited ingest; expire in 14 days unless claimed |

Rejections return the reason synchronously (`400`/`413`/`429`) — and land on
your project's ingest-health record so the console can show it too.

## "Nothing is showing up"

```bash
curl -s https://loopops.dev/v1/ingest/health -H "authorization: Bearer <any project key>"
```

Three honest states:

- `no_events` — nothing keyed to this project has reached ingest.
- `rejecting` — your producer is reaching us but the newest request was
  refused; the record carries the exact reason, route, and status.
- `receiving` — ingest accepted; the **read path rolls ~60–90 s behind**
  (console, diagnose, `/v1/telemetry`). Fresh events are latency, not loss.

The console's empty state and the onboarding runbook's first-event check read
the same record, so a misconfigured first POST shows its reason instead of a
silent wait.

## Retention & deletion

Sandbox projects expire and are purged. **Archive** a project
(`POST /v1/projects/<id>/archive`, or `loopops_archive_project`) to stop
ingest and downgrade its keys to read-only; rows are purged by the retention
job. Full data-handling detail: [/security](/security).

**Next:** [API reference →](/docs/api)