---
type: api
title: Create a case attachment
description: **Spaces method and path for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4641/api/doc/kibana/v9/operation/operation-createcaseattachmentdefaultspace
resource: https://www.elastic.co/elastic/docs-builder/docs/4641/api/doc/kibana/v9/operation/operation-createcaseattachmentdefaultspace
products:
  - Kibana
---

# Create a case attachment

Authentication: required

Availability: Planned

- Server: `https://{kibana_url}`

## Paths

- `POST` `/api/cases/{caseId}/attachments`
- `POST` `/s/{space_id}/api/cases/{caseId}/attachments`

#### Path parameters

- `space_id` (string) — optional
  An identifier for the space. If `space_id` is not provided in the URL, the default space is used. Refer to [Spaces](https://www.elastic.co/docs/deploy-manage/manage-spaces) for more information.
- `caseId` (string) — required
  The identifier for the case. To retrieve case IDs, use the search cases (`_find)` API. All non-ASCII characters must be URL encoded.
  Example: `9c235210-6834-11ea-a78c-6ffb38a34414`

## Description

Adds a single attachment, such as a comment or an alert, to a case. You must have `all` privileges for the **Cases** feature in the **Management**, **Observability**, or **Security** section of the Kibana feature privileges, depending on the owner of the case. NOTE: Each case can have a maximum of 1,000 alerts.

## Header parameters

- `kbn-xsrf` (string) — required
  Cross-site request forgery protection

## Request body

`application/json`

One of:
- **Reference attachment**
  - `attachmentId` (union oneOf) — required
    The ID of the attached item, such as an alert or a dashboard. To attach several alerts, use an array. This isn't the attachment's own ID (`id`).
    One of: `string[]` or `string`
  - `data` (object) — optional — nullable
    The attachment's content. Required for comments, where `content` is the comment text (up to 30,000 characters). In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
  - `metadata` (object) — optional — nullable
    Extra details about the attachment. For alerts, this is the alert's index and rule. Required for some types, such as `dashboard`. In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
  - `owner` (enum) — required
    The application that owns the cases: Stack Management, Observability, or Elastic Security.
    Values: `cases`, `observability`, `securitySolution`
  - `type` (string) — required
    The attachment type, such as `comment`, `security.alert`, `observability.alert`, `stack.alert`, `security.event`, `lens`, `dashboard`, or `file`. `security.*` types only work on Security cases, `observability.*` on Observability cases, and `stack.*` on Stack Management cases. Use `comment` (not the legacy `user` type) and a `*.alert` type (not `alert`). You can't add or replace file attachments with this API. To add a file, use `POST /api/cases/{caseId}/files`.
- **Value attachment**
  - `data` (object) — required — nullable
    The attachment's content. Required for comments, where `content` is the comment text (up to 30,000 characters). In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
  - `metadata` (object) — optional — nullable
    Extra details about the attachment. For alerts, this is the alert's index and rule. Required for some types, such as `dashboard`. In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
  - `owner` (enum) — required
    The application that owns the cases: Stack Management, Observability, or Elastic Security.
    Values: `cases`, `observability`, `securitySolution`
  - `type` (string) — required
    The attachment type, such as `comment`, `security.alert`, `observability.alert`, `stack.alert`, `security.event`, `lens`, `dashboard`, or `file`. `security.*` types only work on Security cases, `observability.*` on Observability cases, and `stack.*` on Stack Management cases. Use `comment` (not the legacy `user` type) and a `*.alert` type (not `alert`). You can't add or replace file attachments with this API. To add a file, use `POST /api/cases/{caseId}/files`.

## Responses

#### `201`

Indicates a successful call. Returns the new attachment. If some of the alert or event IDs are already attached to the case, they are skipped and the new attachment holds only the remaining IDs.

`application/json`

- `attachmentId` (union oneOf)
  The ID of the attached item, such as an alert or a dashboard. To attach several alerts, use an array. This isn't the attachment's own ID (`id`).
  One of: `string[]` or `string`
- `created_at` (string · format: date-time)
- `created_by` (object)
  - `email` (string) — nullable
  - `full_name` (string) — nullable
  - `profile_uid` (string)
  - `username` (string) — nullable
- `data` (object) — nullable
  The attachment's content. Required for comments, where `content` is the comment text (up to 30,000 characters). In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
- `id` (string)
  The attachment identifier.
- `metadata` (object) — nullable
  Extra details about the attachment. For alerts, this is the alert's index and rule. Required for some types, such as `dashboard`. In requests, it can be up to 524,288 characters when serialized as JSON and nest up to 30 levels deep.
- `owner` (enum)
  The application that owns the cases: Stack Management, Observability, or Elastic Security.
  Values: `cases`, `observability`, `securitySolution`
- `pushed_at` (string · format: date-time) — nullable
  When this attachment was last pushed to an external system, such as Jira. Is `null` if it hasn't been pushed.
- `pushed_by` (object) — nullable
  - `email` (string) — nullable
  - `full_name` (string) — nullable
  - `profile_uid` (string)
  - `username` (string) — nullable
- `type` (string)
  The attachment type, such as `comment`, `security.alert`, `observability.alert`, `stack.alert`, `security.event`, `lens`, `dashboard`, or `file`. `security.*` types only work on Security cases, `observability.*` on Observability cases, and `stack.*` on Stack Management cases. Use `comment` (not the legacy `user` type) and a `*.alert` type (not `alert`). You can't add or replace file attachments with this API. To add a file, use `POST /api/cases/{caseId}/files`.
- `updated_at` (string · format: date-time) — nullable
- `updated_by` (object) — nullable
  - `email` (string) — nullable
  - `full_name` (string) — nullable
  - `profile_uid` (string)
  - `username` (string) — nullable
- `version` (string)
  The attachment's current version. Include it when you replace the attachment.
#### `400`

The request failed for one of these reasons:
- The request body is invalid.
- The attachment type isn't registered, or is `file`.
- The owner doesn't match the case owner.
- A case limit was exceeded.

`application/json`

- `error` (string)
- `message` (string)
- `statusCode` (integer)
#### `401`

Authorization information is missing or invalid.

`application/json`

- `error` (string)
- `message` (string)
- `statusCode` (integer)
#### `403`

You don't have the required privileges for this case.

`application/json`

- `error` (string)
- `message` (string)
- `statusCode` (integer)
#### `404`

The case was not found.

`application/json`

- `error` (string)
- `message` (string)
- `statusCode` (integer)
#### `409`

Every alert or event ID in the request is already attached to the case.

`application/json`

- `error` (string)
- `message` (string)
- `statusCode` (integer)
## Code examples

#### Console

```console
POST kbn:/api/cases/9c235210-6834-11ea-a78c-6ffb38a34414/attachments
{
  "attachmentId": "6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42",
  "metadata": {
    "index": ".internal.alerts-security.alerts-default-000001",
    "rule": {
      "id": "94309390-b76c-11ee-b4d6-39d8a0fcbc1b",
      "name": "Endpoint Security"
    }
  },
  "owner": "securitySolution",
  "type": "security.alert"
}
```

#### curl

```curl
curl -X POST "${KIBANA_URL}/api/cases/9c235210-6834-11ea-a78c-6ffb38a34414/attachments" \
  -H "kbn-xsrf: true" \
  -H "Authorization: ApiKey ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "attachmentId": "6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42",
    "metadata": {
      "index": ".internal.alerts-security.alerts-default-000001",
      "rule": {
        "id": "94309390-b76c-11ee-b4d6-39d8a0fcbc1b",
        "name": "Endpoint Security"
      }
    },
    "owner": "securitySolution",
    "type": "security.alert"
  }'
```

## Response examples

#### A single comment attachment.

`application/json`

```json
{
  "created_at": "2026-09-30T19:32:13.104Z",
  "created_by": {
    "email": "null",
    "full_name": "null",
    "profile_uid": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
    "username": "elastic"
  },
  "data": {
    "content": "A new comment."
  },
  "id": "8048b460-fe2b-11ec-b15d-779a7c8bbcc3",
  "owner": "cases",
  "pushed_at": "null",
  "pushed_by": "null",
  "type": "comment",
  "updated_at": "null",
  "updated_by": "null",
  "version": "WzIzLDFd"
}
```

#### The attachment payload is invalid.

`application/json`

```json
{
  "error": "Bad Request",
  "message": "Invalid attachment payload for type \u0027comment\u0027: data.content: Comment content must be a non-empty string",
  "statusCode": 400
}
```

#### Authorization information is missing or invalid.

`application/json`

```json
{
  "error": "Unauthorized",
  "message": "Unable to authenticate with the provided credentials.",
  "statusCode": 401
}
```

#### The user does not have access to the requested resource.

`application/json`

```json
{
  "error": "Forbidden",
  "message": "Unauthorized to access cases",
  "statusCode": 403
}
```

#### The requested resource was not found.

`application/json`

```json
{
  "error": "Not Found",
  "message": "Saved object [cases-template/9da1ea2a-09f8-4d0e-bf9d-09bf8c9d0f42] not found",
  "statusCode": 404
}
```

#### Every alert or event in the request is already attached to the case.

`application/json`

```json
{
  "error": "Conflict",
  "message": "Every id in the request is already attached to case 293f1bfe-c4ab-4a0b-9a36-9fd4a1d7d2b1.",
  "statusCode": 409
}
```

