A deploy can make a site answer errors for a minute. Start a maintenance window from your pipeline and its monitors aren’t checked, no incidents open and no alerts go out, and the time doesn’t count against uptime. End the window when the deploy is done and checks resume right away.
Before you start
- The REST API is included in Professional and Business. Create an API key with Read & write under Settings › API, and store it as a secret in your CI, here
UPTIMECHECK_API_KEY. - Find the IDs of the monitors to pause. Each starts with
mon_and is the last part of the monitor page’s address, or list them all:
curl -sS https://app.uptimecheck.com/api/v1/monitors \
-H "Authorization: Bearer $UPTIMECHECK_API_KEY" | jq -r '.data[] | [.id, .name] | @tsv'
GitHub Actions
This workflow starts a 30-minute window, deploys, and ends the window whether the deploy worked or not. Replace the monitor IDs and the deploy step with your own. In any other CI the same two calls work.
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
UPTIMECHECK_API_KEY: ${{ secrets.UPTIMECHECK_API_KEY }}
steps:
- uses: actions/checkout@v4
- name: Start maintenance
id: maintenance
run: |
body=$(jq -n \
--arg start "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg end "$(date -u -d "+30 minutes" +%Y-%m-%dT%H:%M:%SZ)" \
'{title: "Deploying a new version", startsAt: $start, endsAt: $end,
monitorIds: ["mon_9xk2m1q8w4", "mon_4t7p2k8d1z"]}')
id=$(curl -sS -X POST https://app.uptimecheck.com/api/v1/maintenance \
-H "Authorization: Bearer $UPTIMECHECK_API_KEY" \
-H "Content-Type: application/json" \
-d "$body" | jq -r '.data.id // empty')
echo "id=$id" >> "$GITHUB_OUTPUT"
- name: Deploy
run: ./deploy.sh
- name: End maintenance
if: always() && steps.maintenance.outputs.id != ''
run: |
curl -sS -X DELETE \
"https://app.uptimecheck.com/api/v1/maintenance/${{ steps.maintenance.outputs.id }}" \
-H "Authorization: Bearer $UPTIMECHECK_API_KEY"
If Uptimecheck can’t be reached, the deploy still runs, without a window.
The two calls
POST /api/v1/maintenancestarts or schedules a window. Sendtitle,startsAtandendsAtas ISO 8601 times such as2026-10-18T14:00:00Z, andmonitorIds. A start in the past starts it now, and a window lasts at most 14 days. The answer’sdata.idstarts withmw_.- Optional fields:
message, shown on status pages, andnotifySubscribers(false unless you send true), which emails status page subscribers. DELETE /api/v1/maintenance/{id}ends a running window at once, or cancels one that hasn’t started. It answers204.
Good to know
- Set
endsAta little after your slowest deploy. If the job dies before the last step, the window still ends on time. - Status pages that show these monitors say Maintenance in progress during the window and list it with its title, and so does the status widget. Pick a title visitors may see.
- An incident that is open when the window starts is closed, and the monitor starts over with a fresh check when the window ends.
- Cron job pings that arrive during the window are noted but change nothing, and a ping missed during it doesn’t alert.
- The API can also pause and resume single monitors (
POST /api/v1/monitors/{id}/pauseand/resume). A window is simpler for a deploy, as it ends by itself.
Every field is in the API reference. To plan windows in the app instead, see how to schedule a maintenance window. More on the REST API.