Version

Disaster Recovery API

Everything the Disaster Recovery pages show a creator is readable here: what the health probes found broken, what was done about it and whether it can still be undone, how many members a channel recovery has re-admitted so far, how many self-service recoveries the rolling window still allows, and how ready the account is for the next ban.

Everything the Disaster Recovery pages show a creator is readable here: what the health probes found broken, what was done about it and whether it can still be undone, how many members a channel recovery has re-admitted so far, how many self-service recoveries the rolling window still allows, and how ready the account is for the next ban. And everything a creator does about it afterwards is here too: the per-project settings, the standbys kept ready, the two requests that start a chat picker on the connector, the undo, the reminder to stragglers, the handover mail after a bot replacement, and the member list to keep before one.

The ledger endpoints live under /v1/recovery with no project in the path because the ledger belongs to the account holder, not to a project: a ban lands on the creator's sign-in account and on every project at once. Settings and standbys hang off the project and the resource they concern. The creator's own account lives under /v1/me/recovery.

Background

Tenancy

The ledger a token reads is the one of the creator who owns the team the token is scoped to. A teammate holding project-recovery:view-any therefore reads the same rows the owner sees on the dashboard; a token scoped to another team sees none of them, and any id from another creator's ledger is 404 RESOURCE_NOT_FOUND.

Reads are the team's, writes are the owner's. The writes run the same actions the dashboard runs, and those refuse anyone but the project owner (or, for the account, the account holder) with 422 VALIDATION_FAILED and the reason, the same sentence the dashboard would show. Registering a standby installation and replacing the project bot take a credential and stay off tokens altogether.

Every enum value comes with its label beside it (kind_label, status_label, reason_label), the same words the dashboard shows, so a client can render the ledger without a translation table of its own.

Endpoints

GET/v1/projects/{project}/resources/{resource}/standbyGet a resource's standbyPATCH/v1/projects/{project}/resources/{resource}/standbySwitch a standby's live mirrorDELETE/v1/projects/{project}/resources/{resource}/standbyRemove a resource's standbyGET/v1/projects/{project}/recovery/settingsGet a project's recovery settingsPATCH/v1/projects/{project}/recovery/settingsUpdate a project's recovery settingsGET/v1/projects/{project}/recovery/members/exportExport a project's member listGET/v1/recovery/readinessGet the readiness checklistGET/v1/recovery/incidentsList incidentsGET/v1/recovery/incidents/{incident}Get an incidentGET/v1/recovery/operationsList recovery operationsGET/v1/recovery/operations/{operation}Get a recovery operationGET/v1/recovery/operations/{operation}/roll-callGet a recovery's roll callGET/v1/recovery/allowancesGet the recovery allowancesGET/v1/me/recoveryGet the caller's recovery accountGET/v1/me/recovery/handshakes/{handshake}Poll a recovery handshakeDELETE/v1/me/recovery/handshakes/{handshake}Cancel a recovery handshakePOST/v1/projects/{project}/resources/{resource}/standby/requestRequest a standby for a resourceDELETE/v1/projects/{project}/resources/{resource}/standby/requestWithdraw a standby requestPOST/v1/projects/{project}/resources/{resource}/standby/useUse a resource's standby nowPOST/v1/projects/{project}/resources/{resource}/replacement/requestRequest a replacement for a resourceDELETE/v1/projects/{project}/resources/{resource}/replacement/requestWithdraw a replacement requestDELETE/v1/projects/{project}/recovery/standby-installationRemove a project's standby installationPOST/v1/recovery/operations/{operation}/revertUndo a recoveryPOST/v1/recovery/operations/{operation}/nudgeRemind a recovery's stragglersPOST/v1/recovery/operations/{operation}/notify-membersTell members about a bot replacementPOST/v1/me/recovery/handshakesOpen a recovery handshakePOST/v1/me/recovery/handshakes/{handshake}/confirmConfirm a relink handshakePOST/v1/me/recovery/backup-identityRegister a backup accountDELETE/v1/me/recovery/backup-identityRemove the backup accountPOST/v1/me/recovery/backup-identity/switchSwitch to the backup account

Get a resource's standby

GET
curl https://api.subscriby.net/v1/projects/$PROJECT_ID/resources/$RESOURCE_ID/standby \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

