> For the complete documentation index, see [llms.txt](https://docs.clearfeed.ai/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clearfeed.ai/api/reference/api-reference/announcements.md).

# Announcements

Create and track Slack announcements programmatically. An announcement's message body always comes from an existing Slack message — the API turns that message into an announcement and delivers it to the channels or collections you specify.

{% hint style="info" %}
`POST` requests require an API token with **Read & Write** scope. `GET` requests work with a **Read-only** token. See the [Authentication Guide](/api/quick-start/authentication-guide.md) for how to generate a token.
{% endhint %}

## Create and Send or Schedule an Announcement

<mark style="color:blue;">`POST`</mark> `https://api.clearfeed.app/v1/rest/announcements`

Creates an announcement from an existing Slack message and either sends it immediately or schedules it for later delivery.

### Request Body

| Name                                          | Type    | Description                                                                                                              |
| --------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| channel\_id<mark style="color:red;">\*</mark> | string  | Slack channel ID that contains the source message. The ClearFeed bot must be a member of this channel.                   |
| message\_ts<mark style="color:red;">\*</mark> | string  | Timestamp of the Slack message to use as the announcement body.                                                          |
| name<mark style="color:red;">\*</mark>        | string  | Announcement name. Only alphanumeric characters, spaces, hyphens, underscores, and apostrophes are allowed.              |
| recipients<mark style="color:red;">\*</mark>  | array   | At least one [recipient object](#recipient-object). Each entry is a Slack channel or a standard collection.              |
| action<mark style="color:red;">\*</mark>      | string  | `send_now` or `schedule`. Determines which of the [action-specific parameters](#action-specific-parameters) below apply. |
| sender\_config                                | object  | [Sender config object](#sender-config-object). Defaults to sending as the ClearFeed bot.                                 |
| unfurl\_links                                 | boolean | Whether to unfurl links in the message. Defaults to `false`.                                                             |
| unfurl\_media                                 | boolean | Whether to unfurl media in the message. Defaults to `false`.                                                             |

#### Action-Specific Parameters

`scheduled_time` is required when `action` is `schedule`, and must be omitted when `action` is `send_now`.

**`action: "send_now"`** — sends the announcement immediately. No additional parameters.

**`action: "schedule"`**

| Name                                              | Type   | Description                                              |
| ------------------------------------------------- | ------ | -------------------------------------------------------- |
| scheduled\_time<mark style="color:red;">\*</mark> | string | A future ISO 8601 datetime, e.g. `2026-07-10T09:00:00Z`. |

#### Recipient Object

| Name                                   | Type   | Description                                                                                                                                                        |
| -------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type<mark style="color:red;">\*</mark> | string | `channel` to target a single Slack channel, or `collection` to target every channel in a standard collection.                                                      |
| id<mark style="color:red;">\*</mark>   | string | For `channel`, the Slack channel ID. For `collection`, the collection's `id` (see [Get Collections](/api/reference/api-reference/collections.md#get-collections)). |

#### Sender Config Object

| Name         | Type    | Description                                                                                                              |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| type         | string  | `clearfeed` (default) to send as the ClearFeed bot, `user` to send as a specific user, `topicOwner`, or `customerOwner`. |
| senderId     | string  | Required when `type` is `user`. Slack user ID of the sender.                                                             |
| useUserToken | boolean | Only applies when `type` is `user`. If `true`, sends using that user's Slack OAuth token instead of the bot token.       |

### Example cURL Request

```bash
curl --location 'https://api.clearfeed.app/v1/rest/announcements' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
  "channel_id": "C012AB3CD",
  "message_ts": "1719825600.000100",
  "name": "Q3 Update",
  "recipients": [
    { "type": "channel", "id": "C012AB3CD" },
    { "type": "collection", "id": "42" }
  ],
  "action": "schedule",
  "scheduled_time": "2026-07-10T09:00:00Z",
  "sender_config": { "type": "user", "senderId": "U01ABC123", "useUserToken": true },
  "unfurl_links": false,
  "unfurl_media": false
}'
```

### Response

| Name            | Type           | Description                                                                     |
| --------------- | -------------- | ------------------------------------------------------------------------------- |
| id              | number         | The newly created announcement's ID.                                            |
| status          | string         | `pending` for `send_now`, or `scheduled` for `schedule`.                        |
| scheduled\_time | string \| null | The ISO 8601 datetime the announcement is scheduled for. `null` for `send_now`. |

{% tabs %}
{% tab title="200: OK" %}

```json
{
  "announcement": {
    "id": 101,
    "status": "scheduled",
    "scheduled_time": "2026-07-10T09:00:00Z"
  }
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

```json
{
  "message": "Collection with id 42 not found or is not a Slack collection",
  "error": "BAD_REQUEST"
}
```

{% endtab %}

{% tab title="403: Forbidden" %}

```json
{
  "message": "This API token has read-only access and cannot perform write operations.",
  "error": "FORBIDDEN"
}
```

{% endtab %}
{% endtabs %}

### Notes

* If any recipient (channel or collection) fails validation, the announcement is **not** created.
* Collection recipients must reference a standard (Slack) collection. Email, portal, and web-chat collections are rejected with a 400.
* This operation is recorded in [audit logs](/api/reference/api-reference/audit-logs.md) under the `Announcement` resource type.

## Retrieve Announcement Delivery Status

<mark style="color:blue;">`GET`</mark> `https://api.clearfeed.app/v1/rest/announcements/:id`

Retrieves an announcement's status and per-channel delivery details.

### Path Parameters

| Name                                 | Type    | Description                                                                                                                     |
| ------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| id<mark style="color:red;">\*</mark> | integer | The announcement's ID, returned by [Create and Send or Schedule an Announcement](#create-and-send-or-schedule-an-announcement). |

### Example cURL Request

```bash
curl --location 'https://api.clearfeed.app/v1/rest/announcements/101' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
```

### Response

| Name            | Type           | Description                                                                                           |
| --------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| id              | number         | The announcement's ID.                                                                                |
| name            | string         | The announcement's name.                                                                              |
| status          | string         | `pending`, `scheduled`, or `sent`.                                                                    |
| scheduled\_time | string \| null | The ISO 8601 datetime the announcement is scheduled for. `null` unless `status` is `scheduled`.       |
| recipients      | array          | One record per delivered channel. Collection recipients are expanded into individual channel records. |

Each entry in `recipients` has the following shape:

| Name           | Type           | Description                                                                                         |
| -------------- | -------------- | --------------------------------------------------------------------------------------------------- |
| channel\_id    | string         | Slack channel ID the announcement was (or will be) delivered to.                                    |
| collection\_id | number         | Present only when this channel was targeted via a collection. Identifies which collection added it. |
| status         | string \| null | `success`, `fail`, or `null` while delivery is pending or scheduled.                                |
| message\_ts    | string \| null | Timestamp of the delivered Slack message. `null` until delivery succeeds.                           |
| error          | string \| null | Delivery error, present only when `status` is `fail`.                                               |

{% tabs %}
{% tab title="200: OK" %}

```json
{
  "announcement": {
    "id": 101,
    "name": "Q3 Update",
    "status": "scheduled",
    "scheduled_time": "2026-07-10T09:00:00.000Z",
    "recipients": [
      {
        "channel_id": "C012AB3CD",
        "status": null,
        "message_ts": null,
        "error": null
      },
      {
        "channel_id": "C045EF6GH",
        "collection_id": 42,
        "status": "success",
        "message_ts": "1719825800.000200",
        "error": null
      }
    ]
  }
}
```

{% endtab %}

{% tab title="400: Bad Request" %}

```json
{
  "message": "Validation failed (numeric string is expected)",
  "error": "BAD_REQUEST"
}
```

{% endtab %}
{% endtabs %}

### Notes

* This endpoint returns per-channel delivery status only. Interaction metrics such as reactions and replies are available from the Announcements page in the ClearFeed web app.
* This operation is recorded in [audit logs](/api/reference/api-reference/audit-logs.md) under the `Announcement` resource type.
