Custom Metrics (API)
Collect any business or platform signal as custom metrics and visualise it alongside your Host/Kubernetes/Service telemetry in Middleware.
You can send metrics in two ways:
- HTTP (OTLP/JSON): Simple
curl/scripted pushes to/v1/metrics - OpenTelemetry SDKs: Instrument your app and export to Middleware over OTLP
Option A: Send custom data with cURL (OTLP/JSON)
POST your payload to OTLP Metrics HTTP endpoint:
curl -X POST "https://<MW_UID>.middleware.io:443/v1/metrics" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: <MW_API_KEY>" \
-d @- << 'EOF'
{
"resource_metrics": [
{
"resource": {
"attributes": [
{ "key": "mw.resource_type", "value": { "string_value": "custom" } },
{ "key": "service.name", "value": { "string_value": "custom-metrics-pusher" } }
]
},
"scope_metrics": [
{
"metrics": [
{
"name": "swap-usage",
"description": "SWAP usage",
"unit": "By",
"gauge": {
"data_points": [
{
"attributes": [
{ "key": "device", "value": { "string_value": "nvme0n1p4" } }
],
"time_unix_nano": 1759743015000000000,
"asInt": 4000500678
}
]
}
}
]
}
]
}
]
}
EOFNotes:
- Use
asIntfor integer values orasDoublefor floating-point values. time_unix_nanois the event timestamp; if omitted, the backend may use its receive time.- You can send multiple metrics in the same batch; add them to the
metricsarray. - To attach the metric to an existing resource (host/pod/service/etc.), add the required resource attribute(s) (see tables below).
Option B: Send custom metrics via OpenTelemetry
If you want to send custom metrics via your codebase, you need to install the OpenTelemetry Python SDK:
pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlpYou can use the template codebase given below to send custom metrics:
import time
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
# Configure OTLP exporter for Middleware
exporter = OTLPMetricExporter(
endpoint="https://ruplp.middleware.io", # no /v1/metrics for gRPC
headers={"authorization": "<MW_API_KEY>"},
)
# Attach resource attributes (choose one of the options shown in the tables below)
resource = Resource.create({
"mw.resource_type": "custom",
"service.name": "custom-metrics-pusher"
})
metric_reader = PeriodicExportingMetricReader(exporter)
provider = MeterProvider(resource=resource, metric_readers=[metric_reader])
metrics.set_meter_provider(provider)
meter = metrics.get_meter(__name__)
counter = meter.create_counter(
name="custom_counter",
description="Counts something custom",
unit="1",
)
histogram = meter.create_histogram(
name="custom_histogram",
description="Records histogram data",
unit="ms",
)
while True:
counter.add(1, attributes={"environment": "production", "region": "us-east-1"})
histogram.record(100, attributes={"operation": "database_query"})
time.sleep(5)For other languages (Node.js/Go/Java, etc.), configure the OTLP/gRPC or OTLP/HTTP exporter and set the same endpoint and authorization header.
Ingest into existing Middleware resource types
Attach the required resource attribute so the metric lands in the correct dataset:
| Type | Required resource attributes | Data set stored in |
|---|---|---|
host | host.id | Host Metrics |
k8s.node | k8s.node.uid | K8s Node Metrics |
k8s.pod | k8s.pod.uid | K8s Pod Metrics |
k8s.deployment | k8s.deployment.uid | K8s Deployment Metrics |
k8s.daemonset | k8s.daemonset.uid | K8s DaemonSet Metrics |
k8s.replicaset | k8s.replicaset.uid | K8s ReplicaSet Metrics |
k8s.statefulset | k8s.statefulset.uid | K8s StatefulSet Metrics |
k8s.namespace | k8s.namespace.uid | K8s Namespace Metrics |
service | service.name | Service Metrics |
os | os.type | OS Metrics |
Example (host):
Add to the resource.attributes:
{ "key": "host.id", "value": { "string_value": "ip-10-0-0-12" } }Ingest pure custom data (no existing type)
If your metric doesn’t belong to an existing resource, set:
{ "key": "mw.resource_type", "value": { "string_value": "custom" } }These metrics appear under the Custom Metrics dataset in the UI and can be charted, alerted, and filtered using any attributes you attach.
Verify Delivery
- Send a test data point.
- In the dashboard, open dashboard builder → Create a new or open an existing dashboard and add a metrics widget.
- Under the Look for menu, select Custom, and the data should start showing in the selected dashboard.

Troubleshooting (quick)
- 401/403: Check the
Authorizationheader (noBearer), that the key is active, and you’re hitting the correct region. - 400/422: Validate OTLP structure — ensure
resource_metrics[*].scope_metrics[*].metrics[*]contains one ofgauge/sum/histogramwith adata_pointsarray. - No data visible: Confirm
mw.resource_typeor the correct resource attribute (e.g.,host.id) is set. Ensure timestamps are realistic nanoseconds. - High cardinality: Reduce dynamic attribute values; prefer enums/buckets.
- gRPC exporters: Use endpoint without
/v1/metricsand keep TLS enabled (port 443).
Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.