api.ckonto.de  |  ckonto.de

Übersicht

Base URL: https://api.ckonto.de

Version: v1  (alle Endpunkte beginnen mit /v1/)

Format: JSON (Content-Type: application/json)

Discovery: /service  |  OpenAPI 3.0 Schema

Feldreihenfolge: Die Felder werden in einer festen, dokumentierten Reihenfolge ausgegeben (siehe Beispiele unten). Nach RFC 8259 ist die Reihenfolge von JSON-Objektfeldern jedoch nicht bedeutungstragend; Clients dürfen sich darauf nicht verlassen und müssen unbekannte zusätzliche Felder ignorieren, damit spätere Erweiterungen kompatibel bleiben.

Authentifizierung

Alle Endpunkte (außer /service, /service/openapi.json sowie /v1/ping und /v1/test) erfordern einen gültigen API-Schlüssel als Bearer-Token:

Authorization: Bearer API_KEY

Alternativ via Header X-API-Key: API_KEY. Der Schlüssel wird ausschließlich per Header übergeben - nicht als Query-Parameter und nicht im Request-Body. So landet er weder in Server-Logs noch in Browser-Verläufen oder Referer-Headern.

/v1/ping und /v1/test sind bewusst ohne Authentifizierung erreichbar (gedacht für Healthchecks/Monitoring). Ein trotzdem mitgeschickter Token wird dort ignoriert und nicht geprüft.

API-Schlüssel erhalten Sie über ckonto.de/bestellung.htm.

Hinweis: Der Auth-Check läuft bei allen geschützten Endpunkten vor jeder anderen Validierung. Fehlt der Schlüssel oder ist er ungültig, kommt immer 401 invalid_key zurück – auch dann, wenn der Request zusätzlich eine falsche HTTP-Methode, einen falsch geformten Pfad oder fehlende Parameter verwendet (die eigentlich 405 method_not_allowed bzw. 400 liefern würden). Mit gültigem Schlüssel wird der jeweilige strukturelle Fehler wie dokumentiert gemeldet.

Endpunkte

Kontonummer / BLZ prüfen

GET /v1/kto/{kontonummer}/{bankleitzahl}
POST /v1/kto

Prüft eine deutsche Kontonummer und Bankleitzahl. Optional mit IBAN-Generierung (sepa=1).

Beispiel GET

curl -H "Authorization: Bearer API_KEY" \
  "https://api.ckonto.de/v1/kto/0532013000/37040044"

Beispiel POST

curl -H "Authorization: Bearer API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"kontonummer":"0532013000","bankleitzahl":"37040044"}' \
  "https://api.ckonto.de/v1/kto"

Antwort

{
  "status": 1,
  "message": "The bank account details are valid",
  "data": {
    "iban": null,
    "bic": null,
    "kto": "0532013000",
    "blz": "37040044",
    "bank": "Commerzbank",
    "zip": "50447",
    "location": "Köln",
    "country": "DE"
  }
}

Mit sepa=1 (GET: Query-Parameter, POST: im JSON-Body) werden iban und bic zusätzlich zurückgegeben. Zulässig sind ausschließlich 0 und 1; andere Werte liefern HTTP 400 mit Code invalid_sepa. Fehlt der Parameter, gilt der Default 0.

country enthält immer den ISO-3166-1-alpha-2-Ländercode der Bank (z. B. DE), nicht den ausgeschriebenen Ländernamen. Ist kein Code ermittelbar, ist das Feld ein leerer String.

ccd (optional, GET: Query-Parameter, POST: im JSON-Body): 2-stelliger Ländercode, steuert die IBAN-Generierung aus Kontonummer/BLZ für Länder außerhalb Deutschlands. Unterstützt: DE, AT, CH, BE, CZ, SK, ES (Groß-/Kleinschreibung wird toleriert, andere Werte werden ignoriert). Wirkt unabhängig von sepa auch auf das Feld country der Antwort.

Wichtig: kontonummer und bankleitzahl müssen im länderspezifischen Format vorliegen – nicht zwingend 8-stellig wie bei einer deutschen BLZ. ccd allein liefert nur country – für die generierte iban/bic zusätzlich sepa=1 setzen. Beispiel Slowakei:

curl -H "Authorization: Bearer API_KEY" \
  "https://api.ckonto.de/v1/kto/5207004203041425/8360?ccd=SK&sepa=1"
{
  "status": 1,
  "message": "The bank account details are valid",
  "data": {
    "iban": "SK4283605207004203041425",
    "bic": "BREXSKBXXXX",
    "kto": "5207004203041425",
    "blz": "8360",
    "bank": "mBank S.A., pobočka zahraničnej banky",
    "zip": "SK-81109",
    "location": "Bratislava",
    "country": "SK"
  }
}

IBAN prüfen

GET /v1/iban/{iban}
GET /v1/iban/{iban}/{bic}
POST /v1/iban

Prüft eine IBAN (international, Schwerpunkt DE/AT/CH/EU). Optional mit BIC-Validierung. Per POST auch als Batch bis 500 IBANs.