The standby's own identifier on the platform is deliberately absent, as every connector identifier is on the API.

GET
/v1/projects/{project}/resources/{resource}/standby

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Responses

200OK

200 with the standby.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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. On this endpoint: RESOURCE_NOT_FOUND: when the resource keeps no standby; error.context.resource_id names it.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

PATCH
curl -X PATCH https://api.subscriby.net/v1/projects/$PROJECT_ID/resources/$RESOURCE_ID/standby \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{"mirror": true}'

Switches the live mirror on or off: when on, every post made in the channel is copied into the standby as it is made. Only a channel can be mirrored, and switching on needs the Growth plan. Answers 200 with the standby.

PATCH
/v1/projects/{project}/resources/{resource}/standby

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Request body

JSONWhat the request carries

The one switch a resource's standby carries.

Responses

200OK

200 with the standby, updated.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation 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: for a group, a resource without a standby, a plan without the feature, or a caller who is not the project owner.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

DELETE

Stops keeping the standby; the chat itself is untouched. Answers 204 and raises recovery.standby_removed.

DELETE
/v1/projects/{project}/resources/{resource}/standby

Requires ability

The token must hold this ability, or the call is refused with 403.

Delivered to every endpoint subscribed to it once the change is made.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the caller is not the project owner.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl https://api.subscriby.net/v1/projects/$PROJECT_ID/recovery/settings \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
  • auto_failover_enabled says whether the platform may swap a banned channel for its standby on its own; auto_failover_email_consented_at when the creator accepted the per-email fee a failover may charge for the members the bot cannot reach.
  • email_delivery says how members are told after a channel swap the creator ran: self (the creator tells them) or platform (Subscriby emails them at the fee).
  • standby_installation_registered says whether a spare bot is kept; its credentials never appear.
GET
/v1/projects/{project}/recovery/settings

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid

Responses

200OK

200 with the settings.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

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.

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

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Request body

JSONWhat the request carries

Which Disaster Recovery settings to change on a project. Every field is optional and an omitted one keeps its value.

Responses

200OK

200 with the settings, updated.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation 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.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl -L https://api.subscriby.net/v1/projects/$PROJECT_ID/recovery/members/export \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" -o members.csv

The member list a creator keeps before replacing a bot, as a CSV download (text/csv, one member per row: name, email, connector id, active plans, when access ends, resources, whether the bot can still reach them). REST only; there is no MCP tool for a file.

GET
/v1/projects/{project}/recovery/members/export

The token must hold this ability, or the call is refused with 403.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid

Responses

200OK

The CSV, one member per row.

response-200?file
Formatbinary
401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

422Validation failed

When the caller is not the project owner.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

GET
curl https://api.subscriby.net/v1/recovery/readiness \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

The whole checklist the Readiness page shows, with its totals.

  • done is three-valued: true or false when the platform can verify the line, null when it can only remind (reminder: true). Reminders never count toward total.
  • locked says the plan lacks the prevention feature the line needs, so a client shows the upgrade rather than the fix; prevention at the top says whether the plan bundles those features at all.
  • url is where the line is fixed, or null for a reminder. detail is the state in words, such as "2 of 3 projects".
  • connector names the connector a line belongs to (connector_name is its display name); both are null for the account's own lines.

The lines are the ones the dashboard lists, in the same order. The account's come first: second_factor and backup_identity. Then each installed connector's own lines, worded by that connector and keyed within it; Telegram's are standby_installation, standby_spaces, auto_failover and live_mirror, one line per key however many projects run it (the detail counts the projects when they differ). Last the two reminders, off_platform_copy and second_admin. A creator with no connector installed gets the account lines and the reminders alone. Every change to a verifiable line's state raises recovery.readiness_changed.

GET
/v1/recovery/readiness

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Responses

200OK

200 with the checklist.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

List incidents

GET
curl "https://api.subscriby.net/v1/recovery/incidents?status=open" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

An incident is one problem a probe detected and has not yet seen fixed: the creator's sign-in account unreachable (kind: account), a project's bot refused by the platform (bot), or a channel or group the project sells gone or no longer administered (resources). It resolves itself when a later probe finds the thing healthy, or is resolved by the recovery that replaced it, which resolved_by_operation_id then names.

