---
title: "Automations API | Grafana Cloud documentation"
description: "Create, schedule, update, delete, and run Grafana Assistant automations with the HTTP API."
---

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

# Automations API

Use automations to run Assistant prompts on a schedule or on demand. Automations let you set up recurring tasks, such as daily health checks or weekly report generation, and optionally send results to Slack.

Automations have two scopes:

- **User automations** are private to the identity that created them, with the administrator access described below. This is the default scope.
- **Tenant automations** are visible to all users in the organization.

Administrators with `grafana-assistant-app.automations:read` can view all automations in the stack, including private automations. Administrators with `grafana-assistant-app.automations:write` can update them. These permissions don’t grant access to another identity’s private run history or conversation details, or permission to run or delete its private automations.

Automation creation is subject to your stack’s limits. Scheduled automations must have a minimum interval of 15 minutes.

Examples use the base URL and service account token described in [Grafana Assistant HTTP API reference](/docs/grafana-cloud/platform/grafana-assistant/reference/http-apis).

## Create an automation

Create a new automation.

**Endpoint**

`POST /automations`

**Permissions**

Expand table

| Automation scope | Required permission                               |
|------------------|---------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:create`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:create` |

**Request**

Send a JSON request body.

Expand table

| Field              | Required | Description                                                                                             |
|--------------------|----------|---------------------------------------------------------------------------------------------------------|
| `name`             | Yes      | Display name for the automation.                                                                        |
| `prompt`           | Yes      | The prompt sent to Assistant when the automation runs.                                                  |
| `enabled`          | Yes      | Whether the automation is active.                                                                       |
| `scope`            | No       | Automation scope: `user` or `tenant`. Default: `user`.                                                  |
| `scheduleCron`     | No       | Standard cron expression, for example `0 9 * * 1-5` for weekdays at 9 AM. Minimum interval: 15 minutes. |
| `scheduleTimezone` | No       | IANA timezone for the schedule, for example `America/New_York`.                                         |
| `notifications`    | No       | Notification configuration. See **Slack notifications**.                                                |
| `description`      | No       | A short description of the automation.                                                                  |

**Slack notifications**

Configure Slack notifications to receive automation results in a channel or as a direct message. Slack notifications require a connected Slack integration in Grafana.

Include the `notifications` field when creating or updating an automation.

Expand table

| Field                    | Description                                                                                                   |
|--------------------------|---------------------------------------------------------------------------------------------------------------|
| `slack.enabled`          | Whether Slack notifications are active.                                                                       |
| `slack.notifyOn`         | When to notify. Valid values: `completed`, `failed`, `needs_approval`. At least one is required when enabled. |
| `slack.target.type`      | Notification target: `channel` or `dm`.                                                                       |
| `slack.target.channelId` | Slack channel ID. Required when `type` is `channel`.                                                          |
| `slack.target.userId`    | Slack user ID. Required when `type` is `dm`.                                                                  |

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

```json
{
  "name": "Daily SLO report",
  "prompt": "Summarize SLO health for all production services and highlight any that are below target.",
  "enabled": true,
  "scope": "tenant",
  "scheduleCron": "0 9 * * 1-5",
  "scheduleTimezone": "America/New_York",
  "notifications": {
    "slack": {
      "enabled": true,
      "notifyOn": ["completed", "failed"],
      "target": {
        "type": "channel",
        "channelId": "C0123456789"
      }
    }
  }
}
```

**Response**

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

```json
{
  "status": "success",
  "data": {
    "id": "e7f5a6b8-9012-3456-abcd-278901234567",
    "name": "Daily SLO report",
    "prompt": "Summarize SLO health for all production services and highlight any that are below target.",
    "scope": "tenant",
    "enabled": true,
    "createdBy": "sa-5594@serviceaccount.grafana",
    "createdAt": "2025-11-15T12:00:00Z",
    "updatedAt": "2025-11-15T12:00:00Z",
    "schedule": {
      "cron": "0 9 * * 1-5",
      "timezone": "America/New_York",
      "nextRunAt": "2025-11-18T14:00:00Z"
    },
    "notifications": {
      "slack": {
        "enabled": true,
        "notifyOn": ["completed", "failed"],
        "target": {
          "type": "channel",
          "channelId": "C0123456789"
        }
      }
    }
  }
}
```

**Examples**

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

```bash
curl -X POST "${ASSISTANT_API_URL}/automations" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}" \
  -d '{
    "name": "Daily SLO report",
    "prompt": "Summarize SLO health for all production services and highlight any that are below target.",
    "enabled": true,
    "scope": "tenant",
    "scheduleCron": "0 9 * * 1-5",
    "scheduleTimezone": "America/New_York",
    "notifications": {
      "slack": {
        "enabled": true,
        "notifyOn": ["completed", "failed"],
        "target": {
          "type": "channel",
          "channelId": "C0123456789"
        }
      }
    }
  }'
```

