DevOpsil

API Health Monitor

API Health Monitor runs synthetic health checks against any set of HTTP endpoints and returns latency, TLS expiry, DNS resolution status, and custom assertion results — in a single parallel API call.

Quick start →View DocsPOST https://devopsil.com/api/v1/health/check

What is it?

API Health Monitor runs synthetic health checks against any set of HTTP endpoints and returns latency, TLS expiry, DNS resolution status, and custom assertion results — in a single parallel API call. It accepts a single JSON payload and returns a structured response in milliseconds — no agents, plugins, or background workers required. The API is designed for synchronous, real-time use: call it inline in your request handler, CI step, or event pipeline and act on the result immediately.

Why do you need it?

Problem

  • You don't know an endpoint is down until a customer reports it, or your own service tries to call it and throws an error that propagates through your system.
  • TLS certificate expiry is a silent failure — everything works fine until midnight when the cert expires, and then 100% of HTTPS traffic fails with no graceful degradation.
  • DNS failures are notoriously hard to detect proactively — they cause 100% error rates but don't show up in application error logs if the failure happens before the TCP connection is established.

Consequence

  • Partner API outages cascade silently through your system — your service retries, your queues back up, your database connection pool saturates, and by the time on-call is paged the incident has been running for 20 minutes.
  • Expired TLS certs block all traffic and break every client at once — the fix is instant but the damage is done. Average customer-reported TLS outages last 47 minutes because no one is watching cert expiry.
  • DNS failures cause 100% error rates with no alert because most monitoring checks the HTTP response code, not whether DNS resolved. The incident runs silently until someone manually investigates.

Solution

  • Proactive synthetic health checks that run from outside your infrastructure — you know an endpoint is down before your users do.
  • TLS and DNS inspection baked into every check — cert expiry, issuer, days remaining, and DNS resolution time are all returned per endpoint.
  • Runs from your code or CI/CD — no agent to deploy, no dashboard to configure, no external SaaS to trust with your endpoint list.

Use cases

Uptime monitoring cron job

Check all production endpoints every 60 seconds, alert on failure, and track availability over time without deploying a monitoring agent.

Node.js — uptime monitor cron

const API_KEY = process.env.DEVOPSIL_API_KEY;

async function runHealthChecks() {
  const result = await fetch('https://devopsil.com/api/v1/health/check', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      checks: [
        { url: 'https://api.acme.com/health',       assertions: [{ type: 'status_equals', value: 200 }] },
        { url: 'https://app.acme.com',               assertions: [{ type: 'latency_under', value: 1000 }] },
        { url: 'https://payments.acme.com/ping',     assertions: [{ type: 'body_contains', value: 'ok' }] },
      ],
    }),
  }).then(r => r.json());

  for (const check of result.results) {
    if (check.status !== 'healthy') await alertOnCall(check);
  }
}

Each result entry has status ('healthy'|'degraded'|'unhealthy'), latency_ms, and assertion_results. Page on-call when status !== 'healthy'.

Pre-deployment dependency check

Verify all downstream APIs your service depends on are healthy before you deploy, preventing you from shipping code that will immediately fail due to an external outage.

Node.js — pre-deploy dependency check

const API_KEY = process.env.DEVOPSIL_API_KEY;

const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checks: [
      { url: 'https://api.stripe.com/v1/charges',    assertions: [{ type: 'status_equals', value: 200 }] },
      { url: 'https://api.sendgrid.com/v3/mail/send', assertions: [{ type: 'status_equals', value: 200 }] },
      { url: 'https://hooks.slack.com/services/ping', assertions: [{ type: 'latency_under', value: 2000 }] },
    ],
  }),
}).then(r => r.json());

const unhealthy = result.results.filter(r => r.status === 'unhealthy');
if (unhealthy.length > 0) process.exit(1);

Block the deploy pipeline if any dependency is unhealthy. Print the failing assertion details so the team knows which dependency is the issue.

TLS expiry alerting

Check all your TLS certificates daily and alert when any cert is within 30 days of expiry — before the renewal slips through the cracks.

Node.js — daily TLS check

const API_KEY = process.env.DEVOPSIL_API_KEY;

const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checks: allDomains.map(domain => ({
      url: `https://${domain}`,
      assertions: [
        { type: 'tls_valid', value: true },
        { type: 'tls_expires_after', value: 30 }, // alert if < 30 days remaining
      ],
    })),
  }),
}).then(r => r.json());

for (const check of result.results) {
  const tls = check.tls;
  if (tls && tls.days_remaining < 30) await alertSlack(`TLS expiring: ${check.url} in ${tls.days_remaining} days`);
}

check.tls includes days_remaining, issuer, and valid flag. Alert on any domain where days_remaining < 30.

Multi-region health validation

Verify your load balancer returns correct responses from multiple check points to confirm there are no regional routing issues.

Node.js — multi-region check

