Developer Documentation
REST API, webhook payloads, and integration guides for Vigilmon.
API Reference
Authentication
All API requests require a personal API token. Create one in
Settings → API tokens.
Pass the token as a Bearer token in the Authorization header.
curl -H "Authorization: Bearer vtk_your_token_here" \
https://vigilmon.online/api/v1/monitors
Base URL
https://vigilmon.online/api/v1
Rate limit: 60 requests per minute per token.
Monitors
/api/v1/monitors
List all monitors for the authenticated user. Paginated (20 per page).
Example
curl -H "Authorization: Bearer vtk_your_token" \
https://vigilmon.online/api/v1/monitors
{
"data": [
{
"id": 1,
"name": "Production API",
"url": "https://api.example.com/health",
"method": "GET",
"check_interval_seconds": 60,
"is_active": true,
"current_status": "up",
"last_checked_at": "2024-01-15T10:30:00+00:00"
}
],
"meta": { "current_page": 1, "total": 1 }
}
/api/v1/monitors
Create a new monitor.
Request body
{
"name": "Production API", // required
"url": "https://api.example.com", // required
"method": "GET", // optional, default GET
"expected_status_code": 200, // optional, default 200
"check_interval_seconds": 60, // optional, plan minimum applies
"keyword": "healthy", // optional, check response body
"regions": ["us-east", "eu-west"] // optional
}
Example
curl -X POST \
-H "Authorization: Bearer vtk_your_token" \
-H "Content-Type: application/json" \
-d '{"name":"Prod API","url":"https://api.example.com","check_interval_seconds":60}' \
https://vigilmon.online/api/v1/monitors
/api/v1/monitors/{id}
Get monitor details including uptime percentages for the last 24h, 7d, and 30d.
curl -H "Authorization: Bearer vtk_your_token" \
https://vigilmon.online/api/v1/monitors/1
{
"data": {
"id": 1,
"name": "Production API",
"url": "https://api.example.com/health",
"current_status": "up",
"uptime": {
"24h": 100.0,
"7d": 99.95,
"30d": 99.87
}
}
}
/api/v1/monitors/{id}/incidents
List incidents for a monitor. Returns the 30 most recent per page, ordered newest first. Each incident includes start time, resolution time, duration, and status.
curl -H "Authorization: Bearer vtk_your_token" \
https://vigilmon.online/api/v1/monitors/1/incidents
{
"data": [
{
"id": 42,
"started_at": "2024-01-15T08:12:00+00:00",
"resolved_at": "2024-01-15T08:34:00+00:00",
"duration_seconds": 1320,
"cause": "HTTP 503 Service Unavailable",
"confirmed_regions": ["za-vps"],
"status": "resolved"
},
{
"id": 41,
"started_at": "2024-01-10T22:05:00+00:00",
"resolved_at": null,
"duration_seconds": null,
"cause": "Connection timed out",
"confirmed_regions": ["za-vps", "eu-west"],
"status": "ongoing"
}
],
"meta": { "current_page": 1, "total": 2 }
}
/api/v1/monitors/{id}
Update a monitor. All fields are optional — only send what you want to change.
curl -X PATCH \
-H "Authorization: Bearer vtk_your_token" \
-H "Content-Type: application/json" \
-d '{"check_interval_seconds":30}' \
https://vigilmon.online/api/v1/monitors/1
/api/v1/monitors/{id}
Permanently delete a monitor. Returns 204 No Content on success.
curl -X DELETE \
-H "Authorization: Bearer vtk_your_token" \
https://vigilmon.online/api/v1/monitors/1
Error responses
| Status | Meaning |
|---|---|
| 401 | Missing or invalid token |
| 403 | Token does not own this monitor |
| 404 | Monitor not found |
| 422 | Validation error (check errors key) |
| 429 | Rate limit exceeded (60 req/min) |
CI/CD integration example
Pause monitoring during a deployment so you don't get false-positive alerts:
TOKEN="vtk_your_token"
MONITOR_ID=1
# Pause before deploy
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_active":false}' \
https://vigilmon.online/api/v1/monitors/$MONITOR_ID
# ... run your deployment ...
# Resume after deploy
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_active":true}' \
https://vigilmon.online/api/v1/monitors/$MONITOR_ID
Webhooks
Overview
Vigilmon can send an HTTP POST request to any URL when a monitor goes down, recovers, or when an SSL certificate is about to expire. Configure a webhook alert channel in Settings → Alert Channels.
Every webhook POST includes:
- Content-Typeapplication/json
- User-AgentVigilmon/1.0
- X-Vigilmon-Secretyour secret (only if configured)
Event: monitor_down
Fired when a monitor fails its check and the incident is confirmed.
{
"event": "monitor_down",
"monitor": {
"id": 1,
"name": "Production API",
"url": "https://api.example.com/health"
},
"status": "down",
"checked_at": "2024-01-15T08:12:00+00:00",
"region": "za-vps",
"response_time_ms": null,
"error": null
}
| Field | Type | Description |
|---|---|---|
| event | string | Always monitor_down |
| monitor.id | integer | Monitor ID |
| monitor.name | string | Monitor display name |
| monitor.url | string | URL being monitored |
| checked_at | ISO 8601 | Time the incident was detected |
| region | string|null | Check region(s), comma-separated |
| response_time_ms | integer|null | Response time in ms (null if no response) |
| error | string|null | Failure reason if available |
Event: monitor_up
Fired when a previously down monitor successfully responds again.
{
"event": "monitor_up",
"monitor": {
"id": 1,
"name": "Production API",
"url": "https://api.example.com/health"
},
"status": "up",
"checked_at": "2024-01-15T08:34:00+00:00",
"region": "za-vps",
"response_time_ms": null,
"error": null
}
Event: monitor_escalation
Fired when a monitor has been down for an extended period (escalation threshold). Useful for paging on-call staff for prolonged outages.
{
"event": "monitor_escalation",
"monitor": {
"id": 1,
"name": "Production API",
"url": "https://api.example.com/health"
},
"status": "down",
"down_minutes": 30,
"incident_started_at": "2024-01-15T08:12:00+00:00",
"region": "za-vps"
}
| Field | Type | Description |
|---|---|---|
| down_minutes | integer | How long the monitor has been down |
| incident_started_at | ISO 8601 | When the incident first started |
Event: ssl.expiring
Fired when an SSL certificate is within the expiry warning threshold (typically 30 days). Vigilmon checks daily.
{
"event": "ssl.expiring",
"monitor_url": "https://api.example.com",
"days_remaining": 14,
"threshold": 30,
"expires_at": "2024-01-29T23:59:59+00:00"
}
| Field | Type | Description |
|---|---|---|
| monitor_url | string | URL of the monitor whose cert is expiring |
| days_remaining | integer | Days until the certificate expires |
| threshold | integer | Alert threshold configured for this channel |
| expires_at | ISO 8601 | Exact certificate expiry timestamp |
Security
When you configure a secret on a webhook alert channel, Vigilmon sends it in the
X-Vigilmon-Secret header with every request.
Verify this header in your receiver to reject requests from untrusted sources.
// Example: verify the secret in Node.js
app.post('/webhook', (req, res) => {
const secret = req.headers['x-vigilmon-secret'];
if (secret !== process.env.VIGILMON_SECRET) {
return res.status(401).json({ error: 'Unauthorized' });
}
// handle payload
res.sendStatus(200);
});
Retries & delivery
| Property | Value |
|---|---|
| Method | HTTP POST |
| Timeout | 10 seconds |
| Retries on failure | 3 attempts (backoff: 10s → 30s → 60s) |
| Throttle | Max 1 alert per incident per channel per 5 minutes |
| Delivery log | Available in Settings → Alert Channels → View history |
Respond with any 2xx status code to acknowledge delivery. Vigilmon treats non-2xx responses as failures and will retry.
Integrations
Slack
Vigilmon has a native Slack integration that posts richly-formatted alert messages to any Slack channel using Slack's Incoming Webhooks.
-
Create a Slack Incoming Webhook.
Go to api.slack.com/apps → Create New App → Incoming Webhooks → activate and add to the channel you want.
Copy the webhook URL (looks like
https://hooks.slack.com/services/T.../B.../xxx). - Add the Slack channel in Vigilmon. Go to Settings → Alert Channels → Add Channel → choose Slack → paste the webhook URL.
- Assign the channel to your monitors. Edit any monitor and select the Slack channel under Alert Channels.
- Test it. Use the Send test alert button in Settings → Alert Channels to confirm delivery.
Discord
Vigilmon has a native Discord integration that sends colour-coded embed messages to any Discord channel.
- Create a Discord webhook. In Discord, right-click the channel → Edit Channel → Integrations → Create Webhook. Give it a name (e.g., "Vigilmon") and copy the webhook URL.
- Add the Discord channel in Vigilmon. Go to Settings → Alert Channels → Add Channel → choose Discord → paste the webhook URL.
- Assign to monitors and optionally test with Send test alert.
Generic webhook receiver — Node.js
Use a generic Webhook alert channel to POST Vigilmon events to any HTTP endpoint. Here's a minimal Express.js receiver:
// npm install express const express = require('express'); const app = express(); app.use(express.json()); const VIGILMON_SECRET = process.env.VIGILMON_SECRET; // optional app.post('/vigilmon', (req, res) => { // Verify secret if configured if (VIGILMON_SECRET && req.headers['x-vigilmon-secret'] !== VIGILMON_SECRET) { return res.status(401).json({ error: 'Unauthorized' }); } const { event, monitor } = req.body; switch (event) { case 'monitor_down': console.log(`DOWN: ${monitor.name} (${monitor.url})`); // page on-call, update status page, etc. break; case 'monitor_up': console.log(`RECOVERED: ${monitor.name} is back up`); break; case 'monitor_escalation': console.log(`ESCALATION: ${monitor.name} down ${req.body.down_minutes} min`); break; case 'ssl.expiring': console.log(`SSL: ${req.body.monitor_url} expires in ${req.body.days_remaining} days`); break; } res.sendStatus(200); // respond 2xx to acknowledge }); app.listen(3000, () => console.log('Listening on :3000'));
Generic webhook receiver — Python
A minimal Flask receiver:
# pip install flask import os from flask import Flask, request, abort app = Flask(__name__) VIGILMON_SECRET = os.getenv('VIGILMON_SECRET') @app.route('/vigilmon', methods=['POST']) def vigilmon_webhook(): # Verify secret if configured if VIGILMON_SECRET: if request.headers.get('X-Vigilmon-Secret') != VIGILMON_SECRET: abort(401) data = request.get_json() event = data.get('event') monitor = data.get('monitor', {}) if event == 'monitor_down': print(f"DOWN: {monitor.get('name')} ({monitor.get('url')})") # your alerting logic here elif event == 'monitor_up': print(f"RECOVERED: {monitor.get('name')} is back up") elif event == 'monitor_escalation': print(f"ESCALATION: {monitor.get('name')} down {data.get('down_minutes')} min") elif event == 'ssl.expiring': print(f"SSL: {data.get('monitor_url')} expires in {data.get('days_remaining')} days") return '', 200 if __name__ == '__main__': app.run(port=3000)
Generic webhook receiver — Laravel
Add a route to receive Vigilmon webhooks in your own Laravel application:
// routes/web.php or routes/api.php use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; Route::post('/webhooks/vigilmon', function (Request $request) { // Verify secret if configured $secret = config('services.vigilmon.webhook_secret'); if ($secret && $request->header('X-Vigilmon-Secret') !== $secret) { abort(401); } $event = $request->input('event'); $monitor = $request->input('monitor', []); match ($event) { 'monitor_down' => Log::alert('Monitor down', [ 'name' => $monitor['name'], 'url' => $monitor['url'], 'at' => $request->input('checked_at'), ]), 'monitor_up' => Log::info('Monitor recovered', [ 'name' => $monitor['name'], ]), 'monitor_escalation' => Log::critical('Monitor escalation', [ 'name' => $monitor['name'], 'down_minutes' => $request->input('down_minutes'), ]), 'ssl.expiring' => Log::warning('SSL certificate expiring', [ 'url' => $request->input('monitor_url'), 'days_remaining' => $request->input('days_remaining'), ]), default => null, }; return response()->noContent(); // 204 — Vigilmon treats any 2xx as success })->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
Store the secret in your .env as VIGILMON_WEBHOOK_SECRET
and add 'vigilmon' => ['webhook_secret' => env('VIGILMON_WEBHOOK_SECRET')]
to config/services.php.