Skip to content

OTLP ingest

axonpush accepts OpenTelemetry logs and traces in the standard OTLP/HTTP/JSON format. Point any OpenTelemetry Collector, OTel SDK, or otlphttp exporter at the endpoints below and every LogRecord / Span lands as an axonpush event — no proprietary wire format required.

MethodURLBody
POSThttps://api.axonpush.xyz/v1/logsOTLP LogsExportRequest (resourceLogs[])
POSThttps://api.axonpush.xyz/v1/tracesOTLP TracesExportRequest (resourceSpans[])

Only JSON-encoded OTLP is supported today. Binary protobuf is on the roadmap.

HeaderPurpose
X-API-Key: ak_...Auth — a standard axonpush API key.
X-Axonpush-Channel: <id>Numeric channel ID that should receive the events.
Content-Type: application/jsonStandard.
X-Axonpush-Environment: <slug> (optional)Override the environment bound to the API key. Only honored when the key has allowEnvironmentOverride=true. See Environments.

The simplest way to forward existing OTel traffic is an otlphttp exporter block:

exporters:
otlphttp/axonpush:
endpoint: https://api.axonpush.xyz
encoding: json
headers:
X-API-Key: ${env:AXONPUSH_API_KEY}
X-Axonpush-Channel: "1"
X-Axonpush-Environment: production
service:
pipelines:
logs:
receivers: [otlp]
exporters: [otlphttp/axonpush]
traces:
receivers: [otlp]
exporters: [otlphttp/axonpush]

Point the collector’s exporter at https://api.axonpush.xyz (no /v1/... suffix — the OTel otlphttp exporter appends /v1/logs and /v1/traces itself).

from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
exporter = OTLPSpanExporter(
endpoint="https://api.axonpush.xyz/v1/traces",
headers={
"X-API-Key": "ak_prod_...",
"X-Axonpush-Channel": "1",
},
)
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(exporter))

On success the endpoint returns an empty JSON object:

{}

If some records failed validation but others were accepted, you get a partial-success hint matching the OTLP spec:

{
"partialSuccess": {
"rejectedLogRecords": 3,
"errorMessage": "..."
}
}

rejectedSpans is used on the /v1/traces endpoint.

axonpush also sets two response headers so you can verify routing from curl / the collector:

x-axonpush-resolved-environment: production
x-axonpush-resolved-via: api-key
StatusMeaning
400Missing / invalid X-Axonpush-Channel, or body missing resourceLogs[] / resourceSpans[].
401Bad or missing X-API-Key.
403Key doesn’t own the channel in the header.
404Channel doesn’t exist.
413Request body exceeds 6 MB. Split the export into smaller batches.
429Ingest quota exceeded.

The OTLP endpoints are ideal for existing OTel-instrumented services — you get axonpush without touching application code. If you’re writing new code and want agent-semantic events (agent.tool_call.start, agent.handoff, …), the SDKs give you a sharper surface:

Both SDKs ultimately publish to the same ingest pipeline; they just wrap it with ergonomic instrumentation.