status is open (the default: what still needs attention), resolved, or all. Paginated like every list, newest first by detected_at; sort_by also accepts kind, status and resolved_at.

GET
/v1/recovery/incidents

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

status?|

The tab: open (the default, what still needs attention), resolved, or all.

page?integer

The 1-based page to return. A page past the last answers an empty data array with meta.total still filled, so a loop can stop without guessing.

Range1 <= value
Default1
per_page?integer

Rows per page, 1 to 100. A higher value clamps to the cap silently. Defaults to 25.

Range1 <= value <= 100
Default25
sort_by?string

The column to order by. Defaults to detected_at; a column the endpoint does not offer falls back to the default rather than failing.

Default"detected_at"
sort_direction?string

asc or desc. Defaults to desc.

Default"desc"

Value in

  • "asc"
  • "desc"

Responses

200OK

The page, newest first by default.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

422Validation 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 status is not open, resolved or all.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Get an incident

GET
curl https://api.subscriby.net/v1/recovery/incidents/$INCIDENT_ID \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

One incident.

  • reason is the connector's own code for what it saw; reason_label and reason_explanation are that code in the connector's words, the same sentence the alert email carried. Both are null when the probe recorded no reason, which is the case for account incidents.
  • resource_id and resource_title are set on resources incidents only; project_id is null on an account incident.
GET
/v1/recovery/incidents/{incident}

Requires ability

The token must hold this ability, or the call is refused with 403.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

incident*string

The incident, resolved within the ledger by the route binder.

Formatuuid

Responses

200OK

200 with the incident.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

List recovery operations

GET
curl "https://api.subscriby.net/v1/recovery/operations?kind=resources&status=completed" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

An operation is one recovery: run by the creator, by the platform on their behalf (automatic: true, the failover you sleep through), or on demand (on_demand: true, a Swap & Grant of a healthy resource, which spends no allowance). The row exists from the moment the recovery starts, because it is the quota ledger and the audit trail at once.

Both filters are optional: kind is account, bot or resources; status is started, completed, failed or reverted. Newest first by started_at; sort_by also accepts kind, status and completed_at.

GET
/v1/recovery/operations

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

kind?|

Narrow to one kind: account, bot or resources. An unknown value is refused.

status?|

Narrow to one status: started, completed, failed or reverted. An unknown value is refused.

page?integer

The 1-based page to return. A page past the last answers an empty data array with meta.total still filled, so a loop can stop without guessing.

Range1 <= value
Default1
per_page?integer

Rows per page, 1 to 100. A higher value clamps to the cap silently. Defaults to 25.

Range1 <= value <= 100
Default25
sort_by?string

The column to order by. Defaults to started_at; a column the endpoint does not offer falls back to the default rather than failing.

Default"started_at"
sort_direction?string

asc or desc. Defaults to desc.

Default"desc"

Value in

  • "asc"
  • "desc"

Responses

200OK

The page, newest first by default.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

422Validation 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 kind or status is not one of its values.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Get a recovery operation

GET
curl https://api.subscriby.net/v1/recovery/operations/$OPERATION_ID \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

One operation, with its undo state.

  • status is started while the recovery runs, then completed, failed (with failure_reason) or reverted.
  • revertible says whether the creator may still undo it right now: it is completed, of a kind that can be undone (an account relink or a channel swap, never a bot replacement), and inside the undo window that revert_window_ends_at closes. A client should show the undo exactly when this is true.
  • grant_id names the support grant that paid for the recovery when the self-service allowance was already spent; null otherwise.
GET
/v1/recovery/operations/{operation}

Requires ability

The token must hold this ability, or the call is refused with 403.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

operation*string

The operation, resolved within the ledger by the route binder.

Formatuuid

Responses

200OK

200 with the operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

GET
curl https://api.subscriby.net/v1/recovery/operations/$OPERATION_ID/roll-call \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

Where the re-admission after a channel recovery stands, read live.

  • total is how many members the swap set out to re-admit; regranted how many hold a fresh link into the new chat; failed how many could not be given one.
  • unreachable is how many the bot could not message, and emailed how many of those were told by email instead (at the per-email fee, when the project opted in).
  • joined is stamped the moment the platform approves a member's join request, so pending (regranted − joined) is who is still outside.
  • settled means the queue has handled everyone, so the counters will not move on their own. can_nudge is true when somebody is still outside and the reminder cooldown has passed; cooling_down and nudge_available_at explain a false.