iban und bic werden bei diesem Endpunkt immer zurückgegeben – ein sepa-Parameter wird hier syntaktisch akzeptiert, hat aber keine Wirkung (anders als bei der Kontonummer/BLZ-Prüfung, wo erst sepa=1 sie freischaltet).

Beispiel GET

curl -H "Authorization: Bearer API_KEY" \
  "https://api.ckonto.de/v1/iban/DE89370400440532013000"

Antwort (Einzelprüfung)

{
  "status": 1,
  "message": "The IBAN is valid",
  "data": {
    "iban": "DE89370400440532013000",
    "bic": "COBADEFFXXX",
    "kto": "0532013000",
    "blz": "37040044",
    "bank": "Commerzbank",
    "zip": "DE-50447",
    "location": "Köln",
    "country": "DE",
    "sepa_methods": {
      "sct": 1,
      "sdd": 1,
      "b2b": 1,
      "scc": 1
    }
  }
}

sepa_methods zeigt, welche SEPA-Zahlungsverfahren die Bank unterstützt: sct (Überweisung), sdd (Lastschrift), b2b (Firmenlastschrift), scc (Cards Clearing). Wert 1 = unterstützt, 0 = nicht unterstützt, 9 = nicht ermittelbar (unvollständige Bankstammdaten für dieses Land, kommt vor allem außerhalb DE/AT/CH vor).

country enthält immer den ISO-3166-1-alpha-2-Ländercode der Bank (z. B. DE, AT, CH), nicht den ausgeschriebenen Ländernamen. Ist kein Code ermittelbar, ist das Feld ein leerer String.

Beispiel POST – Einzelprüfung mit BIC

curl -H "Authorization: Bearer API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"iban":"DE89370400440532013000","bic":"COBADEFFXXX"}' \
  "https://api.ckonto.de/v1/iban"

Negativbeispiele (jeweils ein anderer Status/Fehler)

IBANErgebnisGrund
DE00370400440532013000HTTP 200, status: 0Falsche IBAN-Prüfziffer (sonst identisch zum gültigen Beispiel oben)
DE93999999990000000001HTTP 200, status: 7BLZ existiert nicht
XXHTTP 400, invalid_ibanFormatfehler – zu kurz / kein gültiges Länderkürzel

Die ersten beiden Fälle sind keine Fehler im HTTP-Sinn (HTTP 200) – die Anfrage war syntaktisch korrekt, das fachliche Prüfergebnis ist „ungültig" bzw. „BLZ unbekannt". Nur der dritte Fall ist ein echter Request-Fehler (HTTP 400), weil die IBAN nicht einmal dem Grundformat entspricht.

Beispiel POST – Batch (bis 500 IBANs)

curl -H "Authorization: Bearer API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"ibans":["DE89370400440532013000","AT001234512345678901"]}' \
  "https://api.ckonto.de/v1/iban"

Batch-Antwort

Zählung: Jede IBAN in einem Batch zählt als eine Abfrage - auch Einträge, die bereits an der Formatprüfung scheitern.

