Bilder und Objektspeicher

Zuletzt aktualisiert: Aug 31, 2026Abschnitt: Integrationen

Vollständige API-Referenz: https://api.mailoo.app/docs/v1

Mailoo speichert benutzereigene Bilder in S3-kompatiblem Objektspeicher (AWS S3, MinIO usw.). Jeder Zugriff erfolgt über die Mailoo-API; Integratoren und Browser erhalten niemals S3-Zugangsdaten oder interne Objektschlüssel.

Diese Seite richtet sich an Teams, die Mailoo-Integrationen (Blog, Formulare, Chat usw.) einbetten und verstehen müssen, wie Artikelbilder und andere Benutzer-Assets gespeichert werden und wie man sie sicher liest.

Übersicht

  • Namespace: Jeder Dashboard-Benutzer erhält einen dedizierten Schlüsselpräfix users/{userId}/ in einem gemeinsamen Bucket (userId ist die interne Mailoo-Benutzer-ID aus der Datenbank, eine CUID).
  • Öffentlicher Bezeichner: Clients verwenden die Media-ID (CUID), die von der API zurückgegeben wird. S3-Schlüssel sind nur intern.
  • Initialisierung: Die API erstellt ein internes Marker-Objekt unter diesem Präfix bei der ersten authentifizierten API-Aktivität (idempotent). Die Erstellung wird serverseitig protokolliert.
  • Löschung: Wenn ein Benutzerkonto über die API entfernt wird, werden Objekte unter users/{userId}/ als Teil dieses Ablaufs aus dem Speicher gelöscht. Projekt-/Integrations-/Artikel-Löschungen reihen Hintergrund-S3-Bereinigung für zugehörige Medien-Schlüssel ein.
  • Upload / Löschen / Ableiten: Bearer-authentifizierte Dashboard-Abläufe (über Ihre Session / BFF). Legen Sie S3-Schlüssel oder Bucket-Zugangsdaten nicht Browsern oder Drittanbieter-Websites offen.
  • Originale vs. Artikel-Assets: Upload erlaubt größere Originale (bis zu 25 MiB vor Verarbeitung); POST /images/derive erzeugt verkleinerte / neu kodierte Kopien, die dem gleichen Scope wie die Quelle zugeordnet sind.
  • Validierung: Der Dateityp wird mit Magic Bytes überprüft; EXIF-Orientierung wird angewendet und Metadaten werden serverseitig entfernt. Animierte GIFs werden abgelehnt.
  • Kanonische Einbettungs-URLs: Gespeichertes Markdown / HTML verwendet Mailoo-HTTP-URLs mit ``?id={mediaId}`` auf /api/v1/images/public/content. Browser können diese URL nicht mit einem API-Schlüssel aufrufen; Integratoren müssen proxen (siehe unten).
  • Externes Lesen (API-Schlüssel): GET /api/v1/images/public/content?id=… mit X-API-Key und Berechtigung image.external-read (oder ein FULL-Schlüssel) gibt Bytes nur für READY-Medien zurück, die dem API-Schlüssel-Benutzer gehören.
  • ``S3_PUBLIC_BASE_URL``: Optionales internes API-Detail; wird nicht in JSON-Antworten offengelegt und darf nicht als öffentlicher Bildvertrag verwendet werden.

Authentifizierungsübersicht

Dashboard-Bildrouten verwenden eine angemeldete Bearer-Session. Integrator-Lesezugriffe verwenden X-API-Key mit image.external-read (oder FULL). Vollständige Schemas: https://api.mailoo.app/docs/v1.


Operation Authentifizierung


Bilder auflisten (Cursor) Bearer; optional projectUid / integrationId / articleId für Sichtbarkeitskontext

Bild hochladen (Multipart) Bearer; Formularfelder file, scope, optionale Kontext-IDs

Bild ableiten (Größe / Format / Komprimierung) Bearer; JSON sourceId und mindestens eines von maxWidth, maxHeight, format

Bildbytes abrufen (Eigentümer) Bearer; GET /images/{id}/content

Patch / Löschen nach ID Bearer

Bildbytes abrufen (Integrator / Server) X-API-Key mit image.external-read (oder FULL); id muss auf READY-Medien des Schlüsselbesitzers verweisen

Sicherheitsmodell (normativ)

  1. Eigentümer ist die authentifizierte Mailoo-Benutzer-ID aus JWT oder API-Schlüssel --- niemals eine clientseitig bereitgestellte Benutzer-ID.
  2. ``projectUid`` / ``integrationId`` / ``articleId`` sind Kontext innerhalb der Daten dieses Eigentümers; die API löst die Kette auf und prüft sie.
  3. S3-Schlüssel werden niemals an Clients zurückgegeben.
  4. RESTRICTED-API-Schlüssel müssen image.external-read enthalten, um den öffentlichen Leseendpunkt aufzurufen.

Scopes (Sichtbarkeit)

Medien werden mit einem der Scopes USER, PROJECT, INTEGRATION oder ARTICLE gespeichert. Auflistung mit Kontext gibt READY-Elemente zurück, die für diesen Redakteurkontext sichtbar sind.

Stockfotos (Blog-Dashboard)

Jede Blog-Integration kann eigene Unsplash- und Pexels-API-Schlüssel unter Connection & settings speichern (verschlüsselt in integration.config.stockPhotos; nie im Klartext zurückgegeben). Es gibt keine plattformweiten Stock-API-Schlüssel.

