API-dokumentasjon
Referanse for WorkAround sin webhook- og portal-API. Brukes til å sende hendelser inn i systemet og integrere med tredjepartsverktøy.
Oversikt
WorkAround tilbyr to typer API-tilgang:
- Webhook API – Eksternt system poster hendelser til WorkAround (inngående). Brukes av overvåkingssystemer, alarmsentraler og ERP-systemer.
- Portal API – Programmatisk innsending av kundeforespørsler.
Base-URL
https://workaround.nettbook.no
Innholdstype
Alle API-kall bruker Content-Type: application/json med UTF-8-koding. Svar returneres alltid som JSON.
Autentisering
Webhook-endepunkt
Webhook-endepunktet er åpent for inngående POST uten autentisering. Vi anbefaler å sikre det med én av disse metodene:
- HMAC-SHA256 – Legg til en delt hemmelighet og send signaturen i headeren
X-Signature: sha256=<hex>. - IP-hvitelisting – Begrens tilgang til kjente avsender-IP-adresser på nettverksnivå.
- API-nøkkel – Send
X-Api-Key: <nøkkel>. Konfigureres per integrasjon i admin-panelet.
Portal-endepunkt
Portal-innsending krever en gyldig CSRF-token. For automatiserte integrasjoner, se callout om alternativ fremgangsmåte under Portal API.
Feilhåndtering
Feil returneres som JSON med feltene error og message:
{
"error": "validation_failed",
"message": "Feltet 'sender_email' er påkrevd",
"fields": {
"sender_email": "Mangler verdi"
}
}
| Statuskode | Kode | Beskrivelse |
|---|---|---|
| 202 | accepted | Webhook mottatt og lagt i kø |
| 400 | empty_payload | Tomt eller manglende body |
| 400 | validation_failed | Ugyldig eller manglende felt |
| 403 | csrf_mismatch | CSRF-token mangler eller ugyldig |
| 404 | not_found | Ressursen finnes ikke |
| 500 | server_error | Intern feil – prøv igjen etter en stund |
5xx-feil (1 s → 2 s → 4 s → 8 s). Ikke prøv automatisk på nytt ved 4xx – det er en klientfeil.
Inngående webhook
Send hendelser fra eksterne systemer til WorkAround. Hendelsene lagres i integrasjonsloggen og kan utløse automatiserte regler.
URL-parameter
| Parameter | Type | Beskrivelse |
|---|---|---|
system påkrevd |
string |
Identifikator for avsendersystemet. Kun a–z, 0–9, bindestrek og understrek. Eks: scada, alarm-central, erp |
Headers
| Header | Beskrivelse | |
|---|---|---|
Content-Type |
påkrevd | application/json |
X-Event-Type |
valgfritt | Hendelsestype for filtrering i loggen. Eks: alarm.trigger, device.offline |
X-Signature |
valgfritt | HMAC-SHA256 signatur: sha256=<hex-digest> |
Request body
Body er fri JSON. Anbefalt struktur for best integrasjon:
{
"event": "alarm.trigger", // hendelsestype
"timestamp": "2026-04-09T08:14:00Z", // ISO 8601
"source": "SCADA-node-047", // kilde-ID
"severity": "high", // low|medium|high|critical
"data": {
"node_id": "N-201",
"description": "Fiberbrudd på linje 3",
"location": { "lat": 59.4130, "lng": 5.2680 },
"affected_customers": 142
},
"metadata": {
"correlation_id": "abc-12345"
}
}
Hendelsestyper
| X-Event-Type | Typisk brukstilfelle |
|---|---|
alarm.trigger | Alarm utløst (SCADA, NMS) |
alarm.clear | Alarm kvittert / opphørt |
device.offline | Node eller enhet er utilgjengelig |
device.online | Node eller enhet er tilbake online |
workorder.created | Arbeidsordre opprettet i eksternt system |
workorder.updated | Arbeidsordre oppdatert i eksternt system |
customer.complaint | Klage rapportert av kunde |
maintenance.scheduled | Planlagt vedlikehold fra ekstern kalender |
Respons
{ "accepted": true }
{ "error": "Empty payload" }
Portal API
Sender en kundeforespørsel programmatisk, tilsvarende nettskjemaet på /portal.
_csrf-token. For maskin-til-maskin-integrasjoner anbefaler vi webhook-endepunktet i stedet.
Felt (application/x-www-form-urlencoded)
| Felt | Type | Beskrivelse |
|---|---|---|
_csrf påkrevd | string | CSRF-token fra GET /portal |
form_template_slug påkrevd | string | Skjematype-slug fra admin-panelet. Eks: fiber-utfall |
sender_name påkrevd | string | Fullt navn på innsender |
sender_email påkrevd | string | E-postadresse. Bekreftelse sendes hit. |
sender_phone valgfritt | string | Telefonnummer |
subject påkrevd | string | Emne/tittel (maks 255 tegn) |
description påkrevd | string | Detaljert beskrivelse |
extra[*] valgfritt | mixed | Tilleggsfelter definert av det valgte skjemaet |
Respons
Vellykket innsending gir HTTP 200 med HTML-side som viser saksnummeret (format: PR-YYYY-NNNN). Innsender mottar e-postbekreftelse automatisk.
Eksempel: cURL
Alarm-hendelse fra SCADA
curl -X POST \
https://workaround.nettbook.no/api/webhook/scada \
-H "Content-Type: application/json" \
-H "X-Event-Type: alarm.trigger" \
-d '{
"event": "alarm.trigger",
"timestamp": "2026-04-09T08:14:00Z",
"source": "SCADA-node-047",
"severity": "high",
"data": {
"node_id": "N-201",
"description": "Fiberbrudd på linje 3",
"location": { "lat": 59.4130, "lng": 5.2680 },
"affected_customers": 142
}
}'
Enhet offline fra NMS
curl -X POST \
https://workaround.nettbook.no/api/webhook/nms \
-H "Content-Type: application/json" \
-H "X-Event-Type: device.offline" \
-d '{
"event": "device.offline",
"timestamp": "2026-04-09T09:02:17Z",
"source": "OLT-Haugesund-3",
"data": {
"device_id": "OLT-003",
"ip": "10.100.3.5",
"ports_affected": 48
},
"metadata": { "correlation_id": "nms-evt-78432" }
}'
Planlagt vedlikehold fra ERP
curl -X POST \
https://workaround.nettbook.no/api/webhook/erp \
-H "Content-Type: application/json" \
-H "X-Event-Type: maintenance.scheduled" \
-d '{
"event": "maintenance.scheduled",
"data": {
"title": "Fiberskjøting Strandgaten 12–18",
"area": "Haugesund sentrum",
"planned_start": "2026-04-14T07:00:00",
"planned_end": "2026-04-14T15:00:00",
"technician": "Ola Nordmann",
"work_order_ref": "WO-20245"
}
}'
Eksempel: Python
Enkel innsending
import requests
from datetime import datetime, timezone
BASE = "https://workaround.nettbook.no"
def send_alarm(node_id, description, severity="high"):
payload = {
"event": "alarm.trigger",
"timestamp": datetime.now(timezone.utc).isoformat(),
"source": f"node-{node_id}",
"severity": severity,
"data": {"node_id": node_id, "description": description},
}
r = requests.post(
f"{BASE}/api/webhook/scada",
json=payload,
headers={"X-Event-Type": "alarm.trigger"},
timeout=10,
)
r.raise_for_status()
return r.json()
# Bruk
send_alarm("N-201", "Fiberbrudd på linje 3", "critical")
Med retry og eksponensiell backoff
import requests, time, logging
def send_with_retry(url, payload, max_attempts=4):
for attempt in range(max_attempts):
try:
r = requests.post(url, json=payload, timeout=10)
if r.status_code == 202:
return True
if 400 <= r.status_code < 500:
logging.error(f"Klientfeil {r.status_code}: {r.text}")
return False # ikke prøv igjen
except requests.RequestException as e:
logging.warning(f"Forsøk {attempt + 1} feilet: {e}")
time.sleep(2 ** attempt) # 1s, 2s, 4s, 8s
return False
Eksempel: Node.js
Med fetch (Node 18+)
const BASE = 'https://workaround.nettbook.no';
async function sendWebhook(system, eventType, payload) {
const r = await fetch(`${BASE}/api/webhook/${system}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Event-Type': eventType,
},
body: JSON.stringify(payload),
signal: AbortSignal.timeout(10000),
});
if (!r.ok) throw new Error(`${r.status}: ${await r.text()}`);
return r.json();
}
// Bruk
sendWebhook('nms', 'device.offline', {
event: 'device.offline',
source: 'OLT-003',
data: { ip: '10.100.3.5', ports_affected: 48 },
}).then(console.log).catch(console.error);
Med HMAC-SHA256 signatur
const crypto = require('crypto');
const axios = require('axios');
const SECRET = process.env.WA_WEBHOOK_SECRET;
function sign(body) {
return 'sha256=' + crypto.createHmac('sha256', SECRET).update(body).digest('hex');
}
async function sendSigned(system, eventType, payload) {
const body = JSON.stringify(payload);
return axios.post(`https://workaround.nettbook.no/api/webhook/${system}`, body, {
headers: {
'Content-Type': 'application/json',
'X-Event-Type': eventType,
'X-Signature': sign(body),
},
timeout: 10000,
});
}
HTTP-statuskoder
| Kode | Navn | Når? |
|---|---|---|
| 200 | OK | Forespørselen behandlet (portal HTML-svar) |
| 202 | Accepted | Webhook mottatt og lagt i kø |
| 400 | Bad Request | Tomt body, ugyldig JSON eller manglende felt |
| 403 | Forbidden | CSRF-token mangler eller ugyldig |
| 404 | Not Found | Endepunktet finnes ikke |
| 405 | Method Not Allowed | Feil HTTP-metode |
| 500 | Internal Server Error | Intern feil – loggføres automatisk |
| 503 | Service Unavailable | Server midlertidig utilgjengelig |
Endringslogg
| Versjon | Dato | Endring |
|---|---|---|
v1.0 |
April 2026 | Første versjon. Inngående webhook (POST /api/webhook/{system}) og portal-innsending (POST /portal). |