const API_KEY = process.env.DEVOPSIL_API_KEY;

const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checks: [
      {
        url: 'https://api.acme.com/health',
        assertions: [
          { type: 'status_equals', value: 200 },
          { type: 'body_json_path', value: "$.status == 'healthy'" },
          { type: 'header_present', value: 'X-Request-Id' },
        ],
      },
    ],
    check_regions: ['us-east', 'eu-west', 'ap-southeast'],
  }),
}).then(r => r.json());

result.results has one entry per region. Compare latencies across regions to detect routing anomalies and regional outages.

SLA reporting

Store health check results over time and generate a weekly availability report for your customers based on real synthetic check data.

Node.js — store for SLA report

const API_KEY = process.env.DEVOPSIL_API_KEY;

const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ checks: monitoredEndpoints }),
}).then(r => r.json());

await db.insert('health_checks', {
  ts: new Date(),
  results: JSON.stringify(result.results),
  overall_status: result.overall_status,
});

Aggregate stored results over 7 days. Availability = (healthy_checks / total_checks) × 100. Publish the number in your status page.

Dependency health in CI

Fail a build if a required external API is down during integration tests, making the failure reason immediately clear rather than showing confusing test timeouts.

Node.js — CI dependency check

const API_KEY = process.env.DEVOPSIL_API_KEY;

// Run before integration test suite
const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checks: integrationTestDependencies.map(url => ({
      url,
      assertions: [{ type: 'status_equals', value: 200 }, { type: 'latency_under', value: 2000 }],
    })),
  }),
}).then(r => r.json());

if (result.overall_status !== 'healthy') {
  console.error('CI SKIP: required dependencies are not healthy', result.results.filter(r => r.status !== 'healthy'));
  process.exit(77); // skip code — not a test failure
}

Exit 77 to mark the CI job as skipped rather than failed, so the status page shows 'skipped due to infrastructure' rather than 'tests failed'.

Assertion types

AssertionWhat it checksExample value
status_equalsHTTP response status code200
latency_underResponse time in milliseconds1000
body_containsString present in response body"status":"ok"
body_json_pathJSONPath expression on response$.data.status == 'active'
tls_validTLS certificate is valid and not expiredtrue
tls_expires_afterCertificate expires after N days30
header_presentResponse header existsX-Request-Id
redirect_allowedFollow redirects (true/false)false

How the API works

All requests use Bearer authentication. Your API key starts with api_. Get one at /dashboard/api-keys.

Request

{
  "checks": [
    {
      "url": "https://api.acme.com/health",
      "assertions": [
        { "type": "status_equals",    "value": 200 },
        { "type": "latency_under",    "value": 800 },
        { "type": "body_json_path",   "value": "$.status == 'healthy'" },
        { "type": "tls_expires_after","value": 30 }
      ]
    }
  ]
}

Response

{
  "overall_status": "healthy",
  "checks_run": 1,
  "duration_ms": 187,
  "results": [
    {
      "url": "https://api.acme.com/health",
      "status": "healthy",
      "latency_ms": 143,
      "http_status": 200,
      "tls": {
        "valid": true,
        "issuer": "Let's Encrypt",
        "expires_at": "2024-06-12T00:00:00Z",
        "days_remaining": 88
      },
      "dns_resolution_ms": 12,
      "assertion_results": [
        { "type": "status_equals",    "passed": true,  "expected": 200, "actual": 200 },
        { "type": "latency_under",    "passed": true,  "expected": 800, "actual": 143 },
        { "type": "body_json_path",   "passed": true,  "expression": "$.status == 'healthy'" },
        { "type": "tls_expires_after","passed": true,  "expected": 30,  "actual": 88 }
      ]
    }
  ]
}

Quick start

1

Get your API key

Create a free account and generate a key at /dashboard/api-keys. Your key starts with api_.

2

Make your first call

Node.js

const API_KEY = process.env.DEVOPSIL_API_KEY; // starts with api_

const result = await fetch('https://devopsil.com/api/v1/health/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    checks: [
      {
        url: 'https://api.example.com/health',
        assertions: [
          { type: 'status_equals', value: 200 },
          { type: 'latency_under', value: 1000 },
        ],
      },
    ],
  }),
}).then(r => r.json());

console.log(result.overall_status, result.results[0].latency_ms + 'ms');
3

Act on the result

Node.js — handle response

if (result.overall_status !== 'healthy') {
  const failed = result.results.filter(r => r.status !== 'healthy');
  for (const check of failed) {
    const failedAssertions = check.assertion_results.filter(a => !a.passed);
    console.error(`UNHEALTHY: ${check.url}`, failedAssertions);
  }
  process.exit(1);
} else {
  console.log(`All ${result.checks_run} checks healthy in ${result.duration_ms}ms`);
}

Frequently asked questions

Ready to integrate?

Free tier included. No credit card required.