Im Artikeleditor-Bildpanel sucht der Reiter Stock mit den Schlüsseln dieser Integration. Die Auswahl eines Fotos importiert die Bytes in UserMedia (gleiche Scopes und öffentliche Einbettungs-URLs wie ein normaler Upload). Unsplash-Download-Tracking verwendet den Unsplash-Schlüssel der Integration beim Import.

Dashboard-API (Bearer, Projektredakteur):

  • GET /api/v1/projects/{uid}/integrations/{id}/stock/search?provider=unsplash|pexels&q=…
  • POST /api/v1/projects/{uid}/integrations/{id}/stock/import --- Body enthält provider, externalId, scope und optionale Hierarchie-IDs

API-Referenz (Bilder)

Basispfad: {apiBase}/api/v1/images.

Auflisten (Bearer, Cursor)

GET /api/v1/images --- Abfrage: limit (1--100, Standard 24), cursor, optionale Filter projectUid, integrationId, articleId, scope, includeNonReady=true. Antwort: items, nextCursor, imagePublicEmbedBaseUrl.

Hochladen (Bearer)

POST /api/v1/images --- Multipart: file, scope (USER | PROJECT | INTEGRATION | ARTICLE), plus Kontextfelder pro Scope (projectUid, integrationId, articleId je nach Bedarf). Antwort enthält id, embedUrl, imagePublicEmbedBaseUrl, Metadaten --- kein S3-Schlüssel.

Bild ableiten (Bearer)

POST /api/v1/images/derive --- JSON: sourceId, optionale maxWidth, maxHeight, format, quality. Mindestens eines von maxWidth, maxHeight oder format ist erforderlich.

Inhalt abrufen (Bearer)

GET /api/v1/images/{id}/content --- Rohbytes für READY-Medien.

Optionale On-the-fly-Größenanpassung / Transkodierung (gleiche sharp-Pipeline wie Ableitung): Abfrageparameter ``w``, ``h``, ``fit`` (inside | cover | fill, Standard inside), ``format`` (jpeg | jpg | png | webp), ``q`` (1--100, Standard 85). Mindestens eines von ``w``, ``h`` oder ``format`` muss vorhanden sein, um die Verarbeitung zu aktivieren; andernfalls wird das Objekt wie gespeichert gestreamt.

Patch / Löschen (Bearer)

  • PATCH /api/v1/images/{id} --- JSON name, altText.
  • DELETE /api/v1/images/{id} --- Einzelmedien-Löschung mit S3-Retry-Outbox bei Fehlschlag.

Inhalt abrufen (API-Schlüssel)

GET /api/v1/images/public/content?id={mediaId} --- X-API-Key; nur für serverseitige Proxys. Dieselben optionalen Transform-Abfrageparameter wie die Bearer-Inhaltsroute (``w``, ``h``, ``fit``, ``format``, ``q``) gelten, wenn mindestens eines von ``w``, ``h`` oder ``format`` gesetzt ist.

Vorab generierte Varianten über ``POST /api/v1/images/derive`` werden weiterhin für stabile URLs unterstützt (eine neue Media-ID pro Variante).

Integrator-Proxy und Blog-HTML

Blog-API-Artikelnutzlasten enthalten ``imagePublicEmbedBaseUrl`` (Präfix endend mit ?id=). Die Artikellisten-Antwort wiederholt dasselbe Präfix auf der obersten Ebene (neben data / pagination). Kategoriebeschreibungs-Antworten enthalten ``imagePublicEmbedBaseUrl`` in data, wenn Beschreibungs-HTML Mailoo-Bilder referenzieren kann. Gespeichertes ``htmlContent`` verwendet absolute kanonische öffentliche URLs unter ``API_PUBLIC_URL``; ersetzen Sie diese URLs im HTML durch die Proxy-URL Ihrer Website mit derselben Media-ID.

Verwenden Sie ``rewriteMailooPublicImageUrls`` aus ``@mailoo/images`` (auch für Hosts re-exportiert, die bereits von diesem Paket abhängen). Siehe nextjs-packages{.interpreted-text role="doc"}.

Betreiberkonfiguration (nur API)

Auf dem API-Host (nicht im Browser) setzen:


Variable Zweck


API_PUBLIC_URL Öffentliche API-Basis (kein abschließender Schrägstrich); verwendet für kanonische Einbettungs-URLs

S3_BUCKET Bucket-Name (erforderlich)

S3_REGION Region (Standard us-east-1 wenn nicht gesetzt)

S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY Zugangsdaten (erforderlich)

S3_ENDPOINT Eigener Endpunkt für MinIO / S3-kompatibel (optional)

S3_FORCE_PATH_STYLE true für viele MinIO-Setups (optional; Standard Path-Style wenn S3_ENDPOINT gesetzt ist)

S3_PUBLIC_BASE_URL Optional; internes API-Detail --- nicht Teil des öffentlichen Integrationsvertrags

Diese Variablen gehören ausschließlich auf das API-Deployment (niemals in den Browser).

Weiterführende Lektüre

  • nextjs-packages{.interpreted-text role="doc"} --- @mailoo/images-Proxy-Fabrik
  • blog-headless-cms{.interpreted-text role="doc"}
  • website-forms{.interpreted-text role="doc"}
  • OpenAPI: https://api.mailoo.app/docs/v1