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 brukes https://.
  • force (valgfri, standard false): 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
400Ugyldig URL eller ugyldig forespørsel.
401Manglende, ukjent eller tilbakekalt API-nøkkel.
404Rapporten finnes ikke.
422Målet er blokkert (for eksempel interne eller private adresser).
429For mange forespørsler eller for mange samtidige skanninger. Se Retry-After.
502Nettstedet kunne ikke nås.
504Skanningen 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; }
Det oppstod en uventet feil. Last inn siden på nytt 🗙

Kobler til serveren igjen …

Tilkoblingen mislyktes. Prøver igjen om sekunder.

Kunne ikke koble til igjen.
Prøv igjen eller last inn siden på nytt.

Økten er satt på pause av serveren.

Kunne ikke gjenoppta økten.
Prøv igjen eller last inn siden på nytt.