Ingest endpoints and errors
Every ingest path, every status code the receiver returns, the rate limits, and the size caps — the page to open when a request is being rejected.
Before you start
Reference for the ingest surface. If a request is being rejected and you want to know why, start with status codes.
Endpoints
Over HTTP, on port 4000 by default:
POST /v1/logs— OTLP logsPOST /v1/metrics— OTLP metricsPOST /v1/traces— OTLP tracesPOST /api/v1/prom/write— Prometheus remote-writeGET /health— liveness; always returns 200 if the process is upGET /readyz— readiness; 200 when the pipeline is reachable, 503 when notGET /metrics— the receiver's own Prometheus metrics
Over gRPC, on port 4317: the standard OTLP logs, metrics, and trace services. Both transports accept the same dashboard-issued key and enforce the same rate limits, quotas, and per-signal entitlements — the only difference is that gRPC metadata keys are lower-case, so the header is x-license-key. See Send data with OpenTelemetry.
The ports above are what the receiver itself binds. The base URL you actually export is shown on Get Started in the dashboard: a hosted deployment and a self-hosted one behind the bundled nginx (which serves OTLP under /otlp and strips the prefix) do not have the same one.
/health is a static check on the process only; it does not test dependencies. Use /readyz if you want a check that fails when the pipeline behind the receiver is unreachable. Wiring a load balancer to /health expecting it to drain an unhealthy receiver will not do what you want.
Authentication
Send your license key one of two ways:
X-License-Key: oiq_4f3c2b1a9e8d7c6b5a4f3e2d1c0b9a8eAuthorization: Bearer oiq_4f3c2b1a9e8d7c6b5a4f3e2d1c0b9a8eX-License-Key takes precedence if both are present. Header names are case-insensitive; the key value is not.
Status codes
202 Accepted — the batch was published to the pipeline. This is success. It acknowledges receipt, not storage; data becomes queryable a few seconds later.
400 Bad Request — the payload did not decode or failed validation. Causes: malformed protobuf, a body that does not match the declared content type, or a payload that decodes but violates the OTLP schema. Rejected payloads are copied to a dead-letter queue, so they are recoverable by an operator.
401 Unauthorized — one of:
- No key supplied — the message names both accepted headers.
- Malformed key — not
oiq_-prefixed, or shorter than 20 characters. - Invalid or revoked key.
403 Forbidden — the key is valid but the request is not allowed: the signal is not enabled for your account, or the source address is not permitted.
413 Payload Too Large — the body exceeded a size cap. See limits.
429 Too Many Requests — a rate limit was hit. A Retry-After header gives the wait in seconds.
500 / 502 / 503 — the receiver could not publish to the pipeline. These are retryable; OpenTelemetry SDKs and Prometheus remote-write both retry with backoff.
Rate limits
Three limits apply to authenticated HTTP ingest:
- 200 requests per second per account, with a burst allowance of 400. Exceeding it returns
429withRetry-After: 1. - 10,000 requests per minute per account. Exceeding it returns
429withRetry-After: 60. - A global per-key limit, which also returns
429.
The per-second limit does not apply to Prometheus remote-write; the per-minute limit does.
These are limits on requests, not on records. Batching is therefore the correct response to hitting them — an SDK exporting 500 spans in one request uses one of your 200 per second, not 500. If you are being rate-limited, look at your exporter's batch settings before asking for a limit increase.
Limits and caps
General ingest:
- 50 MB maximum request body.
Prometheus remote-write, which has its own tighter caps:
- 8 MB compressed body
- 64 MB decompressed
- 10,000 timeseries per request
- 100,000 total samples per request
- 128 labels per series
- 1,024 bytes per label name or value
Exceeding the decompressed cap returns 413; exceeding the series, sample, or label caps returns 400.
Encodings
OTLP/HTTP accepts:
application/jsonapplication/x-protobufapplication/octet-stream— treated as protobuf
Request bodies may be gzip, deflate, or brotli compressed. An unsupported Content-Encoding returns 415; a body that fails to decompress returns 400.
Prometheus remote-write is the exception: it expects snappy-compressed protobuf and has HTTP-level decompression disabled, so gzip on top of it will fail.