Endpoints
OTLP over HTTP, on the standard OpenTelemetry paths. Both JSON and protobuf are accepted, and gzip- or deflate-compressed bodies are inflated transparently.
| Signal | Path | Content types |
|---|---|---|
| Logs | POST /v1/logs | application/json, application/x-protobuf |
| Traces | POST /v1/traces | application/json, application/x-protobuf |
| Metrics | POST /v1/metrics | application/json, application/x-protobuf |
Authentication
Every request carries an ingest API key in the Authorization header. The collector validates it against the control plane (cached briefly) and derives your organization's namespace from it — any namespace in the payload is ignored, so a key can only ever write into its own tenant.
headerAuthorization: Bearer sk_live_…Configure an OTel SDK
Nothing byteshift-specific: the standard OTLP exporter environment variables are all you set.
environmentOTEL_EXPORTER_OTLP_ENDPOINT=https://collect.byteshift.com
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer sk_live_…
OTEL_SERVICE_NAME=checkout-api
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=productionSend a log directly
For a quick smoke test without an SDK, post an OTLP/JSON log record:
curlcurl -X POST https://collect.byteshift.com/v1/logs \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"resourceLogs": [{
"resource": { "attributes": [
{ "key": "service.name", "value": { "stringValue": "checkout-api" } }
]},
"scopeLogs": [{ "logRecords": [{
"timeUnixNano": "1720900000000000000",
"severityText": "ERROR",
"body": { "stringValue": "payment gateway timeout after 3 retries" }
}]}]
}]
}'Enrichment at ingest
Ingest is deterministic and never destructive. A JSON string body is lifted to structured fields; an absentseverity is filled from a parsed level field or inferred from the body — but a severity you already set is never overwritten, and a line that can't be parsed is kept verbatim.
Back-pressure
Writes are buffered and flushed on a short interval with exporter-style retry. If the buffer is full you get a 503 with a Retry-After header — back off and resend. An undecodable payload gets a 400, per OTLP. Well-behaved exporters handle both automatically.
Push, not just pull
Some sources push to byteshift instead of being polled: Vercel log and trace drains deliver straight to the collector, and Claude Code and Cowork can stream their events to an OTLP endpoint you configure. See Integrations for the provider-specific setup.