> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Südafrika – Kontoinhaberverifizierung API

> Südafrika-Kontoinhaberprüfung über Didit: maßgebliche Datenbankabfrage. Pay-per-Call ab $0.40, keine Verträge, keine Mindestabnahme.

Bestätigt, dass ein südafrikanisches Bankkonto dem angegebenen Kontoinhaber gehört, über den bankübergreifenden Dienst Account Holder Verification. Didit stellt diesen Dienst über `POST /v3/database-validation/` bereit, damit Sie die übermittelten Daten mit der maßgeblichen Quelle abgleichen und normalisierte Abgleichsergebnisse erhalten.

## Abdeckung

* **Abdeckung:** —
* **Land:** Südafrika
* **Service-ID:** `zaf_bank_account_holder`
* **Datenbereich:** Finanzen
* **Kategorie:** Bankwesen

## Eingaben

| Feld | Pflichtfeld | Beispiel |
| - | -: | - |
| `national_id` | Ja | `8708150847085` |
| `bank_account_number` | Ja | `1234567890` |
| `bank_name` | Ja | `ABSA` |
| `account_type` | Nein | `current` |
| `first_name` | Nein | `John` |
| `last_name` | Nein | `Doe` |
| `initials` | Nein | `JD` |
| `email` | Nein | `john.doe@example.com` |
| `phone_number` | Nein | `+15550101000` |
| `vendor_data` | Nein | `user-1234` |

* **Pflichteingaben:** `national_id`, `bank_account_number`, `bank_name`
* **Optionale Eingaben:** `account_type`, `first_name`, `last_name`, `initials`, `email`, `phone_number`, `vendor_data`
* **Einwilligung:** Erforderlich
* **Verfügbarkeit im Workflow:** Im Workflow mit Feldzuordnung verfügbar
* **Abdeckung:** —
* **Preis:** \$0.40 pro erfolgreiche Abfrage

Im Workflow werden `bank_account_number` und `bank_name` nicht auf einem Ausweisdokument abgedruckt, daher liefert kein Schritt diese Werte allein. Erfassen Sie sie über eine Antwort im Fragebogen, ein Extraktionsfeld von Document AI oder einen Wert, den Sie beim Erstellen der Sitzung übermitteln, und ordnen Sie jeden davon im Schritt Datenbankvalidierung zu. Solange sie nicht zugeordnet sind, zeigt der Workflow-Editor diesen Service als deaktiviert an und benennt die fehlende Eingabe. Fehlt zur Laufzeit eine Eingabe, wird die Prüfung vor jeder Abfrage übersprungen, sodass Ihnen nie eine Datenbankabfrage berechnet wird, die nicht hätte durchgeführt werden können.

## Body-Parameter

**issuing\_state** `string` *required* (default: ZAF)

ISO-3166-1-Alpha-3-Ländercode für diesen Datenbankservice.

Beispiel: `ZAF`

**services** `string` *required* (default: zaf\_bank\_account\_holder)

Array mit der ID dieses Service. Durch das Festlegen des Service bleibt die Anfrage auf genau diese Datenbank beschränkt.

Beispiel: `zaf_bank_account_holder`

**consent** `boolean` *required* (default: true)

Ausdrückliche Einwilligung des Endbenutzers für diesen Service.

Beispiel: `true`

**national\_id** `string` *required* (default: 8708150847085)

Nationale Identifikationsnummer für diesen Service.

Beispiel: `8708150847085`

**bank\_account\_number** `string` *required* (default: 1234567890)

Von diesem Datenbankservice benötigter Wert für `bank_account_number`.

Beispiel: `1234567890`

**bank\_name** `string` *required* (default: ABSA)

Von diesem Datenbankservice benötigter Wert für `bank_name`.

Beispiel: `ABSA`

**account\_type** `string` (default: current)

Von diesem Datenbankservice benötigter Wert für `account_type`.

Beispiel: `current`

**first\_name** `string`

Zu validierender Vorname.

Beispiel: `John`

**last\_name** `string` (default: Doe)

Zu validierender Nachname.

Beispiel: `Doe`

**initials** `string` (default: JD)

Von diesem Datenbankservice benötigter Wert für `initials`.

Beispiel: `JD`

**email** `string`

E-Mail-Adresse.

Beispiel: `john.doe@example.com`

**phone\_number** `string`

