# PingZen API Reference for AI Agents > Complete API documentation for programmatic access to PingZen monitoring platform ## Base URL ``` https://pingzen.dev/api/v1 ``` ## Authentication All API requests require authentication via one of these methods: ### API Key (Recommended) ``` X-API-Key: pz_abc123... ``` ### JWT Bearer Token ``` Authorization: Bearer eyJhbGciOiJIUzI1NiIs... ``` ## OpenAPI Schema Machine-readable OpenAPI 3.1 specification: ``` https://pingzen.dev/openapi.json ``` --- # Monitors API ## List Monitors ```http GET /api/v1/monitors ``` **Query Parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | page | integer | 1 | Page number | | page_size | integer | 50 | Items per page (max 100) | | workspace_id | integer | required | Workspace ID | | status | string | - | Filter by status: up, down, degraded, pending | | protocol | string | - | Filter by protocol: http, https, tcp, etc. | | search | string | - | Search by name or URL | **Response:** ```json { "monitors": [ { "id": 123, "name": "My Website", "url": "https://example.com", "protocol": "https", "status": "up", "is_active": true, "interval_seconds": 60, "timeout_seconds": 30, "uptime_24h": 99.95, "avg_response_time_24h": 245.5, "last_response_time_ms": 234, "last_check_at": "2026-02-07T10:30:00Z", "ssl_days_until_expiry": 45, "ssl_tls_version": "TLSv1.3", "created_at": "2026-01-01T00:00:00Z" } ], "total": 15, "page": 1, "page_size": 50 } ``` ## Get Monitor ```http GET /api/v1/monitors/{id} ``` **Response:** Single monitor object (same schema as list item) ## Create Monitor ```http POST /api/v1/monitors ``` **Request Body:** ```json { "name": "My Website", "url": "https://example.com", "protocol": "https", "workspace_id": 1, "interval_seconds": 60, "timeout_seconds": 30, "is_active": true, "expected_status": 200, "keyword": "Welcome", "keyword_present": true, "verify_ssl": true, "follow_redirects": true, "headers": {"X-Custom": "value"}, "http_method": "GET" } ``` **Supported Protocols:** - `http`, `https` - HTTP/HTTPS monitoring - `tcp`, `udp` - Network port monitoring - `icmp`, `ping` - ICMP ping - `dns` - DNS resolution - `ssl` - SSL certificate monitoring - `whois` - Domain expiry monitoring - `grpc` - gRPC health checks - `ws`, `wss` - WebSocket monitoring - `smtp`, `imap`, `pop3` - Email servers - `ftp`, `ftps` - FTP servers - `dnsbl` - Blacklist checking - `safebrowsing` - Google Safe Browsing - `pagespeed` - PageSpeed Insights - `api_check` - Multi-step API checks ## Update Monitor ```http PUT /api/v1/monitors/{id} ``` **Request Body:** Same as create (partial updates supported) ## Delete Monitor ```http DELETE /api/v1/monitors/{id} ``` ## Pause/Resume Monitor ```http POST /api/v1/monitors/{id}/toggle ``` ## Run Manual Check ```http POST /api/v1/monitors/{id}/check ``` ## Get Monitor Statistics ```http GET /api/v1/monitors/{id}/stats ``` **Query Parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | period | string | 24h | Period: 24h, 7d, 30d | **Response:** ```json { "monitor_id": 123, "uptime_percentage": 99.95, "avg_response_time_ms": 245.5, "checks_total": 1440, "checks_up": 1438, "checks_down": 2, "checks_timeout": 0, "period_start": "2026-02-06T10:30:00Z", "period_end": "2026-02-07T10:30:00Z" } ``` ## Get Check Results History ```http GET /api/v1/monitors/{id}/results ``` **Query Parameters:** | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | limit | integer | 100 | Max results | | offset | integer | 0 | Offset for pagination | --- # Alerts API ## List Alerts ```http GET /api/v1/alerts ``` **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | workspace_id | integer | Required | | monitor_id | integer | Filter by monitor | ## Create Alert ```http POST /api/v1/alerts ``` **Request Body:** ```json { "monitor_id": 123, "workspace_id": 1, "channel": "telegram", "target": "123456789", "triggers": ["down", "recovered"], "cooldown_minutes": 5, "is_active": true } ``` **Alert Channels:** - `telegram` - Telegram bot (target: chat_id) - `slack` - Slack webhook (target: webhook_url) - `discord` - Discord webhook (target: webhook_url) - `msteams` - MS Teams webhook (target: webhook_url) - `mattermost` - Mattermost webhook (target: webhook_url) - `webhook` - Custom HTTP endpoint (target: url) - `email` - Email (target: email address) - `pagerduty` - PagerDuty (target: routing_key) - `ntfy` - ntfy.sh (target: topic) - `gotify` - Gotify (target: server_url) - `pushover` - Pushover (target: user_key) **Alert Triggers:** - `down` - Monitor went down - `recovered` - Monitor recovered - `degraded` - Response time threshold exceeded - `certificate_expiring` - SSL cert expiring soon - `response_time_high` - High response time ## Update Alert ```http PUT /api/v1/alerts/{id} ``` ## Delete Alert ```http DELETE /api/v1/alerts/{id} ``` ## Test Alert ```http POST /api/v1/alerts/{id}/test ``` --- # Incidents API ## List Incidents ```http GET /api/v1/incidents ``` **Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | workspace_id | integer | Required | | status | string | ongoing, resolved, acknowledged | | monitor_id | integer | Filter by monitor | | page | integer | Page number | | page_size | integer | Items per page | **Response:** ```json { "incidents": [ { "id": 456, "monitor_id": 123, "monitor_name": "My Website", "status": "ongoing", "started_at": "2026-02-07T10:30:00Z", "resolved_at": null, "duration_seconds": null, "error_message": "Connection timeout" } ], "total": 5, "page": 1, "page_size": 50 } ``` ## Get Incident ```http GET /api/v1/incidents/{id} ``` ## Acknowledge Incident ```http POST /api/v1/incidents/{id}/acknowledge ``` ## Resolve Incident ```http POST /api/v1/incidents/{id}/resolve ``` --- # Status Pages API ## List Status Pages ```http GET /api/v1/status-pages ``` ## Create Status Page ```http POST /api/v1/status-pages ``` **Request Body:** ```json { "title": "My Service Status", "slug": "my-service", "description": "Status page for My Service", "workspace_id": 1, "monitor_ids": [123, 456, 789], "is_public": true, "theme": "light" } ``` ## Get Status Page ```http GET /api/v1/status-pages/{id} ``` ## Update Status Page ```http PUT /api/v1/status-pages/{id} ``` ## Delete Status Page ```http DELETE /api/v1/status-pages/{id} ``` ## Get Public Status Page ```http GET /api/v1/public/status/{slug} ``` No authentication required. --- # Workspaces API ## List Workspaces ```http GET /api/v1/workspaces ``` ## Create Workspace ```http POST /api/v1/workspaces ``` **Request Body:** ```json { "name": "Production", "description": "Production environment monitors" } ``` ## Update Workspace ```http PUT /api/v1/workspaces/{id} ``` ## Delete Workspace ```http DELETE /api/v1/workspaces/{id} ``` Only empty workspaces can be deleted. ## Set Default Workspace ```http POST /api/v1/workspaces/{id}/set-default ``` --- # Heartbeats API (Cron Monitoring) ## List Heartbeats ```http GET /api/v1/heartbeats ``` ## Create Heartbeat ```http POST /api/v1/heartbeats ``` **Request Body:** ```json { "name": "Daily Backup", "workspace_id": 1, "expected_interval_seconds": 86400, "grace_period_seconds": 3600 } ``` **Response includes:** ```json { "id": 789, "slug": "abc123", "ping_url": "https://pingzen.dev/api/v1/heartbeats/abc123/ping" } ``` ## Ping Heartbeat (from your cron job) ```http GET /api/v1/heartbeats/{slug}/ping POST /api/v1/heartbeats/{slug}/ping ``` No authentication required for ping endpoint. --- # API Keys API ## List API Keys ```http GET /api/v1/api-keys ``` ## Create API Key ```http POST /api/v1/api-keys ``` **Request Body:** ```json { "name": "CI/CD Integration" } ``` **Response:** ```json { "id": 1, "name": "CI/CD Integration", "key": "pz_abc123...", "created_at": "2026-02-07T10:30:00Z" } ``` Note: The full key is only returned once at creation. ## Revoke API Key ```http DELETE /api/v1/api-keys/{id} ``` --- # Maintenance Windows API ## List Maintenance Windows ```http GET /api/v1/maintenance ``` ## Create Maintenance Window ```http POST /api/v1/maintenance ``` **Request Body:** ```json { "title": "Database Upgrade", "description": "Upgrading PostgreSQL to v17", "workspace_id": 1, "monitor_ids": [123, 456], "scheduled_start": "2026-02-08T02:00:00Z", "scheduled_end": "2026-02-08T04:00:00Z" } ``` ## Cancel Maintenance ```http POST /api/v1/maintenance/{id}/cancel ``` --- # Error Responses All errors follow this format: ```json { "code": "VALIDATION_ERROR", "message": "Validation failed", "details": { "url": ["Invalid URL format"] }, "timestamp": "2026-02-07T10:30:00Z", "request_id": "abc123" } ``` **Common Error Codes:** - `UNAUTHORIZED` - Missing or invalid authentication - `FORBIDDEN` - Insufficient permissions - `NOT_FOUND` - Resource not found - `VALIDATION_ERROR` - Invalid request data - `RATE_LIMITED` - Too many requests - `INTERNAL_ERROR` - Server error --- # Rate Limits | Endpoint | Limit | |----------|-------| | General API | 100 requests/hour | | Monitor checks | 10 requests/minute per monitor | | Authentication | 5 requests/minute | --- # WebSocket Real-time Updates Connect to receive real-time monitor status updates: ``` wss://pingzen.dev/api/v1/ws?token={jwt_token} ``` **Events:** ```json {"type": "monitor_status", "monitor_id": 123, "status": "down", "timestamp": "..."} {"type": "incident_created", "incident_id": 456, "monitor_id": 123} {"type": "incident_resolved", "incident_id": 456} ``` --- # Code Examples ## Python ```python import requests API_KEY = "pz_your_api_key" BASE_URL = "https://pingzen.dev/api/v1" headers = {"X-API-Key": API_KEY} # List monitors monitors = requests.get(f"{BASE_URL}/monitors?workspace_id=1", headers=headers).json() # Create monitor new_monitor = requests.post(f"{BASE_URL}/monitors", headers=headers, json={ "name": "My API", "url": "https://api.example.com/health", "protocol": "https", "workspace_id": 1, "interval_seconds": 60 }).json() # Get statistics stats = requests.get(f"{BASE_URL}/monitors/{new_monitor['id']}/stats", headers=headers).json() print(f"Uptime: {stats['uptime_percentage']}%") ``` ## JavaScript/Node.js ```javascript const API_KEY = 'pz_your_api_key'; const BASE_URL = 'https://pingzen.dev/api/v1'; const headers = { 'X-API-Key': API_KEY }; // List monitors const monitors = await fetch(`${BASE_URL}/monitors?workspace_id=1`, { headers }).then(r => r.json()); // Create monitor const newMonitor = await fetch(`${BASE_URL}/monitors`, { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'My API', url: 'https://api.example.com/health', protocol: 'https', workspace_id: 1, interval_seconds: 60 }) }).then(r => r.json()); ``` ## cURL ```bash # List monitors curl -H "X-API-Key: pz_your_api_key" \ "https://pingzen.dev/api/v1/monitors?workspace_id=1" # Create monitor curl -X POST "https://pingzen.dev/api/v1/monitors" \ -H "X-API-Key: pz_your_api_key" \ -H "Content-Type: application/json" \ -d '{"name":"My API","url":"https://api.example.com","protocol":"https","workspace_id":1}' ``` --- # Links - Website: https://pingzen.dev - OpenAPI Schema: https://pingzen.dev/openapi.json - Documentation: https://pingzen.dev/docs - API Reference: https://pingzen.dev/docs/api-reference