· Developers · 6 Min. Lesezeit

App-Store-Screenshots hochladen mit der App Store Connect API

App-Store-Screenshots hochladen mit der App Store Connect API
TL;DR. Ein Screenshot-Upload über die App Store Connect API ist pro Bild eine Vier-Schritt-Sequenz: ein appScreenshotSet für die richtige Locale und das richtige Gerät anlegen, einen appScreenshot reservieren (Apple gibt dir vorsignierte Chunk-URLs), die Bytes per PUT senden, dann die Reservierung mit uploaded: true und der MD5-Prüfsumme der Datei per PATCH abschließen. Die Authentifizierung läuft über ein 20-minütiges JWT, signiert mit deinem .p8-Schlüssel. Nichts davon ist schwer, aber alles ist fummelig. Hier ist die echte Reihenfolge — und die Abkürzung, falls du es lieber nicht selbst bauen willst.

Apples Dokumentation dazu ist korrekt und fast unlesbar — der Ablauf ist über ein Dutzend Referenzseiten verteilt, ohne ein einziges durchgängiges Beispiel. Dieser Beitrag ist der eine Rundgang, in Reihenfolge, mit den exakten Endpunkten und Feldnamen. Geschrieben für alle, die entscheiden müssen, ob sie die Integration selbst bauen oder ein Tool nehmen, das es schon kann.

Das Objektmodell, in das du hochlädst

Screenshots hängen nicht direkt an deiner App. Sie hängen an einer Kette von Objekten, die du von oben nach unten durchlaufen musst:

  • appStoreVersion — die konkrete Version, die du bearbeitest (muss in einem bearbeitbaren Status sein).
  • appStoreVersionLocalization — eines pro App-Store-Locale (en-US, de-DE, ja usw.).
  • appScreenshotSet — eines pro Display-Typ innerhalb einer Lokalisierung (6.7" iPhone, 13" iPad usw.).
  • appScreenshot — das einzelne Bild, bis zu 10 pro Set.

Ein vollständig lokalisierter Eintrag in 50 Sprachen über zwei iPhone-Größen und eine iPad-Größe sind also 50 × 3 Sets, jedes mit bis zu 10 Screenshots. Genau diese Multiplikation ist der Grund, warum man das automatisiert, statt sich durch die Web-Oberfläche zu klicken.

Schritt 0 — das 20-Minuten-JWT

Jede Anfrage außer den eigentlichen Byte-Uploads braucht einen Authorization: Bearer-Header mit einem selbst signierten JSON Web Token. Du brauchst drei Dinge aus App Store Connect: deine Issuer-ID, eine Key-ID und die .p8-Private-Key-Datei, die du beim Erstellen des Schlüssels einmalig herunterlädst (Apple zeigt sie danach nie wieder).

Das Token wird mit ES256 signiert — ECDSA auf der P-256-Kurve mit SHA-256 —, unter Verwendung dieses .p8-Schlüssels. Der Header trägt die kid; die Payload trägt den Issuer als iss, die Audience als den literalen String appstoreconnect-v1 und ein exp von höchstens 20 Minuten nach iat. Apple lehnt alles mit längerer Lebensdauer ab, du erneuerst also häufig — erstelle lieber pro Batch ein frisches Token, statt eines offen zu halten.

Signiere das mit jeder ES256-fähigen JWT-Bibliothek (jsonwebtoken, PyJWT oder was auch immer dein Stack verwendet), übergib den .p8-Inhalt als Schlüssel und setze das Ergebnis in den Authorization-Header jedes folgenden Aufrufs.

Schritt 1 — das Screenshot-Set anlegen

Ein Set ist auf eine Lokalisierung und einen Display-Typ begrenzt. Du sendest ein POST an /v1/appScreenshotSets mit screenshotDisplayType in den Attributen und einer Relationship, die auf die gewünschte appStoreVersionLocalization zeigt.

Gängige Display-Typen: APP_IPHONE_67 (6.7", 1290 × 2796), die aktuelle große iPhone-Größe, und APP_IPAD_PRO_3GEN_129 (12.9", 2048 × 2732). Eine praktische Sache, die Apple heute macht: Screenshots für die größte iPhone-Größe werden für die kleineren iPhone-Klassen wiederverwendet, und die größte iPad-Größe für die kleineren iPads — in der Praxis brauchst du also oft nur ein iPhone-Set und ein iPad-Set pro Locale, nicht eines pro physischem Gerät. Die Antwort liefert dir eine Set-id, die du in den nächsten Aufruf mitnimmst. Existiert für dieses Locale/diesen Typ bereits ein Set, verwende es weiter, statt ein Duplikat anzulegen.

Schritt 2 — den Screenshot reservieren

Du lädst die Datei nicht in einem Schritt hoch. Zuerst reservierst du sie: Du teilst Apple Dateiname und exakte Bytegröße mit, und bekommst einen Upload-Plan zurück. POST an /v1/appScreenshots mit den Attributen fileName und fileSize sowie einer Relationship zum Set aus Schritt 1.

Die Antwort ist der interessante Teil. In den Attributen des neuen Screenshots erhältst du uploadOperations — ein Array, das genau beschreibt, wie die Bytes zu senden sind. Für eine kleine Datei ist es eine Operation; bei einer großen teilt Apple sie in mehrere auf. Jeder Eintrag liefert eine method (PUT), eine vorsignierte url, den zu sendenden Byte-offset und die length sowie die anzuhängenden requestHeaders.

