---
title: "A channel or group enters or exits a degraded state: banned, deleted, or the bot lost its rights."
method: POST
path: "project.resource.status_changed"
tags: ["project.* events"]
---

# A channel or group enters or exits a degraded state: banned, deleted, or the bot lost its rights.

`POST project.resource.status_changed` (webhook)

### When this fires

A channel or group linked to a project transitions into or out of a degraded state. The degraded reasons are:

| `reason`                | What the platform told us                                                             | Recovery                                                    |
| ----------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `chat_not_found`        | The chat no longer exists: deleted, or banned by the platform.                        | Replace the chat (a channel recovery).                      |
| `bot_removed`           | Our bot was removed from the chat, so it can no longer admit or remove members.       | Re-add the bot as an administrator, or replace the chat.    |
| `bot_not_administrator` | The bot is still in the chat but lost its administrator role.                         | Promote it again with the invite and restrict rights.       |
| `bot_missing_rights`    | The bot is an administrator without the *invite users* or *restrict members* right.   | Grant both rights again.                                    |
| `connector_api_error`   | The platform refused the probe for a reason we could not classify.                    | Re-check; replace the chat if it persists.                  |

The `healthy` event carries `reason: null` and fires when a probe finds the resource answering again, or when a recovery re-points it at a new chat.

A `chat_not_found` or `bot_removed` transition also opens a **recovery incident** on the creator's [Disaster Recovery](https://docs.subscriby.net/disaster-recovery) page, alerts them by email and on their connected account, and, on Growth, with automatic failover switched on, swaps the resource for its standby without anyone signed in.

It does **not** fire when:

- A probe finds the same state as last time. Only transitions are announced.
- A probe cannot reach the platform at all. A transport failure keeps the previous state.
- The resource is a manual perk. Only channels and groups are probed.

> Fires on a **transition**, not on a schedule. Subscriby probes every linked channel and group hourly, every five minutes while a pass window is open or imminent, and immediately when real work fails (an invite link cannot be minted, a join request cannot be approved). You get one event when the resource breaks and one when it recovers, never an event per probe.

### Related events

- `connector.status_changed`: the same idea for the project's installation.
- `project.resource.updated`: fires with `changes.space_id` when a recovery re-points the resource at a replacement place.

## Headers

- `SB-Signature` string, required
- `SB-Event-Id` string, required
- `SB-Event-Name` string, required
- `Content-Type` string, required
- `User-Agent` string, required

## Payload

- object: The envelope every event is delivered in.
  - `id` string, required: A ULID unique to the event, prefixed `evt_`. Every retry carries the same id, so it is the key to deduplicate on.
  - `type` 'project.resource.status_changed', required: The event name, always `project.resource.status_changed` here.
  - `created_at` string, date-time, required: When the event was emitted, server time, ISO 8601.
  - `api_version` string, required: The contract version of the payload shape, `2026-05-01` today. A breaking change to a shape ships under a new version.
  - `project_id` string, uuid, nullable, required: The project the event belongs to; null for team-scoped and billing events.
  - `data` object, required: The event-specific payload. Keys that do not apply to a given emission are omitted rather than sent as null, so check for presence.
    - `project_id` string, uuid, required: Same project, repeated for consumers that read `data` alone.
    - `resource_id` string, uuid, required: The channel or group whose health changed.
    - `status` 'healthy' | 'degraded', required: The state after the transition.
    - `reason` 'chat_not_found' | 'bot_removed' | 'bot_not_administrator' | 'bot_missing_rights' | 'connector_api_error' | 'null', nullable, required: Why it is degraded. `null` on a `healthy` transition.

## Acknowledgement `2XX`

Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.

## Other responses

- `default`: Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or `POST /v1/webhook-deliveries/{delivery}/retry`. After 20 consecutive failures the endpoint is paused until it is resumed.

---

[API](https://skmtc.dev/memberpass/apis/subscriby-rest-api.md) · [All operations](https://skmtc.dev/memberpass/apis/subscriby-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/memberpass/apis/subscriby-rest-api/revisions/59c4df91d764?raw)
