---
title: "Disengage the global dispatcher kill switch"
method: DELETE
path: "/api/v1/admin/kill-switch"
tags: ["Admin"]
---

# Disengage the global dispatcher kill switch

`DELETE /api/v1/admin/kill-switch`

## Request

- Base URL: `https://api.uptimemonitoring.com`
- URL: `https://api.uptimemonitoring.com/api/v1/admin/kill-switch`
- Auth: HTTP bearer

Removes the sentinel file at `KILL_SWITCH_FILE`. Once
observed by the watcher, dispatch resumes.

Requires admin role per #18.

**Idempotent.** A missing sentinel file (ENOENT) is
treated as success; this endpoint returns 200, never 404.

When the handler's own check of the sentinel file, made
before it touches the file, finds the file present, and the
file operation completes without a fatal error, the
dispatcher fires the `kill_switch_flipped` webhook (when both
`SECURITY_ALERT_WEBHOOK_URL` and
`SECURITY_ALERT_WEBHOOK_SECRET` are configured) with `actor`
set to the calling admin's GitHub username. A URL configured
without a secret disables delivery entirely — the dispatcher
logs a `[security:webhook_disabled]` warning at startup and
sends nothing on this or any other security-alert event.
That check is not synchronized with other writers, so the
actor-attributed alert reflects what the check saw, not
whether this call changed the file: concurrent calls, or an
out-of-band `touch`/`rm` between the check and the removal,
can make the two differ. A call whose check finds the file
already absent fires no actor-attributed alert, but still
runs the watcher confirmation step; if that confirmation is
the first to observe an out-of-band change made since the
watcher's last poll, the watcher's own notification path can
emit an alert with no `actor`. Watcher poll-loop suppression
matches the engage path.

The response's `active` field is the state the watcher
actually confirmed after the file removal, not necessarily
the requested one: if the post-removal confirmation hits a
filesystem error, the removal already happened but the
in-memory state could not be confirmed, and the response
is `503` reporting the last known state instead of `200`
with a possibly-wrong `active:false`. The `kill_switch_flipped`
webhook still fires in that case, with `active:false` (the
requested/removed state) — the file removal is the real event,
and withholding the alert would mean a completed disengage could
go unreported (the suppressed watcher poll won't fire it
either, and a client retry afterward is a no-op).

Returns 503 `{"error":"kill switch not configured"}` when
`KILL_SWITCH_FILE` is unset.

## Response `200`

Kill switch is disengaged.

- KillSwitchStatus
  - `active` boolean, required: Whether the global kill switch is currently engaged. Reflects the watcher's in-memory state, which is updated on a 5 s poll cadence (out-of-band flips can lag up to 5 s; REST-driven flips propagate within milliseconds).
  - `sentinel_path` string, required: Absolute path of the sentinel file the watcher is polling — the value of `KILL_SWITCH_FILE` at process start.

## Other responses

- `401`: Missing or invalid credentials.
- `403`: Authenticated but not an admin.
- `429`: Per-account dispatcher rate limit exceeded (200 requests/minute). The `Retry-After` header gives the integer seconds until at least one token has refilled. The `X-RateLimit-*` trio reflects the bucket whose rejection produced this response — usually the global 200/min cap; on `POST /api/v1/monitors` a 429 may instead reflect the per-route 20/min creation limit.
- `500`: Filesystem remove failed for a reason other than ENOENT.
- `503`: Either `KILL_SWITCH_FILE` is unset (`{"error":"kill switch not configured"}`), or the sentinel file removal succeeded but the watcher could not confirm the new state afterward (a filesystem error naming the failure and the last known `active` value it fell back to).

---

[API](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api.md) · [All operations](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api/llms.txt) · [OpenAPI document](https://skmtc.dev/uptimemonitoring/apis/uptimemonitoring-com-api/revisions/ddcb2a8bc70f?raw)
