The NOF REST API uses API keys for authentication. Generate a key in your dashboard under Settings → API Keys. Keys are shown only once at creation.
Include your key in every request as a Bearer token:
curl https://your-domain/api/v1/targets \
-H "Authorization: Bearer nof_a1b2c3d4_<your-secret>"The API enforces 120 requests per minute per API key, independent from the web app session limits.
When you exceed the limit, the API returns 429 Too Many Requests. Check the RateLimit-* response headers:
HTTP/2 429
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 1700000060
{ "error": "Too many requests — API rate limit exceeded (120/min)" }Monitor websites, servers, game servers, and network hosts.
website — HTTP/HTTPS endpoint checkserver — SSH server (credentials required)game — Minecraft, FiveM, SA-MPnetwork — ICMP ping or TCP port checkWhen you configure a custom webhook channel with a signing secret, NOF signs every outbound webhook payload with HMAC-SHA256 and includes the signature in the X-NOF-Signature header.
{
"target_id": "uuid",
"target_name": "My Website",
"target_type": "website",
"event_type": "down", // "up" | "down" | "ssl_expiring"
"old_status": "up",
"new_status": "down",
"error": "HTTP 503 Service Unavailable",
"timestamp": "2025-01-01T00:00:00.000Z",
"days_remaining": null // only set for ssl_expiring events
}// Node.js example
const crypto = require('crypto');
app.post('/webhook', (req, res) => {
const payload = JSON.stringify(req.body);
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(payload)
.digest('hex');
const received = req.headers['x-nof-signature'];
const valid = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
if (!valid) return res.status(401).send('Invalid signature');
// process event...
});All error responses use a consistent JSON shape:
{ "error": "Human-readable error message" }| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request — invalid or missing parameters |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — insufficient permissions |
| 404 | Not Found — resource does not exist |
| 409 | Conflict — duplicate value (e.g. slug already taken) |
| 410 | Gone — invitation expired or already used |
| 429 | Too Many Requests — rate limit exceeded |
| 500 | Internal Server Error |