A recovery of a kind that re-admits nobody (an account relink, a bot replacement) answers the same shape with every counter at zero rather than an error.

GET
/v1/recovery/operations/{operation}/roll-call

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

operation*string

The operation, resolved within the ledger by the route binder.

Formatuuid

Responses

200OK

200 with the counters.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

GET
curl https://api.subscriby.net/v1/recovery/allowances \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

One row per kind, plus the window they are counted in.

  • self_service_remaining is what the rolling window still allows on its own; grant_remaining is what support has released on top and not yet spent. remaining is their sum and allowed whether a recovery of that kind would start right now.
  • uses_grant is true when the next recovery would spend a support grant rather than the self-service allowance.
  • next_self_service_at is when the self-service allowance returns, null while it is available. last_used_at is when the kind was last recovered inside the window.

See Allowances and support review for the rule and what support audits before releasing a grant.

GET
/v1/recovery/allowances

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Responses

200OK

Array of RecoveryAllowanceResource

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl https://api.subscriby.net/v1/me/recovery \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

Recovering the creator's sign-in account, and keeping a backup account ahead of a ban, are two-sided handshakes: the API mints a code, the creator taps the link (or types the code) from the account to detect, the connector records which account that was, and the API confirms. Both sides have to agree, which is what keeps a leaked link from binding a stranger. These endpoints live under /v1/me because they are about the caller, never a project, and the actions behind them refuse anyone but the account holder.

These flows are deliberately not offered as MCP tools: moving a sign-in is a human act, and get_me already shows which accounts are linked.

  • primary_display_name and backup_display_name name the accounts as the connector reported them; their identifiers on the connector never appear.
  • relink_handshake and backup_handshake are the newest handshake of each kind, in whatever state, so a client can pick up a flow the creator started on the dashboard or in the bot.
GET
/v1/me/recovery

Requires ability

The token must hold this ability, or the call is refused with 403.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Responses

200OK

200 with the summary.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

GET

status moves from pending to completed when an account taps, with detected_display_name and detected_identity_id filled; expired when the code ran out or was cancelled; consumed once confirmed.

GET
/v1/me/recovery/handshakes/{handshake}

Requires ability

The token must hold this ability, or the call is refused with 403.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

handshake*string

The handshake, resolved within the caller's own by the route binder.

Formatuuid

Responses

200OK

200 with the handshake.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

DELETE

Cancels a pending handshake so its code stops working. Answers 204.

DELETE
/v1/me/recovery/handshakes/{handshake}

Requires ability

The token must hold this ability, or the call is refused with 403.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

handshake*string

The handshake, resolved within the caller's own by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the handshake is no longer pending; error.context.handshake_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl -X POST https://api.subscriby.net/v1/projects/$PROJECT_ID/resources/$RESOURCE_ID/standby/request \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)"

Asks the creator, on the connector, to pick the chat that becomes the resource's standby (Growth plan). Answers 202 once the request is sent; the standby appears, announced by recovery.standby_registered, the moment they choose.

Linking a standby or a replacement is a conversation with the creator on the connector: the bot messages them with a picker, and the link or the swap happens the moment they choose. The API cannot name the chat directly, because that would take a platform identifier, so it starts the conversation and takes it back. A creator holds one request of each kind at a time, whichever resource it was for.

POST
/v1/projects/{project}/resources/{resource}/standby/request

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

202Accepted

202 with resource_id and status: request_sent.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the resource is a perk rather than a place, the creator cannot be reached on the connector, the plan lacks the feature, or the caller is not the project owner; error.context.resource_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

DELETE

Takes the open standby request back. A creator holds one request of each kind at a time, whichever resource it was for, so the resource in the path only keys the route. Answers 204, also when nothing was open.

DELETE
/v1/projects/{project}/resources/{resource}/standby/request

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST
curl -X POST https://api.subscriby.net/v1/projects/$PROJECT_ID/resources/$RESOURCE_ID/standby/use \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)"

