M2A Cloudwatch Metrics (local)

Download OpenAPI specification:

Cloudwatch Metrics pairs up with the Templates Service to serve up cool graphs that'll provide insight into the current and historic state of the underlying AWS resources that make M2A's services go.

Metrics

Render Cloudwatch metric widget images from templates registered with the m2a-templates-api service.

Render a templated Cloudwatch Metric Widget Image

Render a Cloudwatch Metric Widget Image based on a predefined query template.

A jinja template of service type: METRICS must be registered to the m2a-templates-api with the appropriate placeholder keys (start, end, height, width), along with placeholder keys for any resources that are being monitored.

Placeholder keys for resources are the plural of the resource name (i.e. caches, encoders, packagers, sources, computers) followed by a list of the resource responses for all resources of that type from that resource's GET API endpoint. e.g. a placeholder method within the template could be {{for encoder in encoders}} {{encoder.data.attributes.channel.aws.arn}}.

See the POST template API reference for details on how to build and create a METRICS template.

Example template:

{
  "metrics": [
    {% set comma = joiner(",") %}
    {% for packager in packagers %}
      {{ comma() }}
      {% set region = packager['channel']['arn'].split(':')[3] %}
      {% set packager_id_suffix_safe = '_' + packager['id'].split('-') | join('_') %}
      [
        {
          "expression": "bytes{{packager_id_suffix_safe}} * 8 / PERIOD(bytesRaw{{packager_id_suffix_safe}})",
          "id": "bitRate{{packager_id_suffix_safe}}",
          "color": "#08aad2",
          "label": "{{packager.channel.id}}"
        }
      ],
      [
        {
          "expression": "FILL(bytesRaw{{packager_id_suffix_safe}}, 0)",
          "id": "bytes{{packager_id_suffix_safe}}",
          "visible": false
        }
      ],
      [
        "AWS/MediaPackage", "EgressBytes", "Channel", "{{packager.channel.id}}",
        {
          "id": "bytesRaw{{packager_id_suffix_safe}}",
          "visible": false,
          "stat": "Sum",
          "region": "{{region}}"
        }
      ]
    {% endfor %}
  ],
  "view": "timeSeries",
  "width": {{width}},
  "height": {{height}},
  "period": 60,
  "title": "Channel Throughput",
  "theme": "dark",
  "start": "{{start}}",
  "end": "{{end}}",
  "yAxis": {
    "left": {
      "min": 0,
      "showUnits": false,
      "label": "Bitrate (bps)"
    }
  },
  "legend": {
    "position": "bottom"
  }
}

Example image:

Example rendered Cloudwatch metric widget image

See example query to make into templates in the AWS Cloudwatch Get Metric Widget Image API documentation: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricWidgetImage.html

Authorizations:
BearerAuth
query Parameters
owner-id
required
string <uuid>

Owner of the resources being monitored (the target account ID)

template-name
required
string

Name of the template Cloudwatch Metric Widget Image payload as registered with the m2a-templates-api service

resource
required
Array of strings [ 1 .. 100 ] items [ items^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]... ]

List of resources formed of the ID of resource to monitor and its type separated by a colon. Format: <uuid>:cache|encoder|packager|source|computer. Can pass multiple values. At least one resource is required. A single graph can plot at most 100 Cloudwatch metrics, so requests that expand to more than 100 metrics via the template are rejected by AWS.

start
string
Default: "-PT1H"

Start of the time window shown in the metric graph. Provide either an absolute point in time as an ISO 8601 datetime (e.g., 2018-04-25T12:00:00.000Z) or a relative offset back from "now" as an ISO 8601 duration (e.g., -PT3H for three hours ago). Defaults to -PT1H (one hour ago) if not provided. start and end must be given in the same form (both absolute datetimes or both relative durations), and start must be earlier than end.

end
string

End of the time window shown in the metric graph. Provide either an absolute point in time as an ISO 8601 datetime (e.g., 2018-04-25T12:00:00.000Z) or a relative offset back from "now" as an ISO 8601 duration (e.g., -PT1H for one hour ago). Required when start is an absolute datetime. May be omitted when start is a relative duration, in which case the window ends at the current time. When provided, end must be in the same form as start and must be later than start.

height
required
integer [ 1 .. 2000 ]

Height of the returned image in pixels. Must be between 1 and 2000 inclusive, as enforced by the AWS Cloudwatch GetMetricWidgetImage API.

width
required
integer [ 1 .. 2000 ]

Width of the returned image in pixels. Must be between 1 and 2000 inclusive, as enforced by the AWS Cloudwatch GetMetricWidgetImage API.

header Parameters
Accept
required
string
Value: "image/png"
Example: image/png

Content type (expressed as MIME types) the client is able to understand.

Responses

Response samples

Content type
application/json
{
  • "error": "No identity found in request"
}

Metric Data

Return Cloudwatch time series data plus the rendering metadata a client needs to draw its own charts, from templates registered with the m2a-templates-api service.

Return chart-ready Cloudwatch time series data

Fetch the time series for one or more metric charts and return each chart together with the metadata a client needs to draw it — series values and labels, units, axis binding, chart type, colours, and threshold annotations.

Each requested template is a METRIC_DATA template registered with the m2a-templates-api service that describes one chart: the metrics to query and how the chart should be presented. The service renders every requested template against the supplied resources, resolves the time window, and issues a single batched AWS GetMetricData call covering all of them; the results are split back out and returned as an ordered charts array, one entry per template.

