responsiblo

Für Entwickler

Partner-API

Senden Sie uns einen Kunden unter Ihrer eigenen pseudonymen Kennung - ohne E-Mail, Namen und andere personenbezogene Daten - und lesen Sie jederzeit den Stand seiner Schulung ab. Das dient als Compliance-Check vor einem Vertrag, einer Einzahlung oder einer Auszahlung.

Version 1.3.2 · JSON über HTTPS · OpenAPI

So funktioniert es

Die API ist für alle Partner gleich. In fünf Schritten:

  1. Wir schalten die API für Ihr Unternehmen frei; in Ihrer Administration erstellen Sie im Tab API einen API-Schlüssel.
  2. Soll ein Kunde geschult werden, ruft Ihr System POST /v1/users mit Ihrer Kennung des Kunden auf.
  3. Wir legen ein Profil ohne E-Mail an und geben einen Einstiegslink (entryUrl) zurück; den zeigen Sie dem Kunden als Schaltfläche.
  4. Der Kunde klickt darauf und ist direkt im Kurs.
  5. Den Stand lesen Sie jederzeit über GET /v1/users/{identifier} ab, oder wir melden ihn Ihrem Server per Webhook.

Verantwortlicher für die Kennung sind Sie, wir verarbeiten nur pseudonyme Daten. Senden Sie als Kennung nie eine E-Mail-Adresse oder einen Namen - eine E-Mail-Adresse lehnt die API mit dem Fehler 422 ab.

Adresse und Authentifizierung

Jeder Aufruf geht über HTTPS an die Adresse unten und trägt Ihren API-Schlüssel im Header Authorization.

https://api.responsiblo.com
Authorization: Bearer rsb_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • rsb_live_... öffnet Ihr Produktivprogramm, rsb_test_... Ihr Testprogramm (Sandbox).
  • Der Schlüssel wird nur einmal angezeigt, bei der Erstellung; wir speichern nur seinen Fingerabdruck. Bewahren Sie ihn als Geheimnis auf Ihrem Server auf - nie im Browser oder in einer App.
  • Der Schlüssel hat Berechtigungen: read (Stand und Liste der Personen, Zertifikat) und write (Senden und Anonymisieren von Personen). Er kann auf Ihre IP-Adressen beschränkt sein und eine Gültigkeit haben.
  • Austausch: Sie erstellen einen neuen Schlüssel, der alte gilt noch 7 Tage, dann läuft er ab.
  • Antworten werden nie zwischengespeichert (Cache-Control: no-store) und die API nimmt keine Aufrufe aus dem Browser an (kein CORS).

POST /v1/users

Sendet eine Person in das Programm des Schlüssels (Berechtigung write).

curl -X POST https://api.responsiblo.com/v1/users \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"identifier":"client-48213","language":"cs","label":"campaign-2026-10"}'
FeldPflichtBedeutung
identifier ja Ihr Pseudonym der Person, 1 bis 64 Zeichen A-Z a-z 0-9 . _ : @ -; nie eine E-Mail-Adresse (abgelehnt mit 422).
program nein Code des Programms; wenn Sie ihn angeben, muss es das Programm des Schlüssels sein.
language nein Sprache des Kurses (cs, en, ...); Standard ist die erste Sprache des Programms.
label nein Ihr Label - eine Kohorte oder Kampagne, 1 bis 64 Zeichen, nie personenbezogene Daten.
expiresAt nein Letzter Tag des Zugangs, JJJJ-MM-TT.

201 Created für eine neue Person, 200 OK, wenn die Kennung schon existiert - es ändert sich nichts, der Aufruf kann gefahrlos wiederholt werden. Der Body ist der Stand unten, samt entryUrl. Ein ausgeschöpftes Limit an Personen oder an Lizenzen des Programms gibt 403 zurück.

GET /v1/users/{identifier}

Stand einer Person (Berechtigung read): das, was ein Compliance-Check braucht, nichts darüber hinaus.

curl https://api.responsiblo.com/v1/users/client-48213 -H "Authorization: Bearer $RSB_KEY"