Swaps the resource onto its standby right now: the resource points at the standby chat, the old invite links are revoked, every active member is re-admitted, and the standby is consumed. Answers 200 with the recovery operation the swap ran under (on_demand: true when the resource was healthy with no open incident, spending no allowance). Undo is offered for 24 hours through the revert endpoint. Raises recovery.resource_replaced and recovery.standby_removed with reason: used, beside the operation's recovery.operation_started and recovery.operation_completed.

POST
/v1/projects/{project}/resources/{resource}/standby/use

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

200OK

200 with the recovery operation the swap ran under.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

For a resource without a standby, an allowance already spent for a degraded resource, or a caller who is not the project owner.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Asks the creator, on the connector, to pick the chat that replaces the resource's: the same conversation a standby request starts, ending in a swap instead of a spare. For a degraded resource the swap will spend the channel recovery allowance or join the recovery already absorbing swaps; for a healthy one it is on demand and free. Answers 202 once the request is sent.

POST
/v1/projects/{project}/resources/{resource}/replacement/request

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

202Accepted

202 with resource_id and status: request_sent.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the resource is a perk with nothing to replace, the creator cannot be reached on the connector, or the caller is not the project owner; error.context.resource_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

DELETE

Takes the open replacement request back. Answers 204, also when nothing was open.

DELETE
/v1/projects/{project}/resources/{resource}/replacement/request

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid
resource*string

The resource, resolved within the project by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl -X DELETE https://api.subscriby.net/v1/projects/$PROJECT_ID/recovery/standby-installation \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)"

Stops keeping the spare bot registered for the project and withdraws it from the connector; the live installation, members and access stay as they are. Answers 204. Registering one is not offered to tokens, because it takes a credential; the dashboard's Prevention page does that. Raises recovery.standby_removed with standby: installation.

DELETE
/v1/projects/{project}/recovery/standby-installation

Requires ability

The token must hold this ability, or the call is refused with 403.

Delivered to every endpoint subscribed to it once the change is made.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

project*string

The project, resolved by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the caller is not the project owner.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Undo a recovery

POST
curl -X POST https://api.subscriby.net/v1/recovery/operations/$OPERATION_ID/revert \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{"resource_id": "b73c5f21-9d80-4a6e-8215-4f70ce13a9d6"}'

Inside the undo window (revert_window_ends_at on the operation) a completed recovery can be undone. A channel recovery is undone one swap at a time: resource_id names the resource to put back on its old chat, and every active member is re-admitted there again; the operation reads reverted once its last standing swap is undone. An account relink is undone whole and takes no resource_id: sign-in moves back to the previous account, every browser session is signed out, and a relink_disputed incident opens for support. A bot replacement cannot be undone.

Answers 200 with the operation, its revertible now false. Raises recovery.operation_reverted; a channel undo also moves the resource's place (project.resource.updated with changes.space_id) and an account undo opens the dispute incident (recovery.incident_opened).

POST
/v1/recovery/operations/{operation}/revert

Requires ability

The token must hold this ability, or the call is refused with 403.

Delivered to every endpoint subscribed to them once the change is made.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

operation*string

The operation, resolved within the ledger by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Request body

JSONWhat the request carries

Which part of a recovery to undo. A channel recovery is undone one swap at a time and names the resource; an account relink is undone whole and takes an empty body.

Responses

200OK

200 with the operation, its undo state updated.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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. On this endpoint: RESOURCE_NOT_FOUND: when resource_id is not a resource the token manages.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation 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: for a bot replacement, a channel recovery with no resource_id, a closed window, a swap already put back, or a recovery that is not the token owner's; error.context.operation_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST
curl -X POST https://api.subscriby.net/v1/recovery/operations/$OPERATION_ID/nudge \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)"

Sends one reminder, with a fresh link, to every member a channel recovery re-admitted who has not joined the new chat yet, and records the nudge on the operation. Read the roll call first: can_nudge says whether anyone is still outside and the cooldown has passed. Answers 200 with the count queued.

POST
/v1/recovery/operations/{operation}/nudge

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

operation*string

The operation, resolved within the ledger by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

200OK

200 with operation_id and how many reminders were nudged.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When nobody is waiting, the nudge is too soon, or the recovery is of another kind.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

curl -X POST https://api.subscriby.net/v1/recovery/operations/$OPERATION_ID/notify-members \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)"

