---
title: "Get API request metrics"
method: POST
path: "/v2/logs.getApiRequestMetrics"
tags: ["logs"]
---

# Get API request metrics

`POST /v2/logs.getApiRequestMetrics`

## Request

- Base URL: `https://api.unkey.com`
- URL: `https://api.unkey.com/v2/logs.getApiRequestMetrics`
- Auth: HTTP bearer

Count the requests that the Unkey API served for your workspace per time bucket, split by status class.

The filters have the same shape as in `logs.listApiRequests`, without `requestId`. In one field, values under `is`, `contains`, `startsWith`, and `endsWith` are combined with OR. Values under `isNot` and `notContains`, and the range operators `gt`, `gte`, `lt`, and `lte`, are combined with AND. Different fields are combined with AND. Every text match is exact and case-sensitive.

`filters.time` sets the window. A missing lower bound is the start of your log retention, and a missing upper bound is now. Unkey picks the bucket width from the window. It is the distance between the `time` of two points. The first bucket starts at or before the window start and counts its whole width. Windows reach back at most 100 days, and requests outside the log retention of your workspace are not counted.

**Required Permissions**

Your root key must have the following permission:
- `unkey:v1:<workspace_id>:logs/apiRequests#read`

## Request body

- V2LogsGetApiRequestMetricsRequestBody
  - `filters` V2LogsGetApiRequestMetricsFilters: Filters for the metrics. They have the same shape as the filters of `logs.listApiRequests`, without `requestId`. A missing field does not filter. Different fields are combined with AND.
    - `time` TimeFilter: Filters by the time of the event, in Unix milliseconds. Every bound is combined with AND. Rows older than the workspace's retention are never returned or counted, whatever the bounds.
      - `gt` integer: Keep events after this time.
      - `gte` integer: Keep events at or after this time.
      - `lt` integer: Keep events before this time.
      - `lte` integer: Keep events at or before this time.
    - `path` TextFilter: Filters a text field. Every operator is exact and case-sensitive. `%` and `_` match only themselves. The positive operators (`is`, `contains`, `startsWith`, `endsWith`) are combined with OR. The negated operators (`isNot`, `notContains`) are combined with AND.
      - `is` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
      - `isNot` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
      - `contains` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
      - `notContains` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
      - `startsWith` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
      - `endsWith` string[]: The values of one filter operator. A row matches a positive operator when it matches any value in the list. A row matches a negated operator only when it matches none of the values.
    - `method` MethodFilter: Filters by HTTP method.
      - `is` HttpMethod[]: Keep rows with one of these methods.
      - `isNot` HttpMethod[]: Remove rows with one of these methods.
    - `status` IntFilter: Filters an integer field. `is` keeps rows that equal one of its values. `isNot` and every bound (`gt`, `gte`, `lt`, `lte`) are combined with AND, so `{ "is": [200], "gte": 400 }` matches no rows.
      - `is` integer[]: The values of one filter operator. A row matches `is` when it equals any value in the list. A row matches `isNot` only when it equals none of the values.
      - `isNot` integer[]: The values of one filter operator. A row matches `is` when it equals any value in the list. A row matches `isNot` only when it equals none of the values.
      - `gt` integer: Keep rows where the field is greater than this value.
      - `gte` integer: Keep rows where the field is greater than or equal to this value.
      - `lt` integer: Keep rows where the field is less than this value.
      - `lte` integer: Keep rows where the field is less than or equal to this value.

## Response `200`

One point per bucket, oldest first, with zero counts for buckets without requests.

- V2LogsGetApiRequestMetricsResponseBody
  - `meta` Meta, required: Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
    - `requestId` string, required: A unique id for this request. Always include this ID when contacting support about a specific API request. This identifier allows Unkey's support team to trace the exact request through logs and diagnostic systems to provide faster assistance.
  - `data` ApiRequestMetricsPoint[], required: One point per bucket, oldest first, with no gaps. A bucket with no requests has a point with zero counts. The bucket width is the distance between the `time` of two points.
    - `time` integer, required: The start of the bucket, in Unix milliseconds.
    - `success` integer, required: The number of requests with a 2xx status.
    - `clientError` integer, required: The number of requests with a 4xx status.
    - `serverError` integer, required: The number of requests with a 5xx status.
    - `total` integer, required: The number of requests with any status. It also counts 1xx and 3xx responses, which have no field of their own.

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden - Insufficient permissions (requires `unkey:v1:<workspace_id>:logs/apiRequests#read`)
- `422`: The query exceeds a query limit
- `500`: Internal server error
- `503`: The log store is not available

## Changes

- **2026-10-29** `98f3840fcf12`: 1 info
  - removed the non-success response with the status `429`
- **2026-10-23** `38201ca90b60`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/unkeyed/apis/unkey-api/changes/v2/logs.getApiRequestMetrics/post.md)

---

[API](https://skmtc.dev/unkeyed/apis/unkey-api.md) - [All operations](https://skmtc.dev/unkeyed/apis/unkey-api/llms.txt) - [OpenAPI document](https://skmtc.dev/unkeyed/apis/unkey-api/revisions/6fbaa27f19e0?raw)