{
  "identifier": "client-48213",
  "program": "your-program",
  "status": "in_progress",
  "progress": 43,
  "lessonsCompleted": 3,
  "lessonsTotal": 7,
  "quizScore": null,
  "label": "campaign-2026-10",
  "createdAt": "2026-10-20T10:02:11Z",
  "startedAt": "2026-10-20T10:05:40Z",
  "completedAt": null,
  "lastActivityAt": "2026-10-20T10:31:40Z",
  "expiresAt": null,
  "certificate": null,
  "entryUrl": "https://your-company.responsiblo.com/entry/..."
}
statusBedeutung
enrolled gesendet, noch nicht eingestiegen
started eingestiegen, noch nichts abgeschlossen
in_progress hat Lektionen abgeschlossen, das Programm noch nicht
completed das Programm ist abgeschlossen (completedAt)
expired der Zugang ist beendet (expiresAt ist verstrichen; eine Person in der Sandbox endet nach 7 Tagen)

quizScore ist das Ergebnis des Abschlussquiz in %, sobald es abgeschlossen ist. Zeiten sind in UTC auf ganze Sekunden. Das Feld certificate trägt das Zertifikat der Person (siehe unten), solange sie keines hat, ist es null.

?include=detail

Fügt den Fortschritt in jedem Kurs und das Ergebnis jedes Quiz hinzu - nie die einzelnen Antworten.

"courses": [{"id": "733db340-...", "name": "Introduction", "progress": 40, "lessonsCompleted": 2, "lessonsTotal": 5, "completed": false}],
"quizzes": [{"id": "d2e72fd7-...", "name": "Quiz of the introduction", "score": 85, "completedAt": "2026-10-20T10:31:40Z"}]

GET /v1/users

Liste der Personen, die Sie in das Programm des Schlüssels gesendet haben (Berechtigung read), seitenweise: jeder Eintrag hat die Form des Stands oben. Optional status (nur Personen in diesem Stand), limit (1 bis 500, Standard 100) und cursor.

curl "https://api.responsiblo.com/v1/users?status=completed&limit=100" -H "Authorization: Bearer $RSB_KEY"

{
  "items": [{ "identifier": "client-48213", "status": "completed", "...": "the state of GET /v1/users/{identifier}" }],
  "nextCursor": "MjAyNi0xMC0yMFQxMDowMjoxMVp8...",
  "limit": 100
}

curl "https://api.responsiblo.com/v1/users?status=completed&limit=100&cursor=MjAyNi0xMC0yMFQxMDowMjoxMVp8..." -H "Authorization: Bearer $RSB_KEY"
  • Fahren Sie mit cursor = nextCursor fort, solange nextCursor nicht null ist; der Cursor ist ein undurchsichtiger Text, setzen Sie ihn nie selbst zusammen.
  • Die Personen kommen nach dem Zeitpunkt des Sendens in einer festen Reihenfolge (auch bei gleichem Zeitpunkt), keine doppelt; anonymisierte Personen sind nicht in der Liste.
  • Mit dem Filter status prüfen wir für eine Seite höchstens 2000 Personen, eine Seite kann daher weniger Einträge als limit haben, auch keinen - fahren Sie fort, solange es einen nextCursor gibt.

Zertifikat der Person

Sobald die Person das Programm abschließt, stellt ihr der Kurs ein Zertifikat aus - unter ihrem Pseudonym (Spitzname des Profils ID XXXXXX), ohne Namen und ohne E-Mail. Nichts wird per E-Mail verschickt; im Stand der Person steht das Feld certificate mit Nummer, Zeiten und öffentlicher Verifizierungsseite, und das PDF laden Sie über GET /v1/users/{identifier}/certificate herunter.

"certificate": {
  "number": "RSP-7KQ2-M4XH-9TWB",
  "issuedAt": "2026-10-20T10:39:15Z",
  "expiresAt": "2028-10-20T10:39:12Z",
  "verifyUrl": "https://responsiblo.com/verify/RSP-7KQ2-M4XH-9TWB"
}

curl https://api.responsiblo.com/v1/users/client-48213/certificate -H "Authorization: Bearer $RSB_KEY" -o client-48213.pdf
  • Die Verifizierungsseite verifyUrl zeigt nur Pseudonym, Programm, Partner und Gültigkeit - nie Ihre Kennung.
  • Das PDF gibt application/pdf zurück (Berechtigung read). Ohne Zertifikat lautet die Antwort 404 certificateNotFound, während das PDF noch erstellt wird, 404 certificatePdfNotReady mit Retry-After.
  • Ein widerrufenes Zertifikat wird nie ausgegeben (das Feld certificate ist dann null, das PDF 404); ein Zertifikat mit abgelaufener Gültigkeit bleibt ein wahrer Nachweis und wird ausgegeben.
  • Ein Webhook meldet das Zertifikat mit dem Ereignis certificate.issued (direkt nach user.completed).

