# Textprüfungen

> Reinen Text mit POST /text/detections als von KI verfasst, gemischt oder von Menschen verfasst einstufen. Felder in Anfrage und Antwort, Segment-Offsets, Limits und Abrechnung.

Quelle: https://fileverity.com/de/docs/text-detections

`POST /text/detections` führt eine Textprüfung aus. Der Endpunkt stuft reinen Text mit `fvdoc-3-text` ein und liefert die von KI verfassten Passagen. Der Aufruf ist synchron: Das Ergebnis steht in der Antwort.

Die Beispiele lesen den Text aus einer Datei. Speichern Sie daher zuerst eine beliebige Passage mit mindestens 100 Wörtern als `essay.txt`. Der [Schnellstart](https://fileverity.com/de/docs/quickstart.md#text) enthält einen Befehl, der einen Beispieltext schreibt.

**Anfrage: cURL**

```bash
curl https://api.fileverity.com/v1/text/detections \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6b9d1c1e-3b0f-4c0a-9a53-2d1c9d6b7e11" \
  -d "$(jq -Rs '{text: ., language: "en"}' essay.txt)"
```

**Anfrage: JavaScript**

```javascript
import { readFile } from "node:fs/promises";
import { randomUUID } from "node:crypto";

const response = await fetch("https://api.fileverity.com/v1/text/detections", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.FILEVERITY_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": randomUUID(),
  },
  body: JSON.stringify({ text: await readFile("essay.txt", "utf8"), language: "en" }),
});
const detection = await response.json();
```

**Anfrage: Python**

```python
import os
import uuid
import requests

response = requests.post(
    "https://api.fileverity.com/v1/text/detections",
    headers={
        "Authorization": "Bearer " + os.environ["FILEVERITY_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"text": open("essay.txt", encoding="utf-8").read(), "language": "en"},
)
detection = response.json()
```

## Anfragetext

| Feld | Typ | Erforderlich | Beschreibung |
| --- | --- | --- | --- |
| `text` | string | Ja | Reiner Text mit mindestens 100 Wörtern und höchstens 100.000 Zeichen. |
| `model` | string | Nein | Standardwert `fvdoc-3-text`. Akzeptiert die Modell-ID oder deren Snapshot-ID `fvdoc-3-text-2026-11-03`. |
| `language` | string oder null | Nein | ISO-639-1-Code: `en`, `fr`, `de`, `es`, `zh`. Wird automatisch erkannt, wenn er fehlt. |

Unbekannte Felder werden mit `invalid_parameter` abgelehnt. Bei der Prüfung auf die Mindestlänge von 100 Wörtern zählen zwei chinesische Schriftzeichen etwa als ein Wort.

## Antwort

**200 OK**

```json
{
  "id": "tdet_8Hk2pQ4vN9sL1xR7cW3mY6zB",
  "object": "text.detection",
  "created": 1793664000,
  "model": "fvdoc-3-text-2026-11-03",
  "livemode": true,
  "language": "en",
  "verdict": "mixed",
  "score": 0.97,
  "ai_fraction": 0.41,
  "segments": [
    {
      "start": 212,
      "end": 433,
      "score": 0.97
    },
    {
      "start": 579,
      "end": 790,
      "score": 0.93
    }
  ],
  "usage": {
    "characters": 1412,
    "free_characters": 0,
    "billed_units": 2
  }
}
```

| Feld | Typ | Beschreibung |
| --- | --- | --- |
| `id` | string | ID der Textprüfung mit dem Präfix `tdet_`. |
| `object` | string | Immer `text.detection`. |
| `created` | integer | Unix-Zeitstempel. |
| `model` | string | Snapshot, der das Ergebnis erzeugt hat. |
| `livemode` | boolean | `false` bei Testschlüsseln. |
| `language` | string | Die verwendete Sprache: die von Ihnen gesendete oder die erkannte. |
| `verdict` | string | `ai`: Der Text wirkt durchgehend von KI verfasst. `mixed`: von KI verfasste Passagen in einem von Menschen verfassten Text. `human`: keine von KI verfasste Passage gefunden. |
| `score` | number | Von 0 bis 1. Modell-Score für die Passage mit der stärksten KI-Ähnlichkeit. |
| `ai_fraction` | number | Von 0 bis 1. Anteil des ausgewerteten Textes, der in von KI verfassten Segmenten liegt. |
| `segments` | array | Die von KI verfassten Passagen. Jede hat `start`, `end` (exklusiv) und `score`. |
| `usage` | object | Ausgewertete Zeichen (`characters`), durch Ihren kostenlosen Start abgedeckte Zeichen (`free_characters`) und nach den kostenlosen Zeichen tatsächlich berechnete Einheiten (`billed_units`). |

> **Hinweis.** Die Textprüfung liefert eine statistische Schätzung, keinen Nachweis der Urheberschaft. Die Segmentgrenzen sind ungefähr. Nutzen Sie sie als einen Anhaltspunkt für eine Prüfung durch Menschen und stützen Sie Entscheidungen, die eine Person betreffen, nicht allein darauf.

## Segment-Offsets

`start` und `end` sind Offsets im gesendeten Text, gezählt in Unicode-Codepoints, nicht in Bytes und nicht in UTF-16-Einheiten. Die Segmentgrenzen sind ungefähr und können angrenzende Sätze einschließen. JavaScript-Strings werden nach UTF-16 indiziert; zerlegen Sie den Text daher zuerst in Codepoints:

**Segment ausschneiden: JavaScript**

```javascript
const points = Array.from(text);
for (const { start, end } of detection.segments) {
  console.log(points.slice(start, end).join(""));
}
```

**Segment ausschneiden: Python**

```python
for segment in detection["segments"]:
    print(text[segment["start"]:segment["end"]])
```

Python-Strings werden bereits nach Codepoints indiziert.

## Abrechnung

- Text wird pro 1.000 Zeichen mit 0,14 USD abgerechnet, gezählt in Unicode-Codepoints. Jede Anfrage wird auf ganze Einheiten aufgerundet, mindestens auf eine Einheit.
- Die kostenlosen Zeichen für Textprüfungen aus Ihrem kostenlosen Start werden zuerst verbraucht und in `usage.free_characters` ausgewiesen. `usage.billed_units` ist die Anzahl der danach berechneten Einheiten; die Kosten betragen also `billed_units` mal 0,14 USD. Beispiel: 1.412 Zeichen ohne verbleibende kostenlose Zeichen ergeben 2 Einheiten, 0,28 USD.
- Anfragen, die vor der Auswertung abgelehnt werden, werden nicht berechnet: ungültige Parameter, zu kurzer oder zu langer Text, nicht unterstützte Sprachen und Ähnliches. Eine Prüfung, die im Dienst fehlschlägt (`service_unavailable`), wird freigegeben und nicht berechnet.
- Bei unzureichendem Guthaben wird `insufficient_balance` (402) zurückgegeben.

## Was gespeichert wird

Der Text wird ausgewertet und verworfen. Er wird nie gespeichert und lässt sich daher später nicht abrufen.

Fileverity speichert das Ergebnis ohne den Text (Einstufung, Scores, Passagen-Offsets und Nutzung) 7 Tage lang, damit die Konsole es anzeigen und die Nutzung abgerechnet und nachvollzogen werden kann. Eine wiederholte Anfrage mit demselben `Idempotency-Key` erhält 24 Stunden lang das gespeicherte Ergebnis. Textprüfungen sind synchron: Sie erscheinen nicht in `GET /analyses` und senden keine Webhook-Ereignisse. Testschlüssel zeichnen nichts auf. Siehe [Datenaufbewahrung und Sicherheit](https://fileverity.com/de/docs/security.md).

## Fehler

| Code | Status | Ursache |
| --- | --- | --- |
| `text_too_short` | 400 | Weniger als 100 Wörter. |
| `text_too_long` | 413 | Mehr als 100.000 Zeichen. Teilen Sie den Text auf mehrere Anfragen auf. |
| `unsupported_language` | 400 | Die Sprache wird nicht unterstützt oder konnte nicht erkannt werden. |
| `unsupported_media_type` | 415 | Der Anfragetext wird nicht als `application/json` gesendet. |
| `invalid_json` | 400 | Der Anfragetext ist kein JSON-Objekt. |
| `missing_parameter` | 400 | Das Feld `text` fehlt. |
| `invalid_parameter` | 400 | Ein Feld hat den falschen Typ, ein unbekanntes Feld wurde gesendet oder der `Idempotency-Key` ist ungültig. |
| `model_not_found` | 404 | Das `model` ist unbekannt. |
| `insufficient_balance` | 402 | Das Guthaben reicht für die Anfrage nicht aus. |
| `spend_limit_reached` | 402 | Der Schlüssel hat sein monatliches Ausgabenlimit erreicht. |
| `idempotency_mismatch`, `idempotency_in_progress` | 409 | Der `Idempotency-Key` wurde mit einem anderen Anfragetext verwendet, oder seine erste Anfrage läuft noch. |
| `service_unavailable`, `analysis_failed` | 503, 502 | Der Dienst für die Textprüfung ist vorübergehend nicht verfügbar oder ausgelastet. Es wird nichts berechnet; versuchen Sie es erneut. Bei `service_unavailable` enthält die Antwort den Header `retry-after`. |

> **Hinweis.** Senden Sie einen `Idempotency-Key`, damit ein erneuter Versuch nach einem Timeout nicht doppelt berechnet wird. Siehe [Idempotenz](https://fileverity.com/de/docs/idempotency.md).

