Bewerbungen in dein ATS ziehen
Lies Mieter-Bewerbungen in dein eigenes Applicant-Tracking-System und schreibe Status-Entscheidungen zurück — innerhalb strikter PII- und Consent-Grenzen.
Dieser Guide zeigt, wie du eingehende Bewerbungen für deine Inserate in dein eigenes ATS liest, das grobe Matching-Signal interpretierst und Status-Entscheidungen nach WOHNO zurückschreibst — alles innerhalb strikter Datenminimierungs-Grenzen.
Welches Problem das löst: Dein Team sichtet Bewerber in einem bestehenden ATS. Du möchtest, dass WOHNO-Bewerbungen dort landen und deine Shortlist-/Annahme-/Absage-Entscheidungen zurückfließen.
Beta / dark-shipped · 🔴 PII-kritisch. Die Applications-API (Plan 59) sitzt hinter einem Doppel-Gate: dem Feature-Flag
APPLICATIONS_API_ENABLED(aus →404) und dem organisationsbezogenen Consentapi_applicant_access_enabled(aus →403 CONSENT_REQUIRED, fail-closed). Beide müssen aktiviert sein, bevor ein Call erfolgreich ist. Die Operationen sindx-internalund nicht in der öffentlichen Referenz. Das Aktivieren des Consents begründet eine Auftragsverarbeitung — stimm dich mit deinem WOHNO-Ansprechpartner und deinem Datenschutzbeauftragten ab.
Voraussetzungen
- Ein Secret Key (
sk_live_…) — Bewerbungen sind sk-only. Einpk_-Key wird mit403 INSUFFICIENT_SCOPEabgelehnt (Bewerber-PII darf niemals einen Browser-Key erreichen). - Scope
applications:read;applications:write, um Status/Tags zu setzen. APPLICATIONS_API_ENABLEDan und der Consentapi_applicant_access_enableddeiner Organisation gesetzt.
Was du erhältst (und was nicht)
Antworten sind das reduzierte ApplicationPublicDto. Per Design (DSGVO-
Datenminimierung) enthält es niemals: Einkommen in €, SCHUFA-Score/-Status,
Bürgennamen, Klar-PII (Name / Adresse / Telefon / E-Mail), Dokument- oder
Dossier-URLs, das Anschreiben, interne Score-Gewichte/-Schwellen oder die
K.-o.-Detailliste.
Eine Re-Identifikation erfolgt nur über applicant_ref — ein org-lokales
Pseudonym — niemals über eine globale User-ID. Jeder Lesezugriff und jeder
Status-Write wird gegen deine api_key_id auditiert.
Schritt 1 — Bewerbungen für ein Inserat auflisten
curl "https://wohno.de/api/v1/listings/9f1c2a3b-1111-2222-3333-444455556666/applications?status=new&page=1&per_page=50" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"Antwort (200, offset-paginiert):
{
"data": [
{
"id": "app_7d8e9f01",
"applicant_ref": "ref_3a2b1c",
"status": "new",
"score": "high",
"tags": [],
"created_at": "2026-06-02T09:15:00.000Z"
}
],
"meta": {
"total": 12,
"page": 1,
"perPage": 50,
"hasMore": false,
"timestamp": "2026-06-04T10:30:00.000Z"
}
}per_page (max. 100) begrenzt die Größe jedes PII-Lesezugriffs. Ein Inserat, das
zu einer anderen Organisation gehört, liefert eine leere Liste, statt seine
Existenz preiszugeben.
Schritt 2 — Den Score interpretieren
score ist ein grobes Band (nicht der interne numerische Score, der nie
offengelegt wird). Behandle ihn als Triage-Hinweis — high / medium / low —
und lege dein eigenes Ranking darüber. Versuche nicht, das zugrunde liegende
Modell zu rekonstruieren; Gewichte, Schwellen und K.-o.-Gründe werden bewusst
zurückgehalten.
Schritt 3 — Eine einzelne Bewerbung lesen
curl "https://wohno.de/api/v1/applications/app_7d8e9f01" \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"Unbekannte oder fremde IDs liefern 404 NOT_FOUND (kein Existenz-Leak).
Schritt 4 — Eine Status-Entscheidung zurückschreiben
Setze eine Entscheidung und/oder Tags. Der Write läuft durch die
Bewerbungs-State-Machine, emittiert application.*-Events und wird auditiert:
curl -X PATCH https://wohno.de/api/v1/applications/app_7d8e9f01 \
-H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "status": "shortlisted", "tags": ["viewing-invited"] }'- Setzbare Status:
shortlisted,accepted,rejectednur.newundwithdrawnkönnen nicht gesetzt werden;withdrawn-Bewerbungen sind read-only. - Ein illegaler Übergang (z. B.
accepted → new) liefert409 INVALID_STATUS_TRANSITION. tagsnutzen Mengen-Semantik (max. 20 Tags, je ≤ 40 Zeichen).- Der Body muss
strictsein und mindestens eine Property enthalten; unbekannte Felder →400 VALIDATION_ERROR.
status: accepted emittiert application.accepted; rejected emittiert
application.rejected. Abonniere diese per
Webhooks, um beide
Systeme konsistent zu halten.
Fehlerbehandlung
| Code | HTTP | Was passiert ist | Lösung |
|---|---|---|---|
CONSENT_REQUIRED | 403 | Org-Consent api_applicant_access_enabled nicht gesetzt | Bewerberdaten-Zugriff in den Einstellungen aktivieren. |
INSUFFICIENT_SCOPE | 403 | pk_-Key oder fehlender Scope | Secret Key mit dem richtigen Scope verwenden. |
NOT_FOUND | 404 | Flag aus, oder Ressource nicht in deiner Org | Flag bestätigen; Besitz prüfen. |
INVALID_STATUS_TRANSITION | 409 | Illegaler Statuswechsel / withdrawn ist read-only | Nur shortlisted/accepted/rejected. |
VALIDATION_ERROR | 400 | Leerer Body, unbekanntes Feld, oder new/withdrawn | Mindestens ein erlaubtes Feld senden. |
Siehe die Konventions-Referenz.
Best Practices
- Speichere das Pseudonym, nicht Klar-PII. Schlüssle deine ATS-Datensätze
über
applicant_ref. - Respektiere den Consent. Wird der Consent widerrufen, scheitern Calls
fail-closed — behandle das
403sauber. - Audit-freundliche Writes. Jeder Statuswechsel wird mit deinem Key geloggt; nutze einen Key pro Integration, damit der Audit-Trail aussagekräftig ist.
Nächste Schritte
- Auf Events mit Webhooks reagieren —
application.*-Events gepusht bekommen. - Authentifizierungs-Guide — Scopes und Secret-Key-Handhabung.
- API-Referenz —
ApplicationPublicDto-Felder.