TL;DR. Ja, die App Store Connect API kann dein Keyword-Feld, den Untertitel, die Beschreibung und den Werbetext aktualisieren, ohne dass du App Store Connect von Hand öffnest. Aber Name und Untertitel liegen auf der Ressource
appInfoLocalization, während Keywords, Beschreibung, Werbetext und What’s New aufappStoreVersionLocalizationliegen — einer anderen Ressource mit eigenen Statusregeln. Versuchst du, Keywords bei einer Version zu patchen, die live oder in Review ist, bekommst du einen 409STATE_ERROR. Die API umgeht Apples Release-Zyklus nicht, sie gibt dir nur einen skriptbaren Weg, dieselben Aktionen auszulösen, die du sonst per Klick durchführst.
Wenn du Metadaten für mehr als eine App verwaltest oder in sechs-plus Sprachen lokalisierst und dieselbe Änderung am Keyword-Feld bei jedem Release erneut in sechs Locale-Tabs eintippst, nimmt dir die App Store Connect API das Klicken ab. Sie nimmt dir nicht die Beschränkungen ab. Zu wissen, wo diese Beschränkungen tatsächlich liegen, erspart dir eine Debugging-Session, sobald ein PATCH-Request aus einem Grund fehlschlägt, der nichts mit deinem JSON zu tun hat.
Kann ich mein Keyword-Feld über die App Store Connect API aktualisieren?
Ja. Das Attribut keywords liegt auf der Ressource appStoreVersionLocalization, und du aktualisierst es mit einem PATCH-Request an den Endpoint dieser Ressource, gescoped auf eine Locale. Das funktioniert genau wie das manuelle Bearbeiten des Keyword-Felds im Bereich „Lokalisierbare Informationen” von App Store Connect — gleiches 100-Zeichen-Feld, gleiche Tokenisierungsregeln, derselbe Hinweis, den Titel nicht zu wiederholen. Die API lockert davon nichts; sie ist nur eine andere Tür zum selben Raum.
Was Leuten Probleme macht, ist nicht der Request-Body. Es ist, dass dieser Endpoint Schreibzugriffe nur akzeptiert, solange sich die übergeordnete App-Store-Version in einem bearbeitbaren Status befindet.
Welche Ressource enthält welches Metadatenfeld?
Das ist der Teil, den die meisten Integrationsguides auslassen — und der Grund, warum ein funktionierender PATCH-Request für ein Feld am selben Tag bei einem anderen Feld fehlschlagen kann.
appInfoLocalization enthält Felder, die nicht an eine bestimmte Version gebunden sind:
namesubtitleprivacyPolicyUrl,privacyPolicyText,privacyChoicesUrl
appStoreVersionLocalization enthält Felder, die an eine bestimmte Version gebunden sind:
keywordsdescriptionpromotionalTextwhatsNewmarketingUrl,supportUrl
Die Aufteilung sieht so aus, als könnten Name und Untertitel unabhängig von einer Versionseinreichung live gehen, weil Apples eigenes Ressourcenmodell sie nicht unter einer Version verschachtelt. In der Praxis funktioniert das nicht so: Beide Felder wirken sich erst aus, sobald eine Version veröffentlicht wird — genau wie Keywords. Wenn du eine Untertitel-Änderung prüfst und gewohnt bist, den Versionsstatus auf „Ready for Sale” zu checken, bevor du einer Metrik traust, gilt diese Gewohnheit auch hier — die API ändert, wie du das Feld schreibst, nicht wann Apple es tatsächlich ausliefert. Das ist dieselbe Lücke zwischen Release und Freigabe, die der Guide zu App-Store-Connect-Freigabeoptionen behandelt.
Warum schlägt mein PATCH-Request mit einem 409 STATE_ERROR fehl?
Weil Felder von appStoreVersionLocalization nur bearbeitet werden können, solange sich die übergeordnete Version in einem bearbeitbaren Status befindet — PREPARE_FOR_SUBMISSION, DEVELOPER_REJECTED, REJECTED oder METADATA_REJECTED. Sobald eine Version in WAITING_FOR_REVIEW, IN_REVIEW, PENDING_DEVELOPER_RELEASE oder READY_FOR_SALE wechselt, liefert derselbe PATCH-Request, der gestern noch funktioniert hat, einen 409 mit "code": "STATE_ERROR" und einer Meldung, dass das Attribut gerade nicht bearbeitet werden kann.
Das ist die API, die genau die Regel durchsetzt, die du schon aus der manuellen Oberfläche kennst: Sobald eingereicht wurde, ist das Keyword-Feld gesperrt, bis entweder die Review abgeschlossen ist oder du die Version mit einer Developer-Ablehnung zurückholst. Die Lösung ist keine andere Request-Form — es ist, den Status der Version vor dem Schreibversuch mit einem GET zu prüfen und das Update nur zu senden, wenn der Status einer der oben genannten bearbeitbaren ist. Wenn du das als Teil einer Release-Pipeline skriptest, gehört diese Statusprüfung vor den PATCH, nicht in eine Retry-Schleife danach.
Wie funktioniert die Authentifizierung wirklich?
Jeder Request braucht ein mit ES256 signiertes JSON Web Token, generiert aus einem privaten Schlüssel, den du in App Store Connect erstellst. Team Keys kommen aus Benutzer und Zugriff → Integrations → Team Keys, und einen zu generieren erfordert die Rolle Admin auf dem Account — eine engere Anforderung als die Gruppe Account Holder/Admin/App Manager/Marketing, die das Keyword-Feld von Hand bearbeiten kann. Individual Keys, aus deinem eigenen Nutzerprofil generiert, erben deine eigene Account-Rolle und App-Zuweisungen statt account-weitem Zugriff.
Zwei praktische Konsequenzen:
- Team Keys sehen jede App im Account, ohne Möglichkeit, einen auf eine einzelne App zu beschränken. Wenn du nur eine App verwaltest, ist ein Individual Key an deine eigene App-Manager- oder Marketing-Rolle die enger gescopte Option.
- Der private Schlüssel lässt sich genau einmal herunterladen. Apple speichert keine erneut herunterladbare Kopie. Verlierst du ihn, widerrufst du den Key und generierst einen neuen — weder Zugriffslevel noch Name eines bestehenden Keys lassen sich nachträglich ändern.
- Apple empfiehlt kurze Token-Lebensdauern für Standard-Requests (die App Store Connect API deckelt normale Request-Tokens auf rund 20 Minuten), nicht das Maximum, das für die schmale Gruppe reiner Lese-Reporting-Scopes erlaubt ist. Generiere pro Lauf deines Skripts ein neues Token, statt eines mit langer Gültigkeit fest zu hinterlegen.
Lohnt sich das für ein Indie-Team wirklich?
Wenn du eine App in ein oder zwei Locales verwaltest und dein Keyword-Feld alle paar Wochen änderst, nein — die manuelle Oberfläche ist schneller als eine API-Integration zu schreiben und zu pflegen. Die API zahlt sich erst aus, sobald du Metadaten über mehrere Locales nach Zeitplan verwaltest oder über mehr als eine App, wo dieselbe Feldänderung viele Male identisch wiederholt werden muss und ein Copy-Paste-Fehler in Locale fünf leicht übersehen wird.
Der realistische erste Anwendungsfall ist nicht volle Automatisierung — es ist ein Skript, das dein aktuelles Keyword-Feld, deine Beschreibung und deinen Untertitel über jede Locale einer Version ausliest, sodass du eine geplante Änderung gegen das vergleichen kannst, was gerade tatsächlich live ist, bevor du von Hand etwas anfasst. Lesezugriff hat keines der oben genannten Status-Sperrprobleme, weil GET-Requests unabhängig vom Versionsstatus funktionieren — der risikoärmere Startpunkt.
Bevor du gegen diese API entwickelst
- Kläre, auf welcher Ressource dein Zielfeld liegt, bevor du den Request schreibst —
appInfoLocalizationfür Name/Untertitel,appStoreVersionLocalizationfür Keywords/Beschreibung/Werbetext/What’s New. - Prüfe mit einem GET den Status der Version vor jedem PATCH an
appStoreVersionLocalization. Schreibe nur, wenn erPREPARE_FOR_SUBMISSION,DEVELOPER_REJECTED,REJECTEDoderMETADATA_REJECTEDist. - Entscheide dich für Team Key oder Individual Key nach Scope, nicht nach Bequemlichkeit — ein Team Key, den du nur für eine App gebraucht hast, ist ein stehendes account-weites Credential, das du nicht gebraucht hättest.
- Denk daran: Die API ändert, wie du Metadaten bearbeitest, nicht wann sie live gehen. Das Release-Timing folgt weiterhin derselben Release-vs-Freigabe-Regel wie manuelle Bearbeitungen, und die Rollenanforderungen folgen weiterhin den Regeln, wer das Keyword-Feld überhaupt anfassen darf.