# Get a metric

> One metric over time, one value per step: gauges averaged in each step (or min or max), sums added (a cumulative sum becomes its increase), histograms their mean or a percentile (p50, p95, p99) from their buckets. group_by splits it into a series per value of an attribute (or service).

<div class="g1t-endpoint"><span class="g1t-method" data-method="get">GET</span><code>/workspaces/{workspace}/projects/{project}/observability/metrics/{metric}</code></div>

The last 24 hours unless from and to say. Needs a role on the project's repository.

A metric name with characters outside letters, digits, `.`, `_` and `-` is URL-encoded in the path. Gauges average in each step unless `aggregate` says `min` or `max`; sums add, and a cumulative sum becomes its increase; histograms give their mean, or a percentile from their buckets.

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`observability`](/reference/mcp/#observability) with `action` `metric`, and the same inputs
- **Scope:** An access token needs [`observability:read`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace` | string | Yes | The workspace's slug, e.g. "flagon-io". |
| `project` | string | Yes | The project's slug, as in g1t.sh/{workspace}/{project}. |
| `metric` | string | Yes | The metric's name, such as http.server.request.duration. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | No | The start of the period: an RFC 3339 time or Unix milliseconds. 24 hours before `to` unless you say. |
| `to` | string | No | The end of the period: an RFC 3339 time or Unix milliseconds. Now unless you say. |
| `aggregate` | string | No | How each step's values are reduced: avg for gauges and sum for sums unless you say; a percentile for histograms. One of `avg`, `sum`, `min`, `max`, `p50`, `p95`, `p99`. |
| `group_by` | string | No | An attribute (or service) to split it into a series per value. |
| `step` | integer | No | Seconds per point; chosen from the period unless you say. |
| `service` | string | No | Only what this service sent (OpenTelemetry's service.name; an app on g1t.page is its project's name); several comma-separated. |
| `environment` | string | No | Only what ran in this environment, such as production or preview; several comma-separated. |

## Example request

```sh
curl "https://api.g1t.sh/workspaces/flagon-io/projects/g1t/observability/metrics/http.server.request.duration?aggregate=p95&group_by=http.route&step=300" \
  -H "Authorization: Bearer $G1T_TOKEN"
```

## Example response

A successful request answers `200` with:

```json
{
  "name": "http.server.request.duration",
  "unit": "s",
  "step_s": 300,
  "series": [
    {
      "group": "/repos/:owner/:name/pulls",
      "points": [
        {
          "time_us": 1791813300000000,
          "value": 0.212
        },
        {
          "time_us": 1791813600000000,
          "value": 0.236
        }
      ]
    }
  ]
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change, or a token without the scope it needs. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
