7.

App Store Connect API 完全ガイド

編集
この記事の要点
  • App Store Connect API は Apple Developer 公式の REST API。アプリ管理 / TestFlight / 売上を自動化
  • 認証は JWTAPI Key (Key ID) + Issuer ID + Private Key (.p8) で署名
  • アプリメタデータ更新、レビュー状況取得、TestFlight ベータテスター追加、売上レポート取得
  • Fastlanedeliver / pilot は内部でこの API を利用
  • Python: appstoreconnect-api、Ruby: spaceship / fastlane
  • レート制限あり (組織単位)。指数バックオフ + キャッシュで対応

App Store Connect API の概要

2018 年に Apple が公開した REST API。それ以前は非公式の iTMSTransporter や spaceship (リバースエンジニアリング) に頼っていた処理を、公式 API で行えるようになりました。

主なユースケース:

  • CI/CD でのアプリ申請自動化 (Fastlane など)
  • TestFlight のベータテスター一括追加 / 削除
  • アプリのメタデータ (スクリーンショット / 説明文) 一括更新
  • 売上 / 利用統計レポートのダウンロード
  • レビュー状況の監視 (Slack 通知連携)
  • プロビジョニングプロファイル / 証明書管理

API キーの取得

  1. App Store Connect にログイン
  2. ユーザとアクセス → キータブ
  3. App Store Connect API → 「キーを生成」
  4. 役割 (Admin / Developer / App Manager 等) を選択
  5. 生成された .p8 ファイルをダウンロード (再ダウンロード不可)
  6. Key ID と Issuer ID をメモ

取得物:

  • Key ID — 10 文字程度の英数字
  • Issuer ID — UUID 形式
  • Private KeyAuthKey_XXXXXX.p8 (PEM 形式 EC 鍵)

JWT 認証

毎回のリクエストで JWT を作って Authorization: Bearer ヘッダに付けます。有効期限は最大 20 分。

Python での JWT 生成

# pip install pyjwt cryptography requests
import time
import jwt
import requests

KEY_ID    = "ABC123DEFG"
ISSUER_ID = "57246542-96fe-1a63-e053-0824d011072a"
PRIVATE_KEY_PATH = "AuthKey_ABC123DEFG.p8"

def generate_token():
    with open(PRIVATE_KEY_PATH, "r") as f:
        private_key = f.read()

    headers = {
        "alg": "ES256",
        "kid": KEY_ID,
        "typ": "JWT",
    }
    payload = {
        "iss": ISSUER_ID,
        "iat": int(time.time()),
        "exp": int(time.time()) + 20 * 60,    # 20 分有効
        "aud": "appstoreconnect-v1",
    }
    return jwt.encode(payload, private_key, algorithm="ES256", headers=headers)

# 利用
token = generate_token()
res = requests.get(
    "https://api.appstoreconnect.apple.com/v1/apps",
    headers={"Authorization": f"Bearer {token}"},
)
print(res.json())

Ruby (spaceship) での JWT 生成

require 'spaceship'

Spaceship::ConnectAPI::Token.create(
  key_id:       'ABC123DEFG',
  issuer_id:    '57246542-96fe-...',
  filepath:     'AuthKey_ABC123DEFG.p8',
)

apps = Spaceship::ConnectAPI::App.all
apps.each { |a| puts "#{a.id} #{a.name}" }

主要エンドポイント

エンドポイント用途
GET /v1/appsアプリ一覧
GET /v1/apps/{id}/appStoreVersionsバージョン一覧
POST /v1/appStoreVersions新規バージョン作成
GET /v1/apps/{id}/buildsビルド一覧 (TestFlight)
POST /v1/betaTestersベータテスター追加
GET /v1/betaGroupsテスターグループ
POST /v1/appPreviewSetsスクリーンショット
GET /v1/salesReports売上レポート (gzip)
GET /v1/financeReports会計レポート
GET /v1/devices登録デバイス
POST /v1/certificates証明書作成
POST /v1/profilesプロビジョニングプロファイル作成

Python ライブラリ (appstoreconnect-api)

# pip install appstoreconnect
from appstoreconnect import Api, UserRole

api = Api(KEY_ID, PRIVATE_KEY_PATH, ISSUER_ID)

# アプリ一覧
apps = api.read_apps()
for app in apps:
    print(app.id, app.name, app.bundleId)

