JKz JKz Logo API-Docs

1. Einleitung

Diese Seite dokumentiert die öffentlichen Endpoints der JKz-API v1. Alle Endpoints folgen einem REST-ähnlichen Design und liefern JSON-Antworten.

Die Dokumentation beschreibt:

  • Pfad & HTTP-Methode
  • Erwartete Parameter (Query & Body)
  • Antwort-Struktur (Beispiel)
  • Hinweise zu Authentifizierung & Berechtigungen
  • Beispielaufrufe in PHP, C# und JavaScript

2. Basis-URL & Authentifizierung

Sofern nicht anders angegeben, sind alle Endpoints unter folgendem Host erreichbar:

https://api.jkz-group.de

2.1 Authentifizierung

Viele Endpoints (z. B. Chat, Profile, Friend-Requests) erwarten ein gültiges JWT Access Token (z. B. aus Keycloak) im HTTP-Header:

Authorization: Bearer <access_token>

Endpoints ohne Authentifizierung sind in dieser Dokumentation entsprechend markiert (z. B. /v1/badges/list).

2.2 Sicherheits-Hinweise

  • Immer HTTPS verwenden.
  • Tokens niemals im Frontend-Quellcode oder in Logs speichern.
  • Alle Client-Eingaben serverseitig validieren (ID-Formate, Längen, Datentyp).
  • In Backend-Integrationen Zeitouts und Fehler-Handling implementieren.

3. Allgemeine Code-Beispiele

Die folgenden Beispiele zeigen sichere Standard-Aufrufe für GET- und POST-Requests. Sie können für alle Endpoints entsprechend angepasst werden (Pfad & Payload austauschen).

3.1 PHP (cURL, mit Timeout & Fehlerbehandlung)

<?php
$baseUrl = 'https://api.jkz-group.de/v1/users/';
$token   = 'DEIN_ACCESS_TOKEN'; // sicher speichern, z.B. in .env

$ch = curl_init($baseUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_TIMEOUT        => 10,
    CURLOPT_HTTPHEADER     => [
        'Accept: application/json',
        'Authorization: Bearer ' . $token,
    ],
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($response === false) {
    throw new RuntimeException('cURL-Fehler: ' . curl_error($ch));
}

curl_close($ch);

if ($httpCode >= 200 && $httpCode < 300) {
    $data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
    // $data sicher weiterverarbeiten
} else {
    // Fehler-Handling
    error_log('API-Fehler (' . $httpCode . '): ' . $response);
}

3.2 C# (.NET HttpClient)

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public class JkzApiClient
{
    private readonly HttpClient _httpClient;

    public JkzApiClient(string token)
    {
        _httpClient = new HttpClient
        {
            BaseAddress = new Uri("https://api.jkz-group.de/")
        };
        _httpClient.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", token);
        _httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/json");
    }

    public async Task GetAllUsernamesAsync()
    {
        using var response = await _httpClient.GetAsync("v1/users/");
        var content = await response.Content.ReadAsStringAsync();

        if (!response.IsSuccessStatusCode)
        {
            Console.Error.WriteLine($"API-Fehler ({(int)response.StatusCode}): {content}");
            return;
        }

        Console.WriteLine(content);
        // JSON sicher deserialisieren (z.B. System.Text.Json)
    }
}

3.3 JavaScript (Fetch, Browser oder Node)

async function getAllUsernames(token) {
    const response = await fetch(
        "https://api.jkz-group.de/v1/users/",
        {
            method: "GET",
            headers: {
                "Accept": "application/json",
                "Authorization": "Bearer " + token,
            },
        }
    );

    if (!response.ok) {
        const errorText = await response.text();
        console.error("API-Fehler", response.status, errorText);
        return;
    }

    const data = await response.json();
    console.log(data);
}

// Niemals Token hartkodieren, sondern sicher laden (z.B. aus sicheren Storage-Lösungen)

4. Badges

4.1 GET /v1/badges/list

Gibt alle verfügbaren Badges aus der Datenbank zurück. Dieser Endpoint ist nur lesend und typischerweise ohne Auth nutzbar (CORS ist serverseitig freigegeben).

Request

GET https://api.jkz-group.de/v1/badges/list

Antwort-Beispiel

{
  "data": [
    {
      "ID": 1,
      "NAME": "Early Supporter",
      "ABKUERZUNG": "ES",
      "HEX_FARBE": "#ff8800",
      "LEVELABLE": 0,
      "LOGO_URL": "https://.../badges/early-supporter.png",
      "NUTZERANZAHL": 123
    }
  ],
  "count": 1
}

Beispiel-Aufruf in PHP

$response = file_get_contents('https://api.jkz-group.de/v1/badges/list');
$badges   = json_decode($response, true, 512, JSON_THROW_ON_ERROR);

4.2 GET /v1/badges/user/?id=UUID

Gibt alle Badges eines Users anhand seiner UUID zurück. Die UUID stammt in der Regel aus dem Identity-Provider (z. B. Keycloak).

Parameter

  • id (Query, required) – User-UUID

Request

GET https://api.jkz-group.de/v1/badges/user/?id=<user-uuid>

Antwort-Beispiel

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "count": 2,
  "badges": [
    {
      "BADGE_ID": 1,
      "NAME": "Early Supporter",
      "ABKUERZUNG": "ES",
      "HEX_FARBE": "#ff8800",
      "LOGO_URL": "https://.../badges/early-supporter.png",
      "LEVELABLE": 0,
      "LEVEL": null,
      "DATE_EARNED": "2025-01-01T12:00:00Z"
    }
  ]
}

