Skip to content

Ingest Endpoints

The ingest service receives OpenTelemetry data and publishes it to NATS JetStream.

All three OTLP endpoints accept JSON only (OTLP/HTTP proto3 JSON mapping). Protobuf is not yet supported — requests with Content-Type: application/x-protobuf return 415 Unsupported Media Type. Gzip-compressed bodies (Content-Encoding: gzip) are decompressed transparently.

Ingest OTLP log records.

POST /v1/logs
Authorization: Bearer gck_your_key
Content-Type: application/json

Accepts OTLP LogsData as JSON.

Response: 200 OK on success.

Ingest OTLP metric data points.

POST /v1/metrics
Authorization: Bearer gck_your_key
Content-Type: application/json

Accepts OTLP MetricsData as JSON, including Gauge, Sum, Histogram, and Summary metrics.

Response: 200 OK on success.

source_event_id identifies each metric datapoint. In R1 and R2, its canonical derivation hashes the schema-bearing metric parent representation together with the individual datapoint. The metric parent representation contains the metric data container but excludes sibling datapoints. In a Sum metric, Metric.sum is an object container, not a scalar value. By contrast, the sum on Histogram and Summary datapoints is numeric.

Ingest OTLP trace spans.

POST /v1/traces
Authorization: Bearer gck_your_key
Content-Type: application/json

Accepts OTLP TracesData as JSON.

Response: 200 OK on success.

Health check endpoint. Returns a plain-text body.

GET /health

Response:

  • 200 OK with body ok when NATS is connected.
  • 503 Service Unavailable with body nats unhealthy when NATS is down.

The /health endpoint does not send Retry-After. That header is added only on the OTLP endpoints when the NATS publish pipeline is under backpressure (Retry-After: 5).

  • OTLP endpoints accept JSON only; other content types return 415.
  • Oversized payloads return 413 Payload Too Large.
  • Under NATS backpressure, OTLP endpoints return 503 with Retry-After: 5.
  • The ingest service is stateless — it publishes to NATS and returns immediately.
  • Data flows: Ingest → NATS JetStream → worker archival and landing lanes.

The plugin uses the following authenticated routes:

  • POST /v1/prompts — capture a prompt turn.
  • POST /v1/prompts/response — capture a response for a prompt.
  • GET /v1/plugin/config — resolve runtime configuration for the plugin.
  • POST /v1/setup-complete — plugin signals the end of /prism:setup.

Modern response capture selects the prompt with prompt_id or client_event_id and includes response_operation_id. Retries with the same semantic response are idempotent. When both prompt_id and client_event_id are supplied, prompt_id takes precedence.

Semantic response content consists of response_text and the stable response fields already stored with it: elapsed_ms, input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, model, and cost_usd. cost_catalog_revision and cost_kind are additive catalog provenance, not semantic response content. A later identical retry may fill in missing catalog provenance. If a retry supplies a different value for provenance that is already stored, the first value is preserved and the retry remains an idempotent no-op. response_content_hash is optional. When supplied, it must equal the server-canonical SHA-256 of response_text and the seven governed response fields: elapsed_ms, input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, model, and cost_usd.

POST /v1/prompts/response returns:

  • 204 No Content for a successful capture or idempotent no-op.
  • 400 Bad Request when request validation fails, including when a supplied response_content_hash does not equal the server-canonical SHA-256.
  • 404 Not Found when the selected prompt does not exist.
  • 409 Conflict when the response operation or semantic content conflicts.
  • 413 Payload Too Large when the request exceeds the raw ingress frame bound (currently 4 MiB). This is permanent for the request as sent — retrying the same body will not succeed, and the response carries no Retry-After.
  • 503 Service Unavailable with Retry-After: 5 when the underlying transport is temporarily saturated — this is retryable, unlike 413.

POST /v1/prompts returns the same 413/503 pair for the same reasons.

Session-only response selection with tool_session_id is legacy compatibility only: it is accepted only from plugin versions older than 0.5.1 and only before 2026-08-16T00:00:00Z.

For callers that can’t reach the internal API, a small set of API endpoints are proxied through ingest:

RouteMethodTarget
/v1/telemetry/logsGETAPI — see Telemetry Endpoints
/v1/insights/reportGETAPI — see Insights Endpoints
/v1/insights/report/generatePOSTAPI — see Insights Endpoints
/v1/insights/report/quickPOSTAPI — synchronous, LLM-free report (Insights)
/v1/score_v3/realtime/sub-sessionsGETAPI — see Prompt Score v3.0
/v1/score_v3/today-summaryGETAPI — today’s rolled-up v3 summary
/v1/model-catalogGETAPI — compiled model catalog snapshot (Prompt Score v3.0)
/v1/intelligence/prismGETStub — authenticated, always returns { "scores": [], "total": 0 }. The pre-v2.14 prism.prism_scores pipeline was removed; current scoring lives under Prompt Score v3.0.

Proxy routes require the same authentication as any other ingest endpoint.