TL;DR. 네, App Store Connect API로 App Store Connect를 직접 열지 않고도 키워드 필드, 부제목, 설명, 프로모션 텍스트를 업데이트할 수 있습니다. 다만 name과 subtitle은 appInfoLocalization 리소스에 있고, keywords, description, promotionalText, What’s New는 appStoreVersionLocalization이라는 별도 리소스에 있으며, 이 리소스는 자체 상태 규칙을 따릅니다. 이미 출시되었거나 심사 중인 버전에서 keywords를 PATCH하려 하면 409 STATE_ERROR가 돌아옵니다. 이 API는 Apple의 출시 주기를 우회하지 않습니다 — 원래 클릭으로 하던 동작을 스크립트로 실행할 수 있게 해줄 뿐입니다.

앱을 여러 개 관리하거나 6개 이상의 언어로 로컬라이즈하면서 릴리스 때마다 같은 키워드 필드 변경을 6개 로케일 탭에 반복 입력하고 있다면, App Store Connect API는 그 클릭 작업을 없애줍니다. 다만 제약 자체를 없애주지는 않습니다. 그 제약이 실제로 어디에 있는지 알아두면, JSON과는 아무 상관 없는 이유로 PATCH 요청이 실패했을 때 디버깅에 시간을 낭비하지 않을 수 있습니다.

키워드 필드를 App Store Connect API로 업데이트할 수 있나요?

네. keywords 속성은 appStoreVersionLocalization 리소스에 있으며, 로케일을 지정해 해당 리소스의 엔드포인트에 PATCH 요청을 보내 업데이트합니다. 이는 App Store Connect의 “현지화 가능한 정보” 섹션에서 수동으로 키워드 필드를 편집하는 것과 정확히 같은 방식으로 동작합니다 — 같은 100자 필드, 같은 토큰화 규칙, “제목을 반복하지 말라”는 같은 가이드라인이 적용됩니다. API가 그 규칙을 완화해주지는 않습니다. 같은 방으로 들어가는 또 다른 문일 뿐입니다.

사람들이 걸려 넘어지는 부분은 요청 본문이 아닙니다. 이 엔드포인트는 상위 App Store 버전이 편집 가능한 상태일 때만 쓰기를 허용한다는 점입니다.

어떤 리소스가 어떤 메타데이터 필드를 담고 있나요?

이 부분은 대부분의 연동 가이드가 건너뛰는 내용이며, 어떤 필드에 대한 PATCH 요청은 성공하는데 같은 날 다른 필드에 대한 요청은 실패하는 이유이기도 합니다.

**appInfoLocalization**은 특정 버전에 묶이지 않는 필드를 담습니다:

  • name
  • subtitle
  • privacyPolicyUrl, privacyPolicyText, privacyChoicesUrl

**appStoreVersionLocalization**은 특정 버전에 묶인 필드를 담습니다:

  • keywords
  • description
  • promotionalText
  • whatsNew
  • marketingUrl, supportUrl

이렇게 나뉜 걸 보면 Apple 자체의 리소스 모델이 name과 subtitle을 버전 아래에 중첩시키지 않으니 이 두 필드는 버전 제출과 무관하게 바로 반영될 것처럼 보입니다. 하지만 실제로는 그렇지 않습니다. 두 필드 모두 keywords와 마찬가지로 버전이 출시되어야만 반영됩니다. 부제목 변경을 검증하면서 지표를 믿기 전에 버전 상태가 “판매 가능”인지부터 확인하는 습관이 있다면, 그 습관은 여기서도 그대로 적용됩니다 — API가 바꾸는 건 필드를 쓰는 방식이지, Apple이 실제로 그걸 출시하는 시점이 아닙니다. 이는 App Store Connect 출시 옵션 가이드에서 다룬, 출시와 승인 사이의 그 간극과 동일합니다.

PATCH 요청이 409 STATE_ERROR로 실패하는 이유는 뭔가요?

appStoreVersionLocalization 필드는 상위 버전이 편집 가능한 상태 — PREPARE_FOR_SUBMISSION, DEVELOPER_REJECTED, REJECTED, METADATA_REJECTED — 일 때만 편집할 수 있기 때문입니다. 버전이 WAITING_FOR_REVIEW, IN_REVIEW, PENDING_DEVELOPER_RELEASE, READY_FOR_SALE 중 하나로 넘어가면, 어제까지 잘 되던 그 PATCH 요청이 409와 함께 "code": "STATE_ERROR", 그리고 지금은 이 속성을 편집할 수 없다는 메시지를 반환합니다.