DELETE /v1/users/{identifier}

Anonymisiert eine Person (Berechtigung write): aus dem Profil verschwinden Ihre Kennung, das Label und jede Webhook-Nachricht, die sie nennt; die Einstiegslinks verlieren ihre Gültigkeit. Zertifikat und Ergebnis des Kurses bleiben unter der Nummer des Zertifikats - als Compliance-Nachweis.

curl -X DELETE https://api.responsiblo.com/v1/users/client-48213 -H "Authorization: Bearer $RSB_KEY"

HTTP/1.1 204 No Content

Antwort 204 ohne Body; jeder weitere Aufruf mit derselben Kennung gibt 404 userNotFound zurück, eine Wiederholung ist also gefahrlos. Dieselbe Kennung können Sie danach erneut als neue Person senden.

Einstiegslink

Zeigen Sie entryUrl der Person (eine Schaltfläche Kurs starten in Ihrem System). Er meldet sie im Kurs an - ohne E-Mail und ohne Passwort.

Der Link gilt 30 Tage und kann mehrfach verwendet werden; jeder Aufruf GET /v1/users/{identifier} gibt einen neuen zurück. Senden Sie ihn nie an jemand anderen: Wer den Link hat, steigt als diese Person ein.

Webhooks

Im Tab API Ihrer Administration richten Sie für jedes Programm einen Webhook ein: eine öffentliche HTTPS-Adresse Ihres Servers und die Ereignisse. Danach senden wir Ihnen POST mit JSON - nur Kennungen und Stände, nie den Einstiegslink.

EreignisWann
user.enrolled die Person wurde gesendet (das erste Mal, dass Ihr Webhook sie kennt)
user.started die Person ist in den Kurs eingestiegen
user.completed die Person hat das Programm abgeschlossen
certificate.issued die Person hat ein Zertifikat erhalten; data tragen certificate (Nummer, Zeiten, verifyUrl)
user.expired der Zugang der Person ist beendet
POST https://your-server.example/responsiblo/webhook
Content-Type: application/json
X-Responsiblo-Event: user.completed
X-Responsiblo-Delivery: 5b0c1f9e-2d1a-4a57-9a3e-0d6c9c1f2b77
X-Responsiblo-Signature: t=1792492800,v1=3f1c...e9

{
  "id": "5b0c1f9e-2d1a-4a57-9a3e-0d6c9c1f2b77",
  "type": "user.completed",
  "createdAt": "2026-10-20T10:40:00Z",
  "apiVersion": "1.3.2",
  "program": "your-program",
  "data": {
    "identifier": "client-48213",
    "status": "completed",
    "progress": 100,
    "lessonsCompleted": 7,
    "lessonsTotal": 7,
    "quizScore": 85,
    "label": "campaign-2026-10",
    "startedAt": "2026-10-20T10:05:40Z",
    "completedAt": "2026-10-20T10:39:12Z",
    "expiresAt": null
  }
}

Signatur

Jede Nachricht trägt den Header X-Responsiblo-Signature: t=<Unix-Zeit>,v1=<HMAC-SHA256 des Texts t.Body mit dem Geheimnis des Webhooks, hex>. Das Geheimnis (whsec_...) wird einmal bei der Erstellung des Webhooks angezeigt. Bevor Sie einer Nachricht vertrauen, prüfen Sie die Signatur und das Alter von t; als Idempotenzschlüssel verwenden Sie X-Responsiblo-Delivery.

// PHP: $secret = "whsec_...", $header = X-Responsiblo-Signature, $body = the raw body
preg_match('/^t=(\d+),v1=([0-9a-f]{64})$/', $header, $m);
$valid = $m
    && abs(time() - (int) $m[1]) <= 300
    && hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, $secret), $m[2]);

Zustellung und Wiederholung

Zugestellt = Antwort 2xx innerhalb von 10 Sekunden. Sonst versuchen wir es erneut nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden und 12 Stunden, dann geben wir auf. Weiterleitungen folgen wir nicht.

20 nicht zugestellte Nachrichten in Folge schalten den Webhook ab, bis Sie ihn wieder einschalten; die Nachrichten aus dieser Zeit warten. Die Schaltfläche Test sendet einen ping; das Zustellprotokoll finden Sie in Ihrer Administration.

