API Console - Interaktive Dokumentation
POST /api/person

Prüfung einer Privatpersonen-Identität gegen die FR-Personendatenbank. Score 0-100 pro Feld + aggregierter Gesamtscore.

database
Datenbasis+300M FR-Personendatensätze (Multi-Quellen)
speed
LatenzSynchrone Echtzeit-Antwort im JSON-Format
warning
Mehrdeutiger FallScore auf 50 begrenzt bei Namensgleichheit

Erforderliche Header

HeaderWertPflichtfeldBeschreibung
X-API-Keyvkey-...jaAuthentifizierungsschlüssel des Kontos (sonst HTTP 401 missing_api_key)
Content-Typeapplication/jsonjaTyp des Anfrage-Body (JSON). Der Body wird unabhängig vom Wert als JSON geparst.

Body

FeldTypPflichtfeldBeschreibung
referencestringneinKundenkennung, unverändert zurückgegeben
person.first_namestringjaVorname
person.last_namestringjaNachname
person.genderM | FneinAnrede
person.birth_datestringnein*Striktes ISO-8601-Format YYYY-MM-DD (sonst HTTP 400 invalid_birth_date)
person.address.streetstringnein*Straße + Hausnummer
person.address.citystringnein*Stadt
person.address.postal_codestringnein*5 Ziffern (automatisches Null-Padding)
person.emailstringnein*E-Mail (Formatvalidierung)
person.mobilestringnein*FR-Mobilnummer strict (sonst HTTP 400 invalid_mobile)
person.landlinestringnein*FR-Festnetz strict (sonst HTTP 400 invalid_landline)
person.phonestringnein*FR-Telefon (automatische Erkennung mobil/Festnetz). Gibt matches.phone.resolved_as = mobile | landline zurück
match_ruleobjectneinOptionale boolesche Regel: Baum {"and":[...]} / {"or":[...]} über die Felder (+ Alias address = street UND city UND postal_code). Gibt rule.passed zurück. Fehlerhaft -> HTTP 400 invalid_match_rule.
min_scoreintegerneinSchwellenwert 1-100 (Standard 50): ein Feld gilt als erfüllt, wenn sein Score ≥ min_score. Nur mit match_rule berücksichtigt. Außerhalb des Bereichs -> HTTP 400 invalid_min_score.

* Mindestens ein unterscheidendes Kriterium neben first_name + last_name erforderlich: birth_date, email, mobile, landline, phone oder vollständige Adresse (address.street + address.city + address.postal_code). Sonst HTTP 400 insufficient_data.

Die Felder email, mobile, landline und phone akzeptieren den Klartextwert ODER seinen MD5- (32 Hex) / SHA256-Hash (64 Hex), automatisch erkannt. Der Hash wird auf der kanonischen Form berechnet (E-Mail in Kleinbuchstaben; französische nationale Rufnummer mit 10 Ziffern). Ein gehashtes Feld gibt nur match oder no_match zurück.

Antwort 200

FeldTypBeschreibung
transaction_idstringEindeutige Transaktions-ID
referencestring | nullVom Kunden übermittelte Referenz (Passthrough)
scorenumber | nullGesamtscore 0-100 (Durchschnitt der Felder mit Status match / partial / no_match). Status missing und not_searched werden nicht einbezogen. Auf 50 begrenzt wenn ambiguous=true.
ambiguousbooleantrue wenn mehrere unterschiedliche Profile die übermittelten Kriterien erfüllen (Namensgleichheit mit gleicher Adresse aber abweichenden Kontaktdaten). Der Kunde muss mehr Kontaktinformationen angeben (E-Mail, Mobil, Geburtsdatum), um die Mehrdeutigkeit aufzulösen.
matches[field].statusenummatch, partial, no_match, not_searched, missing
matches[field].scorenumber | nullScore 0-100 für dieses Feld (null wenn missing oder not_searched)
timing_msnumberVerarbeitungsdauer serverseitig
ruleobjectNur vorhanden, wenn match_rule angegeben ist: {passed, min_score} (Regelergebnis; ändert weder matches noch score).

Beispiel

curl -X POST https://verify.zecible.fr/api/person \
  -H 'X-API-Key: vkey-...' \
  -H 'Content-Type: application/json' \
  -d '{
    "reference": "tx-001",
    "person": {
      "first_name": "Jean",
      "last_name": "Dupont",
      "birth_date": "1980-05-15"
    }
  }'
