Blog

How to monitor API endpoint uptime: status codes, latency, body checks, health endpoints and third-party APIs

An API can return 200 and still be broken. Define what up means, build a health endpoint that tests dependencies, handle auth and rate limits, and watch third-party APIs.

To monitor API endpoint uptime properly, check three things on every request: the status code, the response time against a fixed budget, and the response body for a value that proves the API actually worked. Point those checks at a health endpoint that tests your real dependencies, run them from several regions with a dedicated read-only credential, and monitor the third-party APIs you depend on as separate checks with their own alert routing.

The rest of this guide covers each of those pieces with commands, example code and thresholds you can copy.

What does "up" mean for an API endpoint?

For a website, a 200 response is often good enough. For an API it is not. APIs fail in ways that still produce a clean HTTP response, and a check that only looks at the status line will report them as healthy.

Typical examples:

  • A 200 OK with a body like {"error": "database unavailable"}, because a framework error handler swallowed the exception.
  • A 200 OK with an HTML maintenance page served by a proxy or CDN instead of JSON.
  • A 200 OK with an empty list, because a cache returned stale or empty data after a failed refresh.
  • A correct response that takes 25 seconds, so every client with a 10 second timeout sees a failure.

So define "up" as three conditions that must all be true. An API endpoint is up only when it returns the expected status code, within your latency budget, with a response body that proves the work was done. Anything less is a partial signal.

You can test all three from a shell before configuring any tool:

curl -sS --max-time 10 \
  -o /tmp/body.json \
  -w "%{http_code} %{time_total}s\n" \
  https://api.example.com/v1/health

jq -e '.status == "ok"' /tmp/body.json

The first command prints the status code and total time. The second exits non-zero if the body does not contain the expected value. If you want to separate server time from network time, %{time_starttransfer} gives you something close to TTFB and the other monitoring terms you will see in dashboards.

How to monitor API endpoint uptime step by step

  1. Pick the endpoints. Start with one health endpoint plus one or two real business endpoints that customers call most, for example a read endpoint like GET /v1/projects. Avoid endpoints that write data.
  2. Define the success criteria. Expected status (usually 200), a timeout (for example 10 seconds), a latency warning threshold (for example 2 seconds) and a body assertion such as a JSON field or a known string.
  3. Create a monitoring credential. A dedicated, read-only token scoped to the endpoints you check. Never reuse a personal or admin key.
  4. Run checks from several regions. Require at least two locations to agree before an alert fires, so one bad network route does not wake anyone up.
  5. Require consecutive failures. Alert after two failed checks in a row, not one. At a one minute interval that adds about a minute of detection time and removes most noise.
  6. Route alerts by severity. Your own API being down pages on-call. Slow responses or a degraded third-party dependency go to a team channel.
  7. Test the alert path. Break the check on purpose, for example by asserting a body value that does not exist, and confirm the alert arrives where you expect.

What should a health-check endpoint test?

A health endpoint that only returns {"status":"ok"} without touching anything proves that the process is running and the router works. That is useful, but it misses the most common API outages: the database is unreachable, the connection pool is exhausted, the cache is down.

The usual pattern is two endpoints:

  • /health/live checks only that the process responds. Container orchestrators use this to decide whether to restart the process. It must never depend on external systems, or a database blip restarts every instance at once.
  • /health/ready checks the dependencies the API needs to serve requests. This is the one your external uptime checks should call.

A readiness check should run a cheap query against each critical dependency, each with its own short timeout, and return 503 when a critical dependency fails. A sketch in Node.js:

const withTimeout = (p, ms) =>
  Promise.race([p, new Promise((_, rej) =>
    setTimeout(() => rej(new Error('timeout')), ms))]);

app.get('/health/ready', async (req, res) => {
  const [db, cache] = await Promise.allSettled([
    withTimeout(pool.query('SELECT 1'), 2000),
    withTimeout(redis.ping(), 1000),
  ]);

  const checks = {
    database: db.status === 'fulfilled' ? 'ok' : 'fail',
    cache: cache.status === 'fulfilled' ? 'ok' : 'degraded',
  };
  const healthy = checks.database === 'ok';

  res.status(healthy ? 200 : 503).json({
    status: healthy ? 'ok' : 'fail',
    checks,
  });
});

A few rules keep this endpoint honest without turning it into a liability:

  • Separate critical from optional dependencies. If the API can serve requests without the cache, a cache failure should report degraded with a 200, not a 503.
  • Keep the total time below your monitor timeout. With per-dependency timeouts of 1 to 2 seconds running in parallel, the endpoint answers in under 3 seconds even when something hangs, so your check sees a clear 503 instead of an ambiguous timeout.
  • Cache the result for a few seconds. If checks arrive from several regions plus a load balancer, a 5 to 10 second cache stops the health endpoint from becoming a measurable share of database load.
  • Do not call third-party APIs here. If a payment provider is slow, your health check should not time out because of it. Monitor those separately, as described below.
  • Leak nothing sensitive. Status words and latencies are fine. Hostnames, connection strings and stack traces are not.

The health endpoint is not the whole picture. It runs your code path for health, not the code path customers use. That is why the step list above also includes one or two real read endpoints with body assertions.

How to authenticate uptime checks against a protected API

