Posty API, MCP und CLI Referenz
Diese Seite ist die vollständige Referenz der programmierbaren Schnittstellen von Posty: jeder öffentliche REST-Endpunkt, alle Befehle des Kommandozeilentools und die Tools des MCP-Servers. Wenn du noch nicht entschieden hast, welche Schnittstelle du brauchst, die Entwicklerübersicht ist der Einstieg.
Eine eigene Seite pro Endpunkt, mit Parametern und ausführbaren Beispielen, steht in der vollständigen Dokumentation: posty.hu/dokumentacio/api/vegpontok.
So funktioniert es
Posty verwaltet über drei Schnittstellen denselben Arbeitsbereich wie die Weboberfläche. Die REST-API aus deinem eigenen Code, das Kommandozeilentool aus dem Terminal und deinen Skripten, der MCP-Server aus einem KI-Agenten. Alle drei nutzen dieselben Berechtigungen und Limits. Was du auf der einen tun kannst, kannst du auch auf den anderen tun.
Die Basis-URL der REST-API ist https://api.posty.hu/public/v1. Die Version steht in der Route, und jede Antwort ist JSON.
Verbinden in drei Schritten
1. Registriere dich unter posty.hu/regisztracio. Kein Verkaufsgespräch, keine Warteliste.
2. Verknüpfe in der Oberfläche mindestens ein Social-Media-Konto. Diesen Schritt kannst du nicht über die API erledigen, weil die Plattform die Einwilligung eines Menschen braucht.
3. Lege dir selbst einen Schlüssel an: Automatisierungen → Entwickler. Der Schlüssel ist nur einmal sichtbar, im Moment des Anlegens.
Dein erster Aufruf kann prüfen, ob alles sitzt. Dieser Endpunkt antwortet auch ohne Schlüssel und sagt dir, wo du alles findest:
curl https://api.posty.hu/public/v1/statusDer erste authentifizierte Aufruf listet deine Kanäle:
curl https://api.posty.hu/public/v1/integrations \
-H "Authorization: psty_a_kulcsod"Authentifizierung
Zwei Arten von Zugangsdaten funktionieren. Der API-Schlüssel ist der vollständige Wert des Authorization-Headers (psty_…) und ist für deinen eigenen Code. Das OAuth-2.1-Access-Token (Bearer pos_…) brauchst du, wenn eine andere Anwendung im Namen deiner Nutzer auf Posty zugreift. Der Ablauf läuft mit PKCE, die Metadaten sind maschinenlesbar.
Die Berechtigungen eines Schlüssels folgen der aktuellen Rolle seines Inhabers. Wird jemand herabgestuft oder aus dem Arbeitsbereich entfernt, kann der Schlüssel sofort nur noch das, was die Person selbst darf. Gehört ein Schlüssel zu mehreren Arbeitsbereichen, wählt der Header showorg einen davon.
Endpunkte
Jeder Pfad liegt unter https://api.posty.hu/public/v1. Die Spalte „Berechtigung" zeigt, welchen Scope der Schlüssel braucht. Fehlt er, ist die Antwort 403, und sie nennt den fehlenden.
| Methode | Pfad | Was es tut | Berechtigung |
|---|---|---|---|
| GET | /status | Status und Discovery. Antwortet auch ohne Schlüssel. | |
| POST | /signup/start | Schickt einen Einmalcode an die E-Mail-Adresse des Nutzers. Ohne Schlüssel aufrufbar, und die Antwort ist für jede Adresse gleich. | |
| POST | /signup/complete | Legt mit dem Code und der Zustimmung des Nutzers (acceptTerms: true) das Konto an und zeigt einmalig einen vollständigen Arbeitsbereich-Schlüssel (psty_sa_). Es gibt keine kostenlose Testphase, der nächste Schritt ist der Checkout. 409, wenn es für die Adresse schon ein Konto gibt. | |
| GET | /is-connected | Prüft, ob der Schlüssel auf einen gültigen Arbeitsbereich zeigt. | |
| GET | /workspaces | Die Arbeitsbereiche, die der Schlüssel erreicht. `current` markiert den, auf dem die Anfrage ankam. Gilt der Schlüssel für mehrere Arbeitsbereiche, erwarten die übrigen Routen die Arbeitsbereich-ID im Header `showorg`. | |
| GET | /integrations | Die verbundenen Kanäle: ID, Name, @Handle, Plattform, und ob der Kanal gerade posten kann. | channels:read |
| GET | /integration-settings/:id | Die Posting-Regeln und das Einstellungsschema eines Kanals, mit dem für das Konto aufgelösten Zeichenlimit. | channels:read |
| POST | /integration-trigger/:id | Eine plattformspezifische Abfrage auf einem Kanal: Listen von Boards, Subreddits, Seiten. | channels:read |
| GET | /social/:integration | Gibt die Plattform-URL zurück, die ein Mensch öffnen muss, um den Kanal zu verbinden. | channels:write |
| GET | /groups | Die Kundengruppen, in die die Kanäle einsortiert sind. | channels:read |
| GET | /posts | Der Kalender für einen Zeitraum: jeder Beitrag mit Status und Zeitpunkt. | posts:read |
| POST | /posts | Legt einen Beitrag an: Entwurf, geplant oder sofort veröffentlicht, auf einem oder mehreren Kanälen. | posts:draft (zum Veröffentlichen zusätzlich posts:publish) |
| DELETE | /posts/:id | Löscht nur diesen einen Beitrag (einen Kanal) mit seinem Thread. Die anderen Kanäle der Gruppe bleiben. | posts:draft |
| DELETE | /posts/group/:group | Löscht die ganze Gruppe auf allen Kanälen: eine Bearbeitung, die an mehrere Kanäle ging. | posts:draft |
| PUT | /posts/:id/status | Verschiebt einen Beitrag zwischen Entwurf und geplant. | posts:publish |
| GET | /posts/:id/missing | Sagt, was dem Beitrag für die Veröffentlichung noch fehlt. | posts:read |
| PUT | /posts/:id/release-id | Hält ID und URL eines Beitrags fest, der außerhalb der Plattform veröffentlicht wurde. | posts:publish |
| GET | /find-slot/:id | Der nächste freie Termin nach dem Zeitplan des Arbeitsbereichs. | posts:read |
| POST | /upload | Lädt ein Bild oder Video in die Mediathek hoch, bis 1 GB. | media:write |
| POST | /upload-from-url | Holt eine Mediendatei von einer öffentlichen URL in die Mediathek. | media:write |
| POST | /upload-link | Ein Upload-Link für den Browser, wenn die Datei auf dem Gerät des Nutzers liegt. | media:write |
| GET | /upload-link/:id | Die über einen Upload-Link eingegangenen Dateien, mit einer URL, die in einen Beitrag passt. | media:write |
| GET | /analytics/:integration | Die Statistiken eines Kanals für den angefragten Zeitraum. | analytics:read |
| GET | /analytics/post/:postId | Die Plattformstatistiken eines veröffentlichten Beitrags. | analytics:read |
| GET | /notifications | Die Benachrichtigungen des Arbeitsbereichs, seitenweise. | posts:read |
| GET | /fotoai/status | Ob das FotoAI-Konto des Schlüsselinhabers verbunden ist, als wer, und das FotoAI-Guthaben. | media:write |
| GET | /fotoai/models | Die Bild- und Videomodelle von FotoAI mit ihren Parametern (Seitenverhältnis, Auflösung, Länge) und dem Preis in Credits. | media:write |
| POST | /fotoai/quote | Der genaue Preis einer Generierung und eine quote_id, 10 Minuten gültig. Verbraucht nichts. | media:write |
| POST | /fotoai/generations | Startet eine Generierung mit den FotoAI-Credits des Nutzers, mit Preisobergrenze (max_millicredits oder quote_id) und Idempotenzschlüssel. Das Ergebnis landet in der Mediathek. | media:write |
| GET | /fotoai/generations | Die letzten FotoAI-Generierungen des Nutzers aus allen Quellen, markiert, wenn eine schon in der Mediathek dieses Arbeitsbereichs liegt. | media:write |
| GET | /fotoai/generations/:id | Der Status einer Generierung; wenn fertig, die in der Mediathek gespeicherten Bilder und Videos mit einer URL für den Beitrag. | media:write |
| POST | /fotoai/generations/:id/import | Importiert eine beliebige FotoAI-Generierung (auch auf fotoai.hu erstellte) in die Mediathek. Ein zweiter Import liefert dieselben Medien. | media:write |
| GET | /plans | Die vier Tarife (Alap, Pro, Kreátor, Csapat) mit Monats- und Jahrespreis in Forint, Euro, Schweizer Franken und US-Dollar, die wichtigsten Limits, die Regel der Testphase und der aktuelle Tarif des Arbeitsbereichs. Antwortet ohne Tarifsperre. | |
| GET | /subscription | Der Status des Abonnements, das den Arbeitsbereich steuert (none, trialing, active, past_due, read_only, cancelled), der Tarif, das Ende des Zeitraums und ein in der letzten Stunde gestarteter, unbezahlter Checkout. Frag das nach der Zahlung ab. | |
| POST | /subscriptions/checkout | Ein Stripe-Checkout-Link für den gewählten Tarif und Zeitraum. Er belastet nichts: Der Nutzer öffnet den Link und zahlt mit seiner eigenen Link-Wallet oder Karte. Nur ein OAuth-Token oder ein vollständiger Arbeitsbereich-Schlüssel (psty_sa_) des Zahlenden kann ihn aufrufen. | |
| GET | /subscription/portal | Ein kurzlebiger Link zum Stripe-Abrechnungsportal: Tarifwechsel, Kündigung, Rechnungen, Karte. Dieselbe Authentifizierungsregel wie beim Checkout. |
Die genauen Request- und Response-Schemas, Feld für Feld, stehen in der OpenAPI-3-Beschreibung. Daraus kannst du auch Client-Code generieren lassen.
Beispiel: geplanter Beitrag
Das Datum ist immer UTC, im ISO-8601-Format. type kann draft, schedule oder now sein.
curl -X POST https://api.posty.hu/public/v1/posts \
-H "Authorization: psty_a_kulcsod" \
-H "Content-Type: application/json" \
-d '{
"type": "schedule",
"date": "2026-09-15T09:00:00.000Z",
"shortLink": false,
"posts": [{
"integration": { "id": "deine_kanal_id" },
"value": [{ "content": "<p>Hallo zusammen!</p>" }]
}]
}'Die Antwort gibt pro Kanal eine Zeile zurück, mit dem postId-Wert, den du zum Löschen und zum Ändern des Status verwendest.
Fehler
Jeder Fehler ist JSON. Bei Fehlern, die Posty auslöst, trägt das msg Feld den Satz für Menschen. Aufrufe, die an der formalen Prüfung der Anfrage scheitern, bekommen das Format des Frameworks (statusCode, message, error). Die 403 wegen fehlender Berechtigung nennt den fehlenden Scope und die Rolle des Schlüsselinhabers, weil der häufigste Grund nicht der falsche Schlüssel ist, sondern der herabgestufte Nutzer.
Der Statuscode sagt dir, ob sich ein erneuter Versuch lohnt: 400, 401, 403 und 404 gehen nicht weg, bis du etwas änderst. 429 und 5xx schon. Das Schema ApiError beschreibt das auch maschinenlesbar in der OpenAPI-Beschreibung.
Ratenlimits
Jede Antwort trägt die Header RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset (in Sekunden, kein Zeitstempel) und RateLimit-Policy. Bei 429 kommt zusätzlich Retry-After. Jede Route hat ein eigenes Kontingent, pro Schlüssel. Warte nicht auf die 429: am Restwert kannst du vorher drosseln.
Versionierung und Abkündigung
Die Version steht in der Route: jeder öffentliche Aufruf läuft unter /public/v1. Eine inkompatible Änderung würde als neue Version erscheinen (/public/v2), und v1 hält seinen Vertrag. Erweiterungen (neues optionales Feld, neue Route, neuer Enum-Wert) erfolgen innerhalb von v1. Dein Code ignoriert deshalb Felder, die er nicht kennt.
Würden wir eine Route abkündigen, bekäme ihre Antwort den Header Deprecation: true, dazu im Header Sunset das Datum, ab dem sie nicht mehr funktioniert. Dieses Datum liegt nie weniger als 180 Tage in der Zukunft. Jede Antwort trägt außerdem einen Link-Header mit der Relation rel="sunset", der auf diesen Abschnitt zeigt. Derzeit ist nichts abgekündigt.
Kommandozeilentool
posty-cli nutzt dieselbe API, nur vom Terminal aus. Installation und Anmeldung:
npm install -g posty-cli
posty auth:login
posty integrations:listDie Anmeldung öffnet einen Browser und speichert den Schlüssel auf deinem Rechner, damit du ihn nicht in deine Skripte schreiben musst. Jeder Befehl kann --json-Ausgabe liefern, die für die maschinelle Verarbeitung gedacht ist.
| posty auth:login | Sign in through the browser. The machine stores the key. |
| posty auth:signup --email <address> | A new account with a code sent by email, without a free trial. The machine stores the key, then comes billing:subscribe. |
| posty auth:status | Which workspace this machine is linked to. |
| posty auth:logout | Delete the stored key. |
| posty integrations:list | The connected channels, with IDs. |
| posty integrations:settings <id> | A channel's rules and settings. |
| posty integrations:trigger <id> <method> | A platform-specific lookup on the channel. |
| posty posts:create -c "text" --date "..." -i "<id>" | A scheduled post to one or more channels. |
| posty posts:create -c "text" -t draft ... | The same as a draft, without publishing. |
| posty posts:create --json file.json | The full request from a file, for scripts. |
| posty posts:list | The calendar contents. |
| posty posts:delete <id> | Delete one post (one channel). |
| posty posts:delete-group <group> | Delete the whole group, from every channel. |
| posty posts:status <id> --status draft | Switch between draft and scheduled. |
| posty posts:find-slot <id> | The next free time slot. |
| posty upload <file> | Upload media to the media library. |
| posty upload:link | A browser upload link, for when the file is not on this machine. |
| posty upload:files <id> | What has arrived on the upload link. |
| posty analytics:platform <id> -d 30 | Channel statistics for the last N days. |
| posty analytics:post <id> | A post's statistics. |
| posty posts:missing <id> | What a post still needs. |
| posty fotoai:status | Whether FotoAI is connected, as whom, and the credit balance. |
| posty fotoai:models --category image | FotoAI's models with their parameters and price. |
| posty fotoai:generate -m <model> -p "prompt" --aspect 4:5 | Quote, confirm, generate with your own FotoAI credits; the result goes into the media library. |
| posty fotoai:get <id> | A generation's status and the URLs of the files saved in the media library. |
| posty billing:plans | The prices and limits of the four plans. |
| posty billing:subscribe --tier pro --period yearly | A Stripe Checkout link for the plan. --open opens it in the browser. The user pays. |
| posty billing:status | The subscription status. Check it after payment. |
| posty billing:manage | A link to the Stripe billing portal. |
MCP-Server
Die Adresse des MCP-Servers ist https://api.posty.hu/mcp-oauth, mit Streamable HTTP-Übertragung und OAuth-2.1-Authentifizierung. Dein Agent sieht diese Tools:
| Tool | Was es tut | Schreibt? |
|---|---|---|
| get_workspace_context | Die genaue Zeit in UTC, die Zeitzone des Nutzers und der Name des Arbeitsbereichs. | nein |
| list_workspaces | Listet die Arbeitsbereiche des Nutzers auf und markiert den, in dem die Verbindung arbeitet. | nein |
| switch_workspace | Stellt die Verbindung auf einen anderen Arbeitsbereich um. Danach arbeiten alle Werkzeuge dort. | ja |
| list_integrations | Die verbundenen Kanäle mit ID, @Handle und Status. | nein |
| list_groups | Die Kundengruppen. | nein |
| get_integration_schema | Die Regeln eines Kanals und das für das Konto aufgelöste Zeichenlimit. | nein |
| get_channel_options | Plattformspezifische Auswahlwerte für einen Kanal. | ja |
| preview_post | Zeigt pro Kanal, was rausgehen würde. Schreibt nichts. | nein |
| list_posts | Der Kalender, in UTC und Ortszeit, mit Kanalnamen. | nein |
| delete_post | Löscht einen nicht veröffentlichten Beitrag (einen Kanal), mit allChannels: true die ganze Gruppe. Einen, der schon online ist, lehnt es ab. | ja |
| create_post | Entwurf, Planung oder sofortige Veröffentlichung. | ja |
| upload_media_from_url | Ein Bild oder Video von einer URL oder Data-URL in die Mediathek. | ja |
| create_upload_link | Ein Browser-Link, auf den der Nutzer eine Datei von seinem eigenen Rechner zieht. Gilt zwei Stunden. | ja |
| list_upload_link_files | Was über den Upload-Link eingegangen ist, mit einer URL, die in einen Beitrag passt. | nein |
| fotoai_list_models | Die Bild- und Videomodelle von FotoAI mit Parametern und Preis in Credits. | nein |
| fotoai_quote | Der genaue Preis einer FotoAI-Generierung. Verbraucht nichts. | nein |
| fotoai_generate | Generiert mit den FotoAI-Credits des Nutzers zum bestätigten Angebot; das Ergebnis landet in der Mediathek. | ja |
| fotoai_get_generation | Der Status einer Generierung und, wenn fertig, die URLs der in der Mediathek gespeicherten Dateien für den Beitrag. | ja |
| get_plans | Die vier Tarife mit Preisen in Forint, Euro, Schweizer Franken und US-Dollar, die Limits, die Regel der Testphase und der aktuelle Tarif. Nur wenn der Nutzer fragt. | nein |
| subscribe | Ein Stripe-Checkout-Link für den gewählten Tarif. Der Nutzer öffnet ihn und zahlt mit seiner eigenen Wallet. Nur über eine angemeldete (OAuth) Verbindung, für den Inhaber. | ja |
| get_subscription | Der Status des Abonnements und ein unbezahlter Checkout. Nach der Zahlung bestätigt der Agent damit, dass der Tarif aktiv ist. | nein |
| manage_subscription | Ein Link zum Stripe-Abrechnungsportal: Tarifwechsel, Kündigung, Rechnungen, Karte. Nur über eine OAuth-Verbindung, für den Zahlenden. | ja |
| open_posty | Öffnet die Posty App: Kalender, Editor und Kanäle. Sie ist auch in der Seitenleiste von ChatGPT. | nein |
| open_posty_panel | Dieselbe App in der Seitenleiste eines ChatGPT Gesprächs. Die App ruft es auf, nicht das Modell. | nein |
| read_settings | Die Einstellungen des Nutzers: Zeitzone und der Arbeitsbereich dieser Verbindung, mit den wählbaren Werten. | nein |
| update_settings | Speichert die Zeitzone oder stellt die Verbindung auf einen anderen Arbeitsbereich um. Die Plugin Einstellungen in ChatGPT rufen es auf. | ja |
| search_mentions | Kanäle und kommende Beiträge für das @ Menü der ChatGPT Desktop App. Die App ruft es auf, nicht das Modell. | nein |
| get_post | Ein Beitrag vollständig (Thread-Beiträge oder Kommentare, Medien, Einstellungen) für den Editor der Posty App. Die App ruft es auf, nicht das Modell. | nein |
| update_post | Ändert einen geplanten, Entwurfs- oder fehlgeschlagenen Beitrag aus dem Editor der Posty App. Ein veröffentlichter Beitrag wird abgelehnt. Die App ruft es auf, nicht das Modell. | ja |
Die Verbindung verlangt Authentifizierung: ohne Zugangsdaten antwortet der Server mit 401, und der Header WWW-Authenticate sagt, wo du die Freigabe anfragen kannst. Das ist kein Fehler, sondern der Beginn des Ablaufs nach dem MCP-Standard. Die Tool-Liste lässt sich unabhängig davon im Manifest lesen.
Maschinenlesbar
Jedes Dokument, das ein Agent oder ein Generator anfragt:
- OpenAPI 3: https://posty.hu/openapi.json
- MCP-Manifest: https://posty.hu/.well-known/mcp.json
- Status und Erkennung:
https://api.posty.hu/public/v1/status - OAuth-Metadaten:
https://api.posty.hu/.well-known/oauth-protected-resource - Kurze Zusammenfassung für Agenten: https://posty.hu/llms.txt
Publikum statt Extraschicht
Posty führt deine Social-Media-Konten in einem Kalender zusammen. So hast du mehr Zeit für Interessierte und dein Unternehmen. Verbringe nicht zehn Stunden pro Woche mit der Kontoverwaltung.
Kostenlos testen