API Integration Guide
Alternate frontends treat NIE-SLA as a credential-free, read-only, cacheable data source. Do not proxy or reuse an Admin Session, and do not call unversioned internal routes directly.
Initialization Order
- Normalize user input and keep only the Worker
origin. - Request
GET /api/v1and verifyapi_version === "v1". - Decide available features from the Manifest
endpointsand capability fields. - Fetch
/api/v1/status?days=30&lite=1for the first screen. - Request checks, metrics, pings or latency only when the user opens details.
- Pause polling when the page is hidden; add a random delay when it comes back.
Minimal Client
export function createNieSlaClient(input) {
const base = new URL(input)
if (base.username || base.password) throw new Error('API base must not contain credentials')
if (base.protocol !== 'https:' && !['localhost', '127.0.0.1', '[::1]'].includes(base.hostname)) {
throw new Error('production API must use HTTPS')
}
const origin = base.origin
async function get(path, params = {}, timeoutMs = 12_000) {
const url = new URL(`/api/v1/${path}`.replace(/\/$/, ''), origin)
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null && value !== '') url.searchParams.set(key, String(value))
}
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), timeoutMs)
try {
const response = await fetch(url, {
signal: controller.signal,
credentials: 'omit',
headers: { accept: 'application/json' },
})
const body = await response.json().catch(() => null)
if (!response.ok || body?.ok === false) throw new Error(body?.error || `HTTP ${response.status}`)
return body
} finally {
clearTimeout(timer)
}
}
return {
manifest: async () => {
const body = await get('')
if (body?.api_version !== 'v1') throw new Error('response is not a NIE-SLA v1 manifest')
return body
},
status: options => get('status', { days: 30, lite: 1, ...options }),
checks: (targetId, options) => get('checks', { target_id: targetId, ...options }),
metrics: (agentId, options) => get('metrics', { agent_id: agentId, ...options }),
pings: (agentId, options) => get('pings', { agent_id: agentId, ...options }),
latency: (targetId, options) => get('latency', { target_id: targetId, ...options }),
}
}The example checks both the HTTP status and body.ok, because a compatibility endpoint can return a business error inside an HTTP 200. Production projects should also validate the types of key fields and surface AbortError as a timeout state.
React/Vue State Model
Do not collapse everything into a single loading boolean; distinguish at least:
type ResourceState<T> =
| { state: 'idle' }
| { state: 'loading'; previous?: T }
| { state: 'ready'; data: T; warnings: string[] }
| { state: 'empty'; data: T; message: string }
| { state: 'error'; error: string; retryAt?: number }Keep previous while refreshing so charts do not flash empty; warnings[] means partial data degradation and does not replace successfully loaded main data.
Polling and Caching
- Status: 20-60 seconds recommended; honor
Cache-Controland observeX-NIE-SLA-Cache(X-NStatus-Cacheremains a v1 alias). - Manifest caches 300 seconds by default; Metrics 15; Pings 20; Latency 30.
- Checks include the normalized
target_id,hoursandlimitin the cache key. - 429 and 5xx use capped exponential backoff; 400/403/404 are not retried as-is.
- Do not add random query parameters to bypass Worker/Cloudflare caching.
Chart Data
- Sort time series by timestamp explicitly; do not rely on response order.
- Latency with
ok = falseis an outage or fault marker; do not plot it as0 ms. - With
format=columns, checkdtand the length of every values array. history_downsampledorpings_downsampledmeans the data has been downsampled.- Cloudflare checks, Agent pings and external latency use different legends and source labels.
- Hide series for optional fields such as temperature or GPU when missing; do not fill in zeros.
Server-Side Integration
Server-side requests are not bound by browser CORS but still count against rate limits. Use a shared cache, a reasonable User-Agent, timeouts and bounded retries; do not re-fetch all history for every end-user request. The public API has no write capability, and servers should not store admin or Agent credentials to work around the boundary.
Browser Security
- Always use
credentials: 'omit'with fetch. - The API base comes from deployment config or validated user input; URL query parameters must never silently override the production address.
- Allow HTTPS origins only; local HTTP is the dev exception.
- Render API text with framework default escaping or
textContent. - Do not write full responses into public error telemetry; they may contain node profiles the deployer chose to expose but that are still identifying.
Continue with Status, Checks, Metrics, Pings and Latency for endpoint fields and parameters.