Das Ereignis certificate.issued fügen Sie einem Webhook in seinen Einstellungen hinzu; ein Webhook, der vor Version 1.2 angelegt wurde, erhält es nicht von selbst.

Fehler

Jeder Fehler hat eine Form: status, code, reason und message; ein Fehler 422 fügt errors hinzu (Feld - was falsch ist).

{ "status": "error", "code": 422, "reason": "invalidBody", "message": "The body is not valid.",
  "errors": { "identifier": "identifier must be a pseudonym of the partner, never an e-mail address" } }
HTTPreasonWas tun
400 invalidJson senden Sie ein einziges JSON-Objekt
401 missingToken, invalidToken senden Sie einen gültigen Schlüssel (ein widerrufener und ein abgelaufener Schlüssel sehen gleich aus); der Header WWW-Authenticate sagt Bearer
403 scopeDenied, ipNotAllowed, apiDisabled, partnerInactive, spaceUnavailable, httpsRequired, userLimitReached, seatsExhausted der Schlüssel darf das nicht, die API ist für Ihr Unternehmen ausgeschaltet, oder das Programm ist voll
404 userNotFound, notFound im Programm des Schlüssels gibt es keine Person mit dieser Kennung (auch keine anonymisierte)
404 certificateNotFound, certificatePdfNotReady die Person hat noch kein Zertifikat, oder sein PDF wird erstellt - versuchen Sie es nach Retry-After erneut
409 identifierTaken die Kennung gehört einer Person eines anderen Programms
422 invalidBody, invalidParameter siehe errors (Feld des Bodys oder Parameter der Abfrage - was falsch ist)
429 rateLimited warten Sie Retry-After Sekunden
500 internalError versuchen Sie es später; nennen Sie unserem Support die incidentId

Für Programme und Agenten

  • Entscheiden Sie nach code und reason, nie nach dem Text von message; errors ist ein Objekt Feld -> was falsch ist.
  • Wiederholen Sie nur 429, 500 und certificatePdfNotReady, und zwar nach Retry-After Sekunden (sonst mit wachsendem Abstand); 4xx außer 429 wiederholen Sie nicht ohne Korrektur des Aufrufs.
  • POST /v1/users ist idempotent nach identifier (201 beim ersten Mal, dann 200); DELETE gibt beim ersten Mal 204 und danach 404 zurück - beides kann gefahrlos wiederholt werden.
  • Deduplizieren Sie Webhooks nach X-Responsiblo-Delivery; die Reihenfolge der Nachrichten ist nicht garantiert, entscheidend ist der Stand in data.

Kreditbegleiter

Der Kreditbegleiter ist ein kurzer Kurs für die antragstellende Person bei einem Kreditgeber: Vor der Unterzeichnung des Vertrags durchläuft sie drei Lektionen, acht praktische Situationen und gegebenenfalls ein Quiz, alles mit den Zahlen ihres eigenen Angebots, und bestätigt am Ende das Angebot. Auf jedem Bildschirm kann sie um eine Erklärung bitten. Das Angebot senden Sie über die API, Sie erhalten einen Einstiegslink und das Ergebnis meldet Ihnen ein Webhook.

Den Kreditbegleiter aktivieren wir nach Absprache mit Ihnen.

Die antragstellende Person ist auch hier nur Ihr pseudonymes Profil aus POST /v1/users. Das Angebot bestimmen Ihre Referenzen (externalApplicationId, offerReference) und die Dokumente nur ein Link mit einem SHA-256-Fingerabdruck - nie ein Name, eine E-Mail, eine Geburtsnummer, eine Kontonummer oder eine Telefonnummer. responsiblo genehmigt keinen Kredit, lädt keine Dokumente herunter und speichert keine, prüft keine Identität und stellt zum Kreditbegleiter kein Zertifikat aus.

  1. Sie legen das Profil der antragstellenden Person an: POST /v1/users mit Ihrem Pseudonym.
  2. Sie senden das Angebot: POST /v1/users/{identifier}/loan-offers; die Antwort 201 trägt entryUrl.
  3. entryUrl übergeben Sie der antragstellenden Person über Ihren eigenen verifizierten Kanal. Der Link gilt 30 Tage und kann mehrfach verwendet werden; der Kreditbegleiter zeigt die Zahlen ihres Angebots.
  4. Das Ende erfahren Sie per Webhook (loanGuide.completed, loanGuide.assistanceRequested und weitere).
  5. Den Stand lesen Sie über GET …/loan-offers/{offerReference}, den Nachweis für Ihre Akte über GET …/evidence. Geändertes Angebot = neues Angebot mit supersedes, zurückgezogener Antrag = POST …/cancel.

