Offene Community-API
Eine API auf Community-Ebene: Ein Schlüssel ist an eine Community gebunden und handelt im Namen der Mitglieder, die Sie benennen. Sie ist weder die API des Creator-Dashboards noch die Mitglieder-API — hier gibt es keine Anmeldesitzung.
Bevor Sie anfangen
Zwei Dinge müssen zutreffen, bevor irgendein Schlüssel funktioniert — und keines davon lässt sich aus Ihrem eigenen Code heraus lösen.
1. Der Tarif der Community muss API-Zugang enthalten
Darüber entscheidet die Person, der die Community gehört, nicht die integrierende Seite. Der Tarif braucht die Funktion API-Zugang — sonst gibt jeder Aufruf 22203 zurück — und ein Tageskontingent ungleich null, andernfalls gibt jeder Aufruf 22204 zurück.
Bei Communitys, die vor einiger Zeit angelegt wurden, ist der API-Zugang standardmäßig ausgeschaltet, auch wenn der Tarif bereits andere fortgeschrittene Funktionen enthält. Wenn ein frisch ausgestellter Schlüssel bei jedem Aufruf 22203 liefert, bitten Sie die Eigentümerseite, in der Konsole nachzusehen, statt Ihren Code erneut zu lesen.
Sie müssen das nicht über gesammelte Fehler herausfinden: /capabilities/get beantwortet es direkt und funktioniert auch in genau diesen beiden Fällen.
2. Einen Schlüssel in der Admin-Konsole der Community erstellen
Community-Verwaltung → Integrationen → API Keys → Erstellen. Ein Schlüssel besteht aus mfk_ gefolgt von 64 Hexadezimalzeichen, und der vollständige Wert wird genau einmal angezeigt — danach ist nur noch das Präfix sichtbar.
Die beim Anlegen gesetzten Scopes bestimmen, welche Endpunkte der Schlüssel aufrufen darf. Sie lassen sich später nicht ändern; erstellen Sie dafür einen neuen Schlüssel und widerrufen Sie den alten.
Optional können Sie einen Schlüssel auf eine IP-Freigabeliste beschränken (einzelne Adressen oder CIDR-Bereiche). Anfragen von anderswo scheitern mit 10007 — demselben Code wie bei einem ungültigen Schlüssel, was man sich merken sollte, wenn ein gestern noch funktionierender Schlüssel von einem neuen Host aus versagt.
Scopes
| Scope | Deckt ab |
|---|---|
| site.read | Profil und Einstellungen der Community |
| content.read | Beiträge lesen, Feeds, Suche und Antwortbäume |
| content.write | Beiträge anlegen, bearbeiten und löschen |
| media.read | Signierte URLs für gespeicherte Medien |
| media.write | Upload-Tokens für Medien — liest aus Kompatibilitätsgründen auch signierte URLs |
| spaces.read | Space-Verzeichnis und -Details |
| members.read | Mitglieder lesen und per E-Mail nachschlagen |
Was * bedeutet, hat sich im September 2026 geändert
Früher hieß es „alles, einschließlich später hinzugefügter Scopes“ — und erweiterte damit stillschweigend jeden jemals ausgestellten Schlüssel, sobald die Plattform eine neue Fähigkeit ausrollte. Heute speichert ein neuer Schlüssel die konkrete Liste, die bei seiner Erstellung galt, und ein altes * deckt nur die vier Scopes ab, die bei seiner Ausstellung existierten: site.read, content.read, content.write und media.write.
Ein älterer Schlüssel kann die neueren Endpunkte also nicht aufrufen — Spaces, Mitglieder und das Lesen signierter URLs. Stellen Sie einen neuen Schlüssel mit diesen Scopes aus. Das ist Absicht: Niemand sollte sein Mitgliederverzeichnis herausgeben, nur weil die Plattform eine neue Funktion veröffentlicht hat.
Authentifizierung
Senden Sie Ihren Schlüssel in einem von zwei Headern. Beide sind gleichwertig; senden Sie beide, gewinnt X-API-Key. Die Community wird aus dem Schlüssel abgeleitet, Sie übergeben also nie eine Site-ID.
X-API-Key: mfk_xxx
Authorization: Bearer mfk_xxx
Der Schlüssel ist für sich genommen das Zugangsmittel — bewahren Sie ihn serverseitig auf. Er gehört weder in Browser-Code noch in ein Mobile-Bundle, wo ihn jeder auslesen und damit im Namen Ihrer Mitglieder posten kann.
Konventionen
Sie gelten für jeden Endpunkt weiter unten.
- Jeder Endpunkt ist ein POST. Es gibt kein GET, PUT oder DELETE — auch Lesezugriffe sind POSTs.
- Senden Sie Content-Type: application/json. Endpunkte ohne Parameter erwarten trotzdem einen leeren JSON-Body.
- Jede ID ist ein Hashid-String wie "kZ3mQ9x" — für Community, Nutzer, Beitrag, Space und Medium gleichermaßen. Numerische IDs werden abgelehnt.
- Zeitstempel kommen als RFC3339 zurück, zum Beispiel 2026-08-18T10:00:00Z.
- Beträge sind Ganzzahlen in der kleinsten Währungseinheit (Cent).
- Ein optionaler Accept-Language-Header (zh, en, ja, ko, es, fr, de, pt) lokalisiert die Fehlermeldungen.
- Die Community wird aus Ihrem API-Schlüssel abgeleitet. Senden Sie keine Site-ID, weder im Pfad noch im Body.
Eine Eingabe bricht diese Regel: scheduled_at bei /post/create und /post/update ist ein i64-Unix-Zeitstempel in Sekunden, kein String. Siehe geplante Beiträge weiter unten.
Erfolg und Fehler teilen sich einen Umschlag
{
"code": 0,
"msg": "success",
"data": { }
}Endpunkte
Alle Endpunkte liegen unter /site_open_api/v1, nutzen POST mit JSON-Body und verlangen den angegebenen Scope auf Ihrem Schlüssel.
Die Scopes Ihres Schlüssels, ob der API-Zugang aktiv ist, sowie verbrauchtes und verbleibendes Kontingent samt Rücksetzzeitpunkt. Der einzige Endpunkt, der noch antwortet, wenn Tarifschranke oder Tageskontingent alles andere blockieren — und er verbraucht selbst kein Kontingent. Ein quota_limit von -1 bedeutet unbegrenzt; die drei Kontingentfelder erscheinen und verschwinden gemeinsam, prüfen Sie also vor dem Subtrahieren, ob eines existiert.
Profil, Einstellungen und Metadaten der Community
Ein Beitrag anhand der ID
Erforderlich: id
Bis zu 50 Beiträge auf einmal; nicht gefundene IDs kommen in missing_ids zurück, statt den Stapel scheitern zu lassen
Erforderlich: ids
Beiträge durchsuchen — das Feld heißt query, nicht keyword
Erforderlich: query
Hervorgehobene Beiträge, optional auf einen Space eingegrenzt
Alle Antworten unter einem Beitrag
Erforderlich: post_id
Nur Antworten der ersten Ebene
Erforderlich: post_id
Der Teilbaum unterhalb einer Antwort
Erforderlich: post_id
Die Vorfahrenkette einer Antwort
Erforderlich: post_id
Community-Feed, neueste zuerst (String-Cursor). since_id holt nur neuere Beiträge — Änderungen und Löschungen sieht es nicht, es füllt also eine Timeline auf, statt sie zu synchronisieren
Community-Feed nach Score (Fließkomma-Cursor)
Feed der Highlights (String-Cursor)
Der Feed eines Space, mit optionaler Sortierung, Suche und Q&A-Filtern (String-Cursor)
Erforderlich: space_id
Der Feed eines Space nach Score (Fließkomma-Cursor) — der alte Einstieg, aus Kompatibilitätsgründen erhalten
Erforderlich: space_id
Als Mitglied veröffentlichen. Text, Space, Titel, Antwort- und Zitatziele, Medien, Umfragen, Audio und Terminierung sind alle optional
Erforderlich: author_user_id, idempotency_key
Einen Beitrag bearbeiten; übergeben Sie version für optimistisches Sperren
Erforderlich: actor_user_id, idempotency_key, post_id
Einen Beitrag löschen
Erforderlich: actor_user_id, idempotency_key, post_id
Die für den Betrachter sichtbaren Spaces — lassen Sie viewer_user_id weg für die anonyme Sicht auf öffentlich Lesbares
Ein Space anhand der ID
Erforderlich: id
Ein Mitglied anhand der ID
Erforderlich: id
Eine exakte E-Mail-Adresse einem Mitglied zuordnen
Erforderlich: email
Kurzlebiges Token für den Medien-Upload-Dienst
Erforderlich: author_user_id
Signierte URLs für private Medien (sie laufen ab — neu signieren, nicht speichern)
Erforderlich: author_user_id, items, access_level
curl -X POST https://api.mateflow.com/site_open_api/v1/capabilities/get \
-H "X-API-Key: mfk_xxx" -H "Content-Type: application/json" -d '{}'
# → data: {
# "api_version": "v1",
# "site_id": "kZ3mQ9x",
# "scopes": ["site.read", "content.read"],
# "api_access": true,
# "quota_limit": 5000, // -1 means unlimited
# "quota_used": 128,
# "quota_reset_at": "2026-09-15T00:00:00Z"
# }- Lesezugriffe mit einer ID-Liste sind bei 50 gedeckelt, und limit ist bei allen paginierten Endpunkten ebenfalls bei 50 gedeckelt.
- Bei /space/feed/list folgt die Cursor-Kodierung dem sort-Wert; ein Sortierwechsel bedeutet also, die Paginierung neu zu beginnen. Q&A-Spaces ignorieren sort und ordnen stattdessen nach qa_sort. Neue Integrationen sollten /space/feed/list mit sort=top statt /space/feed/top verwenden.
- Mitgliederantworten sind eine schmale Projektion: id, username, display_name, avatar_url, status, role und created_at. Die E-Mail-Adresse wird nie zurückgegeben, auch dann nicht, wenn Sie darüber gesucht haben — Sie besitzen diese Adresse ohnehin, und die jedes Mitglieds zurückzuspiegeln würde /member/get in einen Adressbuch-Export verwandeln. Die Suche funktioniert nur bei exakter Übereinstimmung, und kein Treffer ist ein normaler Erfolg, kein Fehler: Treffer und Nicht-Treffer sind weder am Statuscode noch an der Antwortzeit zu unterscheiden. Auch die Ratenbegrenzung ist hier die strengste der gesamten API.
Im Namen eines Mitglieds handeln
Die API kennt keine Anmeldesitzung; wer handelt — und aus wessen Sicht Ergebnisse dargestellt werden — steht deshalb immer explizit im Anfrage-Body. Alle drei erwarten eine Mitglieds-Hashid.
author_user_idDas Mitglied, in dessen Namen ein neuer Beitrag erscheint. Es muss dieser Community bereits angehören, sonst 20303.
actor_user_idWer eine Bearbeitung oder Löschung ausführt. Die Rechte werden an diesem Mitglied geprüft — wer weder Verfasser noch Admin ist, erhält 10004.
viewer_user_idBeim Lesen optional. Liefert die Ergebnisse so, wie dieses Mitglied sie sieht: private Spaces, Zustand von Likes und Lesezeichen. Weglassen ergibt die anonyme Sicht auf ausschließlich Öffentliches.
Paginierung
- Feeds und Listen liefern ihre Einträge samt next_cursor. Schicken Sie next_cursor unverändert zurück, um die nächste Seite zu holen; ein leeres next_cursor heißt, Sie sind am Ende angekommen.
- limit ist überall bei 50 gedeckelt.
- Bei /space/feed/list kodiert der Cursor die aktuelle Sortierung. Ein Sortierwechsel mitten in der Liste macht ihn ungültig — beginnen Sie wieder bei der ersten Seite.
Achtung: Die Cursor von /feed/top und /space/feed/top sind Fließkomma-Scores, keine Strings. Beide Arten in derselben String-Variablen zu halten, bricht die Paginierung lautlos.
Idempotenz
Jeder Schreibzugriff erwartet einen idempotency_key im Anfrage-Body. Hier gibt es genau eine Idempotenzebene — lesen Sie den Hinweis unten, falls Sie die Header-basierte der Plattform kennen.
- idempotency_key ist bei jedem Schreibzugriff Pflicht und auf 190 Zeichen begrenzt. Ihn wiederzuverwenden erzeugt nie einen zweiten Beitrag.
- Sein Gültigkeitsbereich ist die Kombination aus Community, Anfragetyp und Schlüsselwert, unabhängig davon, welchen API-Schlüssel Sie benutzt haben: Senden zwei verschiedene Schlüssel derselben Community denselben idempotency_key an denselben Endpunkt, gibt der zweite Aufruf das Ergebnis des ersten zurück.
- Derselbe Schlüssel mit einem anderen Body ergibt einen stabilen Konfliktfehler, statt stillschweigend als erfolgreicher Wiederholungsversuch durchzugehen.
- Läuft eine Anfrage in einen Timeout, wiederholen Sie sie mit demselben Schlüssel — erzeugen Sie niemals einen neuen.
Der allgemeine Idempotency-Key-Header der Plattform — jener mit dem 24-Stunden-Antwortcache — gilt nicht für /site_open_api/**. Diese Ebene sitzt vor der Schlüsselprüfung, ein Cache-Treffer würde die Prüfung des Schlüssels also komplett überspringen. Senden Sie den Header nicht in der Erwartung, dass er hier etwas bewirkt.
Geplante Beiträge
Die Terminierung ist die einzige Stelle, an der sowohl das Eingabeformat als auch das Verhalten vom Rest abweichen.
- scheduled_at ist ein i64-Unix-Zeitstempel in Sekunden — nicht der RFC3339-String, den alle anderen Zeitangaben verwenden.
- Lassen Sie scheduled_at bei /post/update weg, bleibt die bestehende Terminierung unangetastet. Es ist kein Zurücksetzen.
Ein Wert von 0 oder kleiner storniert die Terminierung und schickt den Beitrag zurück in den Entwurf — allerdings haben nur Blogbeiträge einen Entwurfszustand. Bei einem gewöhnlichen Beitrag liefert derselbe Aufruf 10005 mit schedule_cancel_unsupported, denn der darunterliegende Pfad heißt dort „jetzt veröffentlichen“: Ihn anzunehmen würde den Inhalt vorzeitig öffentlich machen, Feed und Benachrichtigungen auslösen und nichts zum Rückgängigmachen hinterlassen.
Medien hochladen
Dateien gehen an den Mediendienst, nicht an den API-Host. In drei Schritten:
- Tauschen Sie Ihren API-Schlüssel über /media/get_token gegen ein kurzlebiges Upload-Token.
- Senden Sie die Datei per multipart-POST an den Mediendienst, das Token in einem wörtlich "token" genannten Header und file_cate als Media, Avatar, Header, Audio oder File.
- Übergeben Sie die zurückgegebene Medien-ID beim Anlegen des Beitrags in media_ids.
Breaking Change, September 2026
Ein ohne ausdrücklichen Scope ausgestelltes Token trägt jetzt nur noch die Upload-Berechtigung; früher umfasste es Upload, Lesen und Löschen zugleich. Haben Sie damit gelesen oder gelöscht, übergeben Sie ausdrücklich einen Scope read oder delete. Davon getrennt: Einer Community in der Nachfrist — Testphase abgelaufen, keine Karte hinterlegt — verweigert die Tarifschranke das Upload-Token; Lese- und Lösch-Tokens sind nicht betroffen.
# 1. Exchange the API key for a short-lived upload token.
# Since 2026-09 a token with no explicit scope is upload-only.
curl -X POST https://api.mateflow.com/site_open_api/v1/media/get_token \
-H "X-API-Key: mfk_xxx" -H "Content-Type: application/json" \
-d '{"author_user_id": "kZ3mQ9x", "scope": "upload"}'
# 2. Upload the file to the media service (token goes in a "token" header)
curl -X POST https://media.mateflow.com/api/v1/media/upload \
-H "token: <token from step 1>" \
-F "file_cate=Media" -F "file=@photo.jpg"
# 3. Attach the media id when creating the post
curl -X POST https://api.mateflow.com/site_open_api/v1/post/create \
-H "X-API-Key: mfk_xxx" -H "Content-Type: application/json" \
-d '{"author_user_id":"kZ3mQ9x","idempotency_key":"6f1c...","body":"Hi","media_ids":["m8Yq2Lp"]}'Private Medien werden über /media/get_signed_urls gelesen. Der Endpunkt nimmt die items und ein access_level von 1 (öffentlich), 2 (halbprivat) oder 3 (privat) entgegen und liefert URLs mit Ablaufzeit. Fordern Sie sie bei Bedarf an, statt sie zu speichern, sonst liefern sie irgendwann 403.
Medien an einen Beitrag hängen
- Senden Sie entweder medias — eine Liste aus media_id und alt — oder media_ids, eine schlichte Liste von IDs. Beides zu senden ergibt 10005.
- alt ist optional. Ein leerer String löscht den vorhandenen Alternativtext; das Feld wegzulassen belässt ihn unverändert.
Fehlercodes
Erfolg und Fehler teilen sich den Umschlag, und der HTTP-Status folgt dem fachlichen Code. Verzweigen Sie über code, nicht über den Status.
| Code | HTTP | Bedeutung |
|---|---|---|
| 0 | 200 | Erfolg |
| 10005 | 400 | Ungültige Parameter — msg nennt das betroffene Feld |
| 10007 | 401 | Schlüssel ungültig, widerrufen oder abgelaufen, oder die aufrufende IP steht nicht auf der Freigabeliste |
| 21304 | 403 | Dem Schlüssel fehlt der Scope, den dieser Endpunkt verlangt; Scopes stehen ab Erstellung fest |
| 22203 | 403 | Der Tarif enthält keinen API-Zugang — siehe data.required_plan |
| 22204 | 403 | Tageskontingent erschöpft — siehe data.current und data.limit |
| 20303 | 404 | author_user_id / viewer_user_id ist kein Mitglied dieser Community |
| 10003 | 404 | Der Zieldatensatz existiert nicht |
| 10004 | 403 | Die handelnde Person hat keine Rechte an dieser Ressource |
| 10202 | 429 | Rate begrenzt — drosseln Sie und beachten Sie den Retry-After-Header |
| 10001 | 500 | Serverfehler — eine Wiederholung ist unbedenklich |
Achtung, Falle: 22203 und 22204 sind 403, nicht 429. Nur 10202 ist eine Drosselung. Erkennen Sie sie am code, nie am HTTP-Status — das ist die mit Abstand häufigste Fehldeutung dieser API.
Fehlerantworten tragen eine request_id. Nennen Sie sie, wenn Sie ein Problem melden — darüber finden wir genau Ihren Aufruf in den Logs.
Tariffehler tragen strukturierte Metadaten
Beide Tariffehler kommen mit genug Details zurück, um der Eigentümerseite zu sagen, was zu tun ist — Sie können also eine echte Meldung zeigen statt „etwas ist schiefgelaufen“.
// The plan does not include API access
{
"code": 22203,
"msg": "...",
"request_id": "00de5640-8ae5-4a71-aef8-2f2cab0ce8a7",
"data": {
"error_code": "feature_not_available",
"feature": "api_access",
"required_plan": "Growth"
}
}
// The community is out of daily quota
{
"code": 22204,
"data": {
"error_code": "quota_exceeded",
"resource": "api_requests_per_day",
"current": "5001",
"limit": "5000",
"required_plan": "Business"
}
}Kontingent und Ratenbegrenzung
Drei voneinander getrennte Mechanismen. Sie zu verwechseln ist der Grund, warum eine Integration als „ratenbegrenzt“ gemeldet wird, obwohl ihr in Wahrheit das Tarifkontingent ausgegangen ist.
| Ebene | Zählt | Bei Überschreitung |
|---|---|---|
| Tages-Kontingent des Tarifs | Ein ganzer Tag, alle Endpunkte, pro Community | 22204 / HTTP 403 |
| Burst-Budget pro Schlüssel | 10- und 60-Sekunden-Fenster, pro Schlüssel, nach Endpunkt gestaffelt | 10202 / HTTP 429 |
| Allgemeines IP-Limit | Pro Quell-IP, 60 je 10 s und 300 pro Minute | 10202 / HTTP 429 |
Das Tageskontingent zählt Anfragen, die die Authentifizierung passieren, wird um 00:00 UTC zurückgesetzt und meldet in data.limit die tatsächlich geltende Obergrenze — einschließlich einer eigens für diese Community angehobenen Freigabe. Wenn das Backend des Zählers Probleme macht, wird die Anfrage durchgelassen statt abgewiesen; eine gelegentliche Untererfassung heißt also nicht, dass das Kontingent nicht mehr greift.
Burst-Budget pro Schlüssel (neu im September 2026)
Früher gab es nur den Eimer pro IP: Mehrere Kunden hinter einer Ausgangsadresse machten sich gegenseitig Platz streitig, während ein über viele Adressen verteilter Aufrufer kaum eingeschränkt war. Das Budget ist nun pro Schlüssel gestaffelt — jenem Ding, das die Eigentümerseite ausstellt, rotieren kann und für das sie geradesteht.
| Stufe | Deckt ab | Pro 10 s | Pro 60 s |
|---|---|---|---|
| Lesen | Feeds, Beiträge, Antworten, Spaces, Introspektion | 120 | 600 |
| Medien | get_token und get_signed_urls | 30 | 120 |
| Schreiben | Beiträge anlegen, ändern und löschen | 20 | 120 |
| Suche | post/search | 20 | 60 |
| Mitgliedersuche | member/lookup | 5 | 10 |
member/lookup ist deutlich strenger — aus Sicherheitsgründen, nicht wegen der Kapazität. Die übrigen Beschränkungen begrenzen, wie viel eine einzelne Antwort preisgibt; diese begrenzt, wie oft Sie fragen dürfen — und genau das ist der Schritt, der aus einer Suche ein Abgrasen des Verzeichnisses macht. Für den vorgesehenen Zweck, nämlich bereits vorhandene Adressen im menschlichen Tempo aufzulösen, sind zehn pro Minute mehr als genug.
- Eine Überschreitung liefert HTTP 429 mit code 10202, dazu Retry-After sowie die Header X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset.
- Nehmen Sie diese Zahlen als Ausgangspunkt, nicht als Messwert — sie werden anhand des beobachteten Verkehrs angepasst. Verdrahten Sie sie nicht fest in Ihrer Retry-Logik; halten Sie sich an 429 und Retry-After. Die gesamte Ratenbegrenzung ist standardmäßig aus und läuft eine Weile im Beobachtungsmodus, bevor sie greift.
- Implementieren Sie in jedem Fall ein Backoff bei 429 und halten Sie den Leseverkehr bei etwa zehn Anfragen pro Sekunde oder darunter.
Webhooks empfangen
Hat die Eigentümerseite einen Webhook-Endpunkt eingerichtet oder Slack, Discord oder Zapier verbunden, tragen die Zustellungen zwei Sätze von IDs mit unterschiedlicher Bedeutung.
| Feld | Bezeichnet | Über Wiederholungen hinweg |
|---|---|---|
| event_id | Das fachliche Ereignis | Bleibt gleich |
| occurred_at | Wann das Ereignis eintrat | Bleibt gleich |
| delivery_id | Diesen Zustellversuch | Ändert sich |
| timestamp | Wann dieser Versuch gesendet wurde | Ändert sich |
Entdoppeln Sie über event_id. Eine Zustellung, die Sie erfolgreich verarbeitet, aber zu langsam beantwortet haben, trifft erneut ein — mit neuer delivery_id und derselben event_id. Geht ein Ereignis gleichzeitig an einen eigenen Webhook und an einen Zap, sehen beide Seiten dieselbe event_id und lassen sich abgleichen.
Die Zustellung erfolgt mindestens einmal und kann in falscher Reihenfolge ankommen. Sowohl Duplikate als auch verspätet eintreffende ältere Ereignisse sind normal; die empfangende Seite muss idempotent sein.
event_id kann fehlen. Aufträge, die vor Einführung des Felds in die Warteschlange kamen, tragen es nicht, und die Zustellung lässt das Feld ganz weg, statt 0 zu senden — eine 0 ließe alle alten Aufträge wie dasselbe Ereignis aussehen. Akzeptieren Sie das Fehlen und greifen Sie dann auf eine Bestmöglich-Entdopplung über delivery_id zurück.
Fehlerbehebung
Die Symptome, die tatsächlich gemeldet werden, und woran es meist liegt.
| Symptom | Meistens |
|---|---|
| 10007 invalid API key, obwohl der Schlüssel gerade erst aus der Konsole kopiert wurde | Leerzeichen oder ein Zeilenumbruch um den Schlüssel; oder der Schlüssel wurde widerrufen; oder es gibt eine IP-Freigabeliste und Ihre Ausgangsadresse steht nicht darauf |
| 22203 feature_not_available | Im Tarif ist der API-Zugang aus. Nach der Änderung durch die Eigentümerseite dauert es bis zu 10 Minuten, bis der Tarif-Cache abläuft |
| 22204 quota_exceeded mit einem limit von 0 | Das Tages-Anfragekontingent des Tarifs ist 0, was nicht verfügbar heißt — nicht „nicht gesetzt, also unbegrenzt“ |
| 21304 bei einem Endpunkt, von dem Sie dachten, er funktioniere | Dem Schlüssel fehlt dieser Scope. Scopes stehen ab Erstellung fest, die Lösung ist also ein neuer Schlüssel |
| 21304 bei einem Schlüssel mit „allen Rechten“ (*) | Ein altes * deckt später hinzugefügte Scopes nicht ab — media.read, spaces.read, members.read. Stellen Sie einen neuen Schlüssel mit diesen Häkchen aus |
| 10202 mit HTTP 429 | Eine Ratenbegrenzung. Drosseln Sie gemäß Retry-After; trat sie bei member/lookup auf, denken Sie daran, dass dieser Eimer zehn pro Minute erlaubt |
| 10005 mit schedule_cancel_unsupported | Sie haben bei einem gewöhnlichen Beitrag ein scheduled_at von 0 oder kleiner übergeben. Nur Blogbeiträge haben einen Entwurfszustand, in den sie zurückkehren können |
| Ein Medien-Token, mit dem gelesen oder gelöscht wurde, funktioniert nicht mehr | Seit September 2026 ist ein Token ohne Scope reines Upload-Token. Übergeben Sie einen Scope read oder delete |
| /member/lookup liefert 200 mit found false | Das ist ein normales „nicht gefunden“, kein Fehler. Treffer und Nicht-Treffer sind beide 200 — verzweigen Sie über found |
| 10005 invalid params mit Verweis auf query | Das Suchfeld heißt query. keyword ist kein gültiges Feld |
| 20303 user not found | Die ID gehört keinem Mitglied dieser Community, oder Sie haben eine numerische ID statt einer Hashid gesendet |
| Die Paginierung kommt nicht mehr voran | Die Cursor von /feed/top und /space/feed/top sind Fließkommazahlen. Als String serialisiert passen sie nicht mehr |
| Medien-URLs liefern nach einer Weile 403 | Signierte URLs haben eine TTL. Signieren Sie bei Bedarf neu, statt sie zu speichern |
Hinweise
- Die Community wird aus Ihrem API-Schlüssel abgeleitet. Senden Sie keine Site-ID, weder im Pfad noch im Body.
- Scopes stehen mit der Erstellung des Schlüssels fest. Zum Ändern erstellen Sie einen neuen Schlüssel und widerrufen den alten.
- Bewahren Sie Ihre API-Schlüssel serverseitig auf. Ein Schlüssel im Client-Code erlaubt jedem, der ihn liest, im Namen Ihrer Mitglieder zu posten.
- Der OpenAPI-Vertrag deckt jeden Pfad und jedes Schema ab. Ein Vorbehalt: Der Generator, aus dem er stammt, gibt kein required für Anfrage-Bodys aus — nehmen Sie die Pflichtfelder daher von dieser Seite und nicht aus dem Vertrag.
Loslegen
Erstellen Sie in der Admin-Konsole Ihrer Community einen Schlüssel mit Scopes, prüfen Sie ihn mit /capabilities/get, und los geht's.
14 Tage kostenlos testen · Keine Kreditkarte erforderlich