Resolution. The granularity of the returned data is derived from the time window: it is the coarser of the retention floor for the window start (Cloudwatch retains older data only at coarser resolution) and the render-budget ceiling (max-render-points), snapped to a valid Cloudwatch period. The value actually used is returned in meta.effectivePeriod and is the natural basis for cache TTL. The standard resolutions periods that may be snapped to are 1, 5, 10, 20, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200, 21600 seconds. The service always returns the finest period that works for the requested window and render budget, so the client can always render and label the data correctly.

Render budget. The max-render-points parameter is a per-series render budget: the maximum number of datapoints returned per series. The service caps datapoints by promoting the period so that at most this many points (snapped to a valid Cloudwatch period) are returned. The default is 1440 — one day of data at a 60s period — which is also the maximum. A smaller value can be supplied for a lighter payload.



Partial results. A single failed template or unresolvable resource returns a per-chart error while the request as a whole still returns 200. A template that resolves but has no datapoints in the window returns a valid empty chart, not an error.

Authorizations:
BearerAuth
query Parameters
owner-id
required
string <uuid>

Owner of the resources being monitored (the target account ID)

templates
required
Array of strings non-empty [ items non-empty ]

Comma-separated list of METRIC_DATA template names registered with the m2a-templates-api service. At least one template is required. Each template becomes one entry in the charts array, in the order given. Template Id values are namespaced per template server-side before the batched GetMetricData call, so ids never collide across templates. Template names are owned and validated by the m2a-templates-api service, so no name shape is imposed here: a name that service does not know returns a per-chart template_not_found error inside a 200 rather than failing the request, so one unusable name never costs the batch its other charts. Because the list is comma-delimited (explode: false), a template name containing a comma cannot be requested.

resources
required
Array of strings non-empty [ items^(?:cache|encoder|packager|source|computer):[... ]
Example: resources=source:23bb15d0-f458-4d36-b29e-8958d0830226,source:4a553a18-f22c-4b0f-b7e8-e1b8228a3176

Comma-separated list of resources to monitor, each formed of its type and the resource ID (UUID) separated by a colon. Format: cache|encoder|packager|source|computer:<uuid>. At least one resource is required. All resources in a request must be of the same type; mixing resource types (e.g. sources and caches) in one request is not supported and is rejected with a 422. A template only renders for the resource family it was written for, so a request pairing a resource type with a template for another family returns a per-chart error rather than data. The same resource set is supplied to every requested template; each template selects the resources it needs. A request whose templates expand to more Cloudwatch metrics than one GetMetricData call accepts is split across several calls and returned as one page, so no limit on the combined metric count applies here.

range
string <duration>
Default: "PT1H"

Relative time window ending at the current time, given as an ISO 8601 duration (e.g., PT3H for the last three hours). This is the default way to request a window and the natural fit for preset ranges and live refresh. Ignored when an absolute start is supplied. The resolved absolute window is returned in meta.start/meta.end. The service applies the duration backwards from now, so it must be positive and unsigned: a signed duration (-PT1H) or one covering no time at all (PT0S) is rejected with a 422.

start
string <date-time> ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d...
Example: start=2026-01-20T00:00:00Z

Absolute start of the time window, as an ISO 8601 datetime to seconds accuracy with a timezone designator — either Z for UTC or a numeric offset (e.g., 2026-01-20T00:00:00Z or 2026-01-20T01:00:00+01:00). Supplying start selects absolute mode and takes precedence over range. When set, end must also be supplied and must be later than start.

end
string <date-time> ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d...
Example: end=2026-01-20T01:00:00Z

Absolute end of the time window, as an ISO 8601 datetime to seconds accuracy with a timezone designator — either Z for UTC or a numeric offset (e.g., 2026-01-20T01:00:00Z or 2026-01-20T02:00:00+01:00). Defaults to the current time. Only used in absolute mode, i.e. when start is supplied.

period
integer [ 1 .. 86400 ]
Example: period=60

Optional explicit period (resolution) in seconds. Legal values are 1, 5, 10, 20, 30, 60, or any whole multiple of 60; values below 60 are only available for high-resolution metrics. When omitted, the service chooses a period automatically from the requested window and the render budget. A requested period is also subject to a floor: Cloudwatch retains older data only at coarser resolution, so a fine period cannot be served for a window that reaches far into the past. If the requested period cannot be honoured for the requested window the service does not fail — it falls back to the finest period that works for that window. The period actually used is always returned in meta.effectivePeriod. Capped at 86400 seconds, the coarsest resolution the service ever derives.

max-render-points
integer [ 1 .. 1440 ]
Default: 1440

Optional per-series render budget: the maximum number of datapoints returned per series. The service caps datapoints by promoting the period so that at most this many points (snapped to a valid Cloudwatch period) are returned. Defaults to 1440 — one day of data at a 60s period — which is also the maximum. Supply a smaller value for a lighter payload. Echoed back in meta.maxRenderPointsPerSeries.

header Parameters
Accept
string
Example: application/json

Content types the client is able to understand. This endpoint serves JSON time series data and nothing else, so the header is a preference rather than a value that must match: it is negotiated as HTTP defines, across the whole weighted list of media ranges. Sending no header, */*, application/*, or a list that includes application/json alongside other types all return the JSON response. Only a header that rules JSON out — one naming solely other types, or weighting JSON at q=0 — is refused, with a 406.

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "charts": [
    ]
}