DEV Community

Mike Tickstem
Mike Tickstem

Posted on • Originally published at tickstem.dev

How to Add Uptime Monitoring to a Next.js App on Vercel (With SSL Alerts and Response Assertions)

The Problem

Vercel tells you when a deployment fails. It doesn't tell you when your app is down at 3am on a Saturday.

There's no built-in uptime monitoring on any Vercel plan. If your API route starts returning 500s, or your SSL cert is two weeks from expiring, you find out when a user reports it — not before.

The Solution

Register your endpoints with an external uptime monitor. It polls your URLs on a schedule, checks that responses look healthy, and emails you the moment something goes wrong.

The approach is straightforward:

Tickstem → GET https://yourapp.vercel.app/api/health → assert status 200 + body contains "ok"

Implementation

Install the SDK:

npm install @tickstem/uptime

Create a scripts/setup-monitors.ts file you run once (or in CI after each deploy):

import { UptimeClient } from "@tickstem/uptime";

const client = new UptimeClient(process.env.TICKSTEM_API_KEY!);

await client.create({
    name: "Production API",
    url: "https://yourapp.vercel.app/api/health",
    interval_secs: 60,
    assertions: [
      { source: "status_code",   comparison: "eq",       target: "200" },
      { source: "response_time", comparison: "lt",       target: "3000" },
      { source: "body",          comparison: "contains", target: '"status":"ok"' },
    ],
  });

console.log("monitor registered");
Enter fullscreen mode Exit fullscreen mode

Your health route:

// app/api/health/route.ts
export async function GET() {
  // optionally check DB, Redis, etc.
  return Response.json({ status: "ok" });
}
Enter fullscreen mode Exit fullscreen mode

That's it. Tickstem will poll the endpoint every 60 seconds and email you if any assertion fails — not just if the server is unreachable, but if it returns the wrong status code or the body doesn't look right.

Why assertions matter

A plain ping-check only tells you the server responded. It won't catch:

  • Your health endpoint returning 200 with { "status": "degraded" } because the DB is unreachable
  • A middleware bug that returns 200 for every route including ones that should 404
  • Response times that have quietly climbed from 200ms to 4 seconds

Assertions let you define what healthy actually means for your specific endpoint.

SSL certificate expiry

For any HTTPS endpoint, Tickstem automatically captures the SSL certificate expiry date on every check. When a cert is within 30 days of expiry you get an email alert — before it affects users.

const checks = await client.checks(monitorId, { limit: 1 });
console.log(checks[0].ssl_expires_at); // "2026-08-14T00:00:00Z"
Enter fullscreen mode Exit fullscreen mode

Checking status programmatically

You can query check history from anywhere — useful for CI gates or status page scripts:

const monitors = await client.list();

for (const m of monitors) {
  const checks = await client.checks(m.id, { limit: 1 });
  console.log(`${m.name}: ${checks[0]?.status ?? "no checks yet"}`);
}
Enter fullscreen mode Exit fullscreen mode

Key benefits

  • Works on any Vercel plan including free tier
  • Assertions catch logical failures, not just connectivity
  • SSL expiry alerts before users see the browser warning
  • Check history retained (7 days on Free, up to 90 days on Pro)
  • One API key covers cron jobs, uptime monitoring, and email verification — no separate accounts

Free tier includes 5 monitors. Dashboard at https://app.tickstem.dev.

Top comments (0)