Most real endpoints require authentication, so the monitor needs a credential. Treat it like any other production secret.

  • Create a dedicated service account or API key named something obvious like uptime-monitor, so its requests are easy to filter in logs and analytics.
  • Scope it to read-only access on the specific resources you check. If the token leaks, it should not be able to change or export anything meaningful.
  • Point it at a test tenant or project with stable, known data, so your body assertion can check for a specific record.
  • Send it in a header such as Authorization: Bearer ..., not in the query string, where it ends up in access logs.
  • Put the expiry date in your calendar or rotation process. An expired token turns every check into a 401.

That last point matters for alerting. A 401 or 403 from your monitor almost always means the credential broke, not the API. If your tool lets you, route auth failures to the team channel rather than paging, and fix them during working hours.

Be careful with IP allowlists. Monitoring probes run from many locations and their addresses can change, so allowlisting probe IPs tends to break silently. A scoped token is easier to maintain.

How to avoid rate limits when monitoring an API

Monitoring traffic is small but constant, and it adds up. A check every 60 seconds from 3 regions on 4 endpoints is 12 requests per minute, 720 per hour, every hour. If the monitoring key shares a rate limit bucket with a customer or with your own integration tests, you will eventually see 429 Too Many Requests in your checks.

Three ways to handle it:

  • Exempt /health/* from rate limiting entirely, or give it a generous separate limit.
  • Give the monitoring key its own bucket so it never competes with real users.
  • Check business endpoints less often than the health endpoint, for example the health endpoint every minute and a heavier read endpoint every five minutes.

Then decide what a 429 means. If your monitor hits the limit, it is noise. If customers hit it, it is an outage from their point of view. Keeping the monitor out of the customer limit lets you treat any 429 it sees as a real signal.

How to monitor third-party APIs you depend on

Your API can be fully up while a dependency you do not control is failing: a payment provider, an email API, an auth provider, a geocoding service. Customers experience that as your outage.

Monitor these as separate checks:

  • Call a cheap, read-only endpoint with your own credentials, such as fetching account details or a list with a limit of 1. This tests your specific integration, including your key and your network path, which the provider's status page cannot do.
  • Use generous thresholds. Third-party latency varies more than your own, so a timeout of 10 to 15 seconds and three consecutive failures before alerting is reasonable.
  • Route alerts to a team channel, not to on-call, unless the dependency is truly critical and you have a fallback to switch on.
  • Respect their rate limits and terms. One check every few minutes is plenty for awareness.

The value is speed of diagnosis. When your own API starts throwing errors, a red check on the payment provider tells you in seconds where to look, and it tells your support team what to say. The same logic applies to your own infrastructure in between: errors on the proxy layer often look like API failures, and the guide on 502 Bad Gateway causes between proxy and upstream covers how to tell them apart.

Thresholds that work as a starting point

Adjust these to your own traffic, but they are a sensible default for a typical JSON API:

  • Check interval: 60 seconds for the health endpoint, 1 to 5 minutes for business endpoints.
  • Timeout: 10 seconds. Shorter causes flapping on cold starts, longer delays detection.
  • Latency warning: around 3 to 5 times your normal p50 response time, sent to a channel, not a pager.
  • Down: two consecutive failures confirmed from at least two regions.
  • Recovery: one successful check from the confirming regions, so the incident closes promptly.

If you still get alerts that turn out to be nothing, the article on reducing false positive alerts with retries and realistic timeouts goes deeper into tuning.

Setting this up with m0nitor

m0nitor is one option for running these checks. Its HTTP(S) and other monitor types run on a fixed interval from distributed probes in several regions, and an outage must be confirmed by multiple locations before an alert fires. You can point an HTTP(S) monitor at your readiness endpoint, add monitors for the third-party APIs you depend on, and use TCP port or DNS monitors for the layers underneath. With alert workflows you can send different monitor events to different channels, open an incident or call a webhook, which fits the split between paging for your own API and notifying a channel for dependencies.

FAQ

Is a 200 status code enough to know an API is up?

No. APIs regularly return 200 with an error message, an HTML page from a proxy or empty data. Combine the status code with a timeout and a body assertion, such as checking that a JSON field equals an expected value.

Should my health check endpoint test the database?

Yes, the readiness endpoint that external monitors call should run a cheap query like SELECT 1 with a short timeout and return 503 if it fails. Keep a separate liveness endpoint without dependencies for container restarts.

How often should I check an API endpoint?

Every 60 seconds is a common default for a health endpoint. Heavier business endpoints and third-party APIs can run every 1 to 5 minutes to limit load and rate limit usage while still catching outages quickly.

Should uptime checks use authentication?

For real business endpoints, yes. Use a dedicated read-only token scoped to a test tenant, send it in a header, and track its expiry. Keep the health endpoint unauthenticated but strip it of anything sensitive.

Product

  • Pricing
  • Features
  • Integrations
  • Security
  • Free network check

Features

  • Uptime monitoring
  • Status pages
  • Alert workflows
  • Incident management
  • Dependencies
  • AI assistant
  • Global infrastructure
  • On-call schedules
  • Enterprise SSO

Use cases

  • Websites for free
  • Cron jobs
  • SSL certificates
  • Databases
  • IP blacklists
  • GDPR compliance

Resources

  • What is a status page?
  • Documentation
  • API
  • MCP server
  • Monitoring glossary
  • Free tools
  • SLA calculator
  • SSL checker
  • DNS lookup
  • Blog
  • Changelog
  • About
  • Contact

Compare

  • Free uptime monitoring
  • UptimeRobot
  • Better Stack
  • Pingdom
  • StatusCake
  • Uptime Kuma
  • Hyperping
  • Atlassian Statuspage
  • Instatus
  • Cachet
  • Freshping