Schritt 3 — die Bytes per PUT senden

Für jede Operation liest du das Datei-Segment ab offset mit length Bytes und sendest es per PUT an die angegebene url, mit genau den von Apple gelieferten requestHeaders. Diese URLs sind vorsigniert, du sendest hier also kein JWT — ein zusätzlicher Authorization-Header kann die signierte Anfrage sogar unbrauchbar machen. Mehrere Operationen können parallel laufen, aber Apple drosselt aggressive Uploads, also wickle sie in eine Retry-with-Backoff-Logik ein, statt alles auf einmal zu feuern.

Schritt 4 — Commit mit uploaded: true und der MD5

Das Hochladen der Bytes bewirkt nichts, solange du Apple nicht mitteilst, dass die Reservierung abgeschlossen ist. PATCH den Screenshot mit uploaded: true und einem sourceFileChecksum — der MD5-Prüfsumme der gesamten Datei als lowercase Hex-String. Das ist Apples Integritätsprüfung: Stimmt die Prüfsumme nicht mit dem Angekommenen überein, schlägt die Verarbeitung fehl.

Nach dem PATCH geht das Asset auf Apples Seite in die Verarbeitung. Frage den assetDeliveryState des Screenshots ab, bis er einen abgeschlossenen Status erreicht — und lies bei Fehlschlag seine errors, denn dort tauchen falsche Abmessungen und Alphakanal-Probleme auf. PUT und PATCH können beide erfolgreich sein, und der Screenshot kann trotzdem Minuten später während der Verarbeitung abgelehnt werden. Geh nicht davon aus, dass ein 2xx beim Commit bedeutet, dass du fertig bist — beobachte den Delivery-Status.

Schritt 5 — die Anzeigereihenfolge festlegen

Screenshots kommen in der Reihenfolge zurück, in der sie erstellt wurden — selten die Reihenfolge, in der du sie zeigen willst. Die Reihenfolge des Sets ist eine separate Relationship. PATCH /v1/appScreenshotSets/{id}/relationships/appScreenshots mit einem Array von Screenshot-IDs — die Array-Reihenfolge ist die Anzeigereihenfolge im Store.

Die Vorgaben, die Apple tatsächlich durchsetzt

  • Nur PNG oder JPEG. Kein HEIC, kein WebP. Wenn dein Renderer etwas anderes ausgibt, konvertiere zuerst.
  • Kein Alphakanal. Transparenz auf einen soliden Hintergrund flatten und als RGB exportieren. Ein versehentlicher Alphakanal ist eine der häufigsten stillen Ablehnungen bei der Verarbeitung.
  • Exakte Abmessungen je Display-Typ. Das Bild muss der Pixelgröße des Display-Typs exakt entsprechen — keine Abweichung, kein Hochskalieren. Eine 1290 × 2796-Datei gehört in ein APP_IPHONE_67-Set und sonst nirgendwohin.
  • Bis zu 10 pro Set. Maximal zehn Screenshots pro Lokalisierung und Display-Typ.
  • Nur bearbeitbare Version. Du kannst Sets nur bei einer Version verändern, die sich in einem bearbeitbaren Status befindet; eine Version, die schon in Review ist, ist gesperrt.

Warum das mehr Arbeit ist, als es aussieht

Jeder einzelne Aufruf ist simpel. Der Aufwand steckt in allem drumherum: ein 20-Minuten-Token signieren und rotieren, MD5-Prüfsummen berechnen, Dateien passend zu uploadOperations zerteilen, Retries bei unvollständigen Uploads handhaben, den Delivery-Status abfragen, deine Locales auf Apples Locale-Codes abbilden — und das alles 150-plus Mal für einen sauber lokalisierten Eintrag. Bis das zuverlässig läuft, ist ein Wochenende mit Auth, Chunked Uploads und Fehlerbehandlung verplant — und danach musst du es pflegen, jedes Mal wenn Apple einen neuen Display-Typ hinzufügt.

Wenn du den Ablauf willst, ohne ihn selbst zu schreiben: Fastlanes deliver kapselt genau diese API und ist der etablierte Open-Source-Weg. Es löst den Upload; es entwirft weder die Screenshots noch schreibt es die Untertitel.

…oder überspring das alles

Die API bewegt nur fertige Bilder. Etwas anderes muss noch das Karussell entwerfen, die Untertitel schreiben und sie pro Locale übersetzen — und genau das kostet die eigentliche Zeit. Mokbi macht das heute schon: Es entwirft die Screenshots, verfasst die Store-Texte und übersetzt das Ganze in 50 Sprachen, exportiert dann jedes Bild in exakt den Abmessungen, die diese API pro Display-Typ verlangt — PNG, RGB, kein Alphakanal, richtige Größe —, sodass ein Upload nicht schon beim Delivery-Status abprallt.

Danach veröffentlicht es. Für den App Store führt Mokbi unter der Haube genau diese Reserve-und-Commit-Sequenz aus — lädt deine Screenshots und Metadaten hoch und bereitet die Version zur Einreichung vor, damit du nie ein JWT oder einen gechunkten PUT anfassen musst. Apple verlangt weiterhin die finale Einreichung und die Prüfung; alles davor übernimmt Mokbi für dich. Für Google Play wird direkt in den Store gepusht. So oder so bekommst du das API-Ergebnis, ohne den Code zu schreiben — mit Design, Texten und der 50-Sprachen-Übersetzung bereits erledigt.

Was du als Nächstes lesen solltest

Editor öffnen →