API-Dokumentation
Integrieren Sie ComplianceScan in Ihre Systeme. REST API für automatisierte DSGVO-, AI-Act- und NIS2-Scans.
1. Authentifizierung
Alle API-Anfragen (außer /health) erfordern einen API-Key. Erstellen Sie Ihren Key unter Einstellungen → API-Zugang.
API-Keys sind immer an die Organisation gebunden, die beim Erstellen in Ihrem Konto aktiv ausgewählt war. Ein Key kann daher nur Scans und Daten genau dieser Organisation lesen und schreiben.
Header-Format
Authorization: Bearer csk_live_IhrApiKeyHier...Alternativ:
X-API-Key: csk_live_IhrApiKeyHier...2. Rate-Limits
| Plan | Requests/Minute | Requests/Tag | Parallele Scans |
|---|---|---|---|
| Business | 30 | 500 | 2 |
| Enterprise | 120 | 5.000 | 3 |
Response-Header
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1708599120
Retry-After: 45Bei 429 Too Many Requests liefert die API zusätzlich immer den Standard-Header Retry-After in Sekunden.
3. Endpoints
/health(keine Auth)Status-Check der API.
Response:
{
"status": "ok",
"version": "1.0.0"
}/accountKonto-Informationen und verbleibende Credits.
Hinweis: api_usage ist über alle Ihre API-Keys aggregiert, die derselben Organisation zugeordnet sind wie der aktuelle Key.
Response:
{
"plan": "business",
"organization": {
"id": 12,
"name": "Acme GmbH"
},
"email": "user@example.com",
"credits": {
"remaining": 47
},
"scans": {
"running": 0,
"pending": 0,
"concurrency_limit": 2,
"queue_limit": 50
},
"api_usage": {
"requests_this_month": 124,
"scans_this_month": 3
}
}/scansStartet einen neuen Scan. Wartet bis zum Ergebnis (synchron).
Request-Body:
{
"url": "https://example.com",
"type": "full" // Full-Scan (kostet 1 Credit)
}Response:
{
"status": "completed",
"scan": {
"url": "https://example.com",
"type": "full",
"gdpr_score": 70,
"pages_scanned": 45,
"trackers": 3,
"tracker_list": ["google-analytics.com", "doubleclick.net", "facebook.net"],
"third_parties": 28,
"cookies": 15,
"has_privacy_policy": true,
"privacy_urls": ["https://example.com/datenschutz"],
"has_imprint": true,
"imprint_urls": ["https://example.com/impressum"],
"has_terms": true,
"terms_urls": ["https://example.com/agb"],
"has_cookie_banner": true,
"scanned_at": "2026-02-22T08:15:47Z",
"scan_duration_ms": 47320
}
}/scansListe aller Scans (letzte 30 Tage).
Query-Parameter:
limit- Max. Anzahl (default: 50, max: 100)offset- Pagination-Offset
/scans/latestLetzter Scan pro Domain (Dedupliziert).
/scans/:idDetails eines einzelnen Scans.
4. Code-Beispiele
cURL
# Full-Scan starten (kostet 1 Credit)
curl -X POST https://compliancescan.eu/api/v1/scans \
-H "Authorization: Bearer csk_live_IhrKeyHier" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "type": "full"}'
# Ergebnis ausgeben (mit jq)
curl -s -X POST https://compliancescan.eu/api/v1/scans \
-H "Authorization: Bearer csk_live_IhrKeyHier" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "type": "full"}' | jq .
# Account-Info abrufen
curl https://compliancescan.eu/api/v1/account \
-H "Authorization: Bearer csk_live_IhrKeyHier"Python
import requests
API_KEY = "csk_live_IhrKeyHier"
BASE_URL = "https://compliancescan.eu/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Full-Scan
response = requests.post(
f"{BASE_URL}/scans",
headers=headers,
json={"url": "https://example.com", "type": "full"},
timeout=180 # Full-Scans können bis zu 2 Min dauern
)
result = response.json()
print(f"DSGVO-Score: {result['scan']['gdpr_score']}/100")
print(f"Seiten gescannt: {result['scan']['pages_scanned']}")Node.js
const API_KEY = 'csk_live_IhrKeyHier';
const BASE_URL = 'https://compliancescan.eu/api/v1';
async function scan(url, type = 'full') {
const response = await fetch(`${BASE_URL}/scans`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ url, type })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}
// Verwendung
const result = await scan('https://example.com', 'full');
console.log(`DSGVO-Score: ${result.scan.gdpr_score}/100`);
console.log(`Seiten gescannt: ${result.scan.pages_scanned}`);PHP
<?php
$apiKey = 'csk_live_IhrKeyHier';
$baseUrl = 'https://compliancescan.eu/api/v1';
// Full-Scan
$ch = curl_init("$baseUrl/scans");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $apiKey",
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com',
'type' => 'full'
])
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
echo "Trackers: " . $result['scan']['trackers'] . "\n";
echo "Status: " . $result['status'] . "\n";Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"io"
)
func main() {
apiKey := "csk_live_IhrKeyHier"
baseURL := "https://compliancescan.eu/api/v1"
body, _ := json.Marshal(map[string]string{
"url": "https://example.com",
"type": "full",
})
req, _ := http.NewRequest("POST", baseURL+"/scans", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(data, &result)
fmt.Printf("Status: %s\n", result["status"])
}Ruby
require 'net/http'
require 'json'
require 'uri'
api_key = 'csk_live_IhrKeyHier'
base_url = 'https://compliancescan.eu/api/v1'
uri = URI("#{base_url}/scans")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = "Bearer #{api_key}"
request['Content-Type'] = 'application/json'
request.body = { url: 'https://example.com', type: 'full' }.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Trackers: #{result['scan']['trackers']}"
puts "Score: #{result['scan']['gdpr_score']}" if result['scan']['gdpr_score']C# (.NET)
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer csk_live_IhrKeyHier");
var content = new StringContent(
"{\"url\":\"https://example.com\",\"type\":\"full\"}",
System.Text.Encoding.UTF8,
"application/json"
);
var response = await client.PostAsync(
"https://compliancescan.eu/api/v1/scans", content
);
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);Java
import java.net.http.*;
import java.net.URI;
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://compliancescan.eu/api/v1/scans"))
.header("Authorization", "Bearer csk_live_IhrKeyHier")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"url\":\"https://example.com\",\"type\":\"full\"}"
))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());5. Fehlercodes
| Code | Bedeutung | Lösung |
|---|---|---|
400 | Ungültige Anfrage | URL prüfen, JSON-Format validieren |
401 | Nicht authentifiziert | API-Key im Header prüfen |
402 | Keine Credits | Credits kaufen oder Plan upgraden |
403 | Plan nicht berechtigt | Business- oder Enterprise-Plan erforderlich |
429 | Rate-Limit erreicht | `Retry-After` auswerten und danach erneut versuchen |
500 | Server-Fehler | Später erneut versuchen, Support kontaktieren |
Fehler-Response Format
{
"error": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"retry_after": 45
}Für automatisierte Clients ist der Header Retry-After die kanonische Backoff-Information; das JSON-Feld retry_after wird parallel mitgeliefert.
Bereit loszulegen?
Erstellen Sie Ihren ersten organisationsgebundenen API-Key und starten Sie mit automatisierten Compliance-Scans.