Connect
OTLP endpoint
MonitOps receives logs, metrics and traces over OTLP/HTTP, the OpenTelemetry protocol, at three paths, authenticated with the bearer credential of a source. This article is the reference for those paths, the accepted encodings, every response a sender can receive and how to retry.
How it works#
A sender posts an OTLP export request. MonitOps authenticates the credential once for the whole request, which may carry many records and resource groups, and takes the tenant, source, system membership and forwarding policy from that source's configuration. Headers and attributes in the request that claim a different identity are removed. Metadata policy is then applied to each resource group, mandatory masking runs, and the records are handed on for storage.
The response is sent only after the admission receipt is recorded, and, for a request that carries records, after the hand-off is acknowledged. A response is never inferred from elapsed time or from a later, unrelated request.
Configuration#
Paths and headers#
| Signal | Method and path |
|---|---|
| Logs | POST /v1/logs |
| Metrics | POST /v1/metrics |
| Traces | POST /v1/traces |
POST /v1/traces
Authorization: Bearer <source credential>
Content-Type: application/x-protobuf
Content-Encoding: gzip
| Item | Accepted |
|---|---|
| Authentication | Authorization: Bearer <source credential>, on every request |
| Content type | application/x-protobuf or application/json |
| Compression | gzip, or none |
| Response encoding | Matches the request's content type |
For OTLP/JSON, trace and span identifiers are hex strings, enumerations are integers, and 64-bit values round-trip. Any other method on these paths is answered with 405.
A browser session never authenticates to these paths, and a source credential never authenticates to the console or the API.
Limits#
Every request is bounded. Both the size on the wire and the size after decompression are limited, as are the number of resource groups, the number of records, spans or metric data points in a request, the depth and size of nested data, and the rate and volume a source and the system as a whole may send. Limits are transport errors: telemetry is never silently sampled or dropped to stay within them. A request over a size limit receives 413. A request over a rate or volume limit receives 429.
Responses#
| Outcome | Response | What it means for the sender |
|---|---|---|
| Valid empty export | 200 with an empty export response | Nothing was received. It is not treated as freshness for the source |
| All records handed on | 200, no partial success | The records were accepted and acknowledged. Identity resolution and indexing continue afterwards |
| Some or all records rejected by policy | 200 with a partial success and a rejected count | The rejected records are masked and quarantined for correction. Do not retry the whole batch |
| Malformed data | 400 | Not retryable without correction. Nothing is retained |
| Unknown, revoked or disabled credential | 401 | Not retryable without a valid credential |
| Request over a size limit | 413 | Reduce the batch size |
| Unsupported content type or encoding | 415 | Use protobuf or JSON, with gzip or none |
| Wrong method | 405 | Use POST |
| Rate or resource limit, or a hard allowance used up | 429 with Retry-After | Not accepted. Retry with backoff |
| MonitOps could not accept the request | 503 with Retry-After | Not accepted. Retry with backoff |
| Outcome unknown after dispatch | 503 or 504 with Retry-After | Some records may have been accepted |
Error bodies are OTLP status messages with fixed reason text. They never echo your data. Policy rejections carry the reason enforced_metadata_conflict or environment_alias_conflict, described in Masking and Sources. A request that is structurally invalid as a whole is rejected as a whole and is not reported as partial success.
Request identifier#
When a request identifier exists, the response carries it in a header. Quote it when you ask about a specific request.
X-MonitOps-Request-Id: <request id>
Retry guidance#
- Retry
429and503afterRetry-After. The default interval is one second. Apply backoff and jitter on repeated failures. These responses mean the request was not forwarded. - A
503or504after dispatch is an unknown outcome. Some records may exist. An unchanged retry may create duplicates. - A partial success is not retried automatically. The OTLP specification requires no automatic retry for populated partial-success responses. Correct the sender's metadata, then resubmit the quarantined records or have them reprocessed by record identity.
- Do not retry
400,401,413,415or405unchanged. They need a correction first.
What you see in the console#
On Sources, each source shows its admission counts and errors, and administrators can open the outcome of recent requests, each with its request identifier. Counts include requests that were denied by a limit once the source was authenticated. Counts are operational intake statistics for the requests MonitOps could record. If a count could not be completed, for example because the request was rejected before it was fully read, the console marks it as incomplete, and treats a figure as a lower bound.
Failure states#
| State | Behaviour |
|---|---|
| Authority cannot be read | The request is not authorized and is answered with a retryable failure. It is never treated as authorized |
| Receipt cannot be recorded after acknowledgement | 503, reported as unknown until reconciled. A retry may duplicate |
| MonitOps cannot buffer safely | New admission is refused with a retryable 503 and Retry-After instead of accepting what cannot be kept |
A revoked credential or changed source policy takes effect within a short, bounded time. A request already authorized may finish under the policy it started with.
Related#
Last updated October 2026