Modara für Entwickler

Deine Community.
Deine Statistiken.

Zeige Mitgliederzahlen, Aktivität und Wachstum auf deiner eigenen Website. Die Version 1 der API liefert ausschließlich aggregierte Serverstatistiken.

OpenAPI-Spezifikation

In vier Schritten starten

  1. Als Discord-Server-Owner oder Administrator anmelden und im Dashboard deinen Server wählen.
  2. Entwickler-API öffnen und aktivieren. Modara muss auf dem Server installiert sein.
  3. Einen Schlüssel benennen und 30, 90 oder 365 Tage Laufzeit wählen. Den vollständigen Schlüssel sofort in einem Secret Store sichern; er wird nur einmal angezeigt.
  4. Die API von deinem eigenen Backend aufrufen. Dein Frontend erhält nur die Kennzahlen, die du veröffentlichen möchtest.

Jeder Schlüssel gilt nur für den gewählten Server und den Scope stats:read. Es gibt keinen Schreibzugriff auf Discord, Nutzerkonten oder Einstellungen.

Endpunkt und Authentifizierung

GET /discord/api/v1/guilds/{guildId}/stats?days=30
Authorization: Bearer DEIN_API_SCHLUESSEL

guildId ist die Discord-Server-ID aus deiner Dashboard-Adresse. days ist optional, standardmäßig 30; erlaubt sind ganze Zahlen von 1 bis 90. Weitere Queryparameter sind nicht erlaubt.

Die Basis-URL enthält den Modara-Pfad, hier /discord. Kopiere den Endpunkt für deine konkrete Installation im Dashboard. Nutze HTTPS.

curl

Setze MODARA_BASE_URL, MODARA_GUILD_ID und MODARA_API_KEY als Umgebungsvariablen in deiner geschützten Serverumgebung. Einen echten Schlüssel nicht in die Shell-History schreiben.

curl --fail-with-body --max-time 10 \
  --header "Authorization: Bearer $MODARA_API_KEY" \
  "$MODARA_BASE_URL/api/v1/guilds/$MODARA_GUILD_ID/stats?days=30"

Serverseitiges JavaScript

// Node.js 20+: ausschließlich im Backend ausführen.
const base = process.env.MODARA_BASE_URL?.replace(/\/$/, "");
const guildId = process.env.MODARA_GUILD_ID;
const key = process.env.MODARA_API_KEY;
if (!base || !guildId || !key) throw new Error("Konfiguration fehlt");

const response = await fetch(
  base + "/api/v1/guilds/" + encodeURIComponent(guildId) + "/stats?days=30",
  {
    headers: { Authorization: "Bearer " + key },
    signal: AbortSignal.timeout(10000),
    redirect: "error",
    cache: "no-store"
  }
);
if (!response.ok) {
  // Bei 429/503: Retry-After abwarten; keine schnelle Retry-Schleife.
  throw new Error("Modara HTTP " + response.status);
}
const stats = await response.json();
// Nur gewünschte Kennzahlen an dein Frontend geben, niemals den Schlüssel.
const publicStats = {
  members: stats.memberCount,
  messages: stats.coverage.recordedDays > 0 ? stats.totals.messageCount : null,
  updatedAt: stats.generatedAt
};

Keine NEXT_PUBLIC_-Variable für den Schlüssel verwenden. Browser-JavaScript, Apps und öffentliche Repositories dürfen ihn nicht enthalten. Die API bietet keine CORS-Freigabe für direkte Browseraufrufe. Verwende einen eigenen Backend-Endpunkt mit begrenztem Cache, zum Beispiel 60 Sekunden.

Antwort und Bedeutung der Daten

Das folgende JSON ist eine fiktive Beispielantwort zur Erklärung des Formats. Es zeigt keine Live-Daten eines Servers.

