Code Examples
Complete, ready-to-use examples for common API workflows. Each example is a self-contained script you can copy and adapt.
PHP / Laravel
Using Laravel's HTTP client (or any PSR-18 client). These examples assume you store your API key in .env as WATCHCRON_API_KEY.
Create a check and integrate the ping
PHP — Create check and ping on success
<?php use Illuminate\Support\Facades\Http; $apiKey = env('WATCHCRON_API_KEY'); $baseUrl = 'https://watchcron.com/api/v1'; // 1. Create a check for your nightly backup $response = Http::withToken($apiKey) ->post("{$baseUrl}/checks", [ 'name' => 'Nightly DB Backup', 'schedule_type' => 'cron', 'cron_expression' => '0 3 * * *', 'timezone' => 'Europe/Berlin', 'grace_seconds' => 600, 'tags' => ['production', 'database'], ]); $check = $response->json('data'); $pingUrl = $check['ping_url']; echo "Check created: {$check['uuid']}\n"; echo "Ping URL: {$pingUrl}\n"; // 2. In your actual backup script/command, ping on completion: Http::get("{$pingUrl}/start"); // Signal start try { // ... run your backup logic ... Http::get($pingUrl); // Signal success } catch (\Throwable $e) { Http::get("{$pingUrl}/fail"); // Signal failure throw $e; }
List all down checks
PHP — Find failing checks
$response = Http::withToken($apiKey) ->get("{$baseUrl}/checks", ['per_page' => 100]); $downChecks = collect($response->json('data')) ->filter(fn ($c) => $c['status'] === 'down'); foreach ($downChecks as $check) { echo "DOWN: {$check['name']} — last ping: {$check['last_ping_at']}\n"; }
Laravel Scheduler integration
app/Console/Kernel.php
// Laravel's built-in health check ping support $schedule->command('backup:run') ->daily() ->pingBeforeIf(true, 'https://watchcron.com/ping/YOUR-UUID/start') ->thenPing('https://watchcron.com/ping/YOUR-UUID') ->pingOnFailure('https://watchcron.com/ping/YOUR-UUID/fail'); // Multiple tasks, each with its own check $schedule->command('emails:send') ->everyFiveMinutes() ->thenPing('https://watchcron.com/ping/EMAIL-CHECK-UUID'); $schedule->command('reports:generate') ->weeklyOn(1, '8:00') ->thenPing('https://watchcron.com/ping/REPORT-CHECK-UUID');
Python
Using the requests library. Install with pip install requests.
Full workflow: create, ping, and check status
Python — Complete API workflow
import os import requests API_KEY = os.environ["WATCHCRON_API_KEY"] BASE_URL = "https://watchcron.com/api/v1" HEADERS = {"Authorization": f"Bearer {API_KEY}"} def create_check(name, cron_expr, grace=300, tags=None): """Create a new cron job check.""" resp = requests.post( f"{BASE_URL}/checks", headers=HEADERS, json={ "name": name, "schedule_type": "cron", "cron_expression": cron_expr, "grace_seconds": grace, "tags": tags or [], }, ) resp.raise_for_status() return resp.json()["data"] def list_checks(tag=None): """List all checks, optionally filtered by tag.""" params = {} if tag: params["tag"] = tag resp = requests.get( f"{BASE_URL}/checks", headers=HEADERS, params=params, ) resp.raise_for_status() return resp.json()["data"] def ping_check(ping_url, signal="success"): """Send a ping signal. signal: 'success', 'start', or 'fail'.""" url = ping_url if signal == "start": url += "/start" elif signal == "fail": url += "/fail" requests.get(url, timeout=10) # Usage check = create_check("ETL Pipeline", "0 */6 * * *", tags=["etl"]) print(f"Created: {check['name']} — {check['ping_url']}") # In your ETL script: ping_check(check["ping_url"], "start") try: # ... run ETL ... ping_check(check["ping_url"]) except Exception: ping_check(check["ping_url"], "fail") raise
Decorator pattern for automatic monitoring
Python — Decorator for cron job monitoring
import functools import requests def watchcron(ping_url): """Decorator that pings WatchCron on success/failure.""" def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): requests.get(f"{ping_url}/start", timeout=10) try: result = func(*args, **kwargs) requests.get(ping_url, timeout=10) return result except Exception: requests.get(f"{ping_url}/fail", timeout=10) raise return wrapper return decorator @watchcron("https://watchcron.com/ping/YOUR-UUID") def run_backup(): # Your backup logic here print("Backup completed")
Node.js
Using the built-in fetch API (Node.js 18+). No external dependencies needed.
API client helper
Node.js — WatchCron API client
const API_KEY = process.env.WATCHCRON_API_KEY; const BASE_URL = "https://watchcron.com/api/v1"; async function apiRequest(method, path, body = null) { const options = { method, headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json", }, }; if (body) options.body = JSON.stringify(body); const resp = await fetch(`${BASE_URL}${path}`, options); if (!resp.ok) { const err = await resp.json().catch(() => ({})); throw new Error(`API error ${resp.status}: ${err.error || resp.statusText}`); } if (resp.status === 204) return null; return resp.json(); } // Create a check const { data: check } = await apiRequest("POST", "/checks", { name: "Queue Worker Health", schedule_type: "simple", period_seconds: 300, grace_seconds: 120, tags: ["workers"], }); console.log(`Ping URL: ${check.ping_url}`); // List all checks const { data: checks } = await apiRequest("GET", "/checks?per_page=100"); console.log(`Total checks: ${checks.length}`); // Pause a check during deployment await apiRequest("PATCH", `/checks/${check.uuid}/pause`, { paused: true }); // Resume after deployment await apiRequest("PATCH", `/checks/${check.uuid}/pause`, { paused: false });
Go
Create check and send pings
Go — Complete example
package main import ( "bytes" "encoding/json" "fmt" "net/http" "os" ) const baseURL = "https://watchcron.com/api/v1" func main() { apiKey := os.Getenv("WATCHCRON_API_KEY") // Create a check payload, _ := json.Marshal(map[string]any{ "name": "Log Rotation", "schedule_type": "cron", "cron_expression": "0 0 * * 0", "grace_seconds": 1800, }) req, _ := http.NewRequest("POST", baseURL+"/checks", bytes.NewBuffer(payload)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { fmt.Println("Error:", err) return } defer resp.Body.Close() var result struct { Data struct { UUID string `json:"uuid"` PingURL string `json:"ping_url"` } `json:"data"` } json.NewDecoder(resp.Body).Decode(&result) fmt.Printf("Created: %s\nPing URL: %s\n", result.Data.UUID, result.Data.PingURL) // Send a ping (no auth needed) http.Get(result.Data.PingURL) }
Ruby
Ruby — Create and monitor a check
require "net/http" require "json" require "uri" API_KEY = ENV["WATCHCRON_API_KEY"] BASE_URL = "https://watchcron.com/api/v1" def api_request(method, path, body = nil) uri = URI("#{BASE_URL}#{path}") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = case method when :get then Net::HTTP::Get.new(uri) when :post then Net::HTTP::Post.new(uri) when :put then Net::HTTP::Put.new(uri) when :patch then Net::HTTP::Patch.new(uri) when :delete then Net::HTTP::Delete.new(uri) end request["Authorization"] = "Bearer #{API_KEY}" request["Content-Type"] = "application/json" request.body = body.to_json if body response = http.request(request) JSON.parse(response.body) unless response.code == "204" end # Create a check result = api_request(:post, "/checks", { name: "Sidekiq Health", schedule_type: "simple", period_seconds: 600, grace_seconds: 180, }) puts "Ping URL: #{result['data']['ping_url']}" # List all checks checks = api_request(:get, "/checks") checks["data"].each do |c| puts "#{c['name']}: #{c['status']}" end
Bash / Shell
Manage checks from the command line
Bash — API management examples
#!/bin/bash API_KEY="YOUR_API_KEY" BASE="https://watchcron.com/api/v1" # List all checks (formatted with jq) curl -s -H "Authorization: Bearer $API_KEY" \ "$BASE/checks" | jq '.data[] | {name, status, last_ping_at}' # Create a check curl -s -X POST "$BASE/checks" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Weekly Report", "schedule_type": "cron", "cron_expression": "0 9 * * 1", "grace_seconds": 3600 }' | jq '.data.ping_url' # Pause all checks tagged "staging" during deployment curl -s -H "Authorization: Bearer $API_KEY" \ "$BASE/checks?tag=staging&per_page=100" \ | jq -r '.data[].uuid' \ | while read uuid; do curl -s -X PATCH "$BASE/checks/$uuid/pause" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"paused": true}' echo "Paused: $uuid" done
Deployment automation
Pause monitoring during deploys to avoid false alerts, then resume when the deploy completes.
deploy.sh — Pause checks during deployment
#!/bin/bash API_KEY="YOUR_API_KEY" BASE="https://watchcron.com/api/v1" CHECK_UUID="your-check-uuid-here" echo "Pausing monitoring..." curl -s -X PATCH "$BASE/checks/$CHECK_UUID/pause" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"paused": true}' echo "Deploying..." # ... your deploy commands ... echo "Resuming monitoring..." curl -s -X PATCH "$BASE/checks/$CHECK_UUID/pause" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"paused": false}' echo "Deploy complete, monitoring resumed."
Paginating through all results
If you have more checks than fit on a single page, loop through pages until you've seen them all.
def get_all_checks(): all_checks = [] page = 1 while True: resp = requests.get( f"{BASE_URL}/checks", headers=HEADERS, params={"page": page, "per_page": 100}, ) data = resp.json() all_checks.extend(data["data"]) meta = data["meta"]["pagination"] if page >= meta["last_page"]: break page += 1 return all_checks
async function getAllChecks() { const allChecks = []; let page = 1; while (true) { const resp = await fetch( `${BASE_URL}/checks?page=${page}&per_page=100`, { headers: { "Authorization": `Bearer ${API_KEY}` } } ); const { data, meta } = await resp.json(); allChecks.push(...data); if (page >= meta.pagination.last_page) break; page++; } return allChecks; }
$allChecks = []; $page = 1; do { $response = Http::withToken($apiKey) ->get("{$baseUrl}/checks", [ 'page' => $page, 'per_page' => 100, ]); $data = $response->json(); $allChecks = array_merge($allChecks, $data['data']); $lastPage = $data['meta']['pagination']['last_page']; $page++; } while ($page <= $lastPage);