BlipBeat Public API — v1
Versionerad referens för BlipBeats publika API. Bas-URL: /api/public/v1.
Autentisering
Alla endpoints (utom rot-svaret) kräver en API-nyckel:
Authorization: Bearer mr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx- Nycklar skapas under Konto → API-nyckel (eller
POST /api/account/api-keys). - Nyckeln börjar med
mr_och visas exakt en gång vid skapandet. Bara en SHA-256-hash lagras på servern — tappar du nyckeln skapar du en ny och återkallar den gamla. read-scopade nycklar får bara anropa GET-endpoints. Skapa nyckeln medscope: "read"för skrivskyddad åtkomst.- Rate limit:
RATE_LIMIT_PUBLIC_API_LIMIT(default 120) anrop/minut per IP.
Felmodell
Alla fel har samma form (bakåtkompatibel utökning av { error }):
{
"error": "Hittades inte",
"code": "NOT_FOUND",
"requestId": "m8k2jf-abc123"
}Vanliga koder:
| HTTP | code | Betydelse |
|---|---|---|
| 400 | VALIDATION | Ogiltigt fältvärde |
| 400 | TARGET_BLOCKED | Mål-URL blockerad (SSRF-policy, t.ex. privat IP) |
| 401 | UNAUTHORIZED | Saknad/ogiltig API-nyckel |
| 402 | PLAN_LIMIT | Plan-gräns nådd (med upgradeTo) |
| 404 | NOT_FOUND | Resursen finns inte / tillhör inte nyckeln |
| 429 | RATE_LIMITED | Rate limit nådd (svaret har Retry-After) |
requestId korrelerar med x-request-id-headern och serverloggarna.
Endpoints
GET / — tjänsteinfo
curl https://api.example.com/api/public/v1{
"service": "BlipBeat Public API",
"version": "v1",
"docs": "docs/API.md (i detta repo — komplett referens med exempel)",
"endpoints": ["GET/POST/PATCH/DELETE /monitors", "GET /monitors/:id", "..."]
}GET /monitors — lista monitorer
curl -H "Authorization: Bearer mr_..." https://api.example.com/api/public/v1/monitorsSvar: { "monitors": [ Monitor, ... ] }. Fältet headers är alltid null (hemligheter lämnar aldrig servern).
POST /monitors — skapa monitor
curl -X POST -H 'Authorization: Bearer mr_...' -H 'Content-Type: application/json' \
-d '{"name":"Webbplatsen","type":"http","url":"https://example.com","intervalSec":60}' \
https://api.example.com/api/public/v1/monitorsStödda typer: http, keyword, tcp, ping (DNS-baserad), ssl, domain, dns.
Viktiga fält:
| Fält | Typ | Notering | |
|---|---|---|---|
name | string | krävs | |
type | string | default http | |
url | string | SSRF-valideras (publik IP krävs) | |
host / port | string / int | för tcp/dns/ping | |
keyword / keywordType | string | exists \ | not_exists |
expectedStatus | int | förväntad HTTP-status | |
intervalSec | int | 20–3600, respekterar planens minimum | |
timeoutSec | int | 2–60 | |
headers | object | krypteras i vila, returneras aldrig | |
downStatuses | string | t.ex. "404,410,503" | |
slowThresholdMs | int | långsam-svarströskel | |
maintFrom / maintTo | int | underhållsfönster (ms) | |
heartbeatSec | int | heartbeat-monitor (grace i sekunder) | |
confirmations | int | 1–5 misslyckade probes i rad innan incident | |
cooldownMin | int | tyst period (min) efter återhämtning | |
dnsType / dnsExpected | string | DNS-monitor | |
jsonAssertions | array | endast http — [{path, expected}] som alla måste matcha för "up" (max 5) | |
domain | string | domän för domänträdet |
Statusfält i svar (GET /monitors, GET /monitors/:id): up och paused är boolean (true/false) sedan PostgreSQL-migreringen — tidigare SQLite-era returnerade de 0/1. Läs dem som booleans; numerisk jämförelse (Number(x) === 1) fungerar också.
Svar: 201 { "monitor": Monitor }.
GET /monitors/:id — en monitor + nyckeltal
{
"monitor": { "...": "..." },
"uptime24h": 99.95,
"avgResponseMs": 142,
"openIncident": { "id": 7, "cause": "HTTP 500", "started_at": 1750000000000 } | null
}GET /monitors/:id/checks — checklogg
?limit= 1–1000 (default 100). Svar: { "checks": [ { "status", "status_code", "response_time_ms", "error", "created_at" } ] }.
GET /monitors/:id/incidents — incidenthistorik
?limit= 1–500 (default 50). Svar: { "incidents": [ { "id", "cause", "started_at", "resolved_at" } ] }.
PATCH /monitors/:id — uppdatera
Samma fält som POST, partiell uppdatering.
headers är skrivskyddat-hemligt (GET returnerar alltid null, se ovan) och skrivs endast när ett verkligt värde skickas: ett icke-tomt objekt eller en giltig JSON-sträng. null, tomt objekt, tom sträng eller utelämnat fält betyder "oförändrat". Ogiltig JSON-sträng ger 400 VALIDATION utan att något skrivs — delvis uppdaterade övriga fält skrivs inte heller vid valideringsfel.
POST /monitors/:id/pause · POST /monitors/:id/resume
Pausa / återuppta en monitor.
DELETE /monitors/:id
Radera en monitor. Svar: { "ok": true }.
Paginering
List-endpoints har hårda tak (limit cappas): checks 1000, incidents 500. Klienten kan inte begära obegränsat antal rader.
Versionering
/api/public/v1 är explicit versionerad. Brytande ändringar kräver en ny major-version (t.ex. /v2) eller en kompatibilitetsstrategi — aldrig tysta ändringar i /v1.
Exempel: full livscykel
# 1. Skapa
KEY="mr_..."
MON=$(curl -s -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"name":"API","type":"http","url":"https://api.example.com/health"}' \
https://api.example.com/api/public/v1/monitors | jq -r .monitor.id)
# 2. Läs
curl -s -H "Authorization: Bearer $KEY" https://api.example.com/api/public/v1/monitors/$MON
# 3. Pausa vid underhåll
curl -s -X POST -H "Authorization: Bearer $KEY" https://api.example.com/api/public/v1/monitors/$MON/pause
# 4. Återuppta
curl -s -X POST -H "Authorization: Bearer $KEY" https://api.example.com/api/public/v1/monitors/$MON/resume