Bis zur Aktivierung antworten die Operationen des Kreditbegleiters mit 404 notFound oder 409 loanGuideNotConfigured. Die Berechtigung write sendet und storniert ein Angebot, read liest Stand und Nachweis.

POST /v1/users/{identifier}/loan-offers

Sendet ein Angebot zum Profil der antragstellenden Person (Berechtigung write). Der optionale Header Idempotency-Key hat 1 bis 255 sichtbare ASCII-Zeichen. Beispiel: Kredit über 10.000 CZK, zu zahlen 10.800 CZK in einer Zahlung 30 Tage nach der Auszahlung, effektiver Jahreszins 155,10 %.

curl -X POST https://api.responsiblo.com/v1/users/applicant-30417/loan-offers \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: offer-30417-1" \
  -d '{
  "externalApplicationId": "APP-30417",
  "offerReference": "OFF-30417-1",
  "locale": "cs-CZ",
  "currency": "CZK",
  "principalMinor": 1000000,
  "disbursedAmountMinor": 1000000,
  "totalPayableMinor": 1080000,
  "aprPercent": "155.10",
  "interestRate": { "percent": "8", "period": "month" },
  "repayment": {
    "type": "singlePayment",
    "amountMinor": 1080000,
    "due": { "kind": "relative", "days": 30, "anchor": "disbursement" }
  },
  "documents": [
    { "role": "precontract_information", "reference": "DOC-PRE-30417", "title": "Předsmluvní informace",
      "url": "https://documents.lender.example/pre/30417.pdf",
      "sha256": "623f4a37e444268c076896d6c2f389b46f568d1a26539b013f2ba25d03846f72" },
    { "role": "contract_package", "reference": "DOC-CON-30417", "title": "Smlouva a podmínky",
      "url": "https://documents.lender.example/contract/30417.pdf",
      "sha256": "9c7bfe0077d1189914f0e1c483c961f4c5b36e9892385f3d2ab6168e0c088aa6" }
  ],
  "validUntil": "2026-11-15T18:00:00Z"
}'

HTTP/1.1 201 Created

{
  "offerReference": "OFF-30417-1",
  "externalApplicationId": "APP-30417",
  "offerStatus": "active",
  "guideStatus": "created",
  "validUntil": "2026-11-15T18:00:00Z",
  "snapshotSha256": "8055bfa3c5f2c163691b85785eaf61221169a123bed67aff2c1dbaf2a8e44e7e",
  "entryUrl": "https://your-company.responsiblo.com/entry/...",
  "createdAt": "2026-11-10T09:14:05Z"
}
FeldPflichtBedeutung
externalApplicationId ja Ihre Antragsnummer, 1 bis 128 Zeichen A-Z a-z 0-9 . _ : -; nie eine E-Mail-Adresse.
offerReference ja Ihre Referenz des Angebots, dieselben Regeln wie externalApplicationId.
locale ja Sprache und Land des Kreditbegleiters: cs-CZ.
currency ja Währung: CZK.
principalMinor ja Kreditbetrag in Heller, ganze Zahl von 1 bis 10.000.000.000.
disbursedAmountMinor ja Ausgezahlter Betrag in Heller; muss dem Kreditbetrag entsprechen.
totalPayableMinor ja Zu zahlender Gesamtbetrag in Heller; mindestens der Kreditbetrag und genau die Summe der Zahlungen.
aprPercent ja Effektiver Jahreszins in Prozent als Text ("155.10"), von Ihnen berechnet und garantiert. Positive Kosten mit einem effektiven Jahreszins von 0 lehnt die API ab.
interestRate nein Zinssatz {percent, period}, period = year, month oder day.
repayment ja Rückzahlung: singlePayment {amountMinor, due} mit Datum (kind date) oder Anzahl der Tage ab der Auszahlung (kind relative, 1 bis 365), oder installments {schedule: [{date, amountMinor}]} mit 1 bis 360 Raten in aufsteigender Reihenfolge, keine in der Vergangenheit. Der Typ muss dem Produkt entsprechen, das für Ihren Kreditbegleiter eingestellt ist.
documents ja 2 bis 10 Dokumente {role, reference, title, url, sha256}; abgedeckt sind die Rollen, die die Einstellungen Ihres Kreditbegleiters verlangen (standardmäßig precontract_information und contract_package). url nur HTTPS auf einem in den Einstellungen Ihres Kreditbegleiters zugelassenen Host, höchstens 2.048 Zeichen, ohne Anmeldedaten; sha256 = 64 Hexadezimalzeichen, die Sie deklarieren.
validUntil ja Gültigkeit des Angebots, RFC 3339 mit Zeitversatz, in der Zukunft und höchstens 7 Tage im Voraus.
supersedes nein offerReference des aktiven Angebots desselben Profils, das das neue Angebot ersetzt.
returnUrl nein Optional: die Adresse, zu der die Seite „Fertig“ den Antragsteller nach dem Begleiter zurückführt. Nur absolutes HTTPS, höchstens 2.048 Zeichen, ohne Zugangsdaten; die Platzhalter {offerReference} und {externalApplicationId} ersetzen wir durch die Referenzen des Angebots. Ohne sie gilt die Rücksprungadresse aus den Einstellungen Ihres Kreditbegleiters.

