Entwickeln / Referenz

Shield (/v1/shield)

Prüft Text eigenständig über POST /v1/shield/inspect und liest oder aktualisiert die Shield-Richtlinie der Organisation über /v1/shield/policy.

Authentifizierung
Bearer px-... · x-api-key · api-key
Preis (/v1/shield/inspect)
0,40 € / 1 Mio. Eingabe-Tokens
Richtlinienverwaltung
can_manage_shield erforderlich
Format
JSON
Streaming
nein

Unter /v1/shield stellt das Gateway zwei Endpunkt-Gruppen bereit: POST /v1/shield/inspect prüft beliebige Texte direkt auf deutscher Infrastruktur ohne nachgelagerten Modellaufruf, und /v1/shield/policy liest oder ändert die Shield-Richtlinie Ihrer Organisation per API. Wie Shield auf Modell-Endpunkten arbeitet, beschreibt Noirdoc Shield.

Text prüfen

POST /v1/shield/inspect

Prüft einen einzelnen String oder ein Batch aus bis zu 64 Strings anhand der Schutzfilter Ihrer Organisation (optional ergänzt oder verschärft durch policy). Der Endpunkt wertet den optionalen Header X-Noirdoc-Tags aus, prüft Schlüssel- und Tag-Budgets und bucht 0,40 € je 1 Mio. Eingabe-Tokens.

Anfragefelder

FeldPflichtInhalt
inputjaNicht leerer String oder Liste aus 1 bis 64 nicht leeren Strings, zusammen höchstens 256 KB (262.144 Byte) in UTF-8.
rolenein"user", "tool", "system" oder "assistant" (Standard: "user"). Der Filter injection prüft "user" und "tool"; "system" und "assistant" sind von injection ausgenommen, werden aber von den übrigen Filtern geprüft.
policyneinOptionales Überschreibungsobjekt {"rules"?: {...}, "custom_patterns"?: [...]} (oder flache Regel-Map ohne custom_patterns; beides gemischt ergibt 422 shield_policy_invalid). Gilt nur für diesen Aufruf.

Steht die Organisation auf enforced, darf policy keine aktive Regel abschwächen (etwa block auf redact oder off senken) und keine hinterlegten custom_patterns weglassen; andernfalls antwortet das Gateway mit Statuscode 403 (shield_policy_enforced).

Shell
curl https://api.noirdoc.de/v1/shield/inspect \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -H "X-Noirdoc-Tags: mandat-2026-042" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [
      "Mandantin im Verfahren: Anna Schmidt",
      "Kontoverbindung: DE89 3704 0044 0532 0130 00",
      "Notiz zu Projekt Helios, Akte AZ-2026-00418."
    ],
    "role": "user",
    "policy": {
      "rules": { "custom": "redact" },
      "custom_patterns": [
        "Projekt Helios",
        "re:AZ-[0-9]{4}-[0-9]{5}"
      ]
    }
  }'
Python
import os
import httpx

key = os.environ["NOIRDOC_API_KEY"]
patterns = ["Projekt Helios", "re:AZ-[0-9]{4}-[0-9]{5}"]

response = httpx.post(
    "https://api.noirdoc.de/v1/shield/inspect",
    headers={
        "Authorization": f"Bearer {key}",
        "X-Noirdoc-Tags": "mandat-2026-042",
    },
    json={
        "input": [
            "Mandantin im Verfahren: Anna Schmidt",
            "Kontoverbindung: DE89 3704 0044 0532 0130 00",
            "Notiz zu Projekt Helios, Akte AZ-2026-00418.",
        ],
        "role": "user",
        "policy": {
            "rules": {"custom": "redact"},
            "custom_patterns": patterns,
        },
    },
)
response.raise_for_status()
result = response.json()
TypeScript
const url = "https://api.noirdoc.de/v1/shield/inspect";
const patterns = ["Projekt Helios", "re:AZ-[0-9]{4}-[0-9]{5}"];

