The packaged Action
realuptime: check monitor status on the GitHub Marketplace wraps everything on this page in one uses: line. It fails the step when any monitor reports a status in fail-on (default down, degraded), writes all_operational, failure_count and results step outputs, and posts a per-monitor summary to the run. Source lives at RealUptimeHQ/check-status-action.
- name: Confirm production is healthy before finishing
uses: RealUptimeHQ/check-status-action@v1
with:
api-key: ${{ secrets.REALUPTIME_API_KEY }}
check-ids: 11111111-1111-4111-8111-111111111111
# optional: comma-separate multiple ids, and override which
# statuses fail the run (default: down, degraded)
# fail-on: downWithout installing anything
Prefer zero dependencies on a third-party uses: line? Every example below is plain shell against the same public REST API, and works identically.
What it does
Each example below calls GET /checks/:id with curl for each monitor id you give it, and fails the workflow step if any of them comes back down or degraded (adjust the check yourself for a different rule), or errors. Useful as a post-deploy gate, or anywhere a workflow needs to confirm a dependency is actually healthy before continuing. There is nothing to install and no separate GitHub repository to trust: it is the same public REST API, called directly.
Requirements
A RealUptime API key on a Growth or Scale plan. A read-scope key is enough, since these steps only read status and never create, update, or delete anything. Generate one from the dashboard's API & MCP access section and store it as a repository or organization secret, never a literal value in the workflow file. jq is used to pull the status out of the response; it ships preinstalled on GitHub's ubuntu-latest runner image, install it yourself first if you're on a different one.
Basic usage
- name: Confirm production is healthy before finishing
run: |
status=$(curl -sf -H "Authorization: Bearer ${{ secrets.REALUPTIME_API_KEY }}" \
https://realuptime.io/api/v1/checks/11111111-1111-4111-8111-111111111111 \
| jq -r '.status')
echo "RealUptime Status: $status"
if [ "$status" = "down" ] || [ "$status" = "degraded" ]; then
echo "::error::RealUptime reports $status"
exit 1
fiChecking multiple monitors
- name: Confirm all regions are healthy
run: |
for id in 11111111-1111-4111-8111-111111111111 22222222-2222-4222-8222-222222222222; do
status=$(curl -sf -H "Authorization: Bearer ${{ secrets.REALUPTIME_API_KEY }}" \
"https://realuptime.io/api/v1/checks/$id" | jq -r '.status')
echo "$id: $status"
if [ "$status" = "down" ] || [ "$status" = "degraded" ]; then
echo "::error::$id reports $status"
exit 1
fi
doneFind a monitor's id from the dashboard, or by calling GET /checks yourself (see the API reference).
Reporting instead of failing
Skip the exit 1 and write the status to a step output instead, then branch on it in a later step:
- name: Check status
id: check
run: |
status=$(curl -sf -H "Authorization: Bearer ${{ secrets.REALUPTIME_API_KEY }}" \
https://realuptime.io/api/v1/checks/11111111-1111-4111-8111-111111111111 \
| jq -r '.status')
echo "status=$status" >> "$GITHUB_OUTPUT"
- name: Notify on partial degradation
if: steps.check.outputs.status == 'degraded' || steps.check.outputs.status == 'down'
run: echo "Degraded: ${{ steps.check.outputs.status }}"Reading the response
Every call above returns the same JSON shape as GET /checks/:id in the API reference:
{
"check": { "id": "...", "account_id": "...", "name": "API", "url": "https://api.example.com/health", "interval_seconds": 60, "selected_regions": ["iad", "sjc", "fra", "nrt"] },
"status": "operational",
"regions": [
{ "check_id": "...", "region": "iad", "current_state": "operational", "last_checked_at": "2026-08-04T01:29:02.228Z" }
]
}The examples above only read .status, but the same response also carries check (the monitor's own name and URL) and regions (the raw per-region breakdown), if you want a richer notification than a single status string.
Status meanings
Statuses mirror the REST API's aggregation exactly: operational, degraded, down, stale, or unknown. See the API reference for exactly what each one means. stale and unknown are excluded from the failure checks above because they mean missing or old data, not a confirmed outage; add them yourself if you want a stricter gate.
Rate limits
One GET /checks/:id request per monitor id per run, against the same 120-per-minute read budget documented in the API reference.
Which one should I use?
Both paths call the same API with the same key and enforce the same rule. The packaged Action is less yaml and gives you structured outputs; the shell steps depend on no repository outside your own. Pick whichever your team's workflow policy prefers.