App Store Connect API

RSS for tag

The App Store Connect API helps you automate tasks usually done on the Apple Developer website and App Store Connect.

App Store Connect API Documentation

Posts under App Store Connect API subtopic

Post

Replies

Boosts

Views

Activity

续费后originTransactionId没有发生变化,但是userAccountToken却变化了,
我们仅有一个订阅组,一个用户收到了订阅续费消息,我们不知道发生了什么, 续费消息中的originTransactionId没有发生变化,但是userAccountToken却变化了,指向了另一个用户,此时旧的用户不会收到续费在哪的任何消息。 哪位技术大佬可以帮助解答问题,什么情况下会出现这样的情况
0
0
248
Jan ’26
升级前后 userAccountToken 不变,但是 originTransactionId变了
问题:一个用户升级后,苹果的通知消息中 userAccountToken 不变,但是 originTransactionId变了。此时升级前的originTransactionId还会进行周期扣款,升级后的originTransactionId也会进行周期扣款。 注意,订阅的配置是在同一个组中 哪位技术大佬可以帮助解答问题,什么情况下会出现这样的情况
0
0
157
Jan ’26
Cant Create/Update App Clips
Hey there, We've been using App Store Connect API to manage (create/update) Advanced App Clip Experiences via App Store Connect API. Everything has worked fine, we've been able to successfully manage hundreds of app clips but all of a sudden starting on December 15th the API started returning the following error: "id" => "1e15b36b-5347-4af0-9bab-7f6626ffec65" "status" => "409" "code" => "ENTITY_ERROR.INCLUDED.INVALID_ID" "title" => "The provided entity id is invalid" "detail" => "The provided included entity id 'EN' has invalid format" "source" => array:1 [▼ "pointer" => "/included/0/id" ] It does seem to be an API bug considering it has always worked fine and we didn't change anything on our side, the /included/0/id value has always been EN and never changed. Moreover, EN still seems to be a valid value according to the API docs and there are no changes reported of that field in the API release notes. Here's the request ID: 1e15b36b-5347-4af0-9bab-7f6626ffec65 I've tried using different values through trial and error (en, EN, EN-US, ...) and none of them worked.
11
5
926
Jan ’26
App Store Connect API / altool uploads validate IPA against wrong app when multiple apps share account; Transporter succeeds
When uploading an iOS IPA via App Store Connect API or altool, App Store Connect validates the IPA against the wrong existing app record, even though the IPA is correctly signed and provisioned. The exact same IPA uploads successfully via Apple Transporter, which correctly routes it to the intended app. This appears to be an App Store Connect upload-resolution issue specific to API-based delivery. Environment Account: App Store Connect (Admin access) Authentication: App Store Connect API Key (Issuer ID + Key ID) Apps in Account: com.dailyaudiobible.dabapp Apple ID: 121xxxx266 com.dailyaudiobible.dabapp2 Apple ID: 645xxxx428 iOS / SDK Details Platform: iOS Build Artifact: Single signed IPA used for all tests Target SDK: iOS 18.5 Xcode: 16.4 .NET iOS SDK: 18.5.9227 Minimum iOS Version: 18.5 Architecture: ios-arm64 Build Type: App Store distribution (Release) This SDK/Xcode combination previously worked for TestFlight uploads of this app. Expected Behavior When uploading an IPA with: CFBundleIdentifier = com.dailyaudiobible.dabapp Provisioning profile for com.dailyaudiobible.dabapp Embedded provisioning profile matching com.dailyaudiobible.dabapp App Store Connect should validate and associate the build with the dabapp app record. Actual Behavior When uploading the IPA using API-based tools, App Store Connect validates the upload against dabapp2 and rejects it with: Validation failed (409): This bundle is invalid. The bundle identifier cannot be changed from the current value, com.dailyaudiobible.dabapp2. No references to dabapp2 exist in the codebase, build configuration, or signing assets. Delivery Methods Tested (Same IPA) App Store Connect API (automation / CI) Upload accepted Validation fails Error references com.dailyaudiobible.dabapp2 altool (Apple CLI, API key authentication) Same behavior as API Same validation error altool logs confirm API key has access to multiple apps but validation resolves to the wrong app Apple Transporter (manual) Automatically detects com.dailyaudiobible.dabapp Upload succeeds Build appears correctly under the dabapp record in App Store Connect This confirms the IPA itself is valid and correctly signed. Verification Performed From the built IPA: Info.plist CFBundleIdentifier = com.dailyaudiobible.dabapp Embedded provisioning profile Application identifier resolves to com.dailyaudiobible.dabapp Provisioning profile used at build time: Explicitly configured for com.dailyaudiobible.dabapp All values are verified by extracting the IPA contents locally. Questions for Apple Engineering Why do API-based uploads (App Store Connect API / altool) resolve this IPA to the wrong existing app record, while Transporter resolves it correctly, and how can that association be corrected or reset? If this is expected behavior when multiple related apps exist under one provider, is this documented, and are there required parameters or constraints for API-based uploads in this scenario? Additional Notes This is reproducible using only Apple-provided tools and APIs. CI/CD tooling itself is not required to reproduce the issue. Manual Transporter uploads are not a viable long-term solution for automated releases. Any guidance or confirmation from App Store Connect engineering or other developers would be appreciated.
1
0
220
Jan ’26
Incorrect, or missing copyright date-> using a copyright date that is any different from this current year, or missing a date
What am I missing here? 😐 Prepare all required actions Run ./.github/actions/verify-copyright Run echo "📋 Checking copyright file..." 📋 Checking copyright file... ✅ Copyright file exists at: fastlane/metadata/en-US/copyright.txt 📝 Copyright value: © 2025 Enterprise Support ✅ Copyright format valid: © 2025 Enterprise Support ✅ Copyright metadata validation passed
1
0
389
Jan ’26
Can not re-upload an Asset Pack that's been archived?
Hello, I'm trying to upload an asset pack that has the same identifier as an asset pack that I've archived. I understand this isn't likely a common scenario, but I'd expect that uploading an archived Asset Pack to become un-archived. Reverting to the next newest version available for the Asset Pack. Further, this restriction is not clear that you won't be able to reuse the assetPackID on the archive asset pack alert Archive Asset Pack? Are you sure you want to archive "[NAME]" asset pack? All versions of this asset will no longer be accessible by your app. Errors: Failed to create a new background asset pack version for '[NAME]'. (-19243) operation not allowed (409) Cannot create version for an archived background asset. (ID: 2cc6499a-83fa-4bbb-bc1f-0bb67d2a873d) httpBody: { "errors" : [ { "id" : "2cc6499a-83fa-4bbb-bc1f-0bb67d2a873d", "status" : "409", "code" : "STATE_ERROR.ARCHIVED_BACKGROUND_ASSET", "title" : "operation not allowed", "detail" : "Cannot create version for an archived background asset." } ]
3
0
447
Dec ’25
Empty "App Store Purchases Detailed" Analytics Report
Hey there, I'm building a service that requires receiving accurate sales/proceeds data along with the campaign name. From reading the documentation it looks to be fairly understandable, but in practice it is not. I have been testing this for almost a week, and I never got "Detailed Report" for "App Store Purchases Detailed" analytics report. The same report for "App Downloads Detailed" is arriving normally, but not to for the purchases. I tested for two different apps where I have around 200 daily installs and 30 purchases on each. I would love to get any thoughts on this from an Apple engineer!
1
0
571
Dec ’25
Data gaps on App Store Analytics API reports
Hey all, It's been now a few weeks since we started to help clients connect to their App Store Analytics API. I'm starting to notice that very often we'll see things like: Small data gaps. Eg. I have data on June 1, no data on June 2-4, and then data from June 5 to now Big data gaps. Eg. I'd have data on Jan 2024, but not on Feb-Mar 2024, then there's data again from April 2024 onwards. The actual files from Apple are like that we're not doing any treatments whatsoever. That's happening on both ONGOING and ONE_TIME_SNAPSHOT I also opened a Customer Support case and sent the files over 10 days ago, but no definitive answer so far. Are you also seeing gaps like this on your data? Any tips/recommendations?
4
0
1.6k
Dec ’25
How to build reliable Analytics integration via API?
Hey there, I'm building a service that requires receiving accurate app downloads and sales/proceeds data along with the campaign name. From reading the documentation it looks to be fairly understandable, but in practice it is not that straightforward. For example, I received the first one-time-snapshot detailed report for the App Store Purchases, and it contains partial data for several days. Shouldn't that be a full report of everything in analytics for like last year or so? Should I expect it to be updated and extended in the coming days? For the ongoing detailed report, I have not received anything yet, but I'm afraid it might have partial data as well. I will report here as well.
3
1
770
Dec ’25
Analytics Reports API stopped generating daily reports
I am planning to build a service that automatically pulls Apple reports and stores them in my database. I was able to successfully retrieve the APP_USAGE report from the Analytics API; however, while it initially generated daily reports for a couple of days, the daily report generation subsequently stopped. The weekly and monthly reports are generated normally. I also checked the readReportRequest response, and the StoppedDueToInactivity field is returned as false. And also, when I compared the monthly reports between the API and the web console, the data does not match. Does anyone have a solution to this issue, or is there a recommended or updated approach for handling this?
0
1
171
Dec ’25
Analytics Reports API stopped generating daily reports
I am planning to build a service that automatically pulls Apple reports and stores them in my database. I was able to successfully retrieve the APP_USAGE report from the Analytics API. It initially generated daily reports for a couple of days, but then the daily report generation stopped. The weekly and monthly reports continue to generate normally. I also checked the readReportRequest response, and the StoppedDueToInactivity field is returned as false. And also, when I compared the monthly reports between the API and the web console, the data does not match. Does anyone have a solution to this issue, or is there a recommended or updated approach for handling this?
0
0
301
Dec ’25
Cannot submit a new build
Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 Attempting to submit a new build continually failing and I suspect this is due to some issues on Apple's servers (Status code: 502, Bad Gateway) Anyone else seeing this issue? Apple's status page doesn't show any open incidents. [logs] Creating authorization token for App Store Connect API [logs] Ready to upload new build to TestFlight (App: 6746477612)... [logs] Going to upload updated app to App Store Connect [logs] This might take a few minutes. Please don't interrupt the script. [logs] [altool] 2025-12-10 12:04:00.993 *** Error: Unable to upload archive. Failed to authenticate for session: ( [logs] [altool] "Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 \"The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n\" UserInfo={NSLocalizedRecoverySuggestion=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n, NSLocalizedDescription=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n, NSLocalizedFailureReason=App Store operation failed.}" [logs] [logs] [altool] ) (-1011) [logs] [logs] [altool] { [logs] [logs] [altool] NSLocalizedDescription = "Unable to upload archive."; [logs] [altool] NSLocalizedFailureReason = "Failed to authenticate for session: (\n \"Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 \\\"The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n\\\" UserInfo={NSLocalizedRecoverySuggestion=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n, NSLocalizedDescription=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n, NSLocalizedFailureReason=App Store operation failed.}\"\n)"; [logs] [logs] [altool] } [logs] Application Loader output above ^ [logs] The server returned an invalid MIME type: text/html [logs] Error uploading '/var/folders/m1/8_w9962s3b79dqm00nnlm85m0000gn/T/97c174a3-8844-4f85-8fd5-78df1906d170.ipa'. [logs] Unable to upload archive. Failed to authenticate for session: ( [logs] The call to the altool completed with a non-zero exit status: 1. This indicates a failure. [logs] Could not download/upload from App Store Connect! [logs] [!] Error uploading ipa file:
2
2
222
Dec ’25
Are Assets Packs actually downloaded in the background?
Hello, I have a question about when are asset packs actually updated? For Essential Asset Packs, this only during the keys included in the pack? As in, only when the app is installed for firstInstallation. And only when there's an app update for subsequentUpdate? For On Demand Asset Packs, is this only when AssetPackManager.shared.checkForUpdates() is called? Also, are any asset packs ever actually updated in the background? For example, if an On Demand Asset Pack has an update pushed, can the device automatically fetch and download the pack overnight? Or is updating limited to only when the app is active?
2
0
346
Dec ’25
Download Sales and Trends Reports Error
I was using the Download Sales and Trends Reports API (GET https://api.appstoreconnect.apple.com/v1/salesReports), but at some point, the results started not displaying properly. (The reason for this is that all the +sales values ​​aren't showing up in the CSV file.) Below, I'll show you how to use the API in Python with a screenshot. (***** elements are hidden.) If anyone knows why, please let me know.
0
0
251
Dec ’25
Question Regarding Campaign Data Limits in “App Store Downloads” Analytics Report
Regarding the “App Store Downloads” Analytics Report, I have submitted a report generation request with accessType: ONE_TIME_SNAPSHOT. Reference: https://developer.apple.com/documentation/analytics-reports/app-download I would like to confirm the scope of the Campaign data included in the report generated by this request. In the App Store Connect UI, I understand that there is an upper limit of 200 Campaign entries displayed. For the report output, however, could you please confirm whether it includes all Campaigns measured on the App Store Connect side? Or is there also any upper limit on the number of Campaign records included in the report itself?
0
0
172
Dec ’25
Request Analytics Reports via POST Call
Hi everyone! When I attempt the Post Request using Postman, as shown in my attached curl, I receive the error "{ "errors": [ { "status": "405", "code": "METHOD_NOT_ALLOWED", "title": "The request method is not valid for the resource path.", "detail": "The request method used for this request is not valid for the resource path. Please consult the documentation." } ] }". I have constructed the JWT correctly as an admin with correct private Key and Unix Times and I am able to send regular GET requests without issue and I can view the dashboards in App Store Connect. The described POST request is being rejected, although it says so in the documentation: https://developer.apple.com/documentation/appstoreconnectapi/post-v1-analyticsreportrequests. Curl: curl --location 'https://api.appstoreconnect.apple.com/v1/analyticsReportRequests' --header 'Content-Type: application/json' --header 'Authorization: Bearer XXX' --data '{ "data": { "type": "analyticsReportRequests", "attributes": { "accessType": "ONGOING" }, "relationships": { "app": { "data": { "type": "apps", "id": "XXXXXXXXXX" } } } } }' (using ONE_TIME_SNAPSHOT makes no difference) Is this a documentation error ? I'd be happy to hear about a fix.
3
1
506
Nov ’25
I'd like to report an issue with the "App Referrer" source segmentation in the App Store Connect Analytics API.
I'd like to report an issue with the "App Referrer" source segmentation in the App Store Connect Analytics API. Issue Summary When retrieving impression data via the App Store Connect Analytics API using groupBy=["sourceType", "sourceInfo"], the impressions attributed to specific referring apps (e.g., Facebook, Instagram) do not match the values ​​displayed in the App Store Connect web dashboard. Details The total impressions in the API and dashboard are completely consistent, with the report category: App Store Discovery and Engagement Standard_Daily. The aggregated "App Referrer" (overall category) is also consistent. However, the detailed segmentation data in "App Referrer" is inconsistent, with the report category: App Store Discovery and Engagement Detailed_Daily. For example: The web dashboard shows significantly more impressions attributed to Facebook or Instagram. The API returns fewer impressions for the same referral source. Furthermore, the API does not return any "unknown"/"other" referral source entries, and displays no data for presentations where the exact referring app cannot be identified. Therefore, the sum of all sourceInfo entries returned by the API is lower than the app referral source value displayed in the web dashboard. We have confirmed: This is not due to time zone differences—the totals are exactly the same. We used the same date range, region, and platform settings as the dashboard. The difference only appears in the detailed app referral source breakdowns (e.g., "Facebook," "Instagram"). The API does not return missing presentations under any category. Questions for Apple: Does the App Store Connect web interface aggregate presentations from unidentified or privacy-restricted referring apps into known app names (e.g., Facebook or Instagram)? Is it normal for the Analytics API not to expose these presentations when the exact referring app cannot be identified? What official logic does the App Store Connect use to determine and display specific app referral sources (e.g., Facebook, Instagram)? When the API returns fewer referral records than the dashboard, how can developers accurately reproduce the same detailed app referral breakdown data in their reports? Are there any known limitations or privacy thresholds in the API that affect the disclosure of sourceInfo? Other Information Endpoint: Analytics API (Impressions grouped by sourceType and sourceInfo) Metric: Impressions Grouping Criteria: sourceType, sourceInfo We want to understand how App Store Connect allocates impressions to specific third-party apps (e.g., Facebook, Instagram) in the dashboard, and why the Analytics API returns lower numbers for these referral sources.
1
0
300
Nov ’25
App Store Connect API `inAppPurchaseV2` returns `links.next`, even when there's no more `data`
I think there's been a recent change to the App Store Connect API; I claim that it's a bug. When querying App Store Connect API endpoints that return arrays, like https://api.appstoreconnect.apple.com/v1/apps, the response includes a links property, of type PagedDocumentLinks. https://developer.apple.com/documentation/appstoreconnectapi/pageddocumentlinks links should include a next link only if there's more data to provide, and, indeed, this is how it works for the /v1/apps endpoint. But when querying inAppPurchasesV2, I find that starting very recently (this week?) the API always returns a next link, even if there's no more data to show. { data: [], links: { self: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=APo&limit=50', first: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?limit=50', next: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=ASw' }, meta: { paging: { total: 223, nextCursor: 'ASw', limit: 50 } } } If I request the next link, it will generate me another response with empty data and with a new cursor. { data: [], links: { self: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=ASw&limit=50', first: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?limit=50', next: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=AV4' }, meta: { paging: { total: 223, nextCursor: 'AV4', limit: 50 } } } Code I've written against this API (including my open-source library https://github.com/dfabulich/node-app-store-connect-api) assumes that if there's another links.next link, we should follow it; as a result, my code is looping infinitely, requesting empty data until eventually I have to give up. This issue doesn't affect other endpoints, like /v1/apps, just this inAppPurchasesV2 endpoint. Was this an intentional change? It seems to be a bug.
4
5
564
Nov ’25
App Store Connect API – 401 Unauthorized (JWT Authentication Issue)
I’m experiencing an issue while attempting to authenticate API calls to the App Store Connect API using a JWT token. I have App Manager permissions on my apple developer account. Despite following the official documentation and successfully verifying the JWT signature locally, I consistently receive the following response from the API: { "errors": [{ "status": "401", "code": "NOT_AUTHORIZED", "title": "Authentication credentials are missing or invalid.", "detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired." }] } import jwt import time from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend from jwt.exceptions import InvalidSignatureError Replace with your own credentials KEY_ID = "<YOUR_KEY_ID>" ISSUER_ID = "<YOUR_ISSUER_ID>" PRIVATE_KEY_PATH = "AuthKey_<YOUR_KEY_ID>.p8" def generate_token(): """Generate a JWT for App Store Connect API authentication.""" with open(PRIVATE_KEY_PATH, "r") as f: private_key = f.read() header = { "alg": "ES256", "kid": KEY_ID, "typ": "JWT" } now = int(time.time()) payload = { "iss": ISSUER_ID, "iat": now, "exp": now + 1200, # Token valid for 20 minutes "aud": "appstoreconnect-v1" } token = jwt.encode(payload, private_key, algorithm="ES256", headers=header) return token def verify_token_signature(token): """Verify JWT signature locally using the public key derived from the .p8 private key.""" with open(PRIVATE_KEY_PATH, "rb") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) # Derive public key from private key public_key = private_key.public_key() pem_public_key = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) try: decoded = jwt.decode( token, pem_public_key, algorithms=["ES256"], audience="appstoreconnect-v1" ) print("✅ JWT signature verified successfully.") print("Decoded payload:", decoded) except InvalidSignatureError: print("❌ JWT signature is invalid.") except Exception as e: print(f"❌ JWT verification failed: {e}") if name == "main": token = generate_token() print("Generated JWT:", token) verify_token_signature(token) Why might a JWT that is valid locally still fail authentication with a 401 NOT_AUTHORIZED error from the App Store Connect API? Are there any specific permission scopes required for API access beyond App Manager account access from Apple Store connect? Are there any known issues or additional configuration steps required for API key access? Is there a way to validate API access status for a specific key or account? Could you please share the correct example of JWT generation in Python for reference?
0
0
183
Nov ’25
续费后originTransactionId没有发生变化,但是userAccountToken却变化了,
我们仅有一个订阅组,一个用户收到了订阅续费消息,我们不知道发生了什么, 续费消息中的originTransactionId没有发生变化,但是userAccountToken却变化了,指向了另一个用户,此时旧的用户不会收到续费在哪的任何消息。 哪位技术大佬可以帮助解答问题,什么情况下会出现这样的情况
Replies
0
Boosts
0
Views
248
Activity
Jan ’26
升级前后 userAccountToken 不变,但是 originTransactionId变了
问题:一个用户升级后,苹果的通知消息中 userAccountToken 不变,但是 originTransactionId变了。此时升级前的originTransactionId还会进行周期扣款,升级后的originTransactionId也会进行周期扣款。 注意,订阅的配置是在同一个组中 哪位技术大佬可以帮助解答问题,什么情况下会出现这样的情况
Replies
0
Boosts
0
Views
157
Activity
Jan ’26
Cant Create/Update App Clips
Hey there, We've been using App Store Connect API to manage (create/update) Advanced App Clip Experiences via App Store Connect API. Everything has worked fine, we've been able to successfully manage hundreds of app clips but all of a sudden starting on December 15th the API started returning the following error: "id" => "1e15b36b-5347-4af0-9bab-7f6626ffec65" "status" => "409" "code" => "ENTITY_ERROR.INCLUDED.INVALID_ID" "title" => "The provided entity id is invalid" "detail" => "The provided included entity id 'EN' has invalid format" "source" => array:1 [▼ "pointer" => "/included/0/id" ] It does seem to be an API bug considering it has always worked fine and we didn't change anything on our side, the /included/0/id value has always been EN and never changed. Moreover, EN still seems to be a valid value according to the API docs and there are no changes reported of that field in the API release notes. Here's the request ID: 1e15b36b-5347-4af0-9bab-7f6626ffec65 I've tried using different values through trial and error (en, EN, EN-US, ...) and none of them worked.
Replies
11
Boosts
5
Views
926
Activity
Jan ’26
App Store Connect API / altool uploads validate IPA against wrong app when multiple apps share account; Transporter succeeds
When uploading an iOS IPA via App Store Connect API or altool, App Store Connect validates the IPA against the wrong existing app record, even though the IPA is correctly signed and provisioned. The exact same IPA uploads successfully via Apple Transporter, which correctly routes it to the intended app. This appears to be an App Store Connect upload-resolution issue specific to API-based delivery. Environment Account: App Store Connect (Admin access) Authentication: App Store Connect API Key (Issuer ID + Key ID) Apps in Account: com.dailyaudiobible.dabapp Apple ID: 121xxxx266 com.dailyaudiobible.dabapp2 Apple ID: 645xxxx428 iOS / SDK Details Platform: iOS Build Artifact: Single signed IPA used for all tests Target SDK: iOS 18.5 Xcode: 16.4 .NET iOS SDK: 18.5.9227 Minimum iOS Version: 18.5 Architecture: ios-arm64 Build Type: App Store distribution (Release) This SDK/Xcode combination previously worked for TestFlight uploads of this app. Expected Behavior When uploading an IPA with: CFBundleIdentifier = com.dailyaudiobible.dabapp Provisioning profile for com.dailyaudiobible.dabapp Embedded provisioning profile matching com.dailyaudiobible.dabapp App Store Connect should validate and associate the build with the dabapp app record. Actual Behavior When uploading the IPA using API-based tools, App Store Connect validates the upload against dabapp2 and rejects it with: Validation failed (409): This bundle is invalid. The bundle identifier cannot be changed from the current value, com.dailyaudiobible.dabapp2. No references to dabapp2 exist in the codebase, build configuration, or signing assets. Delivery Methods Tested (Same IPA) App Store Connect API (automation / CI) Upload accepted Validation fails Error references com.dailyaudiobible.dabapp2 altool (Apple CLI, API key authentication) Same behavior as API Same validation error altool logs confirm API key has access to multiple apps but validation resolves to the wrong app Apple Transporter (manual) Automatically detects com.dailyaudiobible.dabapp Upload succeeds Build appears correctly under the dabapp record in App Store Connect This confirms the IPA itself is valid and correctly signed. Verification Performed From the built IPA: Info.plist CFBundleIdentifier = com.dailyaudiobible.dabapp Embedded provisioning profile Application identifier resolves to com.dailyaudiobible.dabapp Provisioning profile used at build time: Explicitly configured for com.dailyaudiobible.dabapp All values are verified by extracting the IPA contents locally. Questions for Apple Engineering Why do API-based uploads (App Store Connect API / altool) resolve this IPA to the wrong existing app record, while Transporter resolves it correctly, and how can that association be corrected or reset? If this is expected behavior when multiple related apps exist under one provider, is this documented, and are there required parameters or constraints for API-based uploads in this scenario? Additional Notes This is reproducible using only Apple-provided tools and APIs. CI/CD tooling itself is not required to reproduce the issue. Manual Transporter uploads are not a viable long-term solution for automated releases. Any guidance or confirmation from App Store Connect engineering or other developers would be appreciated.
Replies
1
Boosts
0
Views
220
Activity
Jan ’26
Incorrect, or missing copyright date-> using a copyright date that is any different from this current year, or missing a date
What am I missing here? 😐 Prepare all required actions Run ./.github/actions/verify-copyright Run echo "📋 Checking copyright file..." 📋 Checking copyright file... ✅ Copyright file exists at: fastlane/metadata/en-US/copyright.txt 📝 Copyright value: © 2025 Enterprise Support ✅ Copyright format valid: © 2025 Enterprise Support ✅ Copyright metadata validation passed
Replies
1
Boosts
0
Views
389
Activity
Jan ’26
Can not re-upload an Asset Pack that's been archived?
Hello, I'm trying to upload an asset pack that has the same identifier as an asset pack that I've archived. I understand this isn't likely a common scenario, but I'd expect that uploading an archived Asset Pack to become un-archived. Reverting to the next newest version available for the Asset Pack. Further, this restriction is not clear that you won't be able to reuse the assetPackID on the archive asset pack alert Archive Asset Pack? Are you sure you want to archive "[NAME]" asset pack? All versions of this asset will no longer be accessible by your app. Errors: Failed to create a new background asset pack version for '[NAME]'. (-19243) operation not allowed (409) Cannot create version for an archived background asset. (ID: 2cc6499a-83fa-4bbb-bc1f-0bb67d2a873d) httpBody: { "errors" : [ { "id" : "2cc6499a-83fa-4bbb-bc1f-0bb67d2a873d", "status" : "409", "code" : "STATE_ERROR.ARCHIVED_BACKGROUND_ASSET", "title" : "operation not allowed", "detail" : "Cannot create version for an archived background asset." } ]
Replies
3
Boosts
0
Views
447
Activity
Dec ’25
Empty "App Store Purchases Detailed" Analytics Report
Hey there, I'm building a service that requires receiving accurate sales/proceeds data along with the campaign name. From reading the documentation it looks to be fairly understandable, but in practice it is not. I have been testing this for almost a week, and I never got "Detailed Report" for "App Store Purchases Detailed" analytics report. The same report for "App Downloads Detailed" is arriving normally, but not to for the purchases. I tested for two different apps where I have around 200 daily installs and 30 purchases on each. I would love to get any thoughts on this from an Apple engineer!
Replies
1
Boosts
0
Views
571
Activity
Dec ’25
Data gaps on App Store Analytics API reports
Hey all, It's been now a few weeks since we started to help clients connect to their App Store Analytics API. I'm starting to notice that very often we'll see things like: Small data gaps. Eg. I have data on June 1, no data on June 2-4, and then data from June 5 to now Big data gaps. Eg. I'd have data on Jan 2024, but not on Feb-Mar 2024, then there's data again from April 2024 onwards. The actual files from Apple are like that we're not doing any treatments whatsoever. That's happening on both ONGOING and ONE_TIME_SNAPSHOT I also opened a Customer Support case and sent the files over 10 days ago, but no definitive answer so far. Are you also seeing gaps like this on your data? Any tips/recommendations?
Replies
4
Boosts
0
Views
1.6k
Activity
Dec ’25
How to build reliable Analytics integration via API?
Hey there, I'm building a service that requires receiving accurate app downloads and sales/proceeds data along with the campaign name. From reading the documentation it looks to be fairly understandable, but in practice it is not that straightforward. For example, I received the first one-time-snapshot detailed report for the App Store Purchases, and it contains partial data for several days. Shouldn't that be a full report of everything in analytics for like last year or so? Should I expect it to be updated and extended in the coming days? For the ongoing detailed report, I have not received anything yet, but I'm afraid it might have partial data as well. I will report here as well.
Replies
3
Boosts
1
Views
770
Activity
Dec ’25
Analytics Reports API stopped generating daily reports
I am planning to build a service that automatically pulls Apple reports and stores them in my database. I was able to successfully retrieve the APP_USAGE report from the Analytics API; however, while it initially generated daily reports for a couple of days, the daily report generation subsequently stopped. The weekly and monthly reports are generated normally. I also checked the readReportRequest response, and the StoppedDueToInactivity field is returned as false. And also, when I compared the monthly reports between the API and the web console, the data does not match. Does anyone have a solution to this issue, or is there a recommended or updated approach for handling this?
Replies
0
Boosts
1
Views
171
Activity
Dec ’25
Analytics Reports API stopped generating daily reports
I am planning to build a service that automatically pulls Apple reports and stores them in my database. I was able to successfully retrieve the APP_USAGE report from the Analytics API. It initially generated daily reports for a couple of days, but then the daily report generation stopped. The weekly and monthly reports continue to generate normally. I also checked the readReportRequest response, and the StoppedDueToInactivity field is returned as false. And also, when I compared the monthly reports between the API and the web console, the data does not match. Does anyone have a solution to this issue, or is there a recommended or updated approach for handling this?
Replies
0
Boosts
0
Views
301
Activity
Dec ’25
Cannot submit a new build
Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 Attempting to submit a new build continually failing and I suspect this is due to some issues on Apple's servers (Status code: 502, Bad Gateway) Anyone else seeing this issue? Apple's status page doesn't show any open incidents. [logs] Creating authorization token for App Store Connect API [logs] Ready to upload new build to TestFlight (App: 6746477612)... [logs] Going to upload updated app to App Store Connect [logs] This might take a few minutes. Please don't interrupt the script. [logs] [altool] 2025-12-10 12:04:00.993 *** Error: Unable to upload archive. Failed to authenticate for session: ( [logs] [altool] "Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 \"The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n\" UserInfo={NSLocalizedRecoverySuggestion=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n, NSLocalizedDescription=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\nStatus Code: 502 (bad gateway)\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <style>\n body {\n font-family: \"Helvetica Neue\", \"HelveticaNeue\", Helvetica, Arial, sans-serif;\n font-size: 15px;\n font-weight: 200;\n line-height: 20px;\n color: #4c4c4c;\n text-align: center;\n }\n\n .section {\n margin-top: 50px;\n }\n </style>\n</head>\n<body>\n<div class=\"section\">\n <h1>&#63743;</h1>\n\n <h3>Bad Gateway</h3>\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\n</div>\n</body>\n</html>\n\n, NSLocalizedFailureReason=App Store operation failed.}" [logs] [logs] [altool] ) (-1011) [logs] [logs] [altool] { [logs] [logs] [altool] NSLocalizedDescription = "Unable to upload archive."; [logs] [altool] NSLocalizedFailureReason = "Failed to authenticate for session: (\n \"Error Domain=ITunesConnectionAuthenticationErrorDomain Code=-26000 \\\"The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n\\\" UserInfo={NSLocalizedRecoverySuggestion=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n, NSLocalizedDescription=The server returned an invalid response. This may indicate that a network proxy is interfering with communication, or that Apple servers are having issues. Please try your request again later.\\nStatus Code: 502 (bad gateway)\\n\\n\\n<!DOCTYPE html>\\n<html lang=\\\"en\\\">\\n<head>\\n <style>\\n body {\\n font-family: \\\"Helvetica Neue\\\", \\\"HelveticaNeue\\\", Helvetica, Arial, sans-serif;\\n font-size: 15px;\\n font-weight: 200;\\n line-height: 20px;\\n color: #4c4c4c;\\n text-align: center;\\n }\\n\\n .section {\\n margin-top: 50px;\\n }\\n </style>\\n</head>\\n<body>\\n<div class=\\\"section\\\">\\n <h1>&#63743;</h1>\\n\\n <h3>Bad Gateway</h3>\\n <p>Correlation Key: TGHKWJKO2LITS2DSDATRZZJAPE</p>\\n</div>\\n</body>\\n</html>\\n\\n, NSLocalizedFailureReason=App Store operation failed.}\"\n)"; [logs] [logs] [altool] } [logs] Application Loader output above ^ [logs] The server returned an invalid MIME type: text/html [logs] Error uploading '/var/folders/m1/8_w9962s3b79dqm00nnlm85m0000gn/T/97c174a3-8844-4f85-8fd5-78df1906d170.ipa'. [logs] Unable to upload archive. Failed to authenticate for session: ( [logs] The call to the altool completed with a non-zero exit status: 1. This indicates a failure. [logs] Could not download/upload from App Store Connect! [logs] [!] Error uploading ipa file:
Replies
2
Boosts
2
Views
222
Activity
Dec ’25
Are Assets Packs actually downloaded in the background?
Hello, I have a question about when are asset packs actually updated? For Essential Asset Packs, this only during the keys included in the pack? As in, only when the app is installed for firstInstallation. And only when there's an app update for subsequentUpdate? For On Demand Asset Packs, is this only when AssetPackManager.shared.checkForUpdates() is called? Also, are any asset packs ever actually updated in the background? For example, if an On Demand Asset Pack has an update pushed, can the device automatically fetch and download the pack overnight? Or is updating limited to only when the app is active?
Replies
2
Boosts
0
Views
346
Activity
Dec ’25
Download Sales and Trends Reports Error
I was using the Download Sales and Trends Reports API (GET https://api.appstoreconnect.apple.com/v1/salesReports), but at some point, the results started not displaying properly. (The reason for this is that all the +sales values ​​aren't showing up in the CSV file.) Below, I'll show you how to use the API in Python with a screenshot. (***** elements are hidden.) If anyone knows why, please let me know.
Replies
0
Boosts
0
Views
251
Activity
Dec ’25
No Sandbox appears under developer for Age assurance testing
I have iOS 26.2. App is updated with declared age range capability and entitlement and is calling AgeRangeService.shared.requestAgeRange without any error. No popup alert for Age range sharing appears when app calls for requestAgeRange and there no Sandbox Testing under developer. I have signed in Sandbox test user as well.
Replies
1
Boosts
0
Views
144
Activity
Dec ’25
Question Regarding Campaign Data Limits in “App Store Downloads” Analytics Report
Regarding the “App Store Downloads” Analytics Report, I have submitted a report generation request with accessType: ONE_TIME_SNAPSHOT. Reference: https://developer.apple.com/documentation/analytics-reports/app-download I would like to confirm the scope of the Campaign data included in the report generated by this request. In the App Store Connect UI, I understand that there is an upper limit of 200 Campaign entries displayed. For the report output, however, could you please confirm whether it includes all Campaigns measured on the App Store Connect side? Or is there also any upper limit on the number of Campaign records included in the report itself?
Replies
0
Boosts
0
Views
172
Activity
Dec ’25
Request Analytics Reports via POST Call
Hi everyone! When I attempt the Post Request using Postman, as shown in my attached curl, I receive the error "{ "errors": [ { "status": "405", "code": "METHOD_NOT_ALLOWED", "title": "The request method is not valid for the resource path.", "detail": "The request method used for this request is not valid for the resource path. Please consult the documentation." } ] }". I have constructed the JWT correctly as an admin with correct private Key and Unix Times and I am able to send regular GET requests without issue and I can view the dashboards in App Store Connect. The described POST request is being rejected, although it says so in the documentation: https://developer.apple.com/documentation/appstoreconnectapi/post-v1-analyticsreportrequests. Curl: curl --location 'https://api.appstoreconnect.apple.com/v1/analyticsReportRequests' --header 'Content-Type: application/json' --header 'Authorization: Bearer XXX' --data '{ "data": { "type": "analyticsReportRequests", "attributes": { "accessType": "ONGOING" }, "relationships": { "app": { "data": { "type": "apps", "id": "XXXXXXXXXX" } } } } }' (using ONE_TIME_SNAPSHOT makes no difference) Is this a documentation error ? I'd be happy to hear about a fix.
Replies
3
Boosts
1
Views
506
Activity
Nov ’25
I'd like to report an issue with the "App Referrer" source segmentation in the App Store Connect Analytics API.
I'd like to report an issue with the "App Referrer" source segmentation in the App Store Connect Analytics API. Issue Summary When retrieving impression data via the App Store Connect Analytics API using groupBy=["sourceType", "sourceInfo"], the impressions attributed to specific referring apps (e.g., Facebook, Instagram) do not match the values ​​displayed in the App Store Connect web dashboard. Details The total impressions in the API and dashboard are completely consistent, with the report category: App Store Discovery and Engagement Standard_Daily. The aggregated "App Referrer" (overall category) is also consistent. However, the detailed segmentation data in "App Referrer" is inconsistent, with the report category: App Store Discovery and Engagement Detailed_Daily. For example: The web dashboard shows significantly more impressions attributed to Facebook or Instagram. The API returns fewer impressions for the same referral source. Furthermore, the API does not return any "unknown"/"other" referral source entries, and displays no data for presentations where the exact referring app cannot be identified. Therefore, the sum of all sourceInfo entries returned by the API is lower than the app referral source value displayed in the web dashboard. We have confirmed: This is not due to time zone differences—the totals are exactly the same. We used the same date range, region, and platform settings as the dashboard. The difference only appears in the detailed app referral source breakdowns (e.g., "Facebook," "Instagram"). The API does not return missing presentations under any category. Questions for Apple: Does the App Store Connect web interface aggregate presentations from unidentified or privacy-restricted referring apps into known app names (e.g., Facebook or Instagram)? Is it normal for the Analytics API not to expose these presentations when the exact referring app cannot be identified? What official logic does the App Store Connect use to determine and display specific app referral sources (e.g., Facebook, Instagram)? When the API returns fewer referral records than the dashboard, how can developers accurately reproduce the same detailed app referral breakdown data in their reports? Are there any known limitations or privacy thresholds in the API that affect the disclosure of sourceInfo? Other Information Endpoint: Analytics API (Impressions grouped by sourceType and sourceInfo) Metric: Impressions Grouping Criteria: sourceType, sourceInfo We want to understand how App Store Connect allocates impressions to specific third-party apps (e.g., Facebook, Instagram) in the dashboard, and why the Analytics API returns lower numbers for these referral sources.
Replies
1
Boosts
0
Views
300
Activity
Nov ’25
App Store Connect API `inAppPurchaseV2` returns `links.next`, even when there's no more `data`
I think there's been a recent change to the App Store Connect API; I claim that it's a bug. When querying App Store Connect API endpoints that return arrays, like https://api.appstoreconnect.apple.com/v1/apps, the response includes a links property, of type PagedDocumentLinks. https://developer.apple.com/documentation/appstoreconnectapi/pageddocumentlinks links should include a next link only if there's more data to provide, and, indeed, this is how it works for the /v1/apps endpoint. But when querying inAppPurchasesV2, I find that starting very recently (this week?) the API always returns a next link, even if there's no more data to show. { data: [], links: { self: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=APo&limit=50', first: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?limit=50', next: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=ASw' }, meta: { paging: { total: 223, nextCursor: 'ASw', limit: 50 } } } If I request the next link, it will generate me another response with empty data and with a new cursor. { data: [], links: { self: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=ASw&limit=50', first: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?limit=50', next: 'https://api.appstoreconnect.apple.com/v1/apps/1363309257/inAppPurchasesV2?cursor=AV4' }, meta: { paging: { total: 223, nextCursor: 'AV4', limit: 50 } } } Code I've written against this API (including my open-source library https://github.com/dfabulich/node-app-store-connect-api) assumes that if there's another links.next link, we should follow it; as a result, my code is looping infinitely, requesting empty data until eventually I have to give up. This issue doesn't affect other endpoints, like /v1/apps, just this inAppPurchasesV2 endpoint. Was this an intentional change? It seems to be a bug.
Replies
4
Boosts
5
Views
564
Activity
Nov ’25
App Store Connect API – 401 Unauthorized (JWT Authentication Issue)
I’m experiencing an issue while attempting to authenticate API calls to the App Store Connect API using a JWT token. I have App Manager permissions on my apple developer account. Despite following the official documentation and successfully verifying the JWT signature locally, I consistently receive the following response from the API: { "errors": [{ "status": "401", "code": "NOT_AUTHORIZED", "title": "Authentication credentials are missing or invalid.", "detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired." }] } import jwt import time from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend from jwt.exceptions import InvalidSignatureError Replace with your own credentials KEY_ID = "<YOUR_KEY_ID>" ISSUER_ID = "<YOUR_ISSUER_ID>" PRIVATE_KEY_PATH = "AuthKey_<YOUR_KEY_ID>.p8" def generate_token(): """Generate a JWT for App Store Connect API authentication.""" with open(PRIVATE_KEY_PATH, "r") as f: private_key = f.read() header = { "alg": "ES256", "kid": KEY_ID, "typ": "JWT" } now = int(time.time()) payload = { "iss": ISSUER_ID, "iat": now, "exp": now + 1200, # Token valid for 20 minutes "aud": "appstoreconnect-v1" } token = jwt.encode(payload, private_key, algorithm="ES256", headers=header) return token def verify_token_signature(token): """Verify JWT signature locally using the public key derived from the .p8 private key.""" with open(PRIVATE_KEY_PATH, "rb") as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend() ) # Derive public key from private key public_key = private_key.public_key() pem_public_key = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) try: decoded = jwt.decode( token, pem_public_key, algorithms=["ES256"], audience="appstoreconnect-v1" ) print("✅ JWT signature verified successfully.") print("Decoded payload:", decoded) except InvalidSignatureError: print("❌ JWT signature is invalid.") except Exception as e: print(f"❌ JWT verification failed: {e}") if name == "main": token = generate_token() print("Generated JWT:", token) verify_token_signature(token) Why might a JWT that is valid locally still fail authentication with a 401 NOT_AUTHORIZED error from the App Store Connect API? Are there any specific permission scopes required for API access beyond App Manager account access from Apple Store connect? Are there any known issues or additional configuration steps required for API key access? Is there a way to validate API access status for a specific key or account? Could you please share the correct example of JWT generation in Python for reference?
Replies
0
Boosts
0
Views
183
Activity
Nov ’25