Browse documentation

Reference

Metrics REST API

Use the supported metric discovery, aggregation, histogram, forecast, and deletion endpoints.

Use the Metrics REST API for direct integrations that cannot use the Anectico CLI. Give read clients metrics:read; deletion requires metrics:delete. OTLP ingestion is separate and requires ingest:write at POST https://api.anectico.com/v1/metrics.

All resource calls below use this base URL and header:

https://app.anectico.com/api/v1
X-Anectico-API-Key: an_...

Project selection is endpoint-specific. Name discovery, aggregation, and histogram queries take project_id in the query string; forecasts take it in the JSON body; deletion derives its scope from the credential. Label discovery is currently organization-wide and does not accept a project selector, so do not use it in an integration that requires project-isolated label values.

List metric names

curl --fail-with-body \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  "https://app.anectico.com/api/v1/metrics/names?project_id=$ANECTICO_PROJECT"

Optional start_time and end_time query parameters are RFC 3339 timestamps. The response is alphabetical and capped at 1,000 names:

{
  "metrics": [
    {"name": "checkout.duration_ms", "type": "histogram"},
    {"name": "checkout.queue_depth", "type": "gauge"}
  ],
  "total_count": 2,
  "retrieved_at": "2026-07-21T12:00:00Z"
}

Types are counter, gauge, histogram, or summary when the ingested data supplies one.

Discover labels

curl --fail-with-body \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  "https://app.anectico.com/api/v1/metrics/checkout.duration_ms/labels?start_time=2026-07-21T00:00:00Z&end_time=2026-07-21T12:00:00Z"

The response contains label keys found on the requested metric and available values for each key:

{
  "labels": [
    {"name": "service_name", "values": ["checkout-api", "checkout-worker"]},
    {"name": "environment", "values": ["production"]},
    {"name": "region", "values": ["eu-west", "us-east"]}
  ]
}

URL-encode a metric name when constructing the path programmatically. Label-key discovery accepts the same optional start_time and end_time query parameters. The current value lists are sampled organization-wide for each discovered key, so they can include values emitted by other metrics or outside the requested window.

Aggregate a metric

POST /metrics/aggregate returns time-ordered scalar series. Put project_id in the query string, not the JSON body.

curl --fail-with-body \
  -X POST \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  -H "Content-Type: application/json" \
  "https://app.anectico.com/api/v1/metrics/aggregate?project_id=$ANECTICO_PROJECT" \
  --data '{
    "metric_name": "checkout.queue_depth",
    "aggregation": "max",
    "step": "5m",
    "time_range": {
      "start": "2026-07-21T10:00:00Z",
      "end": "2026-07-21T12:00:00Z"
    },
    "filters": [
      {"key": "region", "values": ["eu-west", "us-east"]}
    ],
    "group_by": ["service_name"],
    "environment": "production"
  }'
{
  "series": [
    {
      "labels": {"service_name": "checkout-api"},
      "points": [
        {"timestamp": "2026-07-21T10:00:00Z", "value": 12},
        {"timestamp": "2026-07-21T10:05:00Z", "value": 18}
      ]
    }
  ]
}

Supported fields:

Field Required Behavior
metric_name Yes Exact metric name
time_range.start, time_range.end No RFC 3339 closed time window; retention still applies
step No Bucket size; defaults to 1h
aggregation No Defaults to avg
service_name No Exact emitting-service filter
environment No Exact deployment-environment filter
filters No Up to two label dimensions
group_by No Up to two label dimensions

Aggregations are avg, sum, min, max, count, p50, p95, p99, stddev, and variance. Steps are 1s, 5s, 10s, 30s, 1m, 5m, 10m, 15m, 30m, 1h, 6h, 12h, 1d, and 7d.

Each filter requires one to 50 non-empty, distinct values. Values within one filter use OR; different filter dimensions use AND. Filter and group keys must begin with a letter or underscore and may then contain letters, digits, _, ., or -, up to 128 characters.

Queries are bounded to 50 grouped series and 500 points per series. Narrow the time range, increase step, or reduce grouping when the API rejects a larger query.

Query a native histogram

POST /metrics/histogram returns the preserved explicit-bucket distribution for an OTLP histogram. It does not accept aggregation or group-by.