## List automations

Retrieve automations visible to the current identity.

**Endpoint**

`GET /automations`

**Permissions**

Expand table

| Automation scope | Required permission                             |
|------------------|-------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:read`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:read` |

Alternatively, `grafana-assistant-app.automations:read` grants access to all automations in the stack.

**Request**

Expand table

| Parameter   | Required | Description                                                      |
|-------------|----------|------------------------------------------------------------------|
| `page_size` | No       | Number of results per page. Range: 1-100. Default: `20`.         |
| `cursor`    | No       | Pagination cursor from a previous response’s `nextCursor` field. |

**Response**

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

```json
{
  "status": "success",
  "data": {
    "automations": [
      {
        "id": "e7f5a6b8-9012-3456-abcd-278901234567",
        "name": "Daily SLO report",
        "prompt": "Summarize SLO health for all production services and highlight any that are below target.",
        "scope": "tenant",
        "enabled": true,
        "createdBy": "sa-5594@serviceaccount.grafana",
        "createdAt": "2025-11-15T12:00:00Z",
        "updatedAt": "2025-11-15T12:00:00Z",
        "schedule": {
          "cron": "0 9 * * 1-5",
          "timezone": "America/New_York",
          "nextRunAt": "2025-11-18T14:00:00Z"
        },
        "notifications": {
          "slack": {
            "enabled": true,
            "notifyOn": ["completed", "failed"],
            "target": {
              "type": "channel",
              "channelId": "C0123456789"
            }
          }
        }
      }
    ],
    "nextCursor": ""
  }
}
```

To paginate, pass the `nextCursor` value from the response as the `cursor` parameter in the next request. An empty `nextCursor` means there are no more results.

**Examples**

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

```bash
curl -X GET "${ASSISTANT_API_URL}/automations?page_size=10" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}"
```

## Get an automation

Retrieve a single automation by ID.

**Endpoint**

`GET /automations/{id}`

**Permissions**

Expand table

| Automation scope | Required permission                             |
|------------------|-------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:read`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:read` |

Alternatively, `grafana-assistant-app.automations:read` grants access to all automations in the stack.

**Request**

Expand table

| Parameter | Required | Description                                               |
|-----------|----------|-----------------------------------------------------------|
| `id`      | Yes      | The automation ID returned when you create an automation. |

**Response**

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

```json
{
  "status": "success",
  "data": {
    "id": "e7f5a6b8-9012-3456-abcd-278901234567",
    "name": "Daily SLO report",
    "prompt": "Summarize SLO health for all production services and highlight any that are below target.",
    "scope": "tenant",
    "enabled": true,
    "createdBy": "sa-5594@serviceaccount.grafana",
    "createdAt": "2025-11-15T12:00:00Z",
    "updatedAt": "2025-11-15T12:00:00Z",
    "schedule": {
      "cron": "0 9 * * 1-5",
      "timezone": "America/New_York",
      "nextRunAt": "2025-11-18T14:00:00Z"
    },
    "lastRun": {
      "status": "completed",
      "chatId": "18289896-b393-4136-9014-c2630a62f67f",
      "method": "schedule",
      "stepsUsed": 12,
      "startedAt": "2025-11-15T14:00:00Z"
    },
    "notifications": {
      "slack": {
        "enabled": true,
        "notifyOn": ["completed", "failed"],
        "target": {
          "type": "channel",
          "channelId": "C0123456789"
        }
      }
    }
  }
}
```

**Latest run (`data.lastRun`)**

The `data.lastRun` object describes the automation’s most recent run. It may be absent before the first run. Scheduled runs and runs started by other callers can change which run appears here.

Expand table

| Field       | Description                                                                                                                                                                                                  |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `status`    | The run’s state, for example `completed` or `failed`.                                                                                                                                                        |
| `chatId`    | The conversation ID. When present, use this value in `GET /chats/{chatId}` to retrieve the conversation. It may be absent before the conversation is available or when you don’t have access to its details. |
| `method`    | How the run was started: `manual`, `schedule`, or `event`.                                                                                                                                                   |
| `stepsUsed` | The number of steps taken during the run.                                                                                                                                                                    |
| `startedAt` | When the run started, if available.                                                                                                                                                                          |
| `error`     | An error message if the run failed, when available to the caller.                                                                                                                                            |

