Stop Deploying Into Outages: Pre-Deploy Dependency Checks with Statusfield's API

Use the Statusfield REST API to check whether your critical dependencies are down before a deploy ships. Works in any CI/CD pipeline — GitHub Actions, shell scripts, or Node.js.

By Javier G · Founder··4 min read

There is a specific kind of bad that a deploy-during-an-outage produces.

Your deploy succeeds. The service looks different. Your users are angry. Your team starts reverting, re-running tests, going through logs — and eventually someone checks the Stripe status page and sees "Degraded - Payment Processing" was there the whole time.

The deploy was fine. You just shipped into a third-party fire.

The fix isn't faster rollbacks. It's not deploying when you already know something upstream is burning.

Statusfield's REST API lets you check whether any of your monitored services are down before your deploy starts. This post shows you how to wire that into a CI/CD pipeline, a pre-commit hook, or a simple shell one-liner.


What you need

  • A Statusfield account on the Hobby plan or above — the API is a paid feature
  • An API key: Settings → API Keys, create one, copy it once (it starts with sf_)
  • The services you care about added to your Statusfield monitor list

The monitor list is the key piece. When you run GET /api/v2/monitors?filter=outages, Statusfield returns the subset of your monitored services that are currently down — not the whole catalog. That scoping is what makes the check useful in CI: you get signal about your dependency graph, not noise from services you've never heard of.


The simplest version: a shell check

This is the whole thing:

#!/bin/bash
# pre-deploy-check.sh
 
OUTAGES=$(curl -sf \
  -H "Authorization: Bearer $SF_API_KEY" \
  "https://statusfield.com/api/v2/monitors?filter=outages")
 
COUNT=$(echo "$OUTAGES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('monitors', [])))")
 
if [ "$COUNT" -gt 0 ]; then
  echo "⚠️  $COUNT monitored service(s) are currently down:"
  echo "$OUTAGES" | python3 -c "