curl --fail-with-body \
  -X POST \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  -H "Content-Type: application/json" \
  "https://app.anectico.com/api/v1/metrics/histogram?project_id=$ANECTICO_PROJECT" \
  --data '{
    "metric_name": "checkout.duration_ms",
    "step": "5m",
    "time_range": {
      "start": "2026-07-21T10:00:00Z",
      "end": "2026-07-21T12:00:00Z"
    },
    "environment": "production"
  }'
{
  "metric_name": "checkout.duration_ms",
  "step": "5m",
  "cells": [
    {
      "timestamp": "2026-07-21T10:00:00Z",
      "upper_bound": 100,
      "upper_bound_infinite": false,
      "count": "42"
    },
    {
      "timestamp": "2026-07-21T10:00:00Z",
      "upper_bound": 0,
      "upper_bound_infinite": true,
      "count": "3"
    }
  ]
}

The terminal +Inf bucket uses upper_bound_infinite: true; ignore its numeric upper_bound. Each count belongs to the range after the preceding bound through the cell’s upper bound; it is not a cumulative count. Protobuf uint64 counts may be encoded as JSON strings. A non-histogram metric, or old histogram data without preserved buckets, returns no distribution cells.

Forecast a metric

POST /metrics/forecast calculates an expected band from an average-value history. Unlike the aggregate and histogram endpoints, project_id is a JSON field.

curl --fail-with-body \
  -X POST \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  -H "Content-Type: application/json" \
  "https://app.anectico.com/api/v1/metrics/forecast" \
  --data @- <<JSON
{
  "metric_name": "checkout.queue_depth",
  "interval": "5m",
  "horizon": 24,
  "sensitivity": 0,
  "environment": "production",
  "project_id": "$ANECTICO_PROJECT",
  "time_range": {
    "start": "2026-07-14T12:00:00Z",
    "end": "2026-07-21T12:00:00Z"
  }
}
JSON

horizon is the number of future buckets, defaults to 24, and cannot exceed 1,000. sensitivity is 0 for automatic band width or a value from 1 through 10. Without a time range, the service uses the last seven days of retained history. The response always explains whether the model could fit the history; forecast is populated only when status is FORECAST_FIT_STATUS_READY.

{
  "metric_name": "checkout.queue_depth",
  "interval": "5m",
  "horizon": 24,
  "history_points": 2016,
  "required_history_points": 576,
  "missing_buckets": 0,
  "status": "FORECAST_FIT_STATUS_READY",
  "status_reason": "Forecast fitted from regular history with a stable daily seasonal pattern.",
  "confidence": 0.91,
  "band_semantics": "additive_holt_winters_brutlag_seasonal_deviation",
  "forecast": [
    {
      "timestamp": "2026-07-21T12:05:00Z",
      "expected": 11.8,
      "lower": 6.1,
      "upper": 17.5
    }
  ]
}

The possible statuses are FORECAST_FIT_STATUS_READY, FORECAST_FIT_STATUS_INSUFFICIENT_HISTORY, FORECAST_FIT_STATUS_IRREGULAR_HISTORY, and FORECAST_FIT_STATUS_NONSEASONAL. status_reason is the stable human-readable explanation; required_history_points is the two-daily-season minimum for the selected interval. missing_buckets counts expected grid timestamps skipped by forward gaps. Duplicate and out-of-order observations also make history irregular but do not themselves increase that count.

confidence is a deterministic seasonal-fit score from 0 through 1, not probability or interval coverage. band_semantics identifies the additive Holt-Winters/Brutlag seasonal-deviation model used for a ready response. An unavailable status returns an empty forecast together with these explicit fields, so an empty array is never ambiguous. A forecast remains a statistical expectation, not a root-cause explanation or capacity guarantee.

Delete a metric

curl --fail-with-body \
  -X DELETE \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  "https://app.anectico.com/api/v1/metrics/anectico.verification.value?project_id=$ANECTICO_PROJECT_ID"

Deletion removes every datapoint with that metric name in one project and cannot be undone through Anectico. project_id is required: an organization-level credential must name the project to delete from, and there is no way to delete a metric across every project in one call. A project-scoped key may omit project_id and stays confined to its own project; naming a different one is rejected. Prefer the CLI, which sends your active project and requires explicit confirmation:

anectico metrics delete anectico.verification.value --yes