API-Dokumentation
Integrieren Sie ComplianceScan in Ihre Systeme. REST API für automatisierte DSGVO-, AI-Act- und NIS2-Scans.
https://compliancescan.eu/api/v1Business-Plan & höher (API-Key erstellen)
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 Überschreitung des Minuten- oder Tageslimits (429 RATE_LIMIT_EXCEEDED bzw. 429 DAILY_LIMIT_EXCEEDED) liefert die API zusätzlich 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 Ihrer Organisation, neueste zuerst (paginiert).
Query-Parameter:
limit- Max. Anzahl (default: 20, 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=600 # Full-Scans können bis zu 8 Min dauern, plus Wartezeit in der Warteschlange
)
result = response.json()
print(f"DSGVO-Score: {result['scan']['gdpr_score']}/100")
print(f"Seiten gescannt: {result['scan']['pages_scanned']}")Node.js
import { fetch, Agent } from 'undici'; // npm install undici
const API_KEY = 'csk_live_IhrKeyHier';
const BASE_URL = 'https://compliancescan.eu/api/v1';
// Full-Scans können bis zu 8 Min dauern, plus Wartezeit in der Warteschlange
const dispatcher = new Agent({ headersTimeout: 600_000, bodyTimeout: 600_000 });
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 }),
dispatcher
});
if (!response.ok) {
const error = await response.json();
throw new Error(`${error.code}: ${error.error}`);
}
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
http.read_timeout = 600 # Full-Scans können bis zu 8 Min dauern, plus Wartezeit in der Warteschlange
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.Timeout = TimeSpan.FromMinutes(10); // Full-Scans können bis zu 8 Min dauern, plus Wartezeit in der Warteschlange
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- oder Tageslimit erreicht, oder Scan-Warteschlange voll (QUEUE_FULL) | Beim Rate- oder Tageslimit `Retry-After` auswerten und danach erneut versuchen; bei QUEUE_FULL (ohne `Retry-After`) später erneut versuchen |
500 | Server-Fehler | Später erneut versuchen, Support kontaktieren |
Fehler-Response Format
{
"error": "Rate limit exceeded. Try again in 45 seconds.",
"code": "RATE_LIMIT_EXCEEDED",
"retry_after": 45
}Für automatisierte Clients ist der Header Retry-After die kanonische Backoff-Information; das JSON-Feld retry_after wird parallel mitgeliefert.
6. Datenexport und Datenformate (Data Act)
Dieses Register beschreibt nach Art. 26 lit. b der Verordnung (EU) 2023/2854 (Data Act) die Datenstrukturen und Datenformate, in denen die nach Ziffer 5.9 unserer AGB exportierbaren Daten bereitstehen, sowie die dabei verwendeten Normen und offenen Spezifikationen. Wir halten es bei jeder Änderung des Exports aktuell.
Normen und offene Spezifikationen
- JSON nach RFC 8259 (ECMA-404), Medientyp
application/json, Zeichenkodierung UTF-8 (RFC 3629). - Zeitpunkte als Zeichenkette nach ISO 8601 im Profil von RFC 3339, in UTC (etwa
2026-10-06T08:00:00.000Z); reine Kalenderdaten alsJJJJ-MM-TT. - Werte: Zahlen als JSON-Zahlen, Wahrheitswerte als
true/false, fehlende Angaben alsnull; strukturierte Felder (etwadataeiner NIS2-Selbsteinschätzung) als eingebettetes JSON. - Übertragung über HTTPS (HTTP nach RFC 9110, verschlüsselt mit TLS).
- Screenshots als WebP-Bilddateien (RFC 9649).
Exportwege (AGB 5.9 a bis d)
| Weg | Ort | Format | Inhalt |
|---|---|---|---|
| (a) Exportfunktion | GET /api/export – für Administratoren der Organisation im angemeldeten Zustand | Datei compliance-export.json (JSON) | Konto, aktive Organisation, Verzeichnisse von Verarbeitungstätigkeiten (Stammdaten), NIS2- und AI-Act-Daten, Credit-Buchungen, Nachweise und Protokoll – Aufbau unten |
| (b) VVT-Modul | Zusammenfassung eines Verzeichnisses, Schaltfläche „JSON herunterladen“ | Datei VVT-Export.json (JSON) | ein Verzeichnis mit allen Verarbeitungstätigkeiten: format (compliancescan.vvt), formatVersion (1), exportedAt, vvt (Verantwortlicher, Tätigkeiten, technische und organisatorische Maßnahmen) |
| (c) API | https://compliancescan.eu/api/v1 – Tarife Business und Enterprise (Abschnitt 3) | JSON | Scan-Listen und Scan-Ergebnisse in der in Abschnitt 3 beschriebenen, gekürzten Form |
| (d) Auf Verlangen | Verlangen in Textform, etwa per E-Mail | je Kategorie eine JSON-Datei (Liste von Objekten; Schlüssel = Spaltennamen gemäß Tabelle unten); Screenshots als WebP | alle exportierbaren Daten nach AGB 5.9, auch die in (a) bis (c) fehlenden – etwa vollständige Scan-Ergebnisse, Domains und Monitoring-Verlauf |
Aufbau von compliance-export.json
Ein JSON-Objekt mit den folgenden Schlüsseln. Listen mit Höchstzahl enthalten die jüngsten Einträge zuerst und enden bei dieser Zahl. Bei Listen mit „alle Felder“ enthält jeder Eintrag sämtliche Felder des gespeicherten Datensatzes.
| Schlüssel | Inhalt | Felder | Umfang |
|---|---|---|---|
exported_at | Zeitpunkt des Exports | Zeichenkette | |
gdpr_basis | Rechtsgrundlage des Exports als Text (Art. 15 und 20 DSGVO) | Zeichenkette | |
organization | Name und Anlagedatum der aktiven Organisation | id, name, created_at | aktive Organisation |
user | E-Mail-Adresse, Tarif und Anlagedatum des abrufenden Kontos | id, email, tier, created_at | abrufendes Konto |
questionnaires | Verzeichnisse von Verarbeitungstätigkeiten (Stammdaten) einschließlich Entwürfen – ohne die einzelnen Tätigkeiten und ohne Änderungsprotokolle | alle Felder:id, organization_id, company_name, employees, industry, processing_purpose, legal_basis, data_subjects, data_types, data_sources, recipients, cloud_services, international_transfers, retention, security_measures, dpo, automated_decisions, compliance_score, dpia_level, dpia_score, created_at, is_draft, updated_at, controller_name, controller_address, controller_email, controller_phone, representative, dpo_name, dpo_email, dpo_phone, joint_controllers, version, approved_by, is_processor, processor_categories, processor_client, processor_contract_ref, country, processor_transfers, processor_toms | aktive Organisation, höchstens 500 Einträge |
nis2_assets | NIS2-Assets | alle Felder:id, organization_id, asset_name, asset_type, asset_location, criticality, owner, deputy, last_audit, next_audit, supplier, backup, patch_status, risk_level, risk_score, created_at, updated_at | aktive Organisation, höchstens 500 Einträge |
nis2_assessment | NIS2-Selbsteinschätzungen; data enthält die Angaben einschließlich Maßnahmen mit Fristen und Vorfällen – ohne Änderungsprotokolle | alle Felder:id, organization_id, data, version, updated_by_id, updated_by_email, created_at, updated_at | aktive Organisation, höchstens 100 Einträge |
aiact_systems | erfasste KI-Systeme mit ihrer AI-Act-Einstufung, einschließlich Entwürfen | alle Felder:id, organization_id, system_name, description, provider_name, operator_name, is_ai, ai_definition, annex_categories, limited_risk_flags, prohibited_practices, checklist_status, risk_class, created_at, is_draft, updated_at, role, gpai_based, gpai_model | aktive Organisation, höchstens 500 Einträge |
credit_transactions | Credit-Buchungen | id, user_id, amount, reason, stripe_payment_id, created_at | abrufendes Konto, höchstens 1000 Einträge |
credit_refund_coverage | je Credit-Kauf die Zahl der Credits, die Erstattungen außerhalb des Widerrufs bereits verrechnet haben | stripe_payment_id, user_id, covered, updated_at | abrufendes Konto, höchstens 1000 Einträge |
audit_logs | Protokoll der Organisation (IP-Adressen gekürzt) | id, org_id, user_id, action, resource, resource_id, ip, timestamp | aktive Organisation, höchstens 1000 Einträge |
passkeys | Angaben zu den Passkeys (ohne Schlüsselmaterial) | id, device_type, backed_up, friendly_name, created_at, last_used_at | abrufendes Konto |
withdrawal_consents | Nachweise der Zustimmung zum vorzeitigen Leistungsbeginn | alle Felder:id, user_id, plan, ip, user_agent, consented_at, policy_version | abrufendes Konto, höchstens 100 Einträge |
terms_consents | Nachweise der AGB-Zustimmungen | id, terms_version, context, ip, user_agent, consented_at | abrufendes Konto, höchstens 100 Einträge |
cancellation_requests | eingegangene Kündigungen und Widerrufe mit Name, Vertragsangaben sowie Eingangs-, Bestätigungs- und Bearbeitungszeitpunkt | id, email, name, contract_type, cancellation_type, contract_reference, reason, desired_end_date, received_at, verified_at, processed_at | abrufendes Konto, höchstens 100 Einträge |
Beispiel (gekürzt)
{
"exported_at": "2026-10-06T08:00:00.000Z",
"gdpr_basis": "Art. 15 / Art. 20 GDPR — personal data export",
"organization": { "id": 1, "name": "ACME", "created_at": "2026-01-15T09:30:00.000Z" },
"user": { "id": 7, "email": "admin@example.com", "tier": "business", "created_at": "2026-01-15T09:30:00.000Z" },
"questionnaires": [{ "id": 3, "organization_id": 1, "company_name": "ACME", "is_draft": false, "…": "…" }],
"nis2_assessment": [{ "id": 2, "organization_id": 1, "data": { "…": "…" }, "version": 4, "…": "…" }],
"credit_transactions": [{ "id": 11, "user_id": 7, "amount": 10, "reason": "purchase", "stripe_payment_id": "pi_…", "created_at": "2026-10-01T12:00:00.000Z" }],
"…": "…"
}Aufbau des Exports auf Verlangen (Weg d)
Auf Verlangen erhalten Sie für jede der folgenden Tabellen eine Datei mit allen Datensätzen Ihrer Organisation bzw. Ihres Kontos – als Liste von Objekten, deren Schlüssel die Spaltennamen sind; Formate wie oben beschrieben, Screenshots als WebP-Dateien. Ausgenommen sind nur die in Ziffer 5.9 der AGB genannten Sicherheitsdaten (Schlüsselmaterial, Hashwerte, Token).
| Datei | Tabelle | Felder |
|---|---|---|
| (1) Konto und Organisation | ||
users.json | users | id, email, email_verified, created_at, scan_credits, tier, stripe_customer_id, subscription_id, subscription_status, subscription_period_start, subscription_ends_at, is_system_admin, updated_at, active_organization_id, budget_pause_notified_at, locale, billing_country, billing_tax_id, billing_tax_id_type, billing_details_updated_atohne: password_hash, token_version |
organizations.json | organizations | id, name, created_at, nis2_in_use, ai_act_in_use, ai_act_literacy_done, ai_act_literacy_date, country |
user_organizations.json | user_organizations | id, user_id, organization_id, role, joined_at, is_owner |
invites.json | invites | id, org_id, email, role, expires_at, used, created_atohne: token |
user_passkeys.json | user_passkeys | id, user_id, device_type, backed_up, transports, friendly_name, created_at, last_used_atohne: credential_id, public_key, counter |
| (2) Verzeichnisse von Verarbeitungstätigkeiten | ||
questionnaire.json | questionnaire | id, organization_id, company_name, employees, industry, processing_purpose, legal_basis, data_subjects, data_types, data_sources, recipients, cloud_services, international_transfers, retention, security_measures, dpo, automated_decisions, compliance_score, dpia_level, dpia_score, created_at, is_draft, updated_at, controller_name, controller_address, controller_email, controller_phone, representative, dpo_name, dpo_email, dpo_phone, joint_controllers, version, approved_by, is_processor, processor_categories, processor_client, processor_contract_ref, country, processor_transfers, processor_toms |
questionnaire_activities.json | questionnaire_activities | id, questionnaire_id, name, purpose, legal_basis, data_subjects, data_types, recipients, processors, transfers, safeguards, retention, toms, automated_decisions, profiling, created_at, department, processing_description, data_origin, dpia_necessary, dpia_details, consent_withdrawal, transfer_country, review_date, review_cycle, art9_legal_basis, processors_structured |
questionnaire_changelog.json | questionnaire_changelog | id, questionnaire_id, version, changed_by, description, changed_at, user_id |
| (3) NIS2 | ||
nis2_assessment.json | nis2_assessment | id, organization_id, data, version, updated_by_id, updated_by_email, created_at, updated_at |
nis2_assessment_changelog.json | nis2_assessment_changelog | id, assessment_id, version, changed_by, description, changed_at |
nis2_assets.json | nis2_assets | id, organization_id, asset_name, asset_type, asset_location, criticality, owner, deputy, last_audit, next_audit, supplier, backup, patch_status, risk_level, risk_score, created_at, updated_at |
nis2_deadline_notifications.json | nis2_deadline_notifications | id, organization_id, incident_id, deadline_type, notified_at |
| (4) KI-Systeme (AI Act) | ||
aiact_systems.json | aiact_systems | id, organization_id, system_name, description, provider_name, operator_name, is_ai, ai_definition, annex_categories, limited_risk_flags, prohibited_practices, checklist_status, risk_class, created_at, is_draft, updated_at, role, gpai_based, gpai_model |
| (5) Scan-Ergebnisse | ||
scans.json | scans | id, organization_id, url, result, created_at, scan_type, score, issues_critical, issues_warning, credit_used, started_by_user_id, scan_duration_ms, access_blocked, access_block_type |
scan_pages.json | scan_pages | id, scan_id, url, page_number, status_code, request_count, third_party_count, cookie_count, created_at |
scan_cookies.json | scan_cookies | id, scan_id, name, value, domain, path, http_only, secure, same_site, expires_at, session_cookie, page_url, storage_type, provider, category, risk_level, created_at, set_before_consent |
scan_trackers.json | scan_trackers | id, scan_id, tracker_evaluation_id, url, name, provider, category, risk_level, description, data_transfer, schrems_ii_risk, confidence, compliance_note, loaded_via, data_transfer_source |
scan_issues.json | scan_issues | id, scan_id, severity, code, message, penalty_code, params |
scan_requests.json | scan_requests | id, scan_id, url, domain, root_domain, resource_type, is_third_party, tracker_evaluation_id, created_at, set_before_consent |
domain_technologies.json | domain_technologies | id, domain, scan_id, organization_id, technology_type, provider, service_name, gdpr_risk, us_transfer, requires_consent, ai_powered, first_seen_at, last_seen_at, observation_count |
consent_diagnostics.json | consent_diagnostics | id, scan_id, organization_id, url, domain, banner_clicked, click_strategy, detected_cmp, buttons_found, shadow_hosts, iframes, dialogs_count, total_buttons, created_at, passive_detection_missed, shadow_candidates |
data_flow_edges.json | data_flow_edges | id, source_type, source_id, source_label, target_type, target_id, target_label, edge_type, data_categories, purposes, legal_basis, country, risk_level, schrems_ii_risk, dpf_status, confidence, source_evidence, domain, organization_id, scan_id, created_at, updated_at, tcf_purpose_ids, retention_exceeds_declared |
hidden_dataflow_nodes.json | hidden_dataflow_nodes | id, organization_id, user_id, domain, node_type, node_id, reason, created_by_user_id, created_at |
scan_unlocks.json | scan_unlocks | id, scan_id, organization_id, source, unlocked_by_user_id, created_at |
scan_reports.json | scan_reports | id, scan_id, user_id, category, message, status, admin_note, created_at, updated_at, context, credit_refunded |
pending_scans.json | pending_scans | id, user_id, scan_type, url, source, api_key_id, status, created_at, started_at, completed_at, error_message, credit_charged_user_id, organization_id |
scan_failures.json | scan_failures | id, url, scan_type, error_message, user_id, created_at |
| (6) Domains und Monitoring | ||
organization_domains.json | organization_domains | id, organization_id, domain, created_at |
monitored_domains.json | monitored_domains | id, organization_id, domain, enabled, last_scan_at, last_score, created_at, scan_frequency, allow_extra_credits, crawl_delay_ms, last_scan_status |
monitoring_settings.json | monitoring_settings | id, organization_id, settings, created_at, updated_at |
domain_scan_history.json | domain_scan_history | id, domain, organization_id, scan_id, scan_type, score, issues_critical, issues_warning, has_hsts, has_csp, has_x_frame, has_referrer_policy, has_permissions_policy, tls_version, tls13_supported, weak_cipher, ssl_expires_at, server_country, server_city, gdpr_adequate, spf_enabled, dmarc_enabled, dkim_found, dnssec_enabled, dane_enabled, mta_sts_enabled, cmp_detected, cookie_banner_found, pre_consent_compliant, pre_consent_severity, dse_completeness, imprint_completeness, total_cookies, total_trackers, third_party_requests, consent_required_services, has_external_fonts, has_chatbot, scanned_at, spf_policy, dmarc_policy, mta_sts_mode, key_size, key_type |
domain_score_history.json | domain_score_history | id, domain, organization_id, scan_id, score, score_breakdown, issues_critical, issues_warning, scanned_at |
| (7) Widget, Badges und API-Schlüssel | ||
widget_keys.json | widget_keys | id, organization_id, created_by_user_id, name, key_prefix, allowed_domains, monthly_cap, rate_limit_per_ip_day, rate_limit_per_ip_week, rate_limit_per_ip_month, theme, active, paused, created_at, last_used_at, revoked_at, require_captcha, paused_atohne: key_hash |
widget_scan_usage.json | widget_scan_usage | id, widget_key_id, ip_hash, scan_id, created_at |
badge_tokens.json | badge_tokens | id, organization_id, domain, token, enabled, min_score, style, created_at, updated_at, cached_score, cached_scanned_at, cached_ssl, cached_cookies, cached_legal, cached_preconsent, cached_mail, cached_trackers |
api_keys.json | api_keys | id, user_id, name, key_prefix, scopes, last_used_at, last_used_ip, request_count, created_at, expires_at, revoked_at, organization_idohne: key_hash |
api_key_usage.json | api_key_usage | id, api_key_id, date, request_count, scan_count |
| (8) Credits und Nachweise | ||
credit_transactions.json | credit_transactions | id, user_id, amount, reason, stripe_payment_id, created_at, metadata |
credit_refund_coverage.json | credit_refund_coverage | stripe_payment_id, user_id, covered, updated_at |
withdrawal_consents.json | withdrawal_consents | id, user_id, plan, ip, user_agent, consented_at, policy_version |
terms_consents.json | terms_consents | id, user_id, terms_version, context, ip, user_agent, consented_at |
terms_notices.json | terms_notices | id, user_id, terms_version, mode, sent_at |
subscription_confirmations.json | subscription_confirmations | stripe_subscription_id, user_id, claimed_at, sent_at |
cancellation_requests.json | cancellation_requests | id, email, user_id, name, contract_type, contract_reference, cancellation_type, reason, desired_end_date, ip, received_at, receipt_sent_at, verified_at, processed_at, processing_result, escalated_at, operator_notified_at |
| (9) Protokoll der Organisation | ||
audit_logs.json | audit_logs | id, user_id, org_id, action, resource, resource_id, ip, details, timestamp, status_code |
Übertragung zu uns (Art. 26 lit. a Data Act)
Eine Funktion, mit der sich Daten aus einem anderen Dienst oder einer eigenen IT-Umgebung in ComplianceScan importieren lassen, gibt es derzeit nicht. Verzeichnisse, NIS2- und AI-Act-Angaben werden über die Eingabemasken erfasst; Scan-Ergebnisse entstehen durch Scans – auch über die API (Abschnitt 3).
7. Datenstandort und Drittstaatszugriff (Data Act)
Nach Art. 28 Abs. 1 der Verordnung (EU) 2023/2854 (Data Act) veröffentlichen wir hier, welcher Gerichtsbarkeit die für unseren Dienst genutzte IKT-Infrastruktur unterliegt und welche Maßnahmen wir gegen einen unrechtmäßigen staatlichen Zugriff aus Drittländern auf in der Union gespeicherte nicht-personenbezogene Daten getroffen haben. Stand: 6. Oktober 2026.
Gerichtsbarkeit der Infrastruktur
Die Plattform läuft mit ihrer Datenbank, ihren Dateien (etwa Screenshots) und ihrem E-Mail-Versand auf einem einzigen Server, den die Contabo GmbH (Sitz München, Deutschland) in einem Rechenzentrum in Deutschland bereitstellt. Diese Infrastruktur unterliegt dem Recht der Europäischen Union und der Bundesrepublik Deutschland. Der Anbieter hat seinen Sitz in Österreich. Datensicherungen überträgt er verschlüsselt über einen verschlüsselten Tunnel auf ein zweites, vom Anbieter selbst betriebenes Sicherungssystem in Österreich; es unterliegt dem Recht der Europäischen Union und der Republik Österreich.
Dienste Dritter
- Google Cloud EMEA Limited (Dublin, Irland) klassifiziert über die Gemini API Cookies, Tracker und Domains. Google erhält dafür nur minimierte technische Beobachtungen (Cookie- und Storage-Bezeichnungen, Domains, Häufigkeits- und Klassifizierungsangaben, CMP-Metadaten), keine Verzeichnisse, NIS2- oder AI-Act-Angaben unserer Kunden. Google LLC (USA) kann als Unterauftragnehmer Zugriff haben.
- Stripe Payments Europe, Limited (Irland) wickelt die Zahlungen ab; Stripe, Inc. (USA) kann als Unterauftragnehmer Zugriff haben.
- Cloudflare, Inc. (San Francisco, USA) schützt mit Cloudflare Turnstile unser einbettbares Scan-Widget vor automatisiertem Missbrauch, soweit es für den jeweiligen Widget-Schlüssel aktiviert ist. Dabei werden die IP-Adresse und technische Browser-/Geräte-Signale des Widget-Besuchers an Cloudflare übermittelt; die Verarbeitung kann in den USA erfolgen und ist durch EU-Standardvertragsklauseln bzw. das EU-US Data Privacy Framework abgesichert.
- Proxy-Dienste: Derzeit setzt der Anbieter keinen externen Proxy-Dienst ein; wird künftig einer eingesetzt, nennen wir ihn hier vorab.
Maßnahmen gegen unrechtmäßigen Zugriff aus Drittländern
- Technisch: Datenbank und interne Dienste sind nur auf dem Server selbst erreichbar; die Firewall lässt von außen nur Web, E-Mail und SSH zu, die Anmeldung per SSH nur mit Schlüssel. Verbindungen zur Plattform sind mit TLS verschlüsselt (HTTPS), die auf das Sicherungssystem übertragenen Datensicherungen sind verschlüsselt (Borg, „repokey-blake2“) und werden über einen verschlüsselten Tunnel (WireGuard) übertragen. Passwörter sowie API- und Widget-Schlüssel speichern wir nur als Hashwert.
- Organisatorisch: Zugang zu Server, Datenbank und Datensicherungen hat ausschließlich der Anbieter. Ein Datenzugangsverlangen eines Gerichts oder einer Behörde eines Drittlands befolgt er nur, wenn es auf einer internationalen Übereinkunft beruht oder die Voraussetzungen des Art. 32 Abs. 3 Data Act erfüllt sind; er gibt dann nur die Mindestmenge an Daten heraus und unterrichtet den Kunden vorher, außer wenn das Verlangen Strafverfolgungszwecken dient, solange dies zur Wahrung der Wirksamkeit der Strafverfolgung erforderlich ist (Art. 32 Abs. 2, 4 und 5 Data Act).
- Vertraglich: Hosting und Klassifizierung erbringen Vertragspartner mit Sitz in der EU (Contabo GmbH, Google Cloud EMEA Limited), mit denen Auftragsverarbeitungsverträge nach Art. 28 DSGVO bestehen.
Bereit loszulegen?
Erstellen Sie Ihren ersten organisationsgebundenen API-Key und starten Sie mit automatisierten Compliance-Scans.