Derselbe Body erneut (unter denselben Referenzen oder demselben Idempotency-Key) gibt 200 mit dem bestehenden Angebot und einem neuen entryUrl zurück; ein anderer Body darunter gibt 409 offerConflict zurück. Ein Profil hat ein aktives Angebot: ein weiteres ohne supersedes gibt 409 activeOfferExists zurück, ein falsches supersedes 409 notSupersedable. Die Einstellungen Ihres Kreditbegleiters (Quiz, Kontakt) werden in diesem Moment für das Angebot fixiert.

Stand, Nachweis und Stornierung

  • GET /v1/users/{identifier}/loan-offers/{offerReference} - Stand (Berechtigung read): offerStatus (active, expired, superseded, cancelled), guideStatus (created, in_progress, completed), abgeschlossene Lektionen, Praxis, Quiz (null, wenn es ausgeschaltet ist) und die Zeitpunkte der Vorlage des Angebots, der Bestätigung und der Bitte um Erklärung. Nie Antworten, Werte des Angebots oder den Link. Der Abschluss bleibt bestehen, auch wenn das Angebot später abläuft.
  • GET /v1/users/{identifier}/loan-offers/{offerReference}/evidence - Nachweis für Ihre Akte (Berechtigung read): schemaVersion loan-guide-evidence/1, Momentaufnahme Ihres Angebots mit dem Fingerabdruck snapshotSha256, Ausgabe des Kurses mit den Fingerabdrücken der Lektionen, Ereignisse in der Reihenfolge sequence, jede Antwort mit allen Versuchen, die Bestätigung und limitations - was der Nachweis nicht belegt (vorgelegt heißt nicht gelesen, die Identität behaupten Sie, Dokumente nur per Referenz, kein Zertifikat, keine Genehmigung des Kredits).
  • POST /v1/users/{identifier}/loan-offers/{offerReference}/cancel - storniert ein aktives Angebot (Berechtigung write), reasonCode = withdrawn_by_provider oder application_closed; 200 gibt den Stand zurück, ein Angebot, das nicht aktiv ist oder dessen Kreditbegleiter abgeschlossen ist, gibt 409 notActive zurück.
curl https://api.responsiblo.com/v1/users/applicant-30417/loan-offers/OFF-30417-1 -H "Authorization: Bearer $RSB_KEY"

{
  "offerReference": "OFF-30417-1",
  "externalApplicationId": "APP-30417",
  "offerStatus": "active",
  "guideStatus": "completed",
  "quizEnabled": true,
  "lessonsCompleted": 3,
  "lessonsTotal": 3,
  "practiceCompleted": true,
  "quizPassed": true,
  "offerPresentedAt": "2026-11-10T18:32:47Z",
  "confirmedAt": "2026-11-10T18:34:02Z",
  "completedAt": "2026-11-10T18:34:02Z",
  "assistanceRequested": false,
  "assistanceRequestedAt": null,
  "validUntil": "2026-11-15T18:00:00Z",
  "evidenceErased": false,
  "...": "..."
}

curl -X POST https://api.responsiblo.com/v1/users/applicant-30417/loan-offers/OFF-30417-1/cancel \
  -H "Authorization: Bearer $RSB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reasonCode":"withdrawn_by_provider"}'

