Skip to main content

Ingestion Gateway API

Base URL: http://localhost:8080

All write endpoints accept an optional API key header: X-API-Key: isage_your_key_here.


POST /api/v1/telemetry

Ingest a single telemetry record.

Request

POST /api/v1/telemetry
Content-Type: application/json
X-API-Key: isage_your_key_here
{
"service_id": "payment-api",
"type": "metric",
"metric_name": "cpu_usage_percent",
"value": 87.3,
"timestamp": "2026-04-10T12:00:00Z",
"attributes": {
"region": "us-east-1",
"env": "production"
}
}
FieldTypeRequiredDescription
service_idstringYesUnique service identifier
typestringNometric (default), log, trace, event, profile, slo
metric_namestringYes for metric, trace, slo, profileMetric identifier
valuefloat64Yes for metric, trace, slo, profileNumeric value
bodystringYes for log, eventText content
trace_idstringNoTrace identifier for trace type
timestampstring (RFC3339)YesRecord timestamp
attributesobjectNoArbitrary key-value tags

Response 200

{"status": "ok", "queued": 1}

Response 400 (validation failure)

{
"status": "error",
"error": "invalid_value",
"message": "value must be a finite float64; got NaN"
}

Response 429 (rate limit exceeded)

{
"status": "error",
"error": "rate_limit_exceeded",
"message": "Tenant quota exceeded. Current plan: Free (10 RPS). Upgrade at /billing/plans."
}

POST /api/v1/telemetry/batch

Ingest up to 10,000 records in one request.

Request

POST /api/v1/telemetry/batch
Content-Type: application/json

Body: a JSON array of telemetry records (same schema as single ingest).

Response 200

{
"status": "ok",
"queued": 1000,
"failed": 2,
"failures": [
{"index": 45, "error": "timestamp_too_old", "message": "Timestamp is more than 24h in the past"},
{"index": 99, "error": "missing_service_id", "message": "service_id is required"}
]
}

Partial success is allowed — valid records are queued even if some fail validation.


GET /api/v1/telemetry-types

List all supported telemetry types.

Response 200

{
"types": ["metric", "log", "trace", "event", "profile", "slo"],
"default": "metric"
}

GET /healthz

Health check endpoint. Returns 200 when the service is ready to accept traffic.

Response 200

{
"status": "ok",
"version": "1.2.0",
"uptime_seconds": 3601,
"clickhouse": "ok",
"kafka": "ok"
}

GET /metrics

Prometheus metrics endpoint. Returns all gateway metrics in Prometheus text format.

Key metrics exposed:

MetricTypeDescription
infrasage_ingestion_events_totalCounterTotal events ingested, by type and status
infrasage_ingestion_batch_sizeHistogramRecords per batch
infrasage_http_request_duration_secondsHistogramAPI latency by endpoint
infrasage_dlq_depthGaugeCurrent DLQ depth
infrasage_validation_failures_totalCounterValidation failures by reason

GET /api/v1/debug/dlq-stats

Dead-letter queue statistics. Requires readonly or higher API key scope.

Response 200

{
"total_failed": 142,
"by_reason": {
"timestamp_too_old": 98,
"invalid_value": 31,
"missing_service_id": 13
},
"oldest_entry": "2026-04-09T08:00:00Z",
"newest_entry": "2026-04-10T11:55:00Z"
}

Prometheus Remote Write

InfraSage accepts Prometheus remote-write at:

POST /api/v1/prometheus/write
Content-Type: application/x-protobuf
Content-Encoding: snappy
X-Prometheus-Remote-Write-Version: 0.1.0

Configure in your prometheus.yml:

remote_write:
- url: http://localhost:8080/api/v1/prometheus/write
queue_config:
max_samples_per_send: 10000
batch_send_deadline: 5s

OTLP Endpoints

SignalEndpointFormats
MetricsPOST /v1/metricsOTLP JSON, OTLP protobuf
TracesPOST /v1/tracesOTLP JSON, OTLP protobuf
LogsPOST /v1/logsOTLP JSON, OTLP protobuf

Content-Type: application/json or application/x-protobuf