# 売上レポート (gzip)
import datetime
data = api.download_sales_and_trends_reports(
    filters={'frequency': 'DAILY', 'reportDate': '2026-06-01',
             'vendorNumber': '12345678'},
    save_to='./sales.gz',
)

# TestFlight ベータテスター追加
api.modify_registered_devices('DEVICE_ID', name='New iPhone')

# レビュー状況
versions = api.read_app_store_versions(app_id=app.id)
for v in versions:
    print(v.versionString, v.appStoreState)
    # IN_REVIEW / WAITING_FOR_REVIEW / READY_FOR_SALE / DEVELOPER_REJECTED

Fastlane との関係

Fastlane は内部で App Store Connect API を利用しています。app_store_connect_api_key アクションで API キーを設定すると、deliver / pilot / match などが API 経由で動作します。

# Fastfile
lane :release do
  api_key = app_store_connect_api_key(
    key_id: "ABC123DEFG",
    issuer_id: "57246542-96fe-...",
    key_filepath: "./AuthKey_ABC123DEFG.p8",
  )

  # ビルドアップロード
  upload_to_app_store(
    api_key: api_key,
    submit_for_review: true,
    automatic_release: true,
  )

  # TestFlight 配信
  pilot(
    api_key: api_key,
    distribute_external: true,
    groups: ["Beta Testers"],
  )
end

レート制限

制限
1 時間あたりリクエスト数 (組織単位)3,600 (おおよそ)
JWT 有効期限最大 20 分
1 回のレスポンスサイズ~10 MB
ファイルアップロード上限~4 GB

超過時は 429 Too Many Requests。指数バックオフでリトライ。

売上レポートの取得

import requests, gzip

token = generate_token()

# 日次レポート (gzip 圧縮 TSV)
params = {
    "filter[frequency]": "DAILY",
    "filter[reportDate]": "2026-06-01",
    "filter[reportType]": "SALES",
    "filter[reportSubType]": "SUMMARY",
    "filter[vendorNumber]": "12345678",
}
res = requests.get(
    "https://api.appstoreconnect.apple.com/v1/salesReports",
    headers={"Authorization": f"Bearer {token}"},
    params=params,
    stream=True,
)
with open("sales.tsv.gz", "wb") as f:
    for chunk in res.iter_content(8192):
        f.write(chunk)

# 解凍して読む
with gzip.open("sales.tsv.gz", "rt") as f:
    for line in f:
        print(line.strip())

TestFlight ベータテスター一括追加

import requests

token = generate_token()

# ベータテスター作成
res = requests.post(
    "https://api.appstoreconnect.apple.com/v1/betaTesters",
    headers={"Authorization": f"Bearer {token}",
             "Content-Type": "application/json"},
    json={
        "data": {
            "type": "betaTesters",
            "attributes": {
                "email": "tester@example.com",
                "firstName": "Test",
                "lastName": "User",
            },
            "relationships": {
                "betaGroups": {
                    "data": [{"type": "betaGroups", "id": "GROUP_ID"}]
                }
            }
        }
    }
)
print(res.status_code, res.json())

エラー処理

ステータス意味対処
401 UnauthorizedJWT 期限切れ or 署名不正トークン再生成、Key ID/Issuer ID 確認
403 Forbidden権限不足API キーの role を Admin / App Manager に
404 Not FoundID が間違い事前に GET /v1/apps で正しい ID を取得
409 Conflict状態遷移不可例: レビュー中はバージョン削除不可
429 Too Many Requestsレート制限指数バックオフ + キャッシュ

FAQ

Q: 秘密鍵 .p8 を紛失した
A: 再ダウンロード不可。App Store Connect で旧キーを失効させ、新規キー生成。

Q: Apple Developer Enterprise Program でも使える?
A: 使えますが、利用可能なエンドポイントが限定されます (Enterprise 配布固有の API が別にあります)。

Q: Fastlane / spaceship との使い分けは?
A: 単純なアプリ公開・TestFlight は Fastlane で十分。複雑な独自ワークフロー (ダッシュボード、社内ツール) は API 直叩き。

Q: Webhook はある?
A: レビュー状況通知の Webhook はありません。定期 polling + Slack 通知が現実解。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. YouTube Data API (v3)
  2. Twitter API
  3. Facebook API
  4. Google Trends
  5. Google Custom Search API
  6. App Store Connect API
  7. Revit API

最近更新/作成されたページ