{
  "apiVersion": "1",
  "guildId": "123456789012345678",
  "generatedAt": "2026-09-13T12:00:00.000Z",
  "window": {
    "days": 1,
    "from": "2026-09-13T00:00:00.000Z",
    "to": "2026-09-13T12:00:00.000Z",
    "timezone": "UTC",
    "includesPartialToday": true
  },
  "coverage": {
    "recordedDays": 1,
    "requestedDays": 1,
    "missingDaysAreZero": false
  },
  "memberCount": 42,
  "totals": {
    "messageCount": 12,
    "activeMemberDays": 4,
    "joinCount": 2,
    "leaveCount": 1,
    "voiceMinutes": 30,
    "moderationCount": 0
  },
  "daily": [
    {
      "date": "2026-09-13",
      "messageCount": 12,
      "activeMemberCount": 4,
      "joinCount": 2,
      "leaveCount": 1,
      "voiceMinutes": 30,
      "moderationCount": 0
    }
  ]
}
FeldBedeutung
memberCountZuletzt bekannter Mitgliederstand des Discord-Servers, inklusive Bots; null, wenn unbekannt. Kein historischer Tagesendstand.
messageCountErfasste Nachrichten von Nicht-Bot-Nutzern in Kanälen, die Modara sehen konnte.
activeMemberCountVerschiedene erfasste Nachrichtenschreiber innerhalb eines UTC-Tages. Kein Online-Zähler.
activeMemberDaysSumme der täglichen aktiven Mitglieder. Dieselbe Person kann an mehreren Tagen zählen; keine eindeutige Nutzerzahl über den gesamten Zeitraum.
joinCount / leaveCountErfasste Serverbeitritte und -austritte. Dieselbe Person kann mehrfach beitreten.
voiceMinutesErfasste Personenminuten im Sprachchat. Zwei Personen mit je zehn Minuten ergeben 20.
moderationCountIm Analytics-System erfasste Moderationsaktionen; kein vollständiger Discord-Audit-Log.
coverage.recordedDaysAnzahl vorhandener Tagesdatensätze. Fehlende Tage werden nicht mit Null aufgefüllt. Vorhandene Tage können bei Ausfällen unvollständig sein.

daily ist nach Datum aufsteigend sortiert. Der Zeitraum beginnt um 00:00 UTC des ersten Tages und enthält den heutigen, noch laufenden Tag. generatedAt bezeichnet den Abrufzeitpunkt, nicht den letzten Discord-Event. Die Verarbeitung erfolgt im Hintergrund; Werte können nachlaufen.

Bei fehlender Historie lautet die Antwort daily: [] mit recordedDays: 0. Summen sind dann technisch 0, belegen aber keine Inaktivität. Kennzeichne das auf deiner Website als „Noch keine Daten“. Eine rückwirkende Erfassung vor der Installation findet nicht statt. Verfügbarkeit hängt von Bot-Rechten, Verbindung und gespeicherter Historie ab.

Mitglieder-IDs, Namen, E-Mail-Adressen und Nachrichteninhalte sind nicht Teil der Statistikantwort. Version 1 enthält keine Kanal-Einzeldaten.

Limits und Fehler

Pro API-Schlüssel sind 60 Anfragen je 60-Sekunden-Fenster erlaubt, zusätzlich 120 pro verifizierter Client-IP. Bei einer Installation ohne vertrauenswürdige Proxy-IP gilt stattdessen ein gemeinsames zusätzliches Limit von 120. Das Fenster beginnt mit der ersten Anfrage. Dashboard-Verwaltung: 30 Anfragen je Minute und Nutzer/Server.

Erfolgreiche Antworten enthalten X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset-After für den Schlüssel. Alle Antworten haben Cache-Control: no-store, private. Bei 429 und 503 enthält Retry-After die Wartezeit in Sekunden.

{
  "error": {
    "code": "API_DISABLED",
    "message": "Die Entwickler-API ist für diesen Server deaktiviert."
  }
}
HTTPCodeWas tun?
400INVALID_QUERYdays oder unbekannte Queryparameter prüfen.
401UNAUTHORIZEDSchlüssel fehlt, ist falsch, abgelaufen, widerrufen oder gehört zu einem anderen Server.
403API_DISABLED / BOT_NOT_INSTALLEDAPI im Dashboard aktivieren bzw. Modara wieder installieren.
404NOT_FOUNDUngültige oder nicht mehr vorhandene Ressource.
429RATE_LIMITEDRetry-After in Sekunden abwarten.
503SERVICE_UNAVAILABLEDatenbank oder Rate-Limiter vorübergehend nicht verfügbar; Retry-After beachten.

Schlüssel pflegen und API ausschalten

Die Entwickler-Seite zeigt aktive und zuletzt erstellte Schlüssel. Mit Widerrufen sperrst du einen Schlüssel dauerhaft. Ersetzen erstellt einen neuen und widerruft den bisherigen sofort. Für einen Wechsel ohne Unterbrechung: zusätzlichen Schlüssel erstellen, dein Backend umstellen, danach den alten widerrufen.

API deaktivieren sperrt alle Schlüssel dieses Servers bei den folgenden Anfragen. Bereits laufende Antworten und Daten, die deine Website gespeichert hat, werden dadurch nicht zurückgerufen. Beim erneuten Aktivieren funktionieren noch gültige Schlüssel wieder. Löscht der Ersteller sein Modara-Konto, werden seine Schlüssel entfernt.

Speichere Schlüssel niemals in URLs oder Logs. Bei versehentlicher Veröffentlichung sofort widerrufen. Bis zu zehn aktive Schlüssel pro Server sind möglich; abgelaufene Schlüssel funktionieren nicht mehr.