const response = await fetch(url, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.NOIRDOC_API_KEY}`,
    "X-Noirdoc-Tags": "mandat-2026-042",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: [
      "Mandantin im Verfahren: Anna Schmidt",
      "Kontoverbindung: DE89 3704 0044 0532 0130 00",
      "Notiz zu Projekt Helios, Akte AZ-2026-00418.",
    ],
    role: "user",
    policy: {
      rules: { custom: "redact" },
      custom_patterns: patterns,
    },
  }),
});
const result = await response.json();

Antwortobjekt (200 OK)

POST /v1/shield/inspect antwortet auch dann mit HTTP 200 OK, wenn action den Wert "block" hat, und führt die Prüfung ohne Kurzschluss (short_circuit=false) aus, sodass sämtliche Treffer im Eingabetext zurückgegeben werden:

FeldInhalt
idEindeutige Prüf-ID der Form "shld_..."
model"noirdoc-shield-v1"
actionGesamtergebnis der Prüfung: "pass", "redact" oder "block"
flaggedtrue, sobald mindestens ein Treffer vorliegt oder action ungleich "pass" ist, sonst false
outputBereinigter Text in derselben Form wie input (string oder string[]) mit eingesetzten [LABEL]-Platzhaltern
findingsListe der Treffer mit category (secrets, pii, ner, injection, custom), label, kind, action, replacement ("[<LABEL>]"), start, end und index
findings_truncatedtrue, falls die Liste findings an die Obergrenze des Prüfdienstes gestoßen ist; action, flagged und output sind davon nicht betroffen
usage{"input_tokens": <int>} – abgerechnete Eingabe-Tokens (mindestens 1)

Ist input eine Liste, nennt findings[].index die Position des jeweiligen Eintrags ab 0.

JSON
{
  "id": "shld_7f3c9a12e4b048d19c2a6e10",
  "model": "noirdoc-shield-v1",
  "action": "redact",
  "flagged": true,
  "output": [
    "Mandantin im Verfahren: [PERSON]",
    "Kontoverbindung: [IBAN]",
    "Notiz zu [CUSTOM], Akte [CUSTOM]."
  ],
  "findings": [
    {
      "category": "ner",
      "label": "PERSON",
      "kind": "PERSON",
      "action": "redact",
      "replacement": "[PERSON]",
      "start": 24,
      "end": 36,
      "index": 0
    },
    {
      "category": "pii",
      "label": "IBAN",
      "kind": "IBAN",
      "action": "redact",
      "replacement": "[IBAN]",
      "start": 17,
      "end": 44,
      "index": 1
    },
    {
      "category": "custom",
      "label": "CUSTOM",
      "kind": "CUSTOM",
      "action": "redact",
      "replacement": "[CUSTOM]",
      "start": 9,
      "end": 23,
      "index": 2
    },
    {
      "category": "custom",
      "label": "CUSTOM",
      "kind": "CUSTOM",
      "action": "redact",
      "replacement": "[CUSTOM]",
      "start": 30,
      "end": 43,
      "index": 2
    }
  ],
  "findings_truncated": false,
  "usage": {
    "input_tokens": 41
  }
}

Richtlinie verwalten

GET /v1/shield/policy
PUT /v1/shield/policy
PATCH /v1/shield/policy

Liest oder ändert die Shield-Richtlinie der Organisation. Alle drei Methoden setzen voraus, dass am aufrufenden API-Schlüssel unter Models → API-Schlüssel die Berechtigung Shield-Richtlinie per API verwalten (can_manage_shield = true) eingeschaltet ist; ohne sie antwortet das Gateway mit Statuscode 403 (insufficient_key_permissions). Ein Schlüssel, der selbst fest auf shield_mode: "on" gestellt ist, darf die bestehende Richtlinie zudem nicht abschwächen (403 insufficient_key_permissions).

Anfragefelder bei PUT und PATCH

FeldInhalt
mode"default_off", "default_on" oder "enforced" (die Aliase "off" für "default_off" und "advisory" für "default_on" sowie die Feldnamen shield_policy und mask_policy werden ebenfalls akzeptiert).
rulesObjekt mit den Schlüsseln secrets, pii, ner, custom ("off" | "redact" | "block") und injection ("off" | "block").
custom_patternsListe aus 0 bis 100 Einträgen à 2 bis 256 Zeichen: literale Teilstrings (Groß-/Kleinschreibung ignoriert) oder reguläre Ausdrücke mit Präfix re: (lineare Laufzeit, ohne Lookaround/Rückreferenzen, nicht leer).
  • PUT /v1/shield/policy vs. PATCH /v1/shield/policy: Übergeben Sie rules bei PUT, werden nicht genannte Regelschlüssel auf ihre Shield-Standardwerte zurückgesetzt (secrets: "block", pii: "redact", ner: "redact", injection: "block", custom: "redact"). Bei PATCH werden übergebene Regelschlüssel in den aktuellen Stand zusammengeführt, während nicht genannte Regelschlüssel erhalten bleiben; wird custom_patterns übergeben, ersetzt die Liste die gespeicherten Sperrbegriffe vollständig (ohne custom_patterns bleibt die bestehende Liste erhalten).
  • Validierung: enforced in Verbindung mit fünf auf "off" gesetzten Filtern lehnt das Gateway mit Statuscode 422 (shield_policy_invalid) ab.
  • Einweg-Umstellung von klassischer Maskierung: Ein erfolgreicher Aufruf von PUT /v1/shield/policy oder PATCH /v1/shield/policy stellt eine Bestandsorganisation mit noch aktiver klassischer Maskierung dauerhaft auf Noirdoc Shield um (legacy_mask_active: false).

Antwortfelder

FeldInhalt
modeAktive Standard-Einstellung: "default_off", "default_on" oder "enforced"
shield_policySpiegelwert zu mode ("default_off", "default_on" oder "enforced")
rulesAktive Aktionen aller fünf Schutzfilter (secrets, pii, ner, injection, custom)
custom_patternsGespeicherte Liste eigener Sperrbegriffe (string[])
price_per_1m_input_tokens_eur"0.40"
legacy_mask_activetrue, solange eine Bestandsorganisation während der Übergangsfrist noch die klassische Maskierung nutzt, sonst false
legacy_mask_sunset_atISO-8601-Zeitstempel "2026-11-30T23:59:59Z", solange das Übergangsfenster auf dem Gateway aktiv ist (auch nach der Umstellung), nach Auslauf null
Shell
curl -X PATCH https://api.noirdoc.de/v1/shield/policy \
  -H "Authorization: Bearer $NOIRDOC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "default_on",
    "rules": {
      "pii": "redact",
      "custom": "block"
    },
    "custom_patterns": [
      "Projekt Helios",
      "Mandat Nordstern",
      "Vertrag Kronos",
      "re:AZ-[0-9]{4}-[0-9]{5}"
    ]
  }'
Python
import os
import httpx

key = os.environ["NOIRDOC_API_KEY"]
patterns = [
    "Projekt Helios",
    "Mandat Nordstern",
    "Vertrag Kronos",
    "re:AZ-[0-9]{4}-[0-9]{5}",
]

response = httpx.patch(
    "https://api.noirdoc.de/v1/shield/policy",
    headers={"Authorization": f"Bearer {key}"},
    json={
        "mode": "default_on",
        "rules": {"pii": "redact", "custom": "block"},
        "custom_patterns": patterns,
    },
)
response.raise_for_status()
policy = response.json()
TypeScript
const url = "https://api.noirdoc.de/v1/shield/policy";
const patterns = [
  "Projekt Helios",
  "Mandat Nordstern",
  "Vertrag Kronos",
  "re:AZ-[0-9]{4}-[0-9]{5}",
];

const response = await fetch(url, {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.NOIRDOC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    mode: "default_on",
    rules: { pii: "redact", custom: "block" },
    custom_patterns: patterns,
  }),
});
const policy = await response.json();
JSON
{
  "mode": "default_on",
  "shield_policy": "default_on",
  "rules": {
    "secrets": "block",
    "pii": "redact",
    "ner": "redact",
    "injection": "block",
    "custom": "block"
  },
  "custom_patterns": [
    "Projekt Helios",
    "Mandat Nordstern",
    "Vertrag Kronos",
    "re:AZ-[0-9]{4}-[0-9]{5}"
  ],
  "price_per_1m_input_tokens_eur": "0.40",
  "legacy_mask_active": false,
  "legacy_mask_sunset_at": "2026-11-30T23:59:59Z"
}

Fehler auf diesem Endpunkt

Status Code Bedeutung
400 invalid_request_error Ein Parameter auf /v1/shield/inspect oder /v1/shield/policy ist ungültig (etwa leerer oder über 256 KB großer input, mehr als 64 Einträge, unbekannte Regel oder ungültiger Sperrbegriff), oder der JSON-Body ist für die Shield-Extraktion zu tief verschachtelt.
400 invalid_request_tags Der Header X-Noirdoc-Tags oder der Tag-Name im Pfad unter /v1/tags ist leer, enthält mehr als 5 Tags oder entspricht nicht dem Format ^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,63}$.
401 invalid_api_key Der Schlüssel fehlt, ist ungültig oder deaktiviert, oder die Organisation ist nicht aktiv.
402 insufficient_credit Das Guthaben der Organisation ist aufgebraucht oder kleiner als die geschätzten Höchstkosten der Anfrage (einschließlich Noirdoc Shield, auch auf BYOK-Routen mit aktivem Shield).
402 key_budget_exhausted Das Budget dieses Schlüssels ist für den laufenden Zeitraum aufgebraucht oder reicht für die geschätzten Kosten der Anfrage nicht aus.
402 tag_budget_exhausted Das Budget eines in X-Noirdoc-Tags genannten Tags ist für den laufenden Zeitraum aufgebraucht oder reicht für die geschätzten Kosten der Anfrage nicht aus; message nennt das Tag.
403 shield_policy_enforced Die Shield-Richtlinie der Organisation steht auf enforced, und die Anfrage auf /v1/shield/inspect versucht über policy eine aktive Regel abzuschwächen oder eigene Sperrbegriffe wegzulassen.
403 tag_not_found Das genannte Tag existiert nicht. Bei Anfragen mit X-Noirdoc-Tags ist die automatische Tag-Anlage ausgeschaltet (Statuscode 403); auf /v1/tags/{name} antwortet das Gateway mit Statuscode 404.
403 tag_disabled Ein in X-Noirdoc-Tags genanntes Tag ist deaktiviert.
403 tag_limit_exceeded Die Organisation hat die Obergrenze von 1.000 Request-Tags erreicht.
403 insufficient_key_permissions Dem API-Schlüssel fehlt die Berechtigung für /v1/tags (can_manage_tags) oder /v1/shield/policy (can_manage_shield), ein Schlüssel mit fest aktiviertem Shield (shield_mode: on) versucht die Shield-Richtlinie oder shield_mode eines Tags abzuschwächen, oder das Tag soll weiter reichende Modelle, Anbieter oder Compliance-Regeln erhalten als der aufrufende Schlüssel selbst besitzt.
413 shield_input_too_large Der zu prüfende Text der Anfrage überschreitet das Limit des Shield-Dienstes von 4 MiB kodiertem Text in einem Aufruf.
422 shield_policy_invalid Die übergebene Shield-Richtlinie ist widersprüchlich, etwa enforced mit allen fünf Schutzfiltern auf off oder eine Mischung aus rules/custom_patterns und flachen Regelschlüsseln.
422 shield_config_invalid Die gespeicherte Shield-Konfiguration der Organisation ist ungültig (zum Beispiel enforced ohne aktiven Schutzfilter oder ein nicht kompilierbares Muster); das Gateway hat die Anfrage nicht weitergeleitet.
429 starter_rate_limit_exceeded Die Organisation nutzt noch ausschließlich das Startguthaben und hat die Grenze von 5 Anfragen je Minute oder 25 Anfragen je Tag (UTC) für verwaltete Anbieter erreicht. Die Antwort enthält Retry-After mit der Wartezeit in Sekunden.
503 service_overloaded Das Gateway ist vorübergehend ausgelastet. Die Antwort enthält Retry-After mit 5 Sekunden.
503 shield_unavailable Der Noirdoc-Shield-Prüfdienst ist vorübergehend nicht erreichbar; das Gateway leitet eine zu prüfende Anfrage niemals ungeprüft weiter (Fail-closed). Die Antwort enthält Retry-After mit 5 Sekunden.