---
title: "Update a project's recovery settings"
method: PATCH
path: "/v1/projects/{project}/recovery/settings"
tags: ["Disaster Recovery"]
---

# Update a project's recovery settings

`PATCH /v1/projects/{project}/recovery/settings`

## Request

- Base URL: `https://api.subscriby.net`
- URL: `https://api.subscriby.net/v1/projects/{project}/recovery/settings`
- Auth: HTTP bearer

```bash
curl -X PATCH https://api.subscriby.net/v1/projects/$PROJECT_ID/recovery/settings \
  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"auto_failover": true, "accepts_email_fee": true, "email_delivery": "platform"}'
```

Every field is optional and omitted ones keep their value. Switching `auto_failover` on needs `accepts_email_fee: true` in the same call and the Growth plan. Answers `200` with the settings as they now stand.

## Path parameters

- `project` string, uuid, required

## Headers

- `Idempotency-Key` string, uuid, required

## Request body

- UpdateRecoverySettingsRequest: Which Disaster Recovery settings to change on a project. Every field is optional and an omitted one keeps its value.
  - `auto_failover` boolean: Whether the platform may swap a banned channel for its standby on its own. Switching it on needs `accepts_email_fee: true` in the same call and the Growth plan.
  - `accepts_email_fee` boolean: Consent to the per-email fee a failover may charge for the members the bot cannot reach; consent is not implied by the switch.
  - `email_delivery` 'platform' | 'self': How a project reaches the members its bot cannot message after a swap. A replaced channel re-admits every live member through the project bot, but a member who never started the bot, or whose bot was banned in the same incident, cannot be reached that way. The creator decides once per project whether the platform emails those members on their behalf, at a per-email fee added to the transaction fees, or whether they download the list and write themselves. The default is the free one, so nobody is charged for a choice they did not make.

## Response `200`

200 with the settings, updated.

- object
  - `data` RecoverySettingsResource, required: A project's Disaster Recovery settings: the switches the Prevention page holds per project. The standby installation's credentials never appear, only the fact that one is registered.
    - `project_id` string, required: The project the settings belong to.
    - `auto_failover_enabled` boolean, required: Whether the platform may swap a banned channel for its standby on its own.
    - `auto_failover_email_consented_at` string, nullable, required: When the creator accepted the per-email fee a failover may charge for the members the bot cannot reach, ISO 8601; null until accepted.
    - `email_delivery` string, required: How members are told after a channel swap the creator ran: `self` (the creator tells them) or `platform` (Subscriby emails them at the fee).
    - `email_delivery_label` 'Email them for me' | 'I will email them myself', required: That choice in the creator's language.
    - `standby_installation_registered` boolean, required: Whether a spare bot is kept for the project.

## Other responses

- `400`: `IDEMPOTENCY_KEY_MISSING`: every write needs an `Idempotency-Key` header. Send a fresh UUID per distinct operation.
- `401`: `AUTHENTICATION_REQUIRED`: the request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an `sbt_test_` token on production).
- `403`: `TOKEN_MISSING_ABILITY`: the token is valid but does not carry the ability this endpoint requires; `error.context.required_ability` names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers `FORBIDDEN`, `TEAM_TIER_REQUIRED` or `CONNECTOR_TIER_REQUIRED` with the same status, and says so in its own description.
- `404`: `RESOURCE_NOT_FOUND`: an id in the path names nothing the token can see. `TENANT_MISMATCH`: the project sits outside the token's `scope:project:` allow-list, or the token carries no team scope. Both answer 404 rather than 403 so that existence outside the token's scope cannot be inferred.
- `409`: `IDEMPOTENCY_KEY_REUSED`: the key was already used in the last 24 hours with a different request body.
- `422`: `VALIDATION_FAILED`: the payload broke a rule, and `error.fields` maps each offending key to its messages. A refusal from the domain, such as a plan that cannot go on sale or a member who cannot be removed, uses the same code with `error.message` saying why and no `fields`. On this endpoint: `VALIDATION_FAILED`: when `auto_failover` is switched on without `accepts_email_fee: true` or without the Growth plan, when the caller is not the project owner, or when `email_delivery` is not `self` or `platform`.
- `425`: `IDEMPOTENCY_REPLAY_IN_PROGRESS`: the first request with this key is still running; retry in a few seconds and the original response is replayed.
- `429`: `RATE_LIMITED`: the token has spent its 300 requests a minute or 10,000 an hour; `Retry-After` says when the next one is accepted.

---

[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)
