API-dokumentasjon
Med API-et kan du kjøre skanninger fra skript og byggløyper, for eksempel for å stoppe en deploy hvis sikkerhetsheaderne har blitt dårligere.
Autentisering
Alle kall krever headeren X-Api-Key med en gyldig API-nøkkel (starter med wsk_).
Nøkler opprettes av administratoren av tjenesten. Ta kontakt hvis du trenger en.
Oppbevar nøkkelen som en hemmelighet, for eksempel i GitHub Secrets.
Grensen er 30 kall per minutt per nøkkel.
Endepunkter
| Metode | Rute | Beskrivelse |
|---|---|---|
| POST | /api/v1/scan |
Kjører en skanning og venter på resultatet. En rapport for samme adresse som er under 5 minutter gammel
returneres i stedet, med mindre force er true.
|
| GET | /api/v1/reports/{id} |
Henter en lagret rapport. |
Eksempel: skann en adresse
curl -sS -X POST https://webscan.stian.net/api/v1/scan \
-H "X-Api-Key: $WEBSCAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://eksempel.no", "force": false }'
Forespørsel
POST /api/v1/scan HTTP/1.1
Host: webscan.stian.net
X-Api-Key: wsk_...
Content-Type: application/json
{
"url": "https://eksempel.no",
"force": false
}
url(påkrevd): adressen som skal skannes. Uten skjema brukeshttps://.force(valgfri, standardfalse): hopp over 5-minutters-cachen.
Svar
JSON (camelCase) med hele skanneresultatet, pluss score og reportUrl på toppnivå.
Eksempelet er forkortet.
{
"score": 87,
"reportUrl": "https://webscan.stian.net/rapport/3q2-7wEjQ0yVbQx1fLk8Zg",
"schemaVersion": 1,
"requestedUrl": "https://eksempel.no/",
"finalUrl": "https://eksempel.no/",
"resolvedIp": "93.184.215.14",
"statusCode": 200,
"scannedAt": "2026-10-13T12:00:00+00:00",
"isHttps": true,
"checks": [
{
"id": "csp",
"name": "Content-Security-Policy",
"category": "Headers",
"status": "Pass",
"points": 15,
"maxPoints": 15,
"value": "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'",
"findings": []
}
],
"scoreBreakdown": {
"total": 87,
"uncapped": 87,
"cap": null,
"categories": [
{ "category": "Headers", "name": "Headere", "points": 52, "maxPoints": 60 }
]
}
}
Hent en lagret rapport
curl -sS https://webscan.stian.net/api/v1/reports/3q2-7wEjQ0yVbQx1fLk8Zg \
-H "X-Api-Key: $WEBSCAN_API_KEY"
Feilkoder
Feil returneres som application/problem+json med norsk title og detail.
| Status | Betydning |
|---|---|
400 | Ugyldig URL eller ugyldig forespørsel. |
401 | Manglende, ukjent eller tilbakekalt API-nøkkel. |
404 | Rapporten finnes ikke. |
422 | Målet er blokkert (for eksempel interne eller private adresser). |
429 | For mange forespørsler eller for mange samtidige skanninger. Se Retry-After. |
502 | Nettstedet kunne ikke nås. |
504 | Skanningen tok for lang tid. |
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json
{
"type": "https://tools.ietf.org/html/rfc4918#section-11.2",
"title": "Blokkert mål",
"status": 422,
"detail": "Adressen peker til en intern eller privat IP-adresse og kan ikke skannes."
}
Bruk i byggløypa
Eksempelet under kjører en skanning i GitHub Actions og feiler bygget hvis scoren er under en terskel.
Det bruker curl og jq, som finnes på GitHubs Ubuntu-maskiner. Legg API-nøkkelen
i repoets secrets som WEBSCAN_API_KEY.
name: Sikkerhetsheadere
on:
push:
branches: [main]
schedule:
- cron: "0 6 * * 1"
jobs:
webscan:
runs-on: ubuntu-latest
steps:
- name: Skann nettstedet med WebScan
env:
WEBSCAN_API_KEY: ${{ secrets.WEBSCAN_API_KEY }}
TARGET_URL: https://eksempel.no
MIN_SCORE: 80
run: |
set -euo pipefail
response=$(curl -sS --fail-with-body -X POST https://webscan.stian.net/api/v1/scan \
-H "X-Api-Key: $WEBSCAN_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg url "$TARGET_URL" '{url: $url, force: true}')")
score=$(echo "$response" | jq -r '.score')
report=$(echo "$response" | jq -r '.reportUrl')
echo "Score: $score av 100 – $report"
if [ "$score" -lt "$MIN_SCORE" ]; then
echo "::error::WebScan-score $score er under terskelen $MIN_SCORE ($report)"
exit 1
fi
Som shell-skript
#!/usr/bin/env bash
# Bruk: WEBSCAN_API_KEY=wsk_... ./webscan.sh https://eksempel.no 80
set -euo pipefail
url="$1"
min_score="${2:-80}"
response=$(curl -sS --fail-with-body -X POST https://webscan.stian.net/api/v1/scan \
-H "X-Api-Key: $WEBSCAN_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg url "$url" '{url: $url, force: true}')")
score=$(jq -r '.score' <<< "$response")
echo "Score: $score ($(jq -r '.reportUrl' <<< "$response"))"
[ "$score" -ge "$min_score" ] || { echo "Under terskelen $min_score" >&2; exit 1; }