ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
App Store Connect API の概要
2018 年に Apple が公開した REST API。それ以前は非公式の iTMSTransporter や spaceship (リバースエンジニアリング) に頼っていた処理を、公式 API で行えるようになりました。
主なユースケース:
- CI/CD でのアプリ申請自動化 (Fastlane など)
- TestFlight のベータテスター一括追加 / 削除
- アプリのメタデータ (スクリーンショット / 説明文) 一括更新
- 売上 / 利用統計レポートのダウンロード
- レビュー状況の監視 (Slack 通知連携)
- プロビジョニングプロファイル / 証明書管理
API キーの取得
- App Store Connect にログイン
- ユーザとアクセス → キータブ
- App Store Connect API → 「キーを生成」
- 役割 (Admin / Developer / App Manager 等) を選択
- 生成された .p8 ファイルをダウンロード (再ダウンロード不可)
- Key ID と Issuer ID をメモ
取得物:
- Key ID — 10 文字程度の英数字
- Issuer ID — UUID 形式
- Private Key —
AuthKey_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 Unauthorized | JWT 期限切れ or 署名不正 | トークン再生成、Key ID/Issuer ID 確認 |
| 403 Forbidden | 権限不足 | API キーの role を Admin / App Manager に |
| 404 Not Found | ID が間違い | 事前に 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 通知が現実解。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- YouTube Data API (v3)
- Twitter API
- Facebook API
- Google Trends
- Google Custom Search API
- App Store Connect API
- Revit API
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?