# Metrics

## Ingest CLI metrics events

> Ingest a batch of sfpowerscripts metrics events into VictoriaMetrics.\
> \
> \*\*Note:\*\* Only application tokens (CI/CD pipelines) can actually ingest metrics.\
> User tokens are silently accepted but not processed to simplify client-side logic.\
> \
> \*\*Metric Types:\*\*\
> \- \`count\`: Counter for discrete events (value auto-set to 1). Use for builds, deployments, failures.\
> \- \`guage\`: Point-in-time measurement. Use for pool sizes, queue depths.\
> \- \`timers\`: Duration measurement. Use for build time, deploy duration.\
> \
> \*\*Naming Convention:\*\* Use dot notation (e.g., \`sfpowerscripts.build.duration\`). Dots are automatically normalized for storage and querying.\
> \
> \*\*Deduplication:\*\* Metrics with identical name and tags are deduplicated within 5-minute windows.\
> \
> \*\*Retention:\*\* Metrics are retained for 12 months by default.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsIngestDto":{"type":"object","properties":{"events":{"type":"array","description":"A batch of metric events to ingest. Each event represents a single data point.\n\n**Supported Metric Types:**\n| Type | Value Required | Use Case | Example |\n|------|----------------|----------|---------|\n| `count` | No (auto=1) | Counting events | Builds, deployments, failures |\n| `guage` | Yes | Point-in-time values | Pool size, queue depth |\n| `timers` | Yes | Duration measurements | Build time, deploy duration |\n\n**Deduplication:** Metrics with identical name and tags within a 5-minute window are deduplicated.\n\n**Retention:** Metrics are retained for 12 months by default.","items":{"$ref":"#/components/schemas/MetricEventDto"}}},"required":["events"]},"MetricEventDto":{"type":"object","properties":{"metric":{"type":"string","description":"Metric name using dot notation. Names are sanitized: only alphanumeric, underscores, colons, and dots are allowed.","pattern":"^[a-zA-Z][a-zA-Z0-9_.:-]*$"},"type":{"$ref":"#/components/schemas/MetricType"},"value":{"type":"number","description":"Metric value. Required for `guage` and `timers` types. Ignored for `count` type (automatically set to 1)."},"timestamp":{"type":"number","description":"Unix timestamp in milliseconds when the metric was recorded."},"tags":{"description":"Additional dimensions/labels for the metric. Can be provided as:\n- **Object**: `{ \"package\": \"core\", \"org\": \"dev\" }`\n- **Array of strings**: `[\"package:core\", \"org:dev\"]` (colon-separated key:value pairs)\n\nTags are used for filtering and grouping in queries. A special `sfp_metric_type` tag is automatically added.","oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"array","items":{"type":"string","pattern":"^[^:]+:.+$"}}]}},"required":["metric","type","timestamp"]},"MetricType":{"type":"string","description":"Metric type determines how the value is interpreted:\n- **count**: Counter for discrete events. Value is automatically set to 1 (any provided value is ignored).\n- **guage**: Point-in-time measurement. Requires an explicit value.\n- **timers**: Duration/timing measurement. Requires an explicit value (typically milliseconds).","enum":["count","guage","timers"]},"MetricsIngestResponseDto":{"type":"object","properties":{"accepted":{"type":"number","description":"Number of events that were accepted and queued for ingestion."},"message":{"type":"string","description":"Optional message providing additional context about the ingestion."}},"required":["accepted"]}}},"paths":{"/sfp/api/metrics/ingest":{"post":{"operationId":"MetricsController_ingest","summary":"Ingest CLI metrics events","description":"Ingest a batch of sfpowerscripts metrics events into VictoriaMetrics.\n\n**Note:** Only application tokens (CI/CD pipelines) can actually ingest metrics.\nUser tokens are silently accepted but not processed to simplify client-side logic.\n\n**Metric Types:**\n- `count`: Counter for discrete events (value auto-set to 1). Use for builds, deployments, failures.\n- `guage`: Point-in-time measurement. Use for pool sizes, queue depths.\n- `timers`: Duration measurement. Use for build time, deploy duration.\n\n**Naming Convention:** Use dot notation (e.g., `sfpowerscripts.build.duration`). Dots are automatically normalized for storage and querying.\n\n**Deduplication:** Metrics with identical name and tags are deduplicated within 5-minute windows.\n\n**Retention:** Metrics are retained for 12 months by default.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsIngestDto"}}}},"responses":{"201":{"description":"Metrics accepted and queued for ingestion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsIngestResponseDto"}}}},"400":{"description":"Invalid request body - events array is empty or malformed"},"401":{"description":"Unauthorized - valid access token required"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## Query metrics (instant query)

> Execute an instant query against VictoriaMetrics using MetricsQL/PromQL syntax.\
> \
> \*\*Query Examples:\*\*\
> \- \`sfpowerscripts.build.duration\` - Get latest value\
> \- \`sum(sfpowerscripts.build.completed)\` - Aggregate counts\
> \- \`sfpowerscripts.build.duration{package="core"}\` - Filter by tag\
> \- \`rate(sfpowerscripts.build.completed\[1h])\` - Calculate rate over 1 hour\
> \
> See \[MetricsQL documentation]\(<https://docs.victoriametrics.com/metricsql/>) for full syntax.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/query":{"get":{"operationId":"MetricsController_query","summary":"Query metrics (instant query)","description":"Execute an instant query against VictoriaMetrics using MetricsQL/PromQL syntax.\n\n**Query Examples:**\n- `sfpowerscripts.build.duration` - Get latest value\n- `sum(sfpowerscripts.build.completed)` - Aggregate counts\n- `sfpowerscripts.build.duration{package=\"core\"}` - Filter by tag\n- `rate(sfpowerscripts.build.completed[1h])` - Calculate rate over 1 hour\n\nSee [MetricsQL documentation](https://docs.victoriametrics.com/metricsql/) for full syntax.","parameters":[{"name":"query","required":true,"in":"query","description":"MetricsQL / PromQL query expression","schema":{"type":"string"}},{"name":"time","required":false,"in":"query","description":"Evaluation timestamp (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"timeout","required":false,"in":"query","description":"Query timeout (duration), forwarded to VictoriaMetrics","schema":{"type":"string"}}],"responses":{"200":{"description":"Query result from VictoriaMetrics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## Query metrics (instant query)

> Execute an instant query against VictoriaMetrics using MetricsQL/PromQL syntax.\
> \
> \*\*Query Examples:\*\*\
> \- \`sfpowerscripts.build.duration\` - Get latest value\
> \- \`sum(sfpowerscripts.build.completed)\` - Aggregate counts\
> \- \`sfpowerscripts.build.duration{package="core"}\` - Filter by tag\
> \- \`rate(sfpowerscripts.build.completed\[1h])\` - Calculate rate over 1 hour\
> \
> See \[MetricsQL documentation]\(<https://docs.victoriametrics.com/metricsql/>) for full syntax.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/api/v1/query":{"get":{"operationId":"MetricsController_query","summary":"Query metrics (instant query)","description":"Execute an instant query against VictoriaMetrics using MetricsQL/PromQL syntax.\n\n**Query Examples:**\n- `sfpowerscripts.build.duration` - Get latest value\n- `sum(sfpowerscripts.build.completed)` - Aggregate counts\n- `sfpowerscripts.build.duration{package=\"core\"}` - Filter by tag\n- `rate(sfpowerscripts.build.completed[1h])` - Calculate rate over 1 hour\n\nSee [MetricsQL documentation](https://docs.victoriametrics.com/metricsql/) for full syntax.","parameters":[{"name":"query","required":true,"in":"query","description":"MetricsQL / PromQL query expression","schema":{"type":"string"}},{"name":"time","required":false,"in":"query","description":"Evaluation timestamp (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"timeout","required":false,"in":"query","description":"Query timeout (duration), forwarded to VictoriaMetrics","schema":{"type":"string"}}],"responses":{"200":{"description":"Query result from VictoriaMetrics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## Query metrics over time range

> Execute a range query to get metrics over a time period with specified resolution.\
> \
> \*\*Use Cases:\*\*\
> \- Generate time-series data for charts\
> \- Analyze trends over time\
> \- Calculate aggregates across time windows\
> \
> \*\*Parameters:\*\*\
> \- \`start\`/\`end\`: Time range (RFC3339 or Unix seconds)\
> \- \`step\`: Resolution (e.g., \`30s\`, \`1m\`, \`5m\`, \`1h\`)\
> \
> \*\*Example:\*\* Query build durations over the last 24 hours with 1-hour resolution.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/query_range":{"get":{"operationId":"MetricsController_queryRange","summary":"Query metrics over time range","description":"Execute a range query to get metrics over a time period with specified resolution.\n\n**Use Cases:**\n- Generate time-series data for charts\n- Analyze trends over time\n- Calculate aggregates across time windows\n\n**Parameters:**\n- `start`/`end`: Time range (RFC3339 or Unix seconds)\n- `step`: Resolution (e.g., `30s`, `1m`, `5m`, `1h`)\n\n**Example:** Query build durations over the last 24 hours with 1-hour resolution.","parameters":[{"name":"query","required":true,"in":"query","description":"MetricsQL / PromQL query expression","schema":{"type":"string"}},{"name":"start","required":true,"in":"query","description":"Range start (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"end","required":true,"in":"query","description":"Range end (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"step","required":true,"in":"query","description":"Step / resolution (duration, e.g. 30s, 1m)","schema":{"type":"string"}},{"name":"timeout","required":false,"in":"query","description":"Query timeout (duration), forwarded to VictoriaMetrics","schema":{"type":"string"}}],"responses":{"200":{"description":"Range query result with time-series data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## Query metrics over time range

> Execute a range query to get metrics over a time period with specified resolution.\
> \
> \*\*Use Cases:\*\*\
> \- Generate time-series data for charts\
> \- Analyze trends over time\
> \- Calculate aggregates across time windows\
> \
> \*\*Parameters:\*\*\
> \- \`start\`/\`end\`: Time range (RFC3339 or Unix seconds)\
> \- \`step\`: Resolution (e.g., \`30s\`, \`1m\`, \`5m\`, \`1h\`)\
> \
> \*\*Example:\*\* Query build durations over the last 24 hours with 1-hour resolution.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/api/v1/query_range":{"get":{"operationId":"MetricsController_queryRange","summary":"Query metrics over time range","description":"Execute a range query to get metrics over a time period with specified resolution.\n\n**Use Cases:**\n- Generate time-series data for charts\n- Analyze trends over time\n- Calculate aggregates across time windows\n\n**Parameters:**\n- `start`/`end`: Time range (RFC3339 or Unix seconds)\n- `step`: Resolution (e.g., `30s`, `1m`, `5m`, `1h`)\n\n**Example:** Query build durations over the last 24 hours with 1-hour resolution.","parameters":[{"name":"query","required":true,"in":"query","description":"MetricsQL / PromQL query expression","schema":{"type":"string"}},{"name":"start","required":true,"in":"query","description":"Range start (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"end","required":true,"in":"query","description":"Range end (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"step","required":true,"in":"query","description":"Step / resolution (duration, e.g. 30s, 1m)","schema":{"type":"string"}},{"name":"timeout","required":false,"in":"query","description":"Query timeout (duration), forwarded to VictoriaMetrics","schema":{"type":"string"}}],"responses":{"200":{"description":"Range query result with time-series data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## List distinct label values

> Get all distinct values for a specific label/tag across metrics.\
> \
> \*\*Common Labels:\*\*\
> \- \`package\`: Package names\
> \- \`org\`: Org aliases\
> \- \`pipeline\`: Pipeline identifiers\
> \- \`sfp\_metric\_type\`: Metric type (count, guage, timers)\
> \- \`\_\_name\_\_\`: Metric names\
> \
> \*\*Use Cases:\*\*\
> \- Populate filter dropdowns in dashboards\
> \- Discover available dimensions for queries

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/label/{name}/values":{"get":{"operationId":"MetricsController_labelValues","summary":"List distinct label values","description":"Get all distinct values for a specific label/tag across metrics.\n\n**Common Labels:**\n- `package`: Package names\n- `org`: Org aliases\n- `pipeline`: Pipeline identifiers\n- `sfp_metric_type`: Metric type (count, guage, timers)\n- `__name__`: Metric names\n\n**Use Cases:**\n- Populate filter dropdowns in dashboards\n- Discover available dimensions for queries","parameters":[{"name":"name","required":true,"in":"path","schema":{"type":"string"}},{"name":"start","required":false,"in":"query","description":"Optional start time (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"end","required":false,"in":"query","description":"Optional end time (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"match","required":false,"in":"query","description":"Optional match[] selectors (repeatable)","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"List of distinct label values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```

## List distinct label values

> Get all distinct values for a specific label/tag across metrics.\
> \
> \*\*Common Labels:\*\*\
> \- \`package\`: Package names\
> \- \`org\`: Org aliases\
> \- \`pipeline\`: Pipeline identifiers\
> \- \`sfp\_metric\_type\`: Metric type (count, guage, timers)\
> \- \`\_\_name\_\_\`: Metric names\
> \
> \*\*Use Cases:\*\*\
> \- Populate filter dropdowns in dashboards\
> \- Discover available dimensions for queries

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"MetricsQueryResponseDto":{"type":"object","properties":{"result":{"type":"object","description":"Opaque VictoriaMetrics response"}},"required":["result"]}}},"paths":{"/sfp/api/metrics/api/v1/label/{name}/values":{"get":{"operationId":"MetricsController_labelValues","summary":"List distinct label values","description":"Get all distinct values for a specific label/tag across metrics.\n\n**Common Labels:**\n- `package`: Package names\n- `org`: Org aliases\n- `pipeline`: Pipeline identifiers\n- `sfp_metric_type`: Metric type (count, guage, timers)\n- `__name__`: Metric names\n\n**Use Cases:**\n- Populate filter dropdowns in dashboards\n- Discover available dimensions for queries","parameters":[{"name":"name","required":true,"in":"path","schema":{"type":"string"}},{"name":"start","required":false,"in":"query","description":"Optional start time (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"end","required":false,"in":"query","description":"Optional end time (RFC3339 or unix seconds)","schema":{"type":"string"}},{"name":"match","required":false,"in":"query","description":"Optional match[] selectors (repeatable)","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"List of distinct label values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Metrics"]}}}}
```