Use `data.lastRun.chatId` as `{chatId}` in `GET /chats/{chatId}`. For the required permissions, refer to the [Conversations API](/docs/grafana-cloud/platform/grafana-assistant/reference/http-apis/conversations/#fetch-conversation-messages).

**Examples**

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

```bash
AUTOMATION_ID="e7f5a6b8-9012-3456-abcd-278901234567"

curl -X GET "${ASSISTANT_API_URL}/automations/${AUTOMATION_ID}" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}"
```

## Update an automation

Update an existing automation. Only the fields you include in the request body are changed.

**Endpoint**

`PUT /automations/{id}`

**Permissions**

Expand table

| Automation scope | Required permission                              |
|------------------|--------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:write`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:write` |

Changing scope requires write permission for both the current and desired scopes. Updating a private automation also requires ownership. Alternatively, `grafana-assistant-app.automations:write` permits updates across both scopes, including another identity’s private automation.

**Request**

Expand table

| Parameter | Required | Description        |
|-----------|----------|--------------------|
| `id`      | Yes      | The automation ID. |

Send a JSON request body with the fields to update.

Expand table

| Field              | Required | Description                                                                                                    |
|--------------------|----------|----------------------------------------------------------------------------------------------------------------|
| `name`             | No       | Updated display name.                                                                                          |
| `prompt`           | No       | Updated prompt.                                                                                                |
| `description`      | No       | Updated description.                                                                                           |
| `scope`            | No       | Updated scope: `user` or `tenant`.                                                                             |
| `enabled`          | No       | Whether the automation is active.                                                                              |
| `scheduleCron`     | No       | Updated cron expression.                                                                                       |
| `scheduleTimezone` | No       | Updated IANA timezone.                                                                                         |
| `notifications`    | No       | Updated notification configuration. Omitted providers remain unchanged. Set a provider to `null` to remove it. |

When you include `notifications.slack`, send the complete Slack configuration. It replaces the existing Slack configuration; omitted Slack fields aren’t preserved.

To remove Slack notifications, set the provider to `null` in an update:

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

```json
{
  "notifications": {
    "slack": null
  }
}
```

**Response**

The response contains the full updated automation.

**Examples**

Disable an automation:

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

```bash
AUTOMATION_ID="e7f5a6b8-9012-3456-abcd-278901234567"

curl -X PUT "${ASSISTANT_API_URL}/automations/${AUTOMATION_ID}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}" \
  -d '{
    "enabled": false
  }'
```

## Delete an automation

Permanently delete an automation and its schedule.

**Endpoint**

`DELETE /automations/{id}`

**Permissions**

Expand table

| Automation scope | Required permission                               |
|------------------|---------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:delete`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:delete` |

**Request**

Expand table

| Parameter | Required | Description        |
|-----------|----------|--------------------|
| `id`      | Yes      | The automation ID. |

**Response**

A successful deletion returns HTTP 200 with an empty data object.

**Examples**

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

```bash
AUTOMATION_ID="e7f5a6b8-9012-3456-abcd-278901234567"

curl -X DELETE "${ASSISTANT_API_URL}/automations/${AUTOMATION_ID}" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}"
```

## Run an automation

Trigger a manual run of an automation. The run executes asynchronously, so a successful request does not mean the run has finished.

**Endpoint**

`POST /automations/{id}/run`

**Permissions**

Expand table

| Automation scope | Required permission                               |
|------------------|---------------------------------------------------|
| `user`           | `grafana-assistant-app.automations.user:create`   |
| `tenant`         | `grafana-assistant-app.automations.tenant:create` |

Both the automation creator and the identity requesting the manual run must have the create permission for the automation’s scope. Only the owner can run a private automation.

**Request**

Expand table

| Parameter | Required | Description        |
|-----------|----------|--------------------|
| `id`      | Yes      | The automation ID. |

No request body is required.

**Response**

A successful request returns HTTP 200. The response does not include a conversation ID immediately.

Call `GET /automations/{id}` to check the automation’s latest run. In the response, [`data.lastRun`](#get-an-automation) describes that run. When `data.lastRun.chatId` is present, pass its value to `GET /chats/{chatId}` to retrieve the conversation. Reading the automation and its conversation requires the permissions documented in [Get an automation](#get-an-automation) and the [Conversations API](/docs/grafana-cloud/platform/grafana-assistant/reference/http-apis/conversations/#fetch-conversation-messages).

`lastRun` describes the most recent run. Scheduled runs and runs started by other callers can change which run appears there.

**Examples**

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

```bash
AUTOMATION_ID="e7f5a6b8-9012-3456-abcd-278901234567"

curl -X POST "${ASSISTANT_API_URL}/automations/${AUTOMATION_ID}/run" \
  -H "Authorization: Bearer ${SERVICE_ACCOUNT_TOKEN}"
```