Von diesem Datenbankservice benötigter Wert für `phone_number`.

Beispiel: `+15550101000`

**vendor\_data** `string` (default: user-1234)

Ihre stabile Benutzerreferenz für diese Person, etwa Ihre interne Benutzer-ID. Didit verwendet sie, um eigenständige Prüfungen demselben Endbenutzer zuzuordnen und das Rauschen bei der Dublettenerkennung zu verringern.

Beispiel: `user-1234`

## Eingaberegeln und Validierungshinweise

* `account_type` muss einer der südafrikanischen AVS-Kontotypen sein: `current`, `savings`, `transmission`, `subscriptionShare`, `notKnown`. Die Groß- und Kleinschreibung wird beim Abgleich nicht berücksichtigt. Lassen Sie das Feld weg, wenn Sie den Kontotyp nicht kennen - Didit sendet dann `notKnown`, und der Abgleich des Kontotyps wird als nicht bestätigt gemeldet, anstatt die Anfrage fehlschlagen zu lassen.

## So rufen Sie es auf

```bash cURL theme={null}
curl -X POST "https://verification.didit.me/v3/database-validation/" \
  -H "x-api-key: YOUR_API_KEY" \
  -F "issuing_state=ZAF" \
  -F "services=zaf_bank_account_holder" \
  -F "vendor_data=user-1234" \
  -F "consent=true" \
  -F "national_id=8708150847085" \
  -F "bank_account_number=1234567890" \
  -F "bank_name=ABSA" \
  -F "account_type=current" \
  -F "last_name=Doe" \
  -F "initials=JD"
```

