# Get a service's SLA report

`GET https://evohub.io/api/v1/catalog/components/{ref}/sla-report`

Part of the [Catalog API](https://docs.evohub.io/catalog.md) reference · operationId `getComponentSLAReport`.

One calendar month in UTC, the current one by default (measured up to
now, `complete: false`). The targets are the service's tier as it
read at the end of the month, with the service's own overrides.
Availability is summed over the Uptime monitors tied to the service;
response and resolution come from the On-Call alerts raised by the
integrations and monitors tied to it, per severity.

Each part says `measured`, `not_connected` or `unavailable`; one
part that cannot be measured never fails the report. Measurement runs
around the clock: support hours are shown but not applied yet.

Requires the `catalog:component:read` scope.

## Authorization

Any one of:

- `bearerKey`
- `headerKey`

Where:

- `bearerKey`: HTTP Bearer — An EvoHub API key (`evohub_…`) as a bearer token.
- `headerKey`: API key in the header `X-API-Key` — An EvoHub API key (`evohub_…`).

## Path parameters

- `ref` (string, required, example `payments-api`): The service's ID (`cmp_…`) or its slug.

## Query parameters

- `month` (string, pattern `^[0-9]{4}-[0-9]{2}$`, example `2026-10`): `YYYY-MM`, from 2020-01 to the current month.

## Responses

### 200 — The report.

Content type: `application/json`

Type: `object`

- `data` (SLAReport)
  - `component_id` (string)
  - `month` (string, example `2026-10`)
  - `from` (string)
  - `to` (string)
  - `complete` (boolean): False for the current month, measured up to now.
  - `tier` (object | null)
    - `id` (string)
    - `name` (string)
    - `version` (integer)
  - `targets` (SLATargets)
    - `availability` (number, example `99.9`): A percentage above 0 and at most 100, up to 3 decimals.
    - `response` (object): Minutes to acknowledge, per On-Call severity (`critical`, `high`, `medium`, `low`, `info`), 1 to 525600.
      - Other keys: integer
    - `resolution` (object): Minutes to resolve, per severity.
      - Other keys: integer
    - `support_hours` (object)
      - `kind` (string, required, one of `24x7`, `business`)
      - `timezone` (string, example `Europe/Istanbul`)
      - `days` (array of integer): ISO weekdays, 1 is Monday.
      - `from` (string, example `09:00`)
      - `to` (string, example `18:00`)
    - `max_unowned_days` (integer, min 0, max 3650)
  - `availability` (object)
    - `status` (MeasureStatus, one of `measured`, `not_connected`, `unavailable`)
    - `target` (number | null)
    - `uptime` (number | null)
    - `total_checks` (integer)
    - `up_checks` (integer)
    - `met` (boolean | null)
    - `monitors` (array of object)
      - `id` (string)
      - `name` (string)
      - `total_checks` (integer)
      - `up_checks` (integer)
      - `uptime` (number | null)
  - `alerts` (object)
    - `status` (MeasureStatus, one of `measured`, `not_connected`, `unavailable`)
    - `severities` (array of object)
      - `severity` (string, example `critical`)
      - `alerts` (integer)
      - `acknowledged` (integer)
      - `resolved` (integer)
      - `open` (integer)
      - `response_target` (integer | null)
      - `resolution_target` (integer | null)
      - `ack_p50_s` (number | null)
      - `ack_p90_s` (number | null)
      - `resolve_p50_s` (number | null)
      - `resolve_p90_s` (number | null)
      - `ack_breaches` (integer)
      - `resolve_breaches` (integer)
      - `response_met` (boolean | null)
      - `resolution_met` (boolean | null)

### 400 — The request is not valid: a field or filter value is wrong (`VALIDATION_ERROR`, with a sentence saying what), the body is not the expected JSON or carries an unknown field (`INVALID_BODY`), the cursor is not one this list gave (`INVALID_CURSOR`), a binding names a service that does not exist (`UNKNOWN_COMPONENT`), or a `PATCH` tries to change a slug (`SLUG_IMMUTABLE`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

### 401 — No API key was sent, or it is unknown, revoked or expired (`UNAUTHORIZED`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

### 403 — The key lacks a scope this endpoint needs (`FORBIDDEN`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

### 404 — Nothing with this ID (or slug) exists in the organization (`NOT_FOUND`).

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

### 429 — Too many requests (`RATE_LIMITED`). Wait for `Retry-After` seconds.

Headers:

- `Retry-After` (integer): Seconds to wait before retrying.

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

### 500 — Something went wrong on EvoHub's side (`INTERNAL_ERROR`). Retry later.

Content type: `application/json`

Type: `Error`

- `error` (object, required)
  - `code` (string, required, example `NOT_FOUND`)
  - `message` (string, required, example `not found`)
  - `request_id` (string)

## Example request

```bash
curl -X GET 'https://evohub.io/api/v1/catalog/components/payments-api/sla-report' \
  -H 'Authorization: Bearer <TOKEN>'
```