import sys, json
d = json.load(sys.stdin)
for m in d.get('monitors', []):
    print(f\"  - {m['name']}: {m['status']}\")
"
  echo ""
  echo "Deploy blocked. Fix the upstream issue or re-run with SF_OVERRIDE=1 to skip."
  [ "${SF_OVERRIDE:-0}" = "1" ] || exit 1
fi
 
echo "✓ All monitored services are up. Proceeding with deploy."

Set SF_API_KEY in your environment (never hardcode it), make the script executable, and call it before your deploy step. If anything's down, the deploy stops. If you need to ship anyway — maybe you're deploying a hotfix because of the outage — run with SF_OVERRIDE=1 ./deploy.sh.


GitHub Actions integration

Here's a reusable step you can drop into any workflow:

# .github/workflows/deploy.yml
 
name: Deploy
 
on:
  push:
    branches: [main]
 
jobs:
  pre-flight:
    name: Dependency status check
    runs-on: ubuntu-latest
    steps:
      - name: Check monitored services
        env:
          SF_API_KEY: ${{ secrets.SF_API_KEY }}
        run: |
          response=$(curl -sf \
            -H "Authorization: Bearer $SF_API_KEY" \
            "https://statusfield.com/api/v2/monitors?filter=outages")
          
          count=$(echo "$response" | python3 -c \
            "import sys,json; print(len(json.load(sys.stdin).get('monitors',[])))")
          
          if [ "$count" -gt 0 ]; then
            echo "::error::$count monitored service(s) are down — deploy blocked"
            echo "$response" | python3 -c "
          import sys, json
          for m in json.load(sys.stdin).get('monitors', []):
              print(f'::warning::  {m[\"name\"]}: {m[\"status\"]}')
          "
            exit 1
          fi
          
          echo "All monitored services are up."
 
  deploy:
    name: Deploy
    needs: pre-flight
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # ... your deploy steps

Add SF_API_KEY as a repository secret (Settings → Secrets → Actions). The pre-flight job gates the deploy job via needs: — if the status check fails, deploy never runs.

GitHub surfaces the ::error:: annotation directly in the workflow run UI, so whoever triggered the deploy sees exactly which service is down without having to read logs.


Node.js version

If your deploy script is already in Node, here's the same check as a module:

// scripts/check-dependencies.ts
 
async function checkDependencies(): Promise<void> {
  const apiKey = process.env.SF_API_KEY;
  if (!apiKey) throw new Error('SF_API_KEY is not set');
 
  const res = await fetch(
    'https://statusfield.com/api/v2/monitors?filter=outages',
    { headers: { Authorization: `Bearer ${apiKey}` } },
  );
 
  if (!res.ok) {
    // Don't block the deploy on API errors — fail open, log the issue
    console.warn(`Statusfield API returned ${res.status} — skipping check`);
    return;
  }
 
  const data = (await res.json()) as { monitors: Array<{ name: string; status: string }> };
  const down = data.monitors ?? [];
 
  if (down.length > 0) {
    console.error(`\n⚠️  ${down.length} monitored service(s) are currently down:\n`);
    for (const m of down) {
      console.error(`  - ${m.name}: ${m.status}`);
    }
    console.error('\nDeploy blocked. Set SF_OVERRIDE=1 to skip this check.\n');
 
    if (process.env.SF_OVERRIDE !== '1') {
      process.exit(1);
    }
  } else {
    console.log('✓ All monitored services are up.');
  }
}
 
checkDependencies().catch(err => {
  // Fail open: log but don't block
  console.warn('Dependency check failed:', err.message);
});

Run it with npx tsx scripts/check-dependencies.ts before your deploy step, or call it from your package.json scripts:

{
  "scripts": {
    "predeploy": "tsx scripts/check-dependencies.ts",
    "deploy": "your-deploy-command"
  }
}

npm runs predeploy automatically before deploy, so you get the check for free every time you run npm run deploy.


What the API returns

The GET /api/v2/monitors?filter=outages response looks like this:

{
  "monitors": [
    {
      "name": "Stripe",
      "slug": "stripe",
      "status": "degraded",
      "components": [
        { "name": "Payment Processing", "status": "degraded" }
      ]
    }
  ],
  "total": 1
}

You get the component-level detail for free — so if GitHub is down but only Actions is affected, you see that, not just "GitHub: down." That matters when you're deciding whether to block a deploy: a documentation outage is different from a CI outage.


A note on fail-open vs fail-closed

The Node.js example above catches API errors and fails open — if Statusfield's API is unreachable, the deploy proceeds. The shell version does the same via curl -sf (silent + fail-on-HTTP-error, but network errors return empty output, which Python parses as 0 outages).

This is intentional. A monitoring check that can itself become a deploy blocker due to network hiccups creates its own category of incident. The value here is catching known outages before you waste a deploy cycle, not adding a new single point of failure.

If you want fail-closed behavior — block on API errors too — remove the catch in the Node version and let it throw.


Setting it up

  1. Sign up for the Hobby plan or above — free plan doesn't include API access
  2. Add the services your team depends on to your monitor list
  3. Generate an API key at Settings → API Keys
  4. Add it as SF_API_KEY in your CI secrets
  5. Drop the pre-flight check into your deploy workflow

Once it's in, the next time GitHub, Stripe, or Vercel has an incident, your deploy will stop and tell you why — before your team spends an hour debugging something that was never their code.


What's next

This covers the read-only v1: query your monitored services, check for outages, gate deploys. Write capabilities — creating monitors programmatically, triggering check-ins — are on the roadmap. The MCP server covers the same catalog for AI tools; if you want to ask Claude about your stack inside an agent loop, that's a separate post.

The full API reference is at statusfield.com/docs/api.

Know the moment a tool you depend on goes down

Statusfield watches 7,000+ services your business depends on and alerts you the moment they break.

Free plan · No credit card