NetQuirk Monitoring API
The NetQuirk Monitoring REST API lets you manage monitors and retrieve metrics programmatically. All responses are JSON.
https://mon.netquirk.com/api/v1
Introduction
The API uses standard HTTP methods and returns JSON responses with consistent error objects. All timestamps are ISO 8601 in UTC.
Base URL:
https://mon.netquirk.com/api/v1
Authentication
All /api/v1/monitors* endpoints require an API key. Keys are created
via the Create key endpoint (which itself requires your
OIDC session token, obtainable from GET /api/auth/me).
Sending your key
Either header works:
Authorization: Bearer nq_<your-key> X-API-Key: nq_<your-key>
Key management endpoints
GET/POST/DELETE /api/v1/keys require your OIDC Bearer token
(the JWT obtained after completing the web login flow).
Errors
All errors return a JSON body with error (machine code) and
message (human description).
{
"error": "not_found",
"message": "Not found"
}
| HTTP Status | error code | Meaning |
|---|---|---|
400 | bad_request | Invalid request body or parameters |
401 | unauthorized | Missing, invalid, or expired API key |
404 | not_found | Resource does not exist or is not owned by you |
409 | conflict | Concurrent operation in progress |
500 | internal_error | Unexpected server error |
Pagination
List endpoints return a pagination object alongside the data array.
{
"monitors": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3
}
}
Use ?page=2&limit=50 query params to navigate. Max limit is 100
for monitors and 500 for results.
API Keys
These endpoints use your OIDC Bearer token (not an API key).
/api/v1/keys
List all active API keys for your account.
Response 200
{
"keys": [
{
"id": "018e5a1b-...",
"name": "Production",
"scopes": [],
"last_used_at": "2026-04-09T12:34:56Z",
"expires_at": null,
"created_at": "2026-04-01T10:00:00Z"
}
]
}
/api/v1/keys
Create a new API key. The raw key is returned once — store it securely.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable label |
scopes | string[] | no | Reserved for future use. Pass [] for full access. |
expires_at | ISO 8601 | no | Optional expiry timestamp |
POST /api/v1/keys
Authorization: Bearer <oidc-token>
{
"name": "CI/CD pipeline",
"scopes": []
}
Response 201
{
"id": "018e5a1b-...",
"name": "CI/CD pipeline",
"key": "nq_4f3a8b...", // shown once — save this
"scopes": [],
"expires_at": null,
"created_at": "2026-04-09T12:00:00Z"
}
/api/v1/keys/:id
Permanently revoke an API key. Requests using this key will immediately return 401.
Response 204 No Content
Monitors
/api/v1/monitors
List all monitors for your account.
Query params
| Param | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-based) |
limit | integer | 20 | Results per page (1–100) |
monitor_type | string | — | Filter: icmp tcp udp http metrics |
enabled | boolean | — | Filter by enabled state |
GET /api/v1/monitors?monitor_type=http&enabled=true&limit=50 X-API-Key: nq_...
Response 200
{
"monitors": [
{
"id": "018e5a1b-...",
"name": "My Website",
"monitor_type": "http",
"target": "https://example.com",
"config": { "type": "http", "method": "GET", "expected_status": 200, ... },
"check_interval_seconds": 60,
"timeout_seconds": 30,
"enabled": true,
"locations": ["us-east", "eu-west"],
"created_at": "2026-04-01T10:00:00Z",
"updated_at": "2026-04-01T10:00:00Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "total_pages": 1 }
}
/api/v1/monitors
Create a new monitor.
Common fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name |
monitor_type | string | yes | icmp tcp udp http metrics |
target | string | yes | Host, URL, or identifier |
config | object | yes | Type-specific config (see below) |
description | string | no | Optional notes |
check_interval_seconds | integer | no | Default 60, min 10 |
timeout_seconds | integer | no | Default 30 |
locations | string[] | no | us-east eu-west ap-south |
enabled | boolean | no | Default true |
Config schemas by type
HTTP
{
"type": "http",
"method": "GET", // GET POST PUT etc.
"expected_status": 200,
"verify_ssl": true,
"follow_redirects": true,
"max_redirects": 5,
"headers": { "X-Custom": "val" }, // optional
"body": null, // optional request body
"response_validation": null // optional response-body assertion, one of:
// { "type": "contains", "pattern": "OK" }
// { "type": "json_path", "pattern": "$.data.status",
// "expected_value": "ok" }
// The json_path subset is a dot path with an
// optional leading `$`; `expected_value` is
// compared against the looked-up value.
}
ICMP (ping)
{
"type": "icmp",
"packet_size": 64,
"count": 3
}
TCP
{
"type": "tcp",
"port": 443,
"expect_open": true
}
UDP
{
"type": "udp",
"port": 53,
"send_data": null, // optional hex or base64 payload
"expect_response": null // optional string to match
}
Metrics (agent push)
{
"type": "metrics",
"expected_interval_seconds": 60,
"accept_unknown_metrics": true,
"metrics": [
{ "key": "cpu_user", "unit": "%", "required": true, "warn_above": 80, "critical_above": 95 }
],
"display_metric": "cpu_user",
"display_mode": "auto_worst"
}
Example: HTTP monitor
POST /api/v1/monitors
X-API-Key: nq_...
{
"name": "API health check",
"monitor_type": "http",
"target": "https://api.example.com/health",
"config": {
"type": "http",
"method": "GET",
"expected_status": 200,
"verify_ssl": true,
"follow_redirects": false,
"max_redirects": 5
},
"check_interval_seconds": 60,
"locations": ["us-east", "eu-west"]
}
Response 201
Returns the created Monitor object.
/api/v1/monitors/:id
Retrieve a single monitor by UUID.
Response 200
Returns the Monitor object.
/api/v1/monitors/:id
Update a monitor. All fields are optional — omitted fields keep their current value.
PUT /api/v1/monitors/018e5a1b-...
X-API-Key: nq_...
{
"enabled": false,
"check_interval_seconds": 120
}
Response 200
Returns the updated Monitor object.
/api/v1/monitors/:id
Permanently delete a monitor and all associated data.
Response 204 No Content
Monitor Data
/api/v1/monitors/:id/status
Current up/down status across all check locations.
Response 200
{
"monitor_id": "018e5a1b-...",
"status": "up", // "up" | "down" | "stale" | "disabled" | "unknown"
"last_checked_at": "2026-04-09T14:59:00Z",
"last_success_at": "2026-04-09T14:59:00Z",
"response_time_ms": 142,
"message": null,
"locations": [
{
"location": "us-east",
"status": "up",
"last_checked_at": "2026-04-09T14:59:00Z",
"response_time_ms": 142,
"message": null
},
{
"location": "eu-west",
"status": "up",
"last_checked_at": "2026-04-09T14:58:57Z",
"response_time_ms": 89,
"message": null
}
]
}
/api/v1/monitors/:id/results
Historical check results (not available for metrics-type monitors).
Query params
| Param | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 50 | Results per page (1–500) |
since | ISO 8601 | — | Only return results after this timestamp |
location | string | — | Filter to a single check location |
GET /api/v1/monitors/018e5a1b-.../results?since=2026-04-08T00:00:00Z&location=us-east X-API-Key: nq_...
Response 200
{
"results": [
{
"checked_at": "2026-04-09T15:00:00Z",
"location": "us-east",
"success": true,
"response_time_ms": 142,
"status_code": 200,
"error_message": null
}
],
"pagination": { "page": 1, "limit": 50, "total": 1440, "total_pages": 29 }
}
/api/v1/monitors/:id/metrics
List all available metric keys for a monitor and their most recent values. Useful for discovering what metrics are being pushed by an agent.
Response 200
{
"metrics": [
{ "key": "cpu_user", "value": 1234, "last_updated_at": "2026-04-09T15:00:00Z" },
{ "key": "cpu_system", "value": 456, "last_updated_at": "2026-04-09T15:00:00Z" },
{ "key": "ram_used", "value": 87432, "last_updated_at": "2026-04-09T15:00:00Z" }
]
}
Values are raw internal units scaled ×100 for percentage metrics (e.g. cpu_user: 1234 = 12.34%).
/api/v1/monitors/:id/metrics/:key
Time-series data for a single metric key. Use this to draw graphs.
Query params
| Param | Type | Default | Description |
|---|---|---|---|
from | ISO 8601 | — | Range start (use with to) |
to | ISO 8601 | — | Range end |
limit | integer | 1000 | Max points (1–10 000) |
GET /api/v1/monitors/018e5a1b-.../metrics/cpu_user?from=2026-04-08T00:00:00Z&to=2026-04-09T00:00:00Z X-API-Key: nq_...
Response 200
{
"monitor_id": "018e5a1b-...",
"metric": "cpu_user",
"points": [
{ "timestamp": "2026-04-08T00:00:00Z", "value": 1024 },
{ "timestamp": "2026-04-08T00:01:00Z", "value": 1156 },
...
]
}
Points are returned in chronological order. If neither from/to nor
limit is provided, the most recent 1 000 samples are returned.
Common metric keys
| Key | Unit | Description |
|---|---|---|
cpu_user | % ×100 | User-space CPU usage |
cpu_system | % ×100 | Kernel CPU usage |
cpu_iowait | % ×100 | I/O wait CPU |
ram_used | % ×100 | RAM used |
ram_free | % ×100 | RAM free |
loadavg | ×100 | 1-minute load average |
disk_used:{path} | % ×100 | Disk used for a path |
net_rx:{iface} | bytes/s | Network receive rate |
net_tx:{iface} | bytes/s | Network transmit rate |
/api/v1/monitors/flapping
Fleet-wide count of up/down transitions per monitor for a chosen window, plus the monitor with the most. Use this to spot monitors that flap (alternate success and failure rapidly) rather than fail cleanly.
Query params
| Param | Type | Default | Description |
|---|---|---|---|
window | string | 24h |
Window length: <n>h or <n>d (e.g. 24h, 7d). |
GET /api/v1/monitors/flapping?window=24h X-API-Key: nq_...
Response 200
{
"window": "24h",
"window_seconds": 86400,
"monitors": [
{ "monitor_id": "018e5a1b-...", "name": "Login API", "transitions": 12 },
{ "monitor_id": "018e5a1c-...", "name": "Static CDN", "transitions": 0 }
],
"top": { "monitor_id": "018e5a1b-...", "name": "Login API", "transitions": 12 }
}
A transition is an adjacent pair of stored checks whose
success flag differs (up→down, down→up, …). top is
null when the caller owns no monitors. The count is
bounded by the same per-monitor limit that powers /uptime;
very high-frequency monitors over a long window may under-count
transitions at the bound.
The Monitor object
{
"id": "018e5a1b-2c3d-7e4f-a5b6-c7d8e9f01234", // UUID
"name": "My Website",
"description": null, // string | null
"monitor_type": "http", // icmp | tcp | udp | http | metrics
"target": "https://example.com",
"config": { ... }, // type-specific config object
"check_interval_seconds": 60,
"timeout_seconds": 30,
"enabled": true,
"locations": ["us-east", "eu-west"], // empty for metrics type
"created_at": "2026-04-01T10:00:00Z",
"updated_at": "2026-04-09T15:00:00Z"
}
Quick start
Create an HTTP monitor and check its status in three curl commands.
# 1. Get your OIDC token (after web login)
TOKEN=$(curl -s https://mon.netquirk.com/api/auth/me \
-H "Authorization: Bearer <session-jwt>" | jq -r .token)
# 2. Create an API key
KEY=$(curl -s -X POST https://mon.netquirk.com/api/v1/keys \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"quickstart"}' | jq -r .key)
# 3. Create a monitor
ID=$(curl -s -X POST https://mon.netquirk.com/api/v1/monitors \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Example",
"monitor_type": "http",
"target": "https://example.com",
"config": {"type":"http","method":"GET","expected_status":200,"verify_ssl":true,"follow_redirects":true,"max_redirects":5},
"locations": ["us-east"]
}' | jq -r .id)
# 4. Check status
curl -s "https://mon.netquirk.com/api/v1/monitors/$ID/status" \
-H "X-API-Key: $KEY" | jq .