After a bot replacement, emails every member the project can reach by email that its bot changed, with the new bot's link and the portal, at the per-email fee added to the creator's transaction fees. Sent once per recovery: a second call answers with the count already sent and sends nothing. Answers 200 with the count.

POST
/v1/recovery/operations/{operation}/notify-members

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

operation*string

The operation, resolved within the ledger by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

200OK

200 with operation_id and how many members were notified, now or earlier.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the recovery belongs to no project, so there is nobody to tell; error.context.operation_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST
curl -X POST https://api.subscriby.net/v1/me/recovery/handshakes \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{"kind": "relink"}'

kind is relink (move the sign-in to a new account; needs the account recovery allowance) or backup (register a backup account; needs the Growth plan). Answers 201 with the pending handshake: code is the eight-character code to type into the bot, start_link the link that opens the bot on it (null when the creator cannot be reached on the connector), and the handshake expires fifteen minutes after it was minted.

POST
/v1/me/recovery/handshakes

Requires ability

The token must hold this ability, or the call is refused with 403.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Request body

JSONWhat the request carries

Which handshake to open.

Responses

201Created

201 with the pending handshake, its code and link.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation 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 the account allowance is spent (relink), the plan lacks the backup feature (backup), kind is neither, or the caller is not the account holder.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST

Confirms a completed relink: the sign-in moves to the account that tapped, every browser session is signed out, the account allowance is spent, and the undo mail goes out. Answers 200 with the recovery operation (kind: account, revertible: true) and raises recovery.identity_relinked beside the operation's recovery.operation_started and recovery.operation_completed.

POST
/v1/me/recovery/handshakes/{handshake}/confirm

Requires ability

The token must hold this ability, or the call is refused with 403.

Delivered to every endpoint subscribed to them once the change is made.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Path Parameters

handshake*string

The handshake, resolved within the caller's own by the route binder.

Formatuuid

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

200OK

200 with the recovery operation.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not 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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

For a pending or expired handshake, a backup handshake (which is confirmed by registering the backup identity), or a caller who is not the account holder; error.context.handshake_id names it.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST
curl -X POST https://api.subscriby.net/v1/me/recovery/backup-identity \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{"handshake_id": "0c4f9e2a-7b31-4d68-a5e2-9f1c3b7d6e80"}'

Registers the account a completed backup handshake detected as the backup (Growth plan). Answers 200 with the account summary.

POST
/v1/me/recovery/backup-identity

Requires ability

The token must hold this ability, or the call is refused with 403.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Request body

JSONWhat the request carries

Which completed backup handshake names the account to keep as the backup.

Responses

200OK

200 with the account summary.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

404Not found

When the handshake is not one of the caller's; error.context.handshake_id names it.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation 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 the handshake is not a completed backup handshake, the plan lacks the feature, or the caller is not the account holder.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

DELETE

Stops keeping a backup. Answers 204.

DELETE
/v1/me/recovery/backup-identity

Requires ability

The token must hold this ability, or the call is refused with 403.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

204No content

No content

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When the caller is not the account holder.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

POST

Moves the sign-in to the backup right now, keeping the previous account as the new backup; spends the account allowance and offers the same undo as a relink. Answers 200 with the recovery operation and raises recovery.identity_relinked beside the operation's recovery.operation_started and recovery.operation_completed.

POST
/v1/me/recovery/backup-identity/switch

Requires ability

The token must hold this ability, or the call is refused with 403.

Delivered to every endpoint subscribed to them once the change is made.

Idempotent

Send the header on every call; the same key replays the original response for 24 hours.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Header Parameters

Idempotency-Key*string

A key unique to this operation, such as a fresh UUID. The same key replays the original 2xx response for 24 hours (with Idempotent-Replay: true), so a retry after a timeout never repeats the write; the same key with a different body is refused with 409.

Formatuuid

Responses

200OK

200 with the recovery operation.

400Bad request

Every write needs an Idempotency-Key header. Send a fresh UUID per distinct operation.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

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.

409Conflict

The key was already used in the last 24 hours with a different request body.

422Validation failed

When no backup is registered, the account allowance is spent, or the caller is not the account holder.

425Too early

The first request with this key is still running; retry in a few seconds and the original response is replayed.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

How is this guide?

Version

On this page

Subscriby is a product
designed by you — for you.
No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request