const r = await fetch('https://verify.zecible.fr/api/person', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.VERIFY_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    reference: 'tx-001',
    person: { first_name: 'Jean', last_name: 'Dupont', birth_date: '1980-05-15' }
  })
});
const data = await r.json();
console.log(data.score, data.matches);
import requests, os
r = requests.post(
    'https://verify.zecible.fr/api/person',
    headers={'X-API-Key': os.environ['VERIFY_KEY']},
    json={
        'reference': 'tx-001',
        'person': {'first_name': 'Jean', 'last_name': 'Dupont', 'birth_date': '1980-05-15'}
    }
)
print(r.json()['score'])
<?php
$ch = curl_init('https://verify.zecible.fr/api/person');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'X-API-Key: ' . getenv('VERIFY_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'reference' => 'tx-001',
        'person'    => ['first_name' => 'Jean', 'last_name' => 'Dupont', 'birth_date' => '1980-05-15'],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data['score'];
wird unverändert in der Antwort zurückgegebentag
Vorname (Umlaute/Akzente akzeptiert)person
Nachname (Umlaute/Akzente akzeptiert)badge
M männlich / F weiblichwc
ISO 8601 strict (z.B. 1980-05-15)cake
Straße + Hausnummersignpost
normalisierte BAN-Ortsbezeichnunglocation_city
5 Ziffern (Null-Padding auto wenn < 5)markunread_mailbox
RFC-5321-Format (eine E-Mail)alternate_email
FR 10 Ziffern - auto mobil/Festnetz (gibt resolved_as zurück)phone_iphone
FR 10 Ziffern Mobil strict (06/07)smartphone
FR 10 Ziffern Festnetz strict (01-05, 09)call
JSON-Baum {and|or:[...]} über die Felder
Schwellenwert 1-100 (Standard 50)speed

infoFiktive Demodaten (keine echten Identitäten).

Antwort
Formular absenden, um die JSON-Antwort anzuzeigen.
POST /api/business BETA

Prüfung eines FR-Unternehmens (KYB) gegen die B2B-Datenbank: SIRET, Firmenname, Kontakte, Führungskräfte. Score 0-100 pro Feld.

database
Datenbasis+50M FR-Unternehmens-Datensätze
speed
LatenzSynchrone Echtzeit-Antwort im JSON-Format
manage_accounts
FührungskräfteBis zu 10 pro Anfrage, unabhängiges Best-Match
warning
Mehrdeutiger FallScore auf 50 begrenzt bei mehreren SIRET

Erforderliche Header

HeaderWertPflichtfeldBeschreibung
X-API-Keyvkey-...jaAuthentifizierungsschlüssel des Kontos (sonst HTTP 401 missing_api_key)
Content-Typeapplication/jsonjaTyp des Anfrage-Body (JSON). Der Body wird unabhängig vom Wert als JSON geparst.

Body

FeldTypPflichtfeldBeschreibung
referencestringneinKundenkennung, unverändert zurückgegeben
business.siretstringnein*14 Ziffern (Betriebsstätte)
business.sirenstringnein*9 Ziffern (juristische Einheit)
business.vat_intracomstringneinUSt-IdNr. (aus SIREN abgeleitet, per Schlüssel verifiziert)
business.namestringnein*Firmenname
business.legal_formstringneinRechtsform (SAS, SARL, EURL...)
business.nafstringneinNAF/APE-Code (z.B. 7311Z)
business.address.streetstringneinStraße + Hausnummer
business.address.citystringneinStadt
business.address.postal_codestringnein5 Ziffern
business.emailstringneinKontakt-E-Mail
business.mobilestringneinFR-Mobilnummer strict (sonst HTTP 400 invalid_mobile)
business.landlinestringneinFR-Festnetz strict (sonst HTTP 400 invalid_landline)
business.phonestringneinFR-Telefon (automatische Erkennung mobil/Festnetz). Gibt matches.business.phone.resolved_as = mobile | landline zurück
business.websitestringneinWebsite-URL
executives[N].first_namestringneinVorname der Führungskraft oder des Kontakts
executives[N].last_namestringneinNachname der Führungskraft oder des Kontakts
executives[N].rolestringneinFunktion (Vorsitzender, Geschäftsführer, Direktor, usw.)

* Mindestens eines von: business.siret, business.siren oder business.name + (business.address.city ODER business.address.postal_code). executives[]: bis zu 10 Einträge pro Anfrage (sonst HTTP 400 too_many_executives). Unabhängiges Best-Match-Scoring für jeden Eintrag gegen alle Kontakte des SIRET des gematchten Unternehmens (max. 100 Kontakte/SIRET). Bei ambiguous=true bleibt der Pool auf Level 1 der Pipeline beschränkt.

Die Felder siren, email, mobile, landline und phone akzeptieren den Klartextwert ODER seinen MD5- (32 Hex) / SHA256-Hash (64 Hex), automatisch erkannt (siren: 9 reine Ziffern). Ein gehashtes Feld gibt nur match oder no_match zurück.

Antwort 200

FeldTypBeschreibung
transaction_idstringEindeutige Transaktions-ID
referencestring | nullVom Kunden übermittelte Referenz (Passthrough)
scorenumber | nullGesamtscore 0-100 (Durchschnitt der Felder mit Status match / partial / no_match). Status missing und not_searched werden nicht einbezogen. Auf 50 begrenzt wenn ambiguous=true.
ambiguousbooleantrue wenn mehrere unterschiedliche Unternehmen die übermittelten Kriterien erfüllen (Betriebsstätten desselben Konzerns oder Namensgleichheit mit gleicher Adresse aber abweichenden Kontaktdaten). Der Kunde muss SIRET oder einen eindeutigen Kontakt (E-Mail, Telefon, Website) angeben, um die Mehrdeutigkeit aufzulösen.
matches.business.<field>.statusenummatch, partial, no_match, not_searched, missing
matches.business.<field>.scorenumber | nullScore 0-100 des Feldes (null wenn missing oder not_searched)
matches.executivesarrayImmer vorhanden (leer wenn keine Führungskräfte im Input). Reihenfolge beibehalten = Input-Reihenfolge.
matches.executives[N].<field>objectStatus + Score pro Feld für jede Führungskraft im Input (unabhängiges Best-Match, gleiche Enum wie business)
timing_msnumberVerarbeitungsdauer serverseitig

Beispiel

curl -X POST https://verify.zecible.fr/api/business \
  -H 'X-API-Key: vkey-...' \
  -H 'Content-Type: application/json' \
  -d '{
    "reference": "tx-biz-001",
    "business": {
      "siret": "00000000000000",
      "name": "ACME SAS",
      "legal_form": "SAS"
    },
    "executives": [
      { "first_name": "Jean", "last_name": "DUPONT", "role": "président" }
    ]
  }'