4.3 Admin-Endpoints (Badges)

Diese Endpoints sind nur für interne/Admin-Tools gedacht (z. B. portal.jkz-group.de oder localhost) und prüfen die Herkunft mittels Access-Control.

  • POST /v1/admin/badges/create – legt ein neues Badge an.
  • POST /v1/admin/badges/update/?badge=ID – aktualisiert ein Badge.
  • DELETE /v1/admin/badges/delete/?badge=ID – löscht ein Badge.
  • GET|POST /v1/admin/badges/grant/?id=UUID&badge=ID&level=... – verleiht einem User ein Badge.
  • GET|DELETE /v1/admin/badges/revoke/?id=UUID&badge=ID – entzieht einem User ein Badge.

Hinweis: Diese Endpoints sollten nicht direkt aus dem öffentlichen Frontend aufgerufen werden.

5. Chat

Alle Chat-Endpoints erfordern ein gültiges JWT im Authorization: Bearer <token>-Header. Die User-ID wird jeweils aus dem Token (sub) gelesen.

5.1 /v1/chat/conversations

GET – Konversationen auflisten

Listet alle Konversationen, an denen der eingeloggte User beteiligt ist.

GET https://api.jkz-group.de/v1/chat/conversations

POST – 1:1-Konversation erstellen/finden

Erstellt (oder findet) eine direkte 1:1-Konversation mit einem anderen User.

POST /v1/chat/conversations
Content-Type: application/json

{
  "userId": "UUID_DES_ANDEREN_USERS"
}

5.2 /v1/chat/messages

GET – Nachrichten einer Konversation

Listet Nachrichten einer Konversation (nur für Teilnehmer).

GET https://api.jkz-group.de/v1/chat/messages?conversationId=<uuid>

POST – Nachricht senden

POST /v1/chat/messages
Content-Type: application/json

{
  "conversationId": "UUID_DER_KONVERSATION",
  "toUserId": "UUID_DES_EMPFÄNGERS",
  "ciphertext": "BASE64_VERSCHLUESSELT",
  "nonce": "RANDOM_NONCE"
}

5.3 POST /v1/chat/keys/me/

Speichert oder aktualisiert den öffentlichen Chat-Identity-Key des eingeloggten Users.

POST /v1/chat/keys/me/
Content-Type: application/json

{
  "publicKeyJwk": { ... },
  "algorithm": "jkz-chat-v1-p256-aesgcm"
}

5.4 GET /v1/chat/keys/user/

Gibt den öffentlichen Chat-Identity-Key eines anderen Users zurück.

GET https://api.jkz-group.de/v1/chat/keys/user/?id=<userId>

Antwort-Beispiel

{
  "data": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "publicKeyJwk": { /* JWK */ },
    "algorithm": "jkz-chat-v1-p256-aesgcm"
  }
}

6. Users & Profile

6.1 GET /v1/users/

Gibt alle registrierten Usernamen eines Realms als JSON zurück. Dieser Endpoint ist lesend, Authentifizierung kann je nach Serverkonfiguration erforderlich sein.

GET https://api.jkz-group.de/v1/users/

Antwort-Beispiel

{
  "count": 3,
  "usernames": ["Alice", "Bob", "Charlie"]
}

6.2 /v1/users/profile/me

Liest und aktualisiert Profildaten des eingeloggten Users. Es werden Daten aus USER_ENTITY (Keycloak-Basisdaten) und USER_ENTITY_PROFILE kombiniert.

