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"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
service_id | string | Yes | Unique service identifier |
type | string | No | metric (default), log, trace, event, profile, slo |
metric_name | string | Yes for metric, trace, slo, profile | Metric identifier |
value | float64 | Yes for metric, trace, slo, profile | Numeric value |
body | string | Yes for log, event | Text content |
trace_id | string | No | Trace identifier for trace type |
timestamp | string (RFC3339) | Yes | Record timestamp |
attributes | object | No | Arbitrary 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:
| Metric | Type | Description |
|---|---|---|
infrasage_ingestion_events_total | Counter | Total events ingested, by type and status |
infrasage_ingestion_batch_size | Histogram | Records per batch |
infrasage_http_request_duration_seconds | Histogram | API latency by endpoint |
infrasage_dlq_depth | Gauge | Current DLQ depth |
infrasage_validation_failures_total | Counter | Validation 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
| Signal | Endpoint | Formats |
|---|---|---|
| Metrics | POST /v1/metrics | OTLP JSON, OTLP protobuf |
| Traces | POST /v1/traces | OTLP JSON, OTLP protobuf |
| Logs | POST /v1/logs | OTLP JSON, OTLP protobuf |
Content-Type: application/json or application/x-protobuf