---
title: "Team hours HTTP API | Grafana Cloud documentation"
description: "Team hours HTTP API Use these endpoints to read and replace a team’s hours. Each team has up to three named intervals, and each interval has up to three time ranges per weekday. The team is within its hours when the current time falls in any range of any interval. For how IRM uses team hours, refer to Configure team hours."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Team hours HTTP API

Use these endpoints to read and replace a team’s hours. Each team has up to three named intervals, and each interval has up to three time ranges per weekday. The team is within its hours when the current time falls in any range of any interval. For how IRM uses team hours, refer to [Configure team hours](https://grafana.com/docs/grafana-cloud/observe-and-act/respond-to-incidents/escalation-and-routing/team-hours).

## Set a team’s hours

**Required permission**: `grafana-irm-app.other-settings:write`

This endpoint replaces all of a team’s intervals with the ones you send. Intervals you leave out are deleted.

shell ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```shell
curl "{{API_URL}}/api/v1/team_working_hours/" \
  --request POST \
  --header "Authorization: Bearer meowmeowmeow" \
  --header "Content-Type: application/json" \
  --header "X-Grafana-URL: https://your-stack.grafana.net" \
  --data '{
    "team_id": "TI73TDU19W48J",
    "irm_working_hours": [
      {
        "name": "Business hours",
        "irm_working_hours": {
          "monday": [{"start": "09:00", "end": "12:00"}, {"start": "13:00", "end": "17:00"}],
          "tuesday": [{"start": "09:00", "end": "17:00"}],
          "wednesday": [{"start": "09:00", "end": "17:00"}],
          "thursday": [{"start": "09:00", "end": "17:00"}],
          "friday": [{"start": "09:00", "end": "17:00"}]
        }
      },
      {
        "name": "Weekend coverage",
        "irm_working_hours": {
          "saturday": [{"start": "10:00", "end": "14:00"}]
        }
      }
    ]
  }'
```

The above command returns `201 Created` and JSON structured in the following way:

JSON ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```json
{
  "team_id": "TI73TDU19W48J",
  "timezone": "Europe/Dublin",
  "irm_working_hours": [
    {
      "name": "Business hours",
      "irm_working_hours": {
        "monday": [
          { "start": "09:00:00", "end": "12:00:00" },
          { "start": "13:00:00", "end": "17:00:00" }
        ],
        "tuesday": [{ "start": "09:00:00", "end": "17:00:00" }],
        "wednesday": [{ "start": "09:00:00", "end": "17:00:00" }],
        "thursday": [{ "start": "09:00:00", "end": "17:00:00" }],
        "friday": [{ "start": "09:00:00", "end": "17:00:00" }],
        "saturday": [],
        "sunday": []
      }
    },
    {
      "name": "Weekend coverage",
      "irm_working_hours": {
        "monday": [],
        "tuesday": [],
        "wednesday": [],
        "thursday": [],
        "friday": [],
        "saturday": [{ "start": "10:00:00", "end": "14:00:00" }],
        "sunday": []
      }
    }
  ]
}
```

To remove all of a team’s hours, send `"irm_working_hours": null` or an empty list. IRM then treats the team as always within its hours.

Expand table

| Parameter           | Required | Description                                                                                                                                                   |
|---------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `team_id`           | Yes      | ID of the team. Obtain team IDs from the [Teams API](https://grafana.com/docs/grafana-cloud/observe-and-act/respond-to-incidents/reference/oncall-api/teams). |
| `irm_working_hours` | Yes      | List of up to three intervals, or `null` to remove all intervals. Refer to **Interval fields** below.                                                         |

**Interval fields**

Expand table

| Parameter           | Required | Description                                                                                                                                             |
|---------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name`              | Yes      | Name of the interval, up to 100 characters.                                                                                                             |
| `irm_working_hours` | Yes      | Object keyed by weekday (`monday` to `sunday`). Each day is a list of up to three time ranges. Omit a day, or send an empty list, to make it a day off. |

Each time range is an object with `start` and `end` times in `HH:MM` or `HH:MM:SS` format, read in the team’s timezone. The following rules apply:

- `start` must be earlier than `end`. Ranges can’t run past midnight, so end the day at `23:59:59` and start the next day at `00:00:00` instead.
- List ranges on the same day in start-time order. Ranges can’t overlap, but one range can start when the previous one ends.
- Each interval needs at least one range on at least one day.

A request that breaks any of these rules returns `400 Bad Request` and changes nothing.

If the **Require team membership for updates** setting is on, users who aren’t members of the team get `403 Forbidden`. Administrators and service accounts can update any team.

The `timezone` field in the response is the team’s timezone, or `null` if it isn’t set, in which case IRM uses UTC. You can’t set the timezone with this endpoint. Set it in **IRM** &gt; **Settings** &gt; **Teams**.

**HTTP request**

`POST {{API_URL}}/api/v1/team_working_hours/`

## List team hours

**Required permission**: `grafana-irm-app.other-settings:read`

This endpoint lists the hours of every team that has team hours and that you can see. Teams without team hours aren’t included.

shell ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```shell
curl "{{API_URL}}/api/v1/team_working_hours/?team_id=TI73TDU19W48J" \
  --request GET \
  --header "Authorization: Bearer meowmeowmeow" \
  --header "Content-Type: application/json" \
  --header "X-Grafana-URL: https://your-stack.grafana.net"
```

The above command returns JSON structured in the following way:

JSON ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "team_id": "TI73TDU19W48J",
      "timezone": "Europe/Dublin",
      "irm_working_hours": [
        {
          "name": "Business hours",
          "irm_working_hours": {
            "monday": [{ "start": "09:00:00", "end": "17:00:00" }],
            "tuesday": [{ "start": "09:00:00", "end": "17:00:00" }],
            "wednesday": [{ "start": "09:00:00", "end": "17:00:00" }],
            "thursday": [{ "start": "09:00:00", "end": "17:00:00" }],
            "friday": [{ "start": "09:00:00", "end": "17:00:00" }],
            "saturday": [],
            "sunday": []
          }
        }
      ]
    }
  ],
  "page_size": 50,
  "current_page_number": 1,
  "total_pages": 1
}
```

> **Note**: The response is [paginated](https://grafana.com/docs/grafana-cloud/observe-and-act/respond-to-incidents/reference/oncall-api/#pagination). You may need to make multiple requests to get all records.

The following available filter parameter should be provided as a `GET` argument:

- `team_id` (Exact match)

**HTTP request**

`GET {{API_URL}}/api/v1/team_working_hours/`