?externalApplicationId= ist nur nötig, wenn eine offerReference zu mehreren Anträgen des Profils gehört (sonst 409 ambiguousOfferReference).

Webhooks des Kreditbegleiters

Der Webhook des Programms (siehe Webhooks) erhält die Ereignisse des Kreditbegleiters ohne gesondertes Abonnement. Signatur, Zustellung und Wiederholung sind dieselben wie bei den anderen Ereignissen; data tragen identifier, offerReference, externalApplicationId, guideStatus, occurredAt und sequence (Reihenfolge der Ereignisse eines Angebots) - nie den Nachweis, Werte des Angebots oder den Einstiegslink.

EreignisWann
loanGuide.completed die antragstellende Person hat den Kreditbegleiter durchlaufen und das Angebot bestätigt
loanGuide.assistanceRequested die antragstellende Person hat um eine Erklärung gebeten (rufen Sie sie an)
loanGuide.expired für das Angebot ist validUntil verstrichen
loanGuide.superseded ein neues Angebot hat es ersetzt (supersedes)
loanGuide.cancelled Sie haben das Angebot storniert
POST https://your-server.example/responsiblo/webhook
Content-Type: application/json
X-Responsiblo-Event: loanGuide.completed
X-Responsiblo-Delivery: 0f6e2a4c-91d3-4b8e-a7c5-3e2d1b9f6a08
X-Responsiblo-Signature: t=1794335647,v1=8b2d...4c

{
  "id": "0f6e2a4c-91d3-4b8e-a7c5-3e2d1b9f6a08",
  "type": "loanGuide.completed",
  "createdAt": "2026-11-10T18:34:07Z",
  "apiVersion": "1.3.2",
  "program": "your-program",
  "data": {
    "identifier": "applicant-30417",
    "offerReference": "OFF-30417-1",
    "externalApplicationId": "APP-30417",
    "guideStatus": "completed",
    "occurredAt": "2026-11-10T18:34:02Z",
    "sequence": 23
  }
}

Jedes Ereignis erreicht einen Webhook höchstens einmal (Idempotenzschlüssel = X-Responsiblo-Delivery). Ein später angelegter Webhook spielt ältere Ereignisse nicht nach, und Ereignisse, die älter als 28 Tage sind, werden nicht mehr gemeldet.

Aufbewahrung des Nachweises

Wenn der Weg eines Angebots endet (abgeschlossenes, storniertes, abgelaufenes oder ersetztes Angebot), läuft die Aufbewahrungsfrist aus den Einstellungen Ihres Kreditbegleiters (standardmäßig 30 Tage). Danach wird der Nachweis gelöscht: GET …/evidence gibt 410 evidenceErased zurück, und der Stand antwortet weiterhin mit evidenceErased: true, den Referenzen und den Zeitpunkten. Ein aktives Angebot wird nie gelöscht. Einen Nachweis, den Sie aufbewahren müssen, laden Sie direkt nach loanGuide.completed herunter.

Fehler des Kreditbegleiters

Die Fehler haben die Form der API oben. Zusätzlich für den Kreditbegleiter:

HTTPreasonWas tun
404 offerNotFound das Profil hat kein solches Angebot (userNotFound = das Profil existiert nicht)
409 offerConflict, activeOfferExists, notSupersedable die Referenzen oder der Idempotency-Key gehören bereits zu einem anderen Body, oder das Profil hat ein anderes aktives Angebot - senden Sie supersedes
409 loanGuideNotConfigured der Kreditbegleiter ist für Ihr Programm nicht aktiviert - schreiben Sie uns
409 ambiguousOfferReference ergänzen Sie ?externalApplicationId=
409 notActive das Angebot ist nicht aktiv oder sein Kreditbegleiter ist abgeschlossen
410 evidenceErased der Nachweis wurde nach der Aufbewahrungsfrist gelöscht, der Stand bleibt
422 invalidOffer errors = {Pfad: Code[,Code]} mit dem Pfad im Body (repayment.schedule[2].date, documents[0].url); die Codes in der Tabelle unten
422 invalidBody supersedes, Idempotency-Key oder Body der Stornierung
errorsCodes des Fehlers invalidOffer
required das Feld fehlt
invalidFormat falsche Form (Typ, Muster, Länge, Link ohne HTTPS oder mit Anmeldedaten)
outOfRange außerhalb des zulässigen Bereichs (Betrag, Anzahl der Dokumente, Raten oder Tage)
notEqualPrincipal der ausgezahlte Betrag entspricht nicht dem Kreditbetrag
sumMismatch die Summe der Zahlungen entspricht nicht dem zu zahlenden Gesamtbetrag
belowPrincipal der zu zahlende Gesamtbetrag ist niedriger als der Kreditbetrag
aprContradiction effektiver Jahreszins 0 bei positiven Kosten
typeMismatch der Typ der Rückzahlung entspricht nicht dem Produkt, das für Ihren Kreditbegleiter eingestellt ist
missingRole es fehlt ein Dokument mit einer Rolle, die die Einstellungen Ihres Kreditbegleiters verlangen
hostNotAllowed der Link eines Dokuments zeigt auf einen Host, den die Einstellungen Ihres Kreditbegleiters nicht zulassen
notAscending die Daten der Raten sind nicht aufsteigend oder wiederholen sich
inPast das Datum einer Rate oder validUntil liegt in der Vergangenheit
tooFar validUntil liegt mehr als 7 Tage im Voraus
unsupported nicht unterstützter Wert (locale, currency, type, period, kind)
unknownField ein Feld, das die API nicht kennt
looksLikeEmail eine Referenz sieht wie eine E-Mail-Adresse aus

