> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rootprint.io/llms.txt
> Use this file to discover all available pages before exploring further.

# OTLP reference

> Rootprint OTLP HTTP endpoint: URL, authentication, content types, limits, and response codes.

Rootprint exposes an OTLP HTTP endpoint that accepts OpenTelemetry logs, authenticates them with an ingest API key, and ingests them into the target index. The target index is fixed by the API key.

## Endpoint

```
POST https://<your-rootprint>/v1/logs
```

## Authentication

```
Authorization: Bearer <ingest-token>
```

When used through `OTEL_EXPORTER_OTLP_LOGS_HEADERS`, the value must be URL-encoded:

```
OTEL_EXPORTER_OTLP_LOGS_HEADERS=Authorization=Bearer%20<your-ingest-token>
```

## Supported content types

Rootprint accepts `application/x-protobuf` only. Any other `Content-Type` returns **415 Unsupported Media Type**.

Every major OTEL SDK already defaults to protobuf for HTTP logs, with one exception: the JavaScript package `@opentelemetry/exporter-logs-otlp-http` defaults to JSON. If you are using that package, switch to `@opentelemetry/exporter-logs-otlp-proto` (same `OTLPLogExporter` API).

## Encoding

`Content-Encoding`: `gzip` / `x-gzip`, `zstd`, `deflate` / `x-deflate`, and `identity` (or no header) for uncompressed. Any other value is rejected. OTEL SDKs send `gzip` or no compression.

## Response codes

Rootprint maps OTLP errors to gRPC-style status codes. Upstream rejections (malformed protobuf, schema mismatch, oversized payload) are normalized to `400`, and any upstream `5xx` or network failure is clamped to a retryable `503`.

| Status | Meaning                                                                 |
| ------ | ----------------------------------------------------------------------- |
| `200`  | Accepted. Empty body.                                                   |
| `400`  | Empty request body, or Quickwit rejected the payload.                   |
| `401`  | Missing Bearer API key.                                                 |
| `403`  | Invalid or unknown ingest API key.                                      |
| `415`  | `Content-Type` is not `application/x-protobuf`.                         |
| `429`  | Upstream Quickwit is rate-limited. `Retry-After` is echoed (default 5). |
| `503`  | Upstream Quickwit error or network failure. `Retry-After: 5`.           |

A `413` never originates from Rootprint — it means a reverse proxy in front of Rootprint rejected an oversized request body. Lower the agent's batch size (`batch.max_bytes` in Vector, `send_batch_max_size` on the Collector's `batch` processor) or raise the proxy's body limit.

## Environment variables

| Variable                           | Value                                        |
| ---------------------------------- | -------------------------------------------- |
| `OTEL_SERVICE_NAME`                | Your service name (lands in `service_name`). |
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | `https://<your-rootprint>/v1/logs`           |
| `OTEL_EXPORTER_OTLP_LOGS_HEADERS`  | `Authorization=Bearer%20<your-ingest-token>` |
| `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` | `http/protobuf` (required)                   |
| `OTEL_LOG_LEVEL`                   | Minimum severity emitted by the SDK itself.  |

## Index target

The target index is pinned by the ingest API key, not by the SDK. To write to a different index, create an ingest API key scoped to that index in **Settings → API keys** and use its value in the `Authorization` header. See [Manage indexes](/configuration/manage-indexes).

## Related

* [Send logs overview](/send-logs/overview)
* [Indexes](/indexes)
* [Manage indexes](/configuration/manage-indexes)