Jeder erfolgreiche Aufruf gibt HTTP `200` zurück. Das Feld **`outcome_code`** zeigt Ihnen, was tatsächlich passiert ist. So lässt sich etwa ein echter biometrischer Nichtabgleich (`BIOMETRIC_NO_MATCH`) von einem Selfie unterscheiden, das nicht gelesen werden konnte (`BIOMETRIC_IMAGE_UNUSABLE`). Der angezeigte `status` ist der Standardstatus der Funktion. Ihre konfigurierten [Aktionen für Teilübereinstimmung / Keine Übereinstimmung](https://docs.didit.me/de/core-technology/database-validation/database-validation-warnings.md) können ihn überschreiben.

**`MATCH`** – Das Register hat die Identität bestätigt, und alle geprüften Felder stimmten überein.

```json 200 OK — MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "Approved",
  "issuing_state": "ZAF",
  "match_type": "full_match",
  "validations": [
    {
      "outcome_code": "MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": true,
        "accepts_debits": true,
        "account_found": true,
        "account_number_length_valid": true,
        "account_open": true,
        "account_type_match": true,
        "id_match": true,
        "identification_number": "SAMPLE-ID-12345",
        "initials_match": true,
        "surname_match": true
      },
      "validation": {
        "full_name": "full_match",
        "identification_number": "full_match"
      }
    }
  ]
}
```

**`PARTIAL_MATCH`** – Die Ausweisnummer wurde gefunden, aber ein oder mehrere persönliche Felder (meist Name oder Geburtsdatum) stimmten nicht vollständig überein.

```json 200 OK — PARTIAL_MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "In Review",
  "issuing_state": "ZAF",
  "match_type": "partial_match",
  "validations": [
    {
      "outcome_code": "PARTIAL_MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": true,
        "accepts_debits": true,
        "account_found": true,
        "account_number_length_valid": false,
        "account_open": true,
        "account_type_match": true,
        "id_match": true,
        "identification_number": "SAMPLE-ID-12345",
        "initials_match": true,
        "surname_match": false
      },
      "validation": {
        "full_name": "partial_match",
        "identification_number": "full_match"
      }
    }
  ]
}
```

**`NO_MATCH`** – Das Register hat für die übermittelten Daten keinen Treffer geliefert.

```json 200 OK — NO_MATCH theme={null}
{
  "request_id": "req_01H…",
  "status": "Declined",
  "issuing_state": "ZAF",
  "match_type": "no_match",
  "validations": [
    {
      "outcome_code": "NO_MATCH",
      "service_id": "zaf_bank_account_holder",
      "service_name": "South Africa - Bank Account Holder Verification",
      "source_data": {
        "accepts_credits": false,
        "accepts_debits": false,
        "account_found": false,
        "account_number_length_valid": false,
        "account_open": false,
        "account_type_match": false,
        "id_match": false,
        "identification_number": "NO_MATCH",
        "initials_match": false,
        "surname_match": false
      },
      "validation": {
        "identification_number": "no_match"
      }
    }
  ]
}
```

## Zurückgegebene Daten

Welche Felder genau in `source_data` erscheinen, hängt davon ab, was das Register zurückgibt. Das generierte Beispiel für `zaf_bank_account_holder` dokumentiert derzeit diese normalisierte Struktur:

* `accepts_credits`
* `accepts_debits`
* `account_found`
* `account_number_length_valid`
* `account_open`
* `account_type_match`
* `id_match`
* `identification_number`
* `initials_match`
* `surname_match`

## Preise & SLAs

Abfragen für South Africa - Bank Account Holder Verification werden nur berechnet, wenn Didit von der Validierungsquelle ein eindeutiges Ergebnis erhält.

* **Preis pro Aufruf:** \$0.40 USD.
* **Abrechnung:** pro erfolgreicher Abfrage. Ihnen wird nichts berechnet, wenn das Register nicht erreichbar ist, wenn Pflichtfelder fehlen oder wenn die Anfrage abgelehnt wird, bevor sie die Quelle erreicht.
* **Latenz:** typischerweise p95 \< 2 s.
* **Verfügbarkeit:** 99.9% pro Quartal auf Seiten von Didit; die Verfügbarkeit nachgelagerter Quellen variiert je nach Land und Datensatz.

## Was ein MATCH bestätigt

Account Holder Verification (AVS) ist eine Reihe von Ja/Nein-Gegenprüfungen und keine Datensatzabfrage. Die Quelle gibt nie einen Namen, eine ID-Nummer oder einen Kontostand zurück. Sie nimmt die übermittelten Daten, vergleicht sie mit dem, was die Bank für dieses Konto gespeichert hat, und beantwortet jeden Vergleich mit einem Flag. `source_data` enthält diese Flags:

* **`account_found`** – Die Bank führt ein Konto mit dieser Nummer. Alles Übrige ist bedeutungslos, wenn dieser Wert `false` ist.
* **`account_open`** – Das Konto ist offen. Ein Konto kann gefunden, aber geschlossen sein.
* **`id_match`** – Das Konto ist der von Ihnen übermittelten nationalen ID zugeordnet. Das ist die Prüfung, für die der Dienst existiert.
* **`initials_match`**, **`surname_match`** – Die übermittelten `initials` und `last_name` stimmen mit dem Kontoinhaber in den Unterlagen überein.
* **`account_type_match`** – Der übermittelte `account_type` entspricht dem tatsächlichen Kontotyp.
* **`email_match`**, **`phone_match`** – Die übermittelten `email` und `phone_number` stimmen mit den Kontaktdaten überein, die die Bank gespeichert hat.
* **`accepts_debits`**, **`accepts_credits`** – Das Konto kann Lastschriftaufträge und Gutschriften annehmen.
* **`account_number_length_valid`** – Die Kontonummer hat die Länge, die die Bank erwartet.

Der Ergebniscode fasst diese Werte zusammen:

* **`MATCH`** – Das Konto existiert und jedes übermittelte Feld stimmt überein, einschließlich `id_match`.
* **`PARTIAL_MATCH`** – Das Konto gehört der übermittelten nationalen ID, aber mindestens ein anderes übermitteltes Feld stimmt nicht überein (zum Beispiel ein Nachname, der in den Unterlagen der Bank anders geschrieben ist). `outcome_detail` nennt die Felder, die nicht übereinstimmen.
* **`NO_MATCH`** – Entweder führt die Bank kein solches Konto, oder das Konto existiert, gehört aber einer anderen Person. Beides sind eindeutige Antworten zur Person.

Eine Gegenprüfung, die Sie nicht angefordert haben, wird weder gezählt noch gemeldet. AVS antwortet mit `N` für jedes Feld, das nicht übermittelt wurde. Deshalb erscheinen `surname_match`, `initials_match`, `email_match`, `phone_match` und `account_type_match` in `source_data` nur, wenn Sie die entsprechende Eingabe gesendet haben. Wenn Sie nur `national_id`, `bank_account_number` und `bank_name` senden, ergibt sich dennoch ein vollständiges `MATCH`.

## Akzeptierte Werte für bank\_name und account\_type

`bank_name` und `account_type` sind Aufzählungen. Ein Wert außerhalb einer der beiden Listen wird abgelehnt, bevor die Abfrage ausgeführt wird. Ein Tippfehler kostet Sie daher einen Hin- und Rückweg, aber keine Gebühr.

`account_type` ist optional und akzeptiert folgende Werte, unabhängig von Groß- und Kleinschreibung:

`current` · `savings` · `transmission` · `subscriptionShare` · `notKnown`

Lassen Sie das Feld weg, wenn Sie den Kontotyp nicht kennen. Didit sendet dann `notKnown`, die Anfrage ist erfolgreich, und `account_type_match` ist `false`, weil es nichts zu vergleichen gab. Jeder andere Wert, etwa `checking`, `cheque` oder `bond`, wird mit einem `400` abgelehnt, der die Liste der akzeptierten Werte auflistet.

`bank_name` ist ein Pflichtfeld. Folgende Werte sind nachweislich akzeptiert (ohne Berücksichtigung von Groß- und Kleinschreibung):

`ABSA` · `Capitec` · `FNB` · `Nedbank` · `Standard Bank` · `Investec` · `African Bank` · `Discovery Bank` · `Old Mutual` · `Bank Zero` · `Tyme` · `Grindrod`

Privatkonten bei all diesen Banken sind im Geltungsbereich enthalten, auch bei Capitec. Verwenden Sie die Kurzform genau so, wie sie aufgelistet ist: `Capitec`, nicht `Capitec Bank`; `Tyme`, nicht `TymeBank`. Eine nicht erkannte Bank liefert als Ergebnis `REGISTRY_ERROR`, dessen `outcome_detail` das Feld nennt, das die Quelle abgelehnt hat.

## Ein fehlendes Konto von einer nicht erreichbaren Quelle unterscheiden

Dies sind unterschiedliche HTTP-Antworten, daher ist kein Parsen von Fehlermeldungen nötig:

* **Das Konto existiert nicht** – `200 OK`, `match_type: "no_match"`, `outcome_code: "NO_MATCH"`, `source_data.account_found: false`. Eine echte Antwort der Bank. Wird berechnet, und Ihre No-Match-Aktion greift.
* **Die Quelle hat nicht geantwortet** – `502 Bad Gateway` mit `validation_errors[].code` = `empty_provider_response` und `retryable: true`. Über die Person wurde nichts festgestellt, es wird nichts berechnet, und die Anfrage kann gefahrlos wiederholt werden.
* **Die Quelle hat die Abfrage nicht ausgeführt** – `400 Bad Request` mit `validation_errors[].code` = `provider_rejected_input` und `retryable: false`. Die Quelle hat nie gesucht, weil sie die übermittelten Eingaben nicht akzeptiert hat. Korrigieren Sie die Daten; ein erneuter Versuch mit denselben Werten kann nicht gelingen. Es wird nichts berechnet.
* **Die Quelle hat geantwortet und Ihre Eingabe abgelehnt** – `502 Bad Gateway` mit `validation_errors[].code` = `provider_invalid_input` (zum Beispiel eine Kontonummer, die das eigene Formatprüfverfahren der Bank nicht besteht). Ein Wiederholungsversuch ist sinnlos, bis die Eingabe korrigiert ist; es wird nichts berechnet.
* **Ihre Anfrage hat Didit nie verlassen** – `400 Bad Request` unter Angabe des zu korrigierenden Feldes. Es wird nichts berechnet.

Nur die erste dieser Antworten ist eine Aussage über die Person. Behandeln Sie einen `502` als vorübergehend. AVS leitet die Anfrage an die Bank des Kontoinhabers weiter, statt ein Register abzufragen, und ist deshalb der langsamste der südafrikanischen Dienste. Wiederholen Sie die Anfrage mit Backoff.

## Weiterlesen

* [Übersicht Datenbankvalidierung Südafrika](https://docs.didit.me/api-reference/database-validation/south-africa.md)
* [Übersicht Datenbankvalidierung](https://docs.didit.me/de/core-technology/database-validation/overview.md)
* [Ergebniscodes](https://docs.didit.me/de/core-technology/database-validation/database-validation-outcome-codes.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.