Uptime Robot
"Uptime Robot: uptime monitoring API, HTTP/keyword/ping checks, status pages, alert contacts, maintenance windows"
You are an expert in integrating Uptime Robot for uptime and availability monitoring. ## Key Points - name: Pause monitors during deploy - name: Deploy application - name: Resume monitors after deploy - **Not handling rate limits** — the API limits requests to roughly 10 per minute; bulk operations (syncing many monitors) need delays between calls or the API will return errors.
skilldb get monitoring-services-skills/Uptime RobotFull skill: 347 linesUptime Robot — Application Monitoring
You are an expert in integrating Uptime Robot for uptime and availability monitoring.
Core Philosophy
Overview
Uptime Robot is an uptime monitoring service that checks websites, APIs, and servers at intervals as short as one minute. It supports HTTP, keyword, ping, and port monitors. Its REST API allows programmatic management of monitors, alert contacts, status pages, and maintenance windows, making it suitable for teams that want to automate monitor provisioning alongside deployments.
Setup & Configuration
API Client Setup
// lib/uptime-robot.ts
const UPTIME_ROBOT_API_URL = "https://api.uptimerobot.com/v2";
interface UptimeRobotConfig {
apiKey: string;
}
class UptimeRobotClient {
private apiKey: string;
constructor(config: UptimeRobotConfig) {
this.apiKey = config.apiKey;
}
private async request<T>(
endpoint: string,
params: Record<string, string | number> = {}
): Promise<T> {
const response = await fetch(`${UPTIME_ROBOT_API_URL}/${endpoint}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
api_key: this.apiKey,
format: "json",
...params,
}),
});
if (!response.ok) {
throw new Error(`Uptime Robot API error: ${response.status}`);
}
const data = (await response.json()) as { stat: string; error?: { message: string } };
if (data.stat !== "ok") {
throw new Error(`Uptime Robot error: ${data.error?.message ?? "Unknown error"}`);
}
return data as T;
}
async getMonitors(params?: {
monitors?: string;
statuses?: string;
search?: string;
}) {
return this.request<GetMonitorsResponse>("getMonitors", {
response_times: 1,
response_times_limit: 24,
logs: 1,
logs_limit: 10,
...params,
});
}
async createMonitor(params: CreateMonitorParams) {
return this.request<CreateMonitorResponse>("newMonitor", params as any);
}
async editMonitor(id: number, params: Partial<CreateMonitorParams>) {
return this.request("editMonitor", { id, ...params } as any);
}
async deleteMonitor(id: number) {
return this.request("deleteMonitor", { id });
}
async getAlertContacts() {
return this.request<GetAlertContactsResponse>("getAlertContacts");
}
}
// Types
interface CreateMonitorParams {
friendly_name: string;
url: string;
type: 1 | 2 | 3 | 4 | 5; // 1=HTTP, 2=keyword, 3=ping, 4=port, 5=heartbeat
interval?: number; // seconds, minimum 60
alert_contacts?: string; // format: "id_threshold_recurrence"
keyword_type?: 1 | 2; // 1=exists, 2=not exists
keyword_value?: string;
http_method?: 1 | 2 | 3 | 4; // 1=HEAD, 2=GET, 3=POST, 4=PUT
http_username?: string;
http_password?: string;
custom_http_headers?: Record<string, string>;
}
interface Monitor {
id: number;
friendly_name: string;
url: string;
type: number;
status: number; // 0=paused, 1=not checked, 2=up, 8=seems down, 9=down
all_time_uptime_ratio: string;
average_response_time: string;
response_times: { datetime: number; value: number }[];
logs: { type: number; datetime: number; duration: number }[];
}
interface GetMonitorsResponse {
stat: string;
monitors: Monitor[];
pagination: { total: number; limit: number; offset: number };
}
interface CreateMonitorResponse {
stat: string;
monitor: { id: number; status: number };
}
interface GetAlertContactsResponse {
stat: string;
alert_contacts: { id: string; type: number; value: string }[];
}
export const uptimeRobot = new UptimeRobotClient({
apiKey: process.env.UPTIME_ROBOT_API_KEY!,
});
Core Patterns
Provision Monitors on Deploy
// scripts/sync-monitors.ts
import { uptimeRobot } from "../lib/uptime-robot";
interface MonitorDefinition {
name: string;
url: string;
type: 1 | 2 | 3 | 4 | 5;
interval: number;
keyword_type?: 1 | 2;
keyword_value?: string;
}
const monitors: MonitorDefinition[] = [
{
name: "API Health",
url: "https://api.example.com/health",
type: 2, // keyword check
interval: 60,
keyword_type: 1,
keyword_value: '"status":"ok"',
},
{
name: "Website Homepage",
url: "https://www.example.com",
type: 1, // HTTP check
interval: 300,
},
{
name: "Auth Service",
url: "https://auth.example.com/.well-known/openid-configuration",
type: 1,
interval: 60,
},
];
async function syncMonitors() {
const existing = await uptimeRobot.getMonitors();
const existingByName = new Map(
existing.monitors.map((m) => [m.friendly_name, m])
);
const contacts = await uptimeRobot.getAlertContacts();
const alertString = contacts.alert_contacts
.map((c) => `${c.id}_0_0`)
.join("-");
for (const def of monitors) {
const existingMonitor = existingByName.get(def.name);
if (existingMonitor) {
console.log(`Updating monitor: ${def.name}`);
await uptimeRobot.editMonitor(existingMonitor.id, {
friendly_name: def.name,
url: def.url,
type: def.type,
interval: def.interval,
keyword_type: def.keyword_type,
keyword_value: def.keyword_value,
});
} else {
console.log(`Creating monitor: ${def.name}`);
await uptimeRobot.createMonitor({
friendly_name: def.name,
url: def.url,
type: def.type,
interval: def.interval,
alert_contacts: alertString,
keyword_type: def.keyword_type,
keyword_value: def.keyword_value,
});
}
}
}
syncMonitors().catch(console.error);
Build a Status Dashboard from the API
// api/status.ts — expose uptime data to your own status page
import { uptimeRobot } from "../lib/uptime-robot";
interface ServiceStatus {
name: string;
status: "operational" | "degraded" | "down" | "unknown";
uptimePercent: string;
avgResponseMs: number;
lastIncident: string | null;
}
export async function getServiceStatuses(): Promise<ServiceStatus[]> {
const data = await uptimeRobot.getMonitors();
return data.monitors.map((monitor) => {
const statusMap: Record<number, ServiceStatus["status"]> = {
0: "unknown", // paused
1: "unknown", // not checked yet
2: "operational",
8: "degraded",
9: "down",
};
const downLogs = monitor.logs.filter((log) => log.type === 1);
const lastIncident = downLogs.length > 0
? new Date(downLogs[0].datetime * 1000).toISOString()
: null;
return {
name: monitor.friendly_name,
status: statusMap[monitor.status] ?? "unknown",
uptimePercent: parseFloat(monitor.all_time_uptime_ratio).toFixed(2),
avgResponseMs: parseInt(monitor.average_response_time, 10),
lastIncident,
};
});
}
Maintenance Window Management
// lib/maintenance.ts
import { uptimeRobot } from "./uptime-robot";
export async function createMaintenanceWindow(
monitorIds: number[],
durationMinutes: number,
reason: string
) {
const startTime = Math.floor(Date.now() / 1000);
const endTime = startTime + durationMinutes * 60;
// Pause monitors during deployment
for (const id of monitorIds) {
await uptimeRobot.editMonitor(id, {
friendly_name: "", // required but won't change
url: "",
type: 1,
});
}
console.log(
`Maintenance window: ${reason} — paused ${monitorIds.length} monitors for ${durationMinutes}m`
);
// Schedule resume
setTimeout(async () => {
for (const id of monitorIds) {
await uptimeRobot.editMonitor(id, {
friendly_name: "",
url: "",
type: 1,
});
}
console.log("Maintenance window ended, monitors resumed");
}, durationMinutes * 60 * 1000);
}
CI/CD Integration
# .github/workflows/deploy.yml
- name: Pause monitors during deploy
run: |
curl -X POST https://api.uptimerobot.com/v2/editMonitor \
-H "Content-Type: application/json" \
-d '{"api_key":"${{ secrets.UPTIME_ROBOT_API_KEY }}","id":${{ vars.MONITOR_ID }},"status":0}'
- name: Deploy application
run: ./deploy.sh
- name: Resume monitors after deploy
if: always()
run: |
curl -X POST https://api.uptimerobot.com/v2/editMonitor \
-H "Content-Type: application/json" \
-d '{"api_key":"${{ secrets.UPTIME_ROBOT_API_KEY }}","id":${{ vars.MONITOR_ID }},"status":1}'
Best Practices
- Use keyword checks over plain HTTP checks — an HTTP 200 does not mean your app is healthy; keyword checks verify the response body contains expected content like
"status":"ok", catching cases where a load balancer returns 200 but the app is broken. - Set up alert contacts before creating monitors — the API requires alert contact IDs when creating monitors; provision Slack webhooks, email, or PagerDuty contacts first, then reference their IDs.
- Sync monitor definitions from code — defining monitors in a script and running it on deploy prevents drift between what is deployed and what is monitored, and makes monitors reviewable in pull requests.
Common Pitfalls
- Using the main API key for read-only dashboards — Uptime Robot's main API key has full write access; use a read-only API key for status pages and public dashboards to avoid accidental or malicious modification.
- Not handling rate limits — the API limits requests to roughly 10 per minute; bulk operations (syncing many monitors) need delays between calls or the API will return errors.
Anti-Patterns
Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.
Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.
Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.
Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.
Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.
Install this skill directly: skilldb add monitoring-services-skills
Related Skills
Baselime
Baselime is a serverless-native observability platform designed for AWS, unifying logs, traces, and metrics. It provides real-time insights and contextualized data to help you understand and troubleshoot your distributed serverless applications.
BetterStack
"BetterStack (formerly Better Uptime + Logtail): uptime monitoring, log management, status pages, incident management, alerting"
Checkly
"Checkly: synthetic monitoring, API checks, browser checks, Playwright-based E2E monitoring, monitoring-as-code CLI"
Cronitor
Cronitor is a robust monitoring service designed to ensure your background jobs (cron jobs, scheduled tasks, async workers) and APIs run reliably. It actively monitors the health and execution of automated processes, alerting you instantly to missed runs, failures, or delays. Use Cronitor to gain peace of mind and critical visibility into your application's backend operations.
Datadog
"Datadog: APM, log management, infrastructure monitoring, RUM, custom metrics, dashboards, Node.js tracing"
Grafana Cloud
Grafana Cloud is a fully managed observability platform that unifies metrics (Prometheus/Graphite), logs (Loki), and traces (Tempo) within a single Grafana interface. Use it to gain deep insights into your applications and infrastructure without the operational overhead of managing your own observability stack, allowing you to focus on building and improving your services.