---
title: "Grafana OnCall users HTTP API | Grafana Cloud documentation"
description: "Grafana OnCall users HTTP API Get a user Required permission: grafana-irm-app.user-settings:read This endpoint retrieves the user object. shell Copy curl \"{{API_URL}}/api/v1/users/current/\" \\ --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:"
---

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

# Grafana OnCall users HTTP API

## Get a user

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

This endpoint retrieves the user object.

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

```shell
curl "{{API_URL}}/api/v1/users/current/" \
  --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](/media/images/icons/icon-copy-small-2.svg) Copy

```json
{
  "id": "U4DNY931HHJS5",
  "grafana_id": 456,
  "email": "public-api-demo-user-1@grafana.com",
  "slack": {
    "user_id": "UALEXSLACKDJPK",
    "team_id": "TALEXSLACKDJPK"
  },
  "username": "alex",
  "role": "admin",
  "timezone": "UTC",
  "teams": [],
  "is_phone_number_verified": true,
  "phone_number": "+12345678901",
  "phone_number_status": "available"
}
```

**HTTP request**

`GET {{API_URL}}/api/v1/users/<USER_ID>/`

Use `{{API_URL}}/api/v1/users/current` to retrieve the current user.

Expand table

| Parameter                  | Unique  | Description                                                                                                                      |
|----------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------|
| `id`                       | Yes/org | OnCall user ID                                                                                                                   |
| `grafana_id`               | Yes/org | Grafana user ID                                                                                                                  |
| `email`                    | Yes/org | User e-mail                                                                                                                      |
| `slack`                    | Yes/org | User ID from connected Slack. User linking key is e-mail.                                                                        |
| `username`                 | Yes/org | User username                                                                                                                    |
| `role`                     | No      | One of: `user`, `observer`, `admin`.                                                                                             |
| `timezone`                 | No      | timezone of the user one of [time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).                          |
| `teams`                    | No      | List of team IDs the user belongs to                                                                                             |
| `is_phone_number_verified` | No      | Whether the user has a verified phone number.                                                                                    |
| `phone_number`             | No      | The user’s verified phone number, or `null` if not configured or private.                                                        |
| `phone_number_status`      | No      | One of: `available` (number returned), `private` (user has hidden their number), `not_configured` (user has no verified number). |

> Note
> 
> When the organization setting **Override phone number privacy for API** is enabled, users who have set their phone number to private will still have their number returned with status `available`. This setting does not affect phone number visibility in the UI.

## List Users

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

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

```shell
curl "{{API_URL}}/api/v1/users/" \
  --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](/media/images/icons/icon-copy-small-2.svg) Copy

```json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "U4DNY931HHJS5",
      "grafana_id": 456,
      "email": "public-api-demo-user-1@grafana.com",
      "slack": {
        "user_id": "UALEXSLACKDJPK",
        "team_id": "TALEXSLACKDJPK"
      },
      "username": "alex",
      "role": "admin",
      "timezone": "UTC",
      "teams": ["TAAM1K1NNEHAG"],
      "is_phone_number_verified": true,
      "phone_number": "+12345678901",
      "phone_number_status": "available"
    }
  ],
  "current_page_number": 1,
  "page_size": 100,
  "total_pages": 1
}
```

> **Note**: The response is [paginated](/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:

- `username` (Exact match)
- `team_id` (Exact match, team ID)

**HTTP request**

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

## Verify a user’s phone number

Use this endpoint to set and verify another user’s phone number without a verification code. Because the endpoint bypasses phone ownership verification, confirm that the number belongs to the user before you submit the request. You can’t use this endpoint to verify your own number or assign a phone number to a service account.

**Required permission**: `grafana-irm-app.user-settings:admin`

This endpoint is available on paid plans. It isn’t available on Free or trial plans. For authentication options, refer to [Authentication](/docs/grafana-cloud/observe-and-act/respond-to-incidents/reference/oncall-api/#authentication).

**HTTP request**: `POST /api/v1/users/{user_id}/verify_phone_number/`

For *USER\_ID*, use the `id` returned by [List users](#list-users).

Send a JSON object with the following fields:

Expand table

| Field              | Required | Description                                                                                                       |
|--------------------|----------|-------------------------------------------------------------------------------------------------------------------|
| `phone_number`     | Yes      | Phone number in E.164 format, including the country code, for example, +12025550123. Extensions aren’t supported. |
| `replace_existing` | No       | Boolean. Set to `true` to replace a different verified number. Defaults to `false`.                               |

To set and verify a number using a service account token:

sh ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```sh
curl "<API_URL>/api/v1/users/<USER_ID>/verify_phone_number/" \
  --request POST \
  --header "Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>" \
  --header "X-Grafana-URL: https://<STACK_SLUG>.grafana.net" \
  --header "Content-Type: application/json" \
  --data '{"phone_number": "+12025550123"}'
```

To approve replacing a different verified number, send this body to the same endpoint:

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

```json
{
  "phone_number": "+12025550124",
  "replace_existing": true
}
```

The request returns a response in the following format:

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

```json
{
  "id": "U4DNY931HHJS5",
  "status": "verified"
}
```

The `status` is `verified` when the number is newly verified or replaces a different number. It is `unchanged` when the user already has that number verified.

IRM attempts to send an SMS confirmation to the newly verified number. If you replace a number, IRM also attempts to send a disconnection message to the previous number. The number remains verified if either message can’t be delivered.

Expand table

| HTTP status | Meaning                                                                                                     |
|-------------|-------------------------------------------------------------------------------------------------------------|
| `200`       | The number is verified or was already verified.                                                             |
| `400`       | The request contains a missing or invalid value, or an unknown field.                                       |
| `403`       | You don’t have the required permission or plan, you’re verifying your own number, or the number is blocked. |
| `404`       | The user wasn’t found in your stack, is inactive, or is a service account.                                  |
| `409`       | The user has a different verified number. To replace it, set `replace_existing` to `true`.                  |
| `429`       | A rate limit was exceeded. Wait for the `Retry-After` interval before retrying.                             |

This endpoint allows **10 requests per minute per caller** and **30 requests per minute per stack**. Retries count toward these limits.

If a request times out, you can retry it with the same phone number. Repeating a successful request returns `unchanged` and doesn’t resend SMS messages.
