{
  "openapi": "3.0.3",
  "info": {
    "title": "cKonto REST API",
    "version": "1.0.0",
    "description": "REST API for bank account / IBAN checks and bank search. Auth via Bearer token."
  },
  "servers": [
    {
      "url": "https://api.ckonto.de"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "opaque"
      }
    },
    "responses": {
      "MethodNotAllowed": {
        "description": "Method Not Allowed – die verwendete HTTP-Methode ist für diesen Endpunkt nicht erlaubt. Erlaubte Methode(n) stehen im `Allow`-Response-Header.",
        "headers": {
          "Allow": {
            "schema": {"type": "string"},
            "description": "Kommagetrennte Liste der erlaubten HTTP-Methoden"
          }
        },
        "content": {
          "application/json": {
            "schema": {"$ref": "#/components/schemas/ErrorResponse"},
            "example": {
              "error": {
                "http_status": 405,
                "code": "method_not_allowed",
                "message": "Methode nicht erlaubt. Erlaubt: GET"
              }
            }
          }
        }
      }
    },
    "schemas": {
      "KtoRequest": {
        "type": "object",
        "required": [
          "kontonummer",
          "bankleitzahl"
        ],
        "properties": {
          "kontonummer": {
            "type": "string",
            "example": "1234567890"
          },
          "bankleitzahl": {
            "type": "string",
            "example": "76543210"
          },
          "sepa": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Optional: include SEPA info if supported."
          }
        },
        "additionalProperties": false
      },
      "IbanRequest": {
        "type": "object",
        "required": [
          "iban"
        ],
        "properties": {
          "iban": {
            "type": "string",
            "example": "DE07100500006603032331"
          },
          "bic": {
            "type": "string",
            "example": "BELADEBEXXX"
          }
        },
        "additionalProperties": false
      },
      "BatchIbanRequest": {
        "type": "object",
        "required": [
          "ibans"
        ],
        "properties": {
          "ibans": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "type": "string",
              "example": "DE07100500006603032331"
            },
            "description": "1 bis 500 IBANs zur gleichzeitigen Prüfung"
          }
        },
        "additionalProperties": false
      },
      "SearchRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Postbank"
          },
          "location": {
            "type": "string",
            "example": "Berlin"
          },
          "zip": {
            "type": "string",
            "example": "10"
          },
          "bankleitzahl": {
            "type": "string",
            "example": "10010010"
          },
          "max": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "example": 10
          }
        },
        "additionalProperties": false
      },
      "CheckData": {
        "type": "object",
        "properties": {
          "bank": {
            "type": "string",
            "example": "Sparkasse Musterstadt"
          },
          "location": {
            "type": "string",
            "example": "Berlin"
          },
          "zip": {
            "type": "string",
            "example": "12345"
          },
          "kto": {
            "type": [
              "string",
              "integer"
            ],
            "example": "1234567890"
          },
          "blz": {
            "type": "string",
            "example": "76543210"
          },
          "iban": {
            "type": [
              "string",
              "null"
            ],
            "example": "DE84012345671234567890"
          },
          "bic": {
            "type": [
              "string",
              "null"
            ],
            "example": "COBAXX13XXX"
          },
          "country": {
            "type": "string",
            "description": "Ländercode (ISO 3166-1 alpha-2) der Bank, z. B. 'DE'. Immer vorhanden, ggf. leer.",
            "example": "DE"
          },
          "sepa_methods": {
            "type": "object",
            "description": "SEPA-Zahlungsverfahren der Bank. Wird bei IBAN-Prüfungen immer zurückgegeben.",
            "properties": {
              "sct": {
                "type": "integer",
                "enum": [0, 1],
                "description": "SEPA Credit Transfer (Überweisung)"
              },
              "sdd": {
                "type": "integer",
                "enum": [0, 1],
                "description": "SEPA Direct Debit Core (Lastschrift)"
              },
              "b2b": {
                "type": "integer",
                "enum": [0, 1],
                "description": "SEPA Direct Debit B2B (Firmenlastschrift)"
              },
              "scc": {
                "type": "integer",
                "enum": [0, 1],
                "description": "SEPA Cards Clearing"
              }
            }
          }
        },
        "additionalProperties": true
      },
      "SuccessResponse": {
        "type": "object",
        "required": [
          "status",
          "message",
          "data"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "description": "Business status code (0/1/2/3/4/7/8/9).",
            "example": 1
          },
          "message": {
            "type": "string",
            "example": "Die Bankverbindung ist gültig"
          },
          "data": {
            "$ref": "#/components/schemas/CheckData"
          }
        }
      },
      "SearchResultItem": {
        "type": "object",
        "properties": {
          "zip": {
            "type": "string",
            "example": "10889"
          },
          "location": {
            "type": "string",
            "example": "Berlin"
          },
          "bank": {
            "type": "string",
            "example": "Landesbank Berlin - Berliner Sparkasse"
          },
          "blz": {
            "type": "string",
            "example": "10050000"
          },
          "bic": {
            "type": [
              "string",
              "null"
            ],
            "example": "BELADEBEXXX"
          }
        },
        "additionalProperties": true
      },
      "SearchSuccessResponse": {
        "type": "object",
        "required": [
          "status",
          "message",
          "results"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "example": 1
          },
          "message": {
            "type": "string",
            "example": "Die Suche war erfolgreich"
          },
          "results": {
            "type": "object",
            "required": ["count", "items"],
            "properties": {
              "count": {
                "type": "integer",
                "description": "Anzahl der gefundenen Einträge",
                "example": 3
              },
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SearchResultItem"
                }
              }
            }
          }
        }
      },
      "BatchIbanSuccessResponse": {
        "type": "object",
        "required": ["status", "message", "batch"],
        "properties": {
          "status": {"type": "integer", "example": 1},
          "message": {"type": "string", "example": "Batch-Verarbeitung abgeschlossen"},
          "batch": {
            "type": "object",
            "required": ["total", "results"],
            "properties": {
              "total": {"type": "integer", "example": 2},
              "results": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "iban":   {"type": "string"},
                    "valid":  {"type": "boolean"},
                    "status": {"type": "integer"},
                    "data":   {"$ref": "#/components/schemas/CheckData"},
                    "error":  {"$ref": "#/components/schemas/ErrorResponse"}
                  }
                }
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "http_status",
              "code",
              "message"
            ],
            "properties": {
              "http_status": {
                "type": "integer",
                "example": 401
              },
              "code": {
                "type": "string",
                "example": "invalid_key"
              },
              "message": {
                "type": "string",
                "example": "Der Zugriffsschlüssel ist nicht gültig"
              }
            },
            "additionalProperties": true
          }
        }
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/kto/{kontonummer}/{bankleitzahl}": {
      "get": {
        "tags": [
          "kto"
        ],
        "summary": "Kontonummer/BLZ prüfen (GET)",
        "description": "Nur GET erlaubt. POST, PUT, DELETE etc. werden mit 405 Method Not Allowed abgewiesen.",
        "parameters": [
          {
            "name": "kontonummer",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            }
          },
          {
            "name": "bankleitzahl",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            }
          },
          {
            "name": "sepa",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                0,
                1
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/kto": {
      "post": {
        "tags": [
          "kto"
        ],
        "summary": "Kontonummer/BLZ prüfen (POST)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KtoRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/iban/{iban}": {
      "get": {
        "tags": [
          "iban"
        ],
        "summary": "IBAN prüfen (GET)",
        "parameters": [
          {
            "name": "iban",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]+$"
            }
          },
          {
            "name": "sepa",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                0,
                1
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/iban/{iban}/{bic}": {
      "get": {
        "tags": [
          "iban"
        ],
        "summary": "IBAN prüfen inkl. BIC (GET)",
        "parameters": [
          {
            "name": "iban",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]+$"
            }
          },
          {
            "name": "bic",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/iban": {
      "post": {
        "tags": [
          "iban"
        ],
        "summary": "IBAN prüfen oder Batch-Prüfung (POST)",
        "description": "Einzelne IBAN prüfen (Body: IbanRequest) oder bis zu 500 IBANs gleichzeitig prüfen (Body: BatchIbanRequest). Einzelprüfung gibt SuccessResponse, Batch gibt BatchIbanSuccessResponse zurück.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {"$ref": "#/components/schemas/IbanRequest"},
                  {"$ref": "#/components/schemas/BatchIbanRequest"}
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Check result (Einzelprüfung: SuccessResponse, Batch: BatchIbanSuccessResponse)",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {"$ref": "#/components/schemas/SuccessResponse"},
                    {"$ref": "#/components/schemas/BatchIbanSuccessResponse"}
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/ping": {
      "get": {
        "tags": ["healthcheck"],
        "summary": "Healthcheck / Ping",
        "description": "Prüft ob der Service erreichbar ist. Benötigt gültigen Bearer-Token.",
        "responses": {
          "200": {
            "description": "Service erreichbar",
            "content": {
              "application/json": {
                "example": {"status": 1, "message": "Pong"}
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"}
        }
      }
    },
    "/v1/test": {
      "get": {
        "tags": ["healthcheck"],
        "summary": "Testmode-Ping",
        "description": "Wie /service/ping, mit Meldung 'Testmode - Ping'. Benötigt gültigen Bearer-Token.",
        "responses": {
          "200": {
            "description": "Service erreichbar",
            "content": {
              "application/json": {
                "example": {"status": 1, "message": "Testmode - Ping"}
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorResponse"}}}
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"}
        }
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Banksuche (GET)",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bankleitzahl",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "max",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Banksuche (POST)",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {"$ref": "#/components/responses/MethodNotAllowed"},
          "500": {
            "description": "Internal Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}