Jedes Element in batch.results enthält immer iban, valid, status und data – auch wenn die IBAN fachlich ungültig ist (z. B. status: 7, „BLZ existiert nicht"). Das ist kein Fehler und trägt kein error-Objekt. Ein error-Objekt erscheint ausschließlich, wenn dieses Item gar nicht geprüft werden konnte (Formatfehler oder Backend-Fehler); es ist flach aufgebaut und nutzt wie die übrigen Fehlerobjekte das Feld code (nicht error_code).

{
  "status": 1,
  "message": "Batch processing completed",
  "batch": {
    "total": 3,
    "results": [
      { "status": 1, "iban": "DE89370400440532013000", "valid": true,  "data": { "country": "DE", "sepa_methods": { "sct": 1, "sdd": 1, "b2b": 1, "scc": 1 }, ... } },
      { "status": 7, "iban": "DE93999999990000000001", "valid": false, "data": { "country": "DE", ... } },
      { "status": 0, "iban": "XX",                     "valid": false, "data": { "country": "", ... },
        "error": { "code": "invalid_iban", "message": "The IBAN is invalid or has an incorrect format", "field": "iban" } }
    ]
  }
}

Banksuche

GET /v1/search?name=&location=&zip=&bankleitzahl=&max=
POST /v1/search

Sucht Banken nach Name, Ort, PLZ oder BLZ. Mindestens eines der Felder name, location, zip oder bankleitzahl muss belegt sein – ohne jedes Suchkriterium liefert die API HTTP 400 mit Code missing_search_criteria. Maximal 50 Treffer.

max begrenzt die Anzahl der Treffer (1–50). Fehlt max, gilt der Default 10. Werte außerhalb 1–50 oder nicht-numerische Werte liefern HTTP 400 mit Code invalid_max.

Hinweis: Liefert die Suche mindestens so viele Treffer wie mit max angefordert (die Ergebnisliste also durch max abgeschnitten wurde), kommt status: 9 statt status: 1 zurück – bei sonst identischer Antwortstruktur (results.count/results.items weiterhin gefüllt, HTTP 200). Das ist gewolltes Verhalten der cKonto-Suche und kein Fehler; es zeigt lediglich an, dass ggf. weitere, hier nicht ausgegebene Treffer existieren. Um alle Treffer zu erhalten, max erhöhen oder die Suchkriterien (name, location, zip, bankleitzahl) weiter eingrenzen.
Hinweis: name und location sind UND-verknüpft und werden jeweils als Teilstring (case-insensitive) gegen die Bankstammdaten gematcht. Beispiel: location=Berlin liefert auch „Bernau bei Berlin" und „Überlingen", weil beide Orte die Zeichenfolge „berlin" enthalten. Das ist gewolltes Verhalten.
Hinweis: Jedes Suchkriterium hat eine Mindestlänge: name/location 3 Zeichen, zip 2 Zeichen, bankleitzahl 4 Zeichen. Das ist kein HTTP-Fehler – ein zu kurzer Wert liefert weiterhin HTTP 200 mit leerem Ergebnis und dem passenden fachlichen Fehlerstatus (status: 2/3/4/8, siehe Business-Status-Tabelle unten).
Einschränkung: name und location akzeptieren live verifiziert nur reine Buchstaben – keine Ziffer (auch nicht in Kombination mit Buchstaben), kein Umlaut, kein ß, kein Leerzeichen. Die Hersteller-Doku bezeichnet die Felder als „alphanumerisch"; tatsächlich wird jede Ziffer an jeder Position abgelehnt. Ein zu kurzer oder unzulässiger Wert liefert HTTP 200 mit status: 3/4 statt eines Treffers. Beispiele: location=Köln, name=Postbank1 und name=Deutsche Bank (mehrwortig) schlagen fehl, location=Koeln und name=Deutsche funktionieren. Das ist ein Limit der cKonto-Suchfunktion selbst, kein Encoding-Problem des Wrappers.

Beispiel GET

curl -H "Authorization: Bearer API_KEY" \
  "https://api.ckonto.de/v1/search?name=Sparkasse&location=Berlin&max=5"

Antwort

{
  "status": 1,
  "message": "The search was successful",
  "results": {
    "count": 4,
    "items": [
      { "bic": "BELADEBEXXX", "blz": "10050000", "bank": "BSK 1818 - Berliner Sparkasse", "zip": "10889", "location": "Berlin" },
      ...
    ]
  }
}

status ist hier wie überall ein numerischer Wert (kein String).

Healthcheck

GET /v1/ping
GET /v1/test

Prüft ob der Service erreichbar ist. /v1/test zeigt zusätzlich Testmode an. Kein Bearer-Token erforderlich – beide Endpunkte sind bewusst ohne Authentifizierung erreichbar (Healthcheck/Monitoring). Ein trotzdem mitgeschickter Token wird ignoriert.

{ "status": 1, "message": "Pong" }

Fehler

Fehler werden immer als JSON-Objekt mit dem Schlüssel error zurückgegeben. Eine vollständige Liste aller Fehlercodes mit Beschreibungen und Beispielen findet sich unter /api/docs/errors.

{
  "error": {
    "http_status": 401,
    "code": "invalid_key",
    "message": "The API key is not valid"
  }
}
Stabil und maschinenlesbar: bei fachlichen Prüfergebnissen status (0–9, siehe unten); bei API-/HTTP-Fehlern error.code und error.http_status. message ist in beiden Fällen englischer Freitext ohne Stabilitätsgarantie – nur zur Anzeige, nicht für Programmlogik verwenden.

Business Status-Codes

Das Feld status in der Erfolgs-Antwort enthält den fachlichen Prüfstatus von cKonto:

CodeBedeutung
0Kontonummer/IBAN nicht gültig / Keine Treffer bei der Suche
1Bankverbindung gültig
2BLZ muss 8-stellig sein / Eingabefehler PLZ
3Eingabefehler Kontonummer / Eingabefehler Ort
4Fehler in Kontonummer und BLZ / Eingabefehler IBAN / Eingabefehler Name
7BLZ existiert nicht / Eingabefehler Max
8Demo-Modus / Eingabefehler BLZ
9Bankverbindung nicht prüfbar / Ausgabe-Begrenzung erreicht

Response-Header

HeaderBeschreibung
X-Request-IDEindeutige ID für den Request – vom Client sendbar, wird gespiegelt (nur [A-Za-z0-9-], andere Zeichen werden entfernt, auf 64 Zeichen gekürzt); sonst serverseitig generiert. Für Log-Korrelation und Debugging.
X-RateLimit-LimitMaximale Anfragen pro Zeitfenster
X-RateLimit-WindowFenstergröße in Sekunden
X-RateLimit-PolicyRate-Limit-Policy als Klartext, z. B. "60 requests per 10 seconds". Die Begrenzung gilt nicht je API-Schlüssel.
X-Idempotency-KeyWird gespiegelt, wenn vom Client gesendet (auf 64 Zeichen gekürzt). Reiner Korrelationswert – es findet keine serverseitige Deduplizierung statt, ein wiederholter POST mit demselben Key wird vollständig erneut verarbeitet.
Tipp: Senden Sie im Request einen eigenen X-Request-ID-Header (z. B. eine UUID), um Ihre Anfragen in Logs eindeutig nachverfolgen zu können.