const r = await fetch('https://verify.zecible.fr/api/business', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.VERIFY_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    reference: 'tx-biz-001',
    business: { siret: '00000000000000', name: 'ACME SAS' },
    executives: [{ first_name: 'Jean', last_name: 'DUPONT' }]
  })
});
console.log((await r.json()).score);
import requests, os
r = requests.post(
    'https://verify.zecible.fr/api/business',
    headers={'X-API-Key': os.environ['VERIFY_KEY']},
    json={
        'reference': 'tx-biz-001',
        'business': {'siret': '00000000000000', 'name': 'ACME SAS'},
        'executives': [{'first_name': 'Jean', 'last_name': 'DUPONT'}]
    }
)
print(r.json()['score'])
<?php
$ch = curl_init('https://verify.zecible.fr/api/business');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'X-API-Key: ' . getenv('VERIFY_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'reference'  => 'tx-biz-001',
        'business'   => ['siret' => '00000000000000', 'name' => 'ACME SAS'],
        'executives' => [['first_name' => 'Jean', 'last_name' => 'DUPONT']],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data['score'];
wird unverändert in der Antwort zurückgegebentag
14 Ziffern (Leerzeichen toleriert)fingerprint
9 Ziffern (juristische Einheit)fingerprint
FR + 11 Ziffern (aus SIREN berechnet)payments
Firmen- oder Handelsname (Fuzzy)storefront
SAS, SARL, EURL, SA, SCI...gavel
4 Ziffern + 1 Buchstabe (z.B. 7311Z)category
z.B. 12 rue de la Paixsignpost
Ort der Betriebsstättelocation_city
5 Ziffernmarkunread_mailbox
Kontakt-E-Mail (RFC 5321)alternate_email
FR 10 Ziffern (auto mobil/Festnetz)call
Vollständige URL (inkl. https://)language
FR 10 Ziffern Mobil strict (06/07)smartphone
FR 10 Ziffern Festnetz strict (01-05, 09)call
Vorname (Umlaute/Akzente OK)person
Nachname (Umlaute/Akzente OK)badge
Vorsitzender, Geschäftsführer, Direktor (Fuzzy)work

infoFiktive Demodaten (keine echten Identitäten).

Antwort
Formular absenden, um die JSON-Antwort anzuzeigen.
GET /api/usage

Nutzungsreporting: Anzahl der Anfragen + Aufschlüsselung nach abrechenbarem Produkt + Gesamtbetrag netto.

person
ScopeAPI-Nutzer des Callers (aktueller Schlüssel)
date_range
StandardzeitraumAktueller Monat (1. - letzter Tag)
euro
WährungEUR netto, realer Anteil pro Produkt

Erforderliche Header

HeaderWertPflichtfeldBeschreibung
X-API-Keyvkey-...jaAuthentifizierungsschlüssel des Kontos (sonst HTTP 401 missing_api_key)

Query-Parameter

ParameterTypPflichtfeldBeschreibung
startstringneinStartdatum YYYY-MM-DD (Standard: erster Tag des aktuellen Monats)
stopstringneinEnddatum YYYY-MM-DD (Standard: letzter Tag des aktuellen Monats)

Antwort 200

FeldTypBeschreibung
periodobject{ start, stop } - tatsächlich abgefragter Zeitraum
requestsnumberGesamtanzahl der Anfragen
succeedednumberAnfragen mit mindestens einem abrechenbaren Produkt
failednumberAnfragen ohne abrechenbares Produkt
total_pretaxnumberGesamtbetrag netto EUR im Zeitraum
currencystringWährungscode (EUR)
products[]arrayAufschlüsselung nach Produkt (key, label, count, cpm_pretax, total_pretax)

Beispiel

curl 'https://verify.zecible.fr/api/usage?start=2026-05-01&stop=2026-05-31' \
  -H 'X-API-Key: vkey-...'
YYYY-MM-DD - Standard: erster Tag des aktuellen Monatsevent_available
YYYY-MM-DD - Standard: letzter Tag des aktuellen Monatsevent_busy

infoFiktive Demodaten (keine echten Identitäten).

Antwort
Formular absenden, um die JSON-Antwort anzuzeigen.
429 Rate-Limiting

Globaler Zähler pro API-Schlüssel, festes 1-Minuten-Fenster, gemeinsam für /api/person, /api/business und /api/usage. Standardlimit: 60 Anfragen pro Minute. Pro Konto überschreibbar (Kontakt aufnehmen für Unternehmensbedarf).

Antwort-Header (alle Antworten)

HeaderBeschreibung
X-RateLimit-LimitMaximales Kontingent für das aktuelle Fenster (z.B. 60). 0 = Konto ohne Limit.
X-RateLimit-RemainingVerbleibendes Kontingent nach dieser Anfrage. -1 wenn das Konto kein Limit hat.
X-RateLimit-ResetUnix-UTC-Timestamp des nächsten Resets (Beginn der nächsten Minute). 0 bei Konto ohne Limit.
Retry-AfterNur bei HTTP 429 vorhanden. Anzahl der Sekunden bis zum Fenster-Reset.

HTTP-Antwort 429 (Kontingent überschritten)

FeldBeschreibung
error"rate_limit_exceeded"
messageLesbarer Text mit der Anzahl der Sekunden bis zum nächsten Reset.
limitKontingent des Kontos.
reset_unixUnix-UTC-Timestamp des nächsten Resets.

Empfohlene Strategie

  • X-RateLimit-Remaining bei jeder Antwort auslesen, um clientseitiges Throttling zu antizipieren.
  • Bei HTTP 429 den Retry-After-Wert abwarten, bevor ein erneuter Versuch gestartet wird (exponentielles Backoff unnötig: das Fenster resettet zur genauen Minute).
  • Für Volumen > 60 Anfragen/Min. ein erhöhtes Kontingent anfragen: Kontakt aufnehmen.
  • Der Zähler startet mit der ersten Anfrage jeder UTC-Minute, unabhängig vom aufgerufenen Endpoint.

Beispiel einer 429-Antwort

# HTTP 429 Too Many Requests
# Headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1779994620
Retry-After: 42

# Body
{
  "error":      "rate_limit_exceeded",
  "message":    "Limite de 60 requetes par minute atteinte. Reessayer dans 42s.",
  "limit":      60,
  "reset_unix": 1779994620
}
4XX Fehlercodes

Vollständige Liste der von der API zurückgegebenen Fehlercodes. Einheitliches Antwortformat: {"error": "code_machine", "message": "explication humaine"}. Immer als JSON, Zeichensatz UTF-8.

Authentifizierung (401)

CodeEndpoint(s)Ursache
missing_api_keyalleHeader X-API-Key fehlt oder ist leer.
invalid_api_keyalleUnbekannter oder widerrufener Schlüssel. Genauen Wert prüfen (Groß-/Kleinschreibung beachten) und sicherstellen, dass er einem aktiven Konto entspricht.
account_disabledalleKonto seitens Zecible gelöscht oder deaktiviert. Support für Reaktivierung kontaktieren.
ip_not_allowedalleAnfragende IP nicht in der Whitelist des Kontos. Die abgelehnte IP ist in der Fehlermeldung enthalten. IP über den Support hinzufügen.

HTTP-Methode (405)

CodeEndpoint(s)Ursache
method_not_allowedallePOST erwartet für /api/person und /api/business. GET erwartet für /api/usage.

Body-Validierung (400)

CodeEndpoint(s)Ursache
invalid_bodyperson, businessBody fehlt, JSON fehlerhaft oder Root kein Objekt.
invalid_referenceperson, businessDas Feld reference überschreitet 256 Zeichen. Passthrough-Wert kürzen.
missing_required_fieldspersonperson.first_name und person.last_name sind Pflichtfelder.
missing_required_fieldsbusinessMindestens eines von business.siret, business.siren oder business.name + business.address.city ODER business.address.postal_code.
insufficient_datapersonIdentität übermittelt, aber kein unterscheidendes Kriterium (Geburtsdatum, Telefon, E-Mail oder vollständige Adresse) zur Identifikation eines Ziels.
insufficient_databusinessKeine verwertbare Kombination (SIRET / SIREN / Name + Adresse / Name + Kontakt).
invalid_birth_datepersonperson.birth_date entspricht nicht dem strikten ISO-8601-Format YYYY-MM-DD.
invalid_mobileperson, businessDas Feld mobile muss eine FR-Mobilnummer sein (10 Ziffern, beginnend mit 06 oder 07).
invalid_landlineperson, businessDas Feld landline muss eine FR-Festnetznummer sein (keine Mobilnummer).
invalid_phoneperson, businessDas Feld phone muss eine gültige FR-Telefonnummer sein (10 Ziffern).
invalid_emailperson, businessDas Feld email muss eine gültige E-Mail-Adresse sein.
invalid_genderpersonDas Feld gender muss M oder F sein.
invalid_siretbusinessDas Feld siret muss eine gültige SIRET sein (14 Ziffern, Luhn-Prüfsumme).
invalid_sirenbusinessDas Feld siren muss eine gültige SIREN sein (9 Ziffern, Luhn-Prüfsumme).
too_many_executivesbusinessexecutives[] enthält mehr als 10 Einträge. Anfrage auf 10 Führungskräfte begrenzen oder mehrere Anfragen verketten.

Payload-Größe (413)

CodeEndpoint(s)Ursache
body_too_largeperson, businessAnfrage-Body größer als 32 KB. JSON-Größe reduzieren (z.B. Anzahl der Führungskräfte begrenzen, Textfelder kürzen).

Kontingente (429)

CodeEndpoint(s)Ursache
rate_limit_exceededalleMinutenkontingent erreicht. Siehe Abschnitt Rate-Limiting für die Retry-Strategie und die Header X-RateLimit-*.

Credits / Budget (402)

CodeEndpoint(s)Ursache
quota_exceededperson, businessPeriodenkreditlimit erreicht (monatliches Budget oder erschöpfbares Guthaben des Kontos). Die Header X-Credit-Limit / X-Credit-Used / X-Credit-Remaining (EUR netto) zeigen das restriktivste Budget an. Support für Erhöhung des Limits kontaktieren.

Antwortformat

# HTTP 4xx
# Content-Type: application/json; charset=UTF-8

{
  "error":   "invalid_birth_date",
  "message": "person.birth_date doit etre au format ISO 8601 (YYYY-MM-DD)."
}

Das Feld error ist stabil und für die programmatische Verarbeitung bestimmt. Das Feld message ist für die Anzeige vorgesehen und kann sich zwischen Versionen ändern.