GET – eigenes Profil lesen

GET https://api.jkz-group.de/v1/users/profile/me

PUT – Profil aktualisieren

Aktualisiert Profilfelder (USER_ENTITY_PROFILE) und optional Username/E-Mail im Identity-Provider.

PUT /v1/users/profile/me
Content-Type: application/json

{
  "displayName": "Neuer Anzeigename",
  "bio": "Kurzbeschreibung",
  "website": "https://example.com"
}

6.3 POST /v1/users/profile/me/avatar

Lädt ein neues Avatar-Bild für den eingeloggten User hoch.

Request

POST https://api.jkz-group.de/v1/users/profile/me/avatar
Content-Type: multipart/form-data

file = <Bilddatei>

Das Bild wird im Upload-Verzeichnis gespeichert, AVATAR_URL in USER_ENTITY_PROFILE wird aktualisiert.

6.4 POST /v1/users/profile/me/banner

Lädt ein neues Profil-Banner für den eingeloggten User hoch.

POST https://api.jkz-group.de/v1/users/profile/me/banner
Content-Type: multipart/form-data

file = <Bilddatei>

Das Bild wird im Upload-Verzeichnis gespeichert, BANNER_URL in USER_ENTITY_PROFILE wird aktualisiert.

6.5 POST /v1/users/profile/me/password

Aktuell nicht produktiv nutzbar.
Dieser Endpoint ist als Platzhalter vorgesehen und gibt derzeit immer 501 Not Implemented zurück.

In der Implementierung wird explizit darauf hingewiesen, dass Passwörter nicht direkt in der Keycloak-Datenbank geändert werden sollen. Stattdessen sollte ein sicherer Flow über die Keycloak-Admin-API oder Account-Management-Funktionen erfolgen.

6.6 GET /v1/users/profile/username

Liest eingeschränkte Profildaten eines beliebigen Users nach Username oder User-ID.

Parameter

  • username (optional, Query)
  • id (optional, Query)

Genau einer der beiden Parameter sollte gesetzt sein.

GET https://api.jkz-group.de/v1/users/profile/username?username=Alice

7. Blocks & Friend-Requests

7.1 /v1/users/blocks/

Verwaltung von Blockierungen durch den eingeloggten User.

GET – Blockierungen auflisten

GET https://api.jkz-group.de/v1/users/blocks/

Listet alle Blockierungen des eingeloggten Users (wen blockiere ich?).

POST – neuen Block erstellen

POST /v1/users/blocks/
Content-Type: application/json

{
  "blockedUserId": "UUID_DES_ZU_BLOCKIERENDEN_USERS"
}

DELETE – Block löschen

DELETE https://api.jkz-group.de/v1/users/blocks/?id=<block-id>

7.2 POST /v1/users/blocks/unblock/

Hebt eine bestehende Blockierung auf (nur für den Owner der Blockierung).

POST /v1/users/blocks/unblock/
Content-Type: application/json

{
  "id": "BLOCK_ID"
}

7.3 /v1/users/friend-requests/

Verwaltung von Freundschaftsanfragen.

GET – Anfragen listen

Listet Friend-Requests (eingehend/ausgehend/alle) für den eingeloggten User.

GET https://api.jkz-group.de/v1/users/friend-requests/?filter=inbound|outbound|all

POST – neue Friend-Request erstellen

POST /v1/users/friend-requests/
Content-Type: application/json

{
  "toUserId": "UUID_DES_ANGESCHRIEBENEN_USERS"
}

7.4 POST /v1/users/friend-requests/accept

Akzeptiert eine bestehende Friend-Request.

POST /v1/users/friend-requests/accept
Content-Type: application/json

{
  "requestId": "UUID_DER_REQUEST"
}

7.5 POST /v1/users/friend-requests/cancel

Bricht eine vom aktuellen User gesendete Friend-Request ab.

POST /v1/users/friend-requests/cancel
Content-Type: application/json

{
  "requestId": "UUID_DER_REQUEST"
}

7.6 POST /v1/users/friend-requests/decline

Lehnt eine eingehende Friend-Request ab.

POST /v1/users/friend-requests/decline
Content-Type: application/json

{
  "requestId": "UUID_DER_REQUEST"
}

7.7 POST /v1/users/friend-requests/unfriend

Entfernt eine bestehende Freundschaft, die über eine akzeptierte Friend-Request entstanden ist.

POST /v1/users/friend-requests/unfriend
Content-Type: application/json

{
  "friendUserId": "UUID_DES_ANDEREN_USERS"
}