Ein Fehler wiederholt nie einen Wert, den Sie gesendet haben. Beispiel: dasselbe Angebot mit einer Zahlung von 10.700 CZK statt 10.800 CZK und einer Gültigkeit von 9 Tagen:

"repayment": { "type": "singlePayment", "amountMinor": 1070000, "due": { "kind": "relative", "days": 30, "anchor": "disbursement" } },
"validUntil": "2026-11-19T18:00:00Z"

HTTP/1.1 422 Unprocessable Entity

{
  "status": "error",
  "code": 422,
  "reason": "invalidOffer",
  "message": "The offer contains invalid data.",
  "errors": {
    "repayment.amountMinor": "sumMismatch",
    "validUntil": "tooFar"
  }
}

Limits

120 Aufrufe pro Minute und Schlüssel. Nach 30 abgelehnten Schlüsseln von einer Adresse innerhalb von zehn Minuten wartet die Adresse 10 Minuten.

Das Protokoll der Aufrufe (ohne Bodys, die Kennung nur als SHA-256-Fingerabdruck) bewahren wir 180 Tage auf, zugestellte und aufgegebene Webhook-Nachrichten 30 Tage.

Status und Vertrag

  • GET /v1/status - ohne Schlüssel, gibt {"status":"ok","version":"1.3.2"} zurück
  • GET /openapi - ohne Schlüssel, das OpenAPI-3-Dokument der Partner-API

Sandbox

Der Testschlüssel rsb_test_... öffnet Ihr Testprogramm mit demselben Kurs. Personen darin enden nach 7 Tagen; der Webhook des Testprogramms ist vom produktiven getrennt.

Versionsverlauf

  • 1.3.2 (2026-11) - Jede Operation des OpenAPI-Dokuments hat einen Namen und eine Beschreibung, und die Operationen sind in Gruppen eingeteilt. /v1/status und die Webhooks melden die Version 1.3.2. Die Form der Anfragen und Antworten bleibt unverändert.
  • 1.3.1 (2026-10) - Korrekturen ohne Änderung der Endpunkte und ihrer Antworten.
  • 1.3.0 (2026-10) - Kreditbegleiter: POST /v1/users/{identifier}/loan-offers, Stand, Nachweis und Stornierung eines Angebots, Webhooks loanGuide.*, Aufbewahrung des Nachweises. Optionales Feld returnUrl eines Angebots (eigene Rücksprungadresse).
  • 1.2.0 (2026-10) - GET /v1/users mit Paginierung, Zertifikat der Person (Feld certificate, GET /v1/users/{identifier}/certificate, Ereignis certificate.issued), DELETE /v1/users/{identifier} (Anonymisierung), Kennung höchstens 64 Zeichen, Aufbewahrung des Protokolls.
  • 1.1.0 (2026-10) - API-Schlüssel, POST /v1/users, GET /v1/users/{identifier} mit ?include=detail, Einstiegslink, Webhooks, eine Form der Fehler, öffentlicher Status und OpenAPI, Limits.
  • 1.0.0 (2024) - GET /v1/user/{identifier} mit dem JWT des Partnerschlüssels.

Möchten Sie die API für Ihr Unternehmen? Schreiben Sie uns