이건 수동 UI에서 이미 알고 있는 규칙을 API가 그대로 강제하는 것뿐입니다: 한번 제출하면, 심사가 끝나거나 개발자 거부로 버전을 다시 가져오기 전까지는 키워드 필드가 잠깁니다. 해결책은 다른 형태의 요청이 아니라, 쓰기를 시도하기 전에 GET으로 버전 상태를 확인하고, 위에 나열된 편집 가능한 상태 중 하나일 때만 업데이트를 보내는 것입니다. 이걸 릴리스 파이프라인의 일부로 스크립트화한다면, 그 상태 확인은 PATCH가 실패한 뒤의 재시도 루프가 아니라 PATCH 앞에 있어야 합니다.

인증은 실제로 어떻게 동작하나요?

모든 요청에는 App Store Connect에서 만든 개인 키로 생성하고 ES256으로 서명한 JSON Web Token이 필요합니다. Team Keys는 “사용자 및 액세스” → Integrations → Team Keys에서 만들며, 생성하려면 계정에 Admin 역할이 있어야 합니다 — 이는 키워드 필드를 수동으로 편집할 수 있는 계정 소유자/관리자/앱 관리자/마케팅 그룹보다 더 좁은 요건입니다. 자신의 사용자 프로필에서 생성하는 Individual Keys는 계정 전체 접근 권한 대신 자신의 계정 역할과 앱 배정을 그대로 물려받습니다.

여기서 실무적으로 두 가지가 따라옵니다:

  • Team Keys는 계정 내 모든 앱을 볼 수 있으며, 하나의 앱으로 범위를 제한할 방법이 없습니다. 앱 하나만 관리한다면, 자신의 앱 관리자나 마케팅 역할에 묶인 Individual Key가 더 좁은 범위로 적합한 선택입니다.
  • 개인 키는 딱 한 번만 다운로드할 수 있습니다. Apple은 다시 다운로드할 수 있는 사본을 보관하지 않습니다. 잃어버리면 그 키를 폐기하고 새로 생성하는 수밖에 없으며, 기존 키의 접근 수준을 나중에 복구하거나 바꿀 수도 없습니다.
  • Apple은 읽기 전용 리포팅 범위에만 허용되는 최대치가 아니라, 일반 요청에는 짧은 토큰 수명을 권장합니다(App Store Connect API는 일반 요청 토큰을 약 20분으로 제한합니다). 유효기간이 긴 토큰 하나를 하드코딩하지 말고, 스크립트를 실행할 때마다 토큰을 새로 생성하세요.

인디 팀에게 이걸 실제로 구축할 가치가 있을까요?

앱 하나를 한두 로케일에서 관리하고 키워드 필드를 몇 주에 한 번 정도 바꾼다면, 아니오 — API 연동을 만들고 유지하는 것보다 수동 UI가 더 빠릅니다. 이 API는 여러 로케일에 걸쳐 일정에 따라 메타데이터를 관리하거나, 앱을 여러 개 관리하면서 같은 필드 변경을 여러 번 똑같이 반복해야 하고, 다섯 번째 로케일에서의 복사-붙여넣기 실수를 놓치기 쉬운 상황부터 제 몫을 하기 시작합니다.

현실적인 첫 사용 사례는 완전 자동화가 아니라, 어떤 버전의 모든 로케일에 걸쳐 현재 키워드 필드, 설명, 부제목을 읽어오는 스크립트입니다. 그러면 직접 손대기 전에, 제안된 변경 사항을 실제로 지금 라이브 상태인 것과 비교해 볼 수 있습니다. GET 요청은 버전 상태와 무관하게 동작하므로 읽기 접근에는 위에서 말한 상태 잠금 문제가 전혀 없어, 시작하기에 위험이 낮은 지점입니다.

이 API로 개발하기 전에

  1. 요청을 작성하기 전에 대상 필드가 어느 리소스에 있는지 확인하세요 — name/subtitle은 appInfoLocalization, keywords/description/promotionalText/What’s New는 appStoreVersionLocalization입니다.
  2. appStoreVersionLocalization에 PATCH하기 전마다 GET으로 버전 상태를 확인하세요. PREPARE_FOR_SUBMISSION, DEVELOPER_REJECTED, REJECTED, METADATA_REJECTED 중 하나일 때만 쓰세요.
  3. Team Key와 Individual Key 중 어느 쪽을 쓸지는 편의가 아니라 범위에 따라 정하세요 — 앱 하나 때문에만 필요했던 Team Key는 원래 필요하지 않았던, 계정 전체에 걸친 상시 자격 증명이 됩니다.
  4. 이 API가 바꾸는 건 메타데이터를 편집하는 방식이지, 그게 언제 라이브가 되는지가 아니라는 점을 기억하세요. 출시 시점은 여전히 수동 편집과 동일한 출시-대-승인 규칙을 따르고, 역할 요건도 여전히 애초에 누가 키워드 필드를 건드릴 수 있는지에 대한 규칙을 따릅니다.