# Telemetry ingestion API

Use the ingestion API to send errors, traces, metrics, logs, and deployment markers to Updog. Requests use a project-scoped ingestion key and return as soon as Updog has durably accepted the payload.

## Authentication

Send your ingestion key and a stable request ID with every request:

```http
X-API-Key: updog_...
X-Updog-Request-ID: 018f4f6c-9f52-7a10-a4d5-87f07bdff35a
```

Keep the same `X-Updog-Request-ID` when retrying a request. Updog deduplicates accepted ingestion requests for 24 hours. If the request ID is missing or invalid, Updog replaces it and returns the generated value in the response header.

## Endpoints

| Signal | Endpoint | Request body |
| --- | --- | --- |
| Errors | `POST /api/v1/notices/bulk` | `{"notices": [...]}` |
| Traces and spans | `POST /api/v1/events` | `{"events": [...]}` |
| Metrics | `POST /api/v1/metrics` | `{"metrics": [...]}` |
| Logs | `POST /api/v1/logs` | `{"logs": [...]}` |
| Deployments | `POST /api/v1/deployments` | One deployment object |

Every record should include a stable `event_id`, its original occurrence timestamp, and the resource fields `service`, `environment`, `release`, `hostname`, `sdk_name`, and `sdk_version` when known.

Logs may include `trace_id` and `span_id`. Trace events preserve `trace_id`, `span_id`, and `parent_span_id`. Metrics include their instrument type, unit, and tags.

## Delivery behavior

Applications should enqueue telemetry locally instead of waiting for an HTTP request. Maintained clients use these bounded defaults:

- 2,048 queued records, 8 MiB total queued bytes, and 64 KiB per record
- 512 records or 512 KiB per request
- A partial-batch flush every five seconds
- One in-flight request per signal
- Three retry attempts after the first request, using capped exponential backoff with full jitter

Retry network failures, `408`, `429`, and `5xx` responses. Honor `Retry-After` when present. Do not retry `400`, `401`, `403`, or `422` responses.

When a multi-record batch receives `413 Payload Too Large`, split the batch and try again. Drop a single record that remains too large. When the local queue is full, drop new lower-priority telemetry instead of blocking the application or allowing memory to grow without limit.

## Responses

`202 Accepted` means the payload was durably accepted or recognized as a duplicate:

```json
{"status":"accepted","duplicate":false}
```

If the ingestion queue is unavailable, Updog returns a retryable `503` response with `Retry-After`. Validation failures return `422` and should not be retried.

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