Übergib deine Website als ZIP direkt an ProntoSite – ohne Dashboard. Ideal, wenn du lokal (z. B. mit KI) bearbeitest und den Stand per Kommandozeile veröffentlichen willst.
Verfügbar ab dem Starter-Plan (wie SFTP; Free ohne) – für die Selbstbedienung des Kunden. Ausnahme Betreuer: Ein Admin/Partner kann im Konto-Detail plan-unabhängig ein Token erzeugen (auch für Free-Kunden, für die er lokal deployt). Solche Tokens sind als „vom Betreuer erzeugt" gekennzeichnet und funktionieren am Deploy-Endpunkt unabhängig vom Plan des Kunden.
1. Token erzeugen #
Dashboard → Konto → „API-Zugang" → „Token erzeugen". Das Token (psk_…) wird nur einmal
angezeigt – kopieren und sicher aufbewahren. Es gilt nur für diese Website und lässt sich jederzeit
widerrufen. (Betreust du fremde Konten als Partner: „Als Kunde arbeiten" starten, dann dort das Token
erzeugen.)
Konto-Token (frisches Konto ohne Website) #
Für den Erst-Import (neues Konto → Website hochladen + veröffentlichen, ohne Dashboard-ZIP-Import) gibt es
das Konto-Token: nicht an eine Website gebunden, sondern ans Konto – mit dem Recht, die erste Website
anzulegen und danach die Website(s) des Kontos zu aktualisieren. Erzeugt wird es im Admin/Partner-Bereich
beim Einrichten des Kontos (auch schon, bevor eine Website existiert). Deployed wird damit auf
/api/deploy/new (siehe Erst-Import unten).
2. Deployen (curl) #
# Update-Import der aktiven Website + direkt veröffentlichen:
curl -X POST "https://app.prontosite.io/api/deploy/<site>?publish=1" \
-H "Authorization: Bearer psk_DEIN_TOKEN" \
-H "Content-Type: application/zip" \
--data-binary @meine-website.zip
<site>= stabile Site-ID (s-…, empfohlen – ändert sich nie) oderactive(nimmt die aktive Website des Kontos, robustest bei „ein Konto, eine Website"). Der Slug wird ebenfalls akzeptiert, kann aber veralten (eigene Domain, Umbenennung) → dann klare Fehlermeldung mit Hinweis auf Site-ID/active, kein stiller 404. Die Site-ID steht im Dashboard (Konto → API-Zugang) und im MCP-Snippet.?publish=1— nach dem Import direkt live schalten. Weglassen = nur importieren (Entwurf), später im Dashboard veröffentlichen.?resetOverlay=1— bisherige Dashboard-Änderungen (Overlay) verwerfen; der ZIP-Stand ist die Wahrheit (empfohlen, wenn du komplett lokal arbeitest). Ohne den Parameter bleiben auflösbare Dashboard-Änderungen erhalten (Merge, wie im Dashboard-Update-Import).
Erst-Import (Konto-Token → Website anlegen + veröffentlichen) #
Mit einem Konto-Token legst du die erste Website direkt an – der Endpunkt erkennt, dass noch keine Website
existiert (oder du gibst explizit /new an):
curl -X POST "https://app.prontosite.io/api/deploy/new?publish=1&slug=meine-firma&name=Meine%20Firma" \
-H "Authorization: Bearer psk_DEIN_KONTO_TOKEN" \
-H "Content-Type: application/zip" \
--data-binary @meine-website.zip
/new— Website anlegen (statt aktualisieren). Ist das Konto noch leer, genügt auch jeder andere<site>-Wert – ohne Website wird immer angelegt.?slug=— Wunsch-Adresse (<slug>.prontosite.io). Ohne Angabe leiten wir sie aus dem Namen ab.?name=— Anzeigename/Website-Titel. Ohne Angabe aus dem Paket/Konto abgeleitet.- Rechts-Automatik (Default beim Erst-Import): Impressum + Datenschutz werden automatisch generiert und
aktiviert und als eigenständige Seiten
/impressum/+/datenschutz/mitveröffentlicht – aus den am Konto hinterlegten Firmendaten. Fehlen Firmendaten, wird trotzdem generiert (sichtbare[Angabe fehlt: …]-Marker); die Antwort listet die fehlenden Felder. Hostet die hochgeladene Website eine Rolle bereits selbst (eigene Impressum-/Datenschutz-Seite), lassen wir sie unangetastet. Mit?legal=0schaltest du die Automatik ab, mit?legal=1erzwingst du sie auch beim Update-Import. - Cookie-Banner wird nicht erzwungen: es aktiviert sich beim Veröffentlichen automatisch, sobald die Seite einwilligungspflichtige Inhalte hat (Google Analytics/Ads oder eingebettete Fremdinhalte).
3. Antwort (JSON) #
{
"ok": true,
"mode": "created",
"site": "s-abc123", "slug": "meine-firma",
"pages": { "added": 6, "changed": 0, "removed": 0 },
"keptOps": 0, "deactivatedOps": 0, "resetOverlay": false,
"rejectedFiles": [{ "file": "skript.php", "reason": "Server-Code wird nicht übernommen" }],
"markers": { "widgets": ["google-reviews"], "forms": [] },
"warnings": ["…"],
"backup": null,
"legal": {
"generated": ["impressum", "datenschutz"],
"standalonePages": ["/impressum/", "/datenschutz/"],
"hostedBySite": [],
"missingCompanyFields": ["Anschrift"],
"notLinked": ["datenschutz"]
},
"published": true, "liveUrl": "https://meine-firma.prontosite.io"
}
So siehst du lokal, was passiert ist: mode (created beim Erst-Import, sonst updated),
übernommene/geänderte/entfallene Seiten, abgelehnte Dateien mit Grund, erkannte Marker/Formulare, Warnungen –
und ob veröffentlicht wurde. Der Block legal meldet, was die Rechts-Automatik getan hat:
generated = erzeugte+aktivierte Rollen (mit standalonePages), hostedBySite = Rollen, die die hochgeladene
Website selbst hostet (übersprungen), missingCompanyFields = fehlende Firmendaten (als [Angabe fehlt] live),
notLinked = generierte Rechtsseiten, auf die die Website (noch) nicht verlinkt – dann im Footer einen Link
ergänzen. Ist die Automatik aus, steht dort "legal": { "disabled": true }.
Weitere Endpunkte (Status, Export, erneut veröffentlichen) #
Neben deploy gibt es drei schlanke Token-Endpunkte (gleiche Auth/Rate-Limit/Audit):
# Status: Plan, Slug, Live-URL, offener Veröffentlichungsbedarf (LESEND)
curl -s "https://app.prontosite.io/api/status/<site>" -H "Authorization: Bearer psk_DEIN_TOKEN"
# Export als ZIP: which=published (Live, Standard) | draft | original (LESEND)
curl -s "https://app.prontosite.io/api/export/<site>?which=published" \
-H "Authorization: Bearer psk_DEIN_TOKEN" -o website.zip
# Erneut veröffentlichen (ohne ZIP) – z. B. um Plattform-Updates live zu bringen
curl -s -X POST "https://app.prontosite.io/api/publish/<site>" -H "Authorization: Bearer psk_DEIN_TOKEN"
# Alle erreichbaren Sites (Betreuer-Token: alle betreuten Kunden; sonst die eigene)
curl -s "https://app.prontosite.io/api/sites" -H "Authorization: Bearer psk_DEIN_TOKEN"
status liefert u. a. { slug, plan, liveUrl, everPublished, publishNeeded, changes }.
Betreuer-Token (Admin/Partner – alle betreuten Kunden) #
Ein konto-übergreifendes Token für Agenturen/Partner: deckt ALLE betreuten Kunden ab (statt ein Token je
Kunde). Erzeugt im Admin/Partner-Bereich (Panel „Betreuer-Token"). <site> = Slug oder stabile Site-ID
(kein active – mehrere Konten); GET /api/sites listet alle betreuten Sites. Erst-Import in ein betreutes
Konto: POST /api/deploy/new?customer=<konto-id>. Der Zugriff wird bei JEDEM Aufruf serverseitig geprüft
(nur betreute Konten; Rollenentzug wirkt sofort), nur Deploy/Status/Export/Veröffentlichen – kein Konto-/
Zahlungszugriff. Optionaler Ablauf (Default 90 Tage) + optionale IP-Bindung; Widerruf sperrt alles auf einmal.
Firmendaten setzen (Company-API) #
Damit die Rechtstext-Automatik beim Deploy ein vollständiges Impressum/Datenschutz erzeugt, kannst du die Firmendaten per Token setzen – konto-weit, mit Teil-Update (nur gesetzte Felder ändern sich):
# Lesen (effektiver Stand + konto-weite Angaben)
curl -s "https://app.prontosite.io/api/company/<site>" -H "Authorization: Bearer psk_DEIN_TOKEN"
# Setzen/ergänzen (JSON) – nur die mitgeschickten Felder werden geändert
curl -X PUT "https://app.prontosite.io/api/company/<site>" \
-H "Authorization: Bearer psk_DEIN_TOKEN" -H "Content-Type: application/json" \
--data '{"company":{"name":"Beispiel GmbH","street":"Hauptstr. 1","zip":"50667","city":"Köln","country":"DE","email":"info@beispiel.de","representative":"Max Mustermann","vatId":"DE123456789"}}'
- Felder wie im Dashboard:
name, legalForm, representative, street, zip, city, country, email, phone, fax, vatId, registerCourt, registerNumber, kammer, berufsbezeichnung, aufsichtsbehoerde, verantwortlichMStV, berufshaftpflicht, social[{label,href}]. - Standard ist konto-weit (
account_company). Für abweichende Daten NUR dieser Website:{"siteOverride":true, "company":{…}}(oder?scope=site). - Die Deploy-Antwort meldet unter
legal.missingCompanyFields, welche Pflichtangaben noch fehlen.
Anzeige-Optionen der Rechtstexte (Legal-Options) #
Pro Rolle (impressum/datenschutz) lassen sich die Anzeige-Optionen der Rechtstext-Widgets per Token setzen –
Teil-Update, nur mitgeschickte Booleans wirken:
curl -X PUT "https://app.prontosite.io/api/legal-options/<site>" \
-H "Authorization: Bearer psk_DEIN_TOKEN" -H "Content-Type: application/json" \
--data '{"impressum":{"showTitle":false},"datenschutz":{"showDate":false,"draftNotice":true}}'
showTitle– Überschrift (H1) des Rechtstextes anzeigen (Default an).showDate– „Stand"-Datum anzeigen (Default an; i. d. R. nur Datenschutz).draftNotice– Entwurfs-Hinweis in der veröffentlichten Seite anzeigen (Default an).falseblendet ihn live aus – der Vorgang wird protokolliert; im Editor bleibt der Hinweis sichtbar.
GET /api/legal-options/<site> liefert den aktuellen Stand beider Rollen.
Konfliktschutz: draftRev und baseRev #
Jede Änderung am Entwurf erhöht seine Revisionsnummer draftRev – egal ob im Dashboard, per KI-Chat, Datei-API
oder Deploy. status liefert sie (draftRev) zusammen mit den letzten Änderungen (recentEdits: wer, wann, welcher
Weg, welche Dateien).
- Export → lokal bearbeiten → Deploy: Jede Export-ZIP enthält eine Datei
.prontosite-export.jsonmit dem Stand (draftRev) zum Zeitpunkt des Exports. Beim Deploy liest ProntoSite sie automatisch alsbaseRev– hat seitdem jemand den Entwurf geändert, kommt409mit der Liste der Zwischen-Änderungen, statt sie still zu überschreiben. Die Datei bitte im ZIP lassen (sie wird nie veröffentlicht). - Ohne Export-Datei kannst du
?baseRev=<draftRev>mitgeben. Fehlt beides, wird per curl (noch) deployt – mit Warnung „ohne Konfliktschutz". Ab MCP 0.12 und am Remote-Endpunkt/mcpistbaseRevbeim Update Pflicht – sonst428. ?force=1übergeht einen Konflikt – nur mit Betreuer-Token, wird im Konto-Verlauf protokolliert; der überschriebene Stand bleibt per Rückgängig im Dashboard erreichbar.- Ein Export des Entwurfs (
which=draft) enthält die Dashboard-Änderungen bereits – beim erneuten Deploy setzt ProntoSite das Overlay daher automatisch zurück (resetOverlay), damit nichts doppelt angewendet wird.
# Konflikt sauber auflösen: frischen Entwurf holen, Änderung einarbeiten, erneut deployen
curl -s "https://app.prontosite.io/api/export/<site>?which=draft" -H "Authorization: Bearer psk_…" -o entwurf.zip
Datei-API: kleine Änderungen am Entwurf ohne lokale Kopie #
Für kleine Änderungen (ein CSS-Wert, ein Absatz, eine neue Seite) musst du nicht die ganze Website exportieren.
Für größere Umbauten bleibt Export → lokal → Deploy der bessere Weg. Lesen und schreiben gehen mit jedem API-Token;
Skriptdateien (JavaScript) lassen sich nur ändern, wenn JavaScript für die Website freigegeben ist (sonst 403 mit
Hinweis); neue externe Adressen im Skript meldet die Antwort als jsExtern. Alles landet im Entwurf – live erst mit publish.
| Aufruf | Wirkung |
|---|---|
GET /api/files/<site> |
Dateien des Entwurfs: Pfad, Größe, Typ, bearbeitbar (+ Grund), draftRev |
GET /api/file/<site>?path=css/style.css |
Inhalt (Text bzw. Base64, max. 5 MB) + draftRev; bei Seiten zusätzlich overlay: Dashboard-Änderungen, die über dem Quelltext liegen |
PUT /api/file/<site>?path=… |
Body { "content": "…", "baseRev": 17 } – Text-Datei ersetzen; eine neue .html-Datei legt eine neue Seite an |
POST /api/file/<site>/delete |
{ "path", "baseRev", "confirmDestructive": true } – Datei entfernen; bei einer Seite = Seite löschen (Startseite geschützt) |
POST /api/file/<site>/rename |
{ "from", "to", "baseRev" } – umbenennen; bei Seiten ändert sich die Adresse, Verweise werden gemeldet, nicht umgeschrieben |
curl -s -X PUT "https://app.prontosite.io/api/file/<site>?path=css/style.css" \
-H "Authorization: Bearer psk_BETREUER" -H "Content-Type: application/json" \
-d '{"content":"body{color:#222}","baseRev":17}'
- Konflikt: Hat jemand seit
baseRevdieselbe Datei geändert →409mitchanges(wer/wann/was). Änderungen an anderen Dateien blockieren nicht, sie stehen als Info unterintervening. - Dashboard-Änderungen bleiben erhalten: Ersetzt du eine Seite, werden ihre Dashboard-Änderungen an die passenden
Elemente umgehängt; findet sich ein Element nicht mehr, wird die Änderung deaktiviert aufbewahrt (nicht verworfen)
und gemeldet.
"overlay":"yield"lässt deine Datei gewinnen, wo sie denselben Inhalt geändert hat. - Grenzen: nur Text (HTML, CSS, JS, SVG, JSON, XML, TXT, MD), max. 1 MB je Datei; Bilder über die Medienverwaltung
oder ZIP. Inhalte werden wie beim Import bereinigt (Plattform-Bausteine, ohne JavaScript-Freigabe auch Skripte).
Rechtstext-Seiten (Impressum/Datenschutz): Footer, Navigation und Gestaltung ja; der Rechtstext selbst (Bereich
data-ps="impressum"/"datenschutz") nein →403mit Hinweis auf die Firmendaten (Company-API). Rate-Limit: 300 Lese- aufrufe je Stunde und Token; Entwurfsänderungen (Datei-API, edit-text/-html, page-texts, page-copy, image-set, widgets, undo/redo) je Website 300 je Stunde, davon 30 direkt hintereinander – für Kunden und Betreuer gleich. Darüber429mitRetry-After,retryAfter(Sekunden) und Klartext; der Entwurf bleibt erhalten, nach der Wartezeit einfach weitermachen.
Text suchen und ersetzen über alle Seiten #
POST /api/edit-text/<site> mit { "find": "02242 123456", "replace": "02242 999999", "scope": "all", "region": "footer" }
sucht im sichtbaren Text aller Seiten und – attributes ist Standard – in Linkzielen (href, tel:/mailto: werden
normalisiert, die Ländervorwahl bleibt) und Attributen (alt, title, aria-label, meta content) und ersetzt alles in
einem Aufruf als eine Rückgängig-Einheit; Formatierung bleibt. region: footer | header | main | all.
scope: "all" ersetzt alle Fundstellen sofort; ohne scope (und ohne pages) wird bei mehr als einer Fundstelle
nichts geändert – die Antwort listet sie (hits, needsSelection: true). pages zeigt je Seite gefunden/geändert.
Rechtstexte und geschützte Bereiche bleiben unberührt (skipped). Steht der Wert in den Firmendaten, nennt company
das Feld – Impressum, Datenschutz und Kontakt-Bausteine dann über die Company-API ändern. MCP: site_edit_text.
Texte einer Seite lesen/setzen, Seite kopieren (Übersetzung) #
GET /api/page-texts/<site>?page=index.html→texts: [{id, role, kind, text, markdown?}](Textknoten, reine Text-Links,alt/title/aria-label/placeholder,head:title,head:description) +draftRev. Rechtstext-Seiten →403.POST /api/page-texts/<site>{ "page": "index.html", "texts": [{ "id": "…", "text": "…" }], "baseRev": 17 }– alles in einem Rückgängig-Schritt; unbekannte IDs →400, nichts geändert.POST /api/page-copy/<site>{ "from": "index.html", "to": "en/index.html" }– Kopie inkl. Dashboard-Änderungen, relative Pfade angepasst, im Sprachordner<html lang>+ Sprachfassung; vorhandene Ziele →409.
Medien hochladen, Bild einsetzen, Screenshot #
POST /api/media-upload/<site>→{ uploadId, uploadUrl }(15 Min., einmalig).PUT <uploadUrl>mit der Datei als Body (oderuploadUrlim Browser öffnen = Upload-Seite).POST /api/media-commit/<site>{ "uploadId": "…" }→mediaId(Prüfung, Kontingent, Optimierung). Bilder JPG/PNG/WebP/SVG und PDF (ohne Skripte, automatische Aktionen, Formular-Versand, Anhänge – sonst422mitreason; Office folgt mit dem Virenscanner); Kontingent erschöpft →413.GET /api/media/<site>– Medienliste + Kontingent.POST /api/image-set/<site>{ "page", "nodeId" | "marker", "mediaId", "alt" }.GET /api/preview-screenshot/<site>?page=index.html&width=1280|390→ PNG des Entwurfs (ohne JavaScript, 30/h).
Bearbeitungs-Sperre („In Bearbeitung durch …") #
POST /api/lock/<site> mit {"action":"lock","note":"Startseite"} zeigt allen anderen „In Bearbeitung durch X seit
10:15". Die Sperre blockiert niemanden – wer trotzdem speichert, bekommt in der Antwort lockWarning. Sie läuft
2 Stunden nach deiner letzten Änderung ab; {"action":"unlock"} gibt sie frei, {"action":"takeover"} übernimmt eine
fremde Sperre (nur Betreuer, wird im Konto-Verlauf protokolliert). GET bzw. status zeigen den aktuellen Stand.
Per KI-Assistent (MCP) #
Dieselben Aktionen gibt es als MCP-Server für Claude Desktop u. a. – „per Terminal (curl)" und „per KI-Assistent (MCP)" stehen bewusst nebeneinander; die HTTP-API bleibt der primäre, dokumentierte Weg, der MCP-Server ist ein zusätzlicher Client darauf (dünner Wrapper, keine eigene Logik, kein Ersatz).
Tools: site_status, site_export, site_deploy (optional company:{…} im selben Aufruf), site_publish,
site_company_get, site_company_set, site_legal_options (auch externe Rechtstext-Adressen), Datei-Tools site_files, site_file_get, site_file_put,
site_file_delete, site_file_rename sowie site_lock/site_unlock. Einrichtung + Claude-Desktop-Config-Snippet:
siehe KI-Assistent (MCP). Token/Site kommen aus lokaler Config
(PRONTOSITE_TOKEN/PRONTOSITE_SITE oder ~/.prontosite.json), nie aus dem Chat. Die schreibenden Tools
(site_deploy, site_publish) sind so beschrieben, dass der Assistent vor dem Ausführen rückfragt.
Grenzen & Sicherheit #
- Es gelten dieselben Grenzen wie im Dashboard-Import: max. 100 MB ZIP, nur
.zip, Server-Code (php/asp …) wird nicht übernommen, eigenes JavaScript wird byte-treu übernommen und ausgeliefert. - Rate-Limit: einige Deploys pro Stunde je Token.
- Veröffentlichen (
/api/publish, Deploy mitpublish=1, MCPsite_publish): Kunden 30, Betreuer 120 je Stunde, jeweils 10 direkt hintereinander. Darüber429mitRetry-After; ein Deploy mitpublish=1landet dann nur im Entwurf (published:false,publishRateLimited). Am besten Änderungen sammeln und am Ende einmal veröffentlichen. - Revisionen: Mehrere Veröffentlichungen desselben Tokens bzw. derselben Person mit weniger als 10 Minuten Abstand ergeben eine Revision (der letzte Stand gilt). Es bleiben die letzten 50 Revisionen, ältere je Tag eine, 30 Tage lang.
- Publish unterliegt den normalen Grenzen (bestätigte E-Mail, KI-/Speicher-Kontingent des Plans).
- Jeder Deploy wird protokolliert. Ein widerrufenes Token wird sofort mit
401abgelehnt.
Fehlercodes #
| Status | Bedeutung |
|---|---|
| 400 | Anfrage unvollständig (z. B. baseRev fehlt bei der Datei-API, ungültiger Pfad) |
| 401 | Token fehlt, ungültig oder widerrufen |
| 403 | Plan ohne API-Zugang, Token gehört nicht zur adressierten Website, Skriptdatei ohne Betreuer-Recht oder Änderung am Rechtstext (useInstead: "site_company_set") |
| 409 | Konflikt: Entwurf bzw. dieselbe Datei wurde seit deinem Stand geändert (changes nennt wer/wann/was) – oder eine Bestätigung fehlt (needsConfirmation) |
| 413 | ZIP zu groß (> 100 MB) bzw. Datei zu groß (> 1 MB / > 5 MB beim Lesen) |
| 415 | Dateityp per Datei-API nicht schreibbar (nur Text) |
| 422 | Import fehlgeschlagen bzw. Datei-Op abgelehnt (z. B. JS ohne Freigabe – Details in error) |
| 428 | Deploy-Update ohne baseRev von MCP ≥ 0.12 bzw. /mcp – erst site_export (which='draft') oder baseRev mitgeben |
| 429 | Rate-Limit erreicht |