Hello fellow developers! I am interested in obtaining the following information regarding one of our Home Screen widgets:
Pull the following data about the "my_app_widget" homepage widget in total and by month for the last 12 months (Sep '23 - Sep '24):
Widget install events
Unique widget installs
Device type (iPad, iOS).
Thus far, I am using AWS Lambda and have the proper credentials within a Secrets Manager and I keep getting a 409 error from this code:
const AWS = require('aws-sdk');
const axios = require('axios');
const jose = require('jose');
const crypto = require('crypto');
const s3 = new AWS.S3();
const secretsManager = new AWS.SecretsManager();
const cloudwatchlogs = new AWS.CloudWatchLogs();
const logGroupName = '/aws/lambda/my_lambda_function';
const logStreamName = '2024/11/05/[$LATEST]XXXXXXXXXXXXXX';
const getSecret = async (secretName) => {
const secret = await secretsManager.getSecretValue({ SecretId: secretName }).promise();
return JSON.parse(secret.SecretString);
};
const logError = async (message) => {
const params = {
logGroupName,
logStreamName,
logEvents: [
{
message: JSON.stringify(message),
timestamp: Date.now()
}
]
};
try {
await cloudwatchlogs.putLogEvents(params).promise();
} catch (error) {
console.error('Failed to log to CloudWatch:', error);
}
};
const getJwtToken = async (keyId, issuerId, privateKeyPem) => {
try {
const privateKey = crypto.createPrivateKey({
key: privateKeyPem,
format: 'pem',
type: 'pkcs8'
});
const payload = {
iss: issuerId,
exp: Math.floor(Date.now() / 1000) + 20 * 60,
aud: 'appstoreconnect-v1'
};
const token = await new jose.SignJWT(payload)
.setProtectedHeader({ alg: 'ES256', kid: keyId })
.sign(privateKey);
return token;
} catch (error) {
await logError({ error: 'Error generating JWT', details: error });
throw new Error('JWT generation failed');
}
};
const fetchAndUploadReport = async (url, token, s3Key, isAnalytics = false, body = null) => {
try {
const headers = {
'Authorization': `Bearer ${token}`,
'Accept': isAnalytics ? 'application/json' : 'application/a-gzip',
'Content-Type': 'application/json'
};
const response = await axios({
method: isAnalytics ? 'post' : 'get',
url: url,
headers: headers,
data: body,
responseType: isAnalytics ? 'json' : 'stream'
});
if (response.status === 200) {
let bodyContent = isAnalytics ? JSON.stringify(response.data) : response.data;
await s3.upload({
Bucket: 'my_bucket_name',
Key: s3Key,
Body: bodyContent
}).promise();
return { statusCode: 200, body: `${s3Key} fetched and uploaded successfully` };
} else {
await logError({ error: 'API response error', status: response.status, statusText: response.statusText, url });
return { statusCode: response.status, body: response.statusText };
}
} catch (error) {
await logError({ error: 'Error fetching report', url, details: error });
return { statusCode: 500, body: JSON.stringify(`Error fetching ${s3Key}`) };
}
};
exports.handler = async (event) => {
const secretName = 'AppStoreConnectPrivateKey';
try {
const secretData = await getSecret(secretName);
const { keyId, issuerId, private_key: privateKeyPem } = secretData;
const token = await getJwtToken(keyId, issuerId, privateKeyPem);
const startDate = '2023-09-01';
const endDate = '2024-09-30';
const apiEndpoints = [
{
url: `https://api.appstoreconnect.apple.com/v1/analyticsReportRequests`, // Changed to request report
s3Key: 'my_folder/my_subfolder/unique_widget_installs.json',
isAnalytics: true,
body: {
"data": {
"type": "analyticsReportRequests",
"attributes": {
"accessType": "ONGOING",
"name": "Home Screen Widget Installs",
"category": "APP_USAGE"
},
"relationships": {
"app": {
"data": {
"type": "apps",
"id": "YYYYYYYYYYYY"
}
}
}
}
}
}
];
Returns the following error :
{
"error": "Error fetching report",
"url": "https://api.appstoreconnect.apple.com/v1/analyticsReportRequests",
"details": {
"message": "Request failed with status code 409",
"name": "AxiosError",
"stack": "AxiosError: Request failed with status code 409\n at settle (/var/task/node_modules/axios/dist/node/axios.cjs:2019:12)\n at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/dist/node/axios.cjs:3135:11)\n at IncomingMessage.emit (node:events:531:35)\n at IncomingMessage.emit (node:domain:488:12)\n at endReadableNT (node:internal/streams/readable:1696:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:82:21)\n at Axios.request (/var/task/node_modules/axios/dist/node/axios.cjs:4287:41)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async fetchAndUploadReport (/var/task/index.js:68:26)\n at async Promise.all (index 0)\n at async exports.handler (/var/task/index.js:174:25)",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"adapter": [
"xhr",
"http",
"fetch"
],
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
So I am not sure if the JSON body I am passing this URL endpoint are correct or if this is the correct API to be using to attempt to obtain this information. Please let me know when you have the chance and I look forward to hearing from you.
App Store Connect API
RSS for tagThe App Store Connect API helps you automate tasks usually done on the Apple Developer website and App Store Connect.
Posts under App Store Connect API tag
164 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I've been working on retrieving total app installs via the Apple Connect API using Python. However, I've noticed a discrepancy between the data obtained manually and the API results.
When I download the Sales & Trends report manually with these settings:
Sales & Trends, Monthly, By Territory, Total Installs
…the results don't match those from the API when I use the following parameters
python
report_date = '2024-09'
params = {
"filter[frequency]": "MONTHLY",
"filter[reportDate]": report_date, # Date for the report
"filter[reportSubType]": "SUMMARY",
"filter[reportType]": "SALES",
"filter[vendorNumber]": vendor_number
}
I’m seeing a clear mismatch in units between the manual download and the API output
Note: This report was generated on 2024-11-05
It's not possible to create a new version for any App Store Connect app.
To reproduce, I navigate to my app and click the (+) button to create a new version number. I type in a version number, and click "Create."
It fails with an error, "An error has occurred. Try again later."
Hi everyone,
I’m working with the App Store Connect API to analyze my app's launch time performance, but I’d like to retrieve historical data spanning multiple dates. However, I haven’t found parameters like startDate or endDate in the API documentation.
Is there any way to retrieve data for past dates, or is the API limited to recent data only? If anyone has experience with this or any workaround, I’d love to hear about it.
Thank you!
Hi Folks,
I'm currently using the App Store Connect API's perfPowerMetrics endpoint to pull launch time metrics for my app, but I want to break down the data by specific iPhone models (e.g., iPhone 13 Pro, iPhone 12, etc.). I’ve tried using filter[deviceType] set to all_iphones, which works, but it aggregates data for all iPhone models.
Does anyone know the specific identifiers for individual iPhone models, or if there's a way to retrieve metrics by specific iPhone model segments?
TIA
Hello All,
New member here so hopefully my post adheres to Dev Forum standards.
My Platform team and I are attempting to gather a bunch of our customer/service data via an automated process where we code a script to obtain data from the App Store Connect dashboard of our app. We need to web scrape most likely with the App-Store-Scraper library. This reason for this is the following challenge we have run into previously while utilizing the App Store Connect API: When we have attempted to fetch data we have seen that the attributes we are looking for cannot be obtained with the query parameters available. Certain reports can only be obtained for DAILY query param values; certain information, such as "File Size" from the "State" report, and "revenue net" of Apple's commissions on sales from the "Proceeds" report within the App Store Connect dashboard, are not able to be obtained via the API, to my knowledge. Of course it can be obtained manually by downloading it through the dashboard, but we want to automate this process.
My question is with regards to web scraping: Will we be able to obtain all the information we need by web scraping the "Event, State, Proceeds" reports that one can find by navigating from the left-hand-side tabs within the App Store Connect dashboard? This information contains PII, but since we have rights to our customer data we should be able to maintain confidentiality by following industry standards.
Please let me know if anyone has any experience with this kind of task before and I look forward to hearing from you.
I would like to know if there is a limit to past information in the Look Up Order ID API.
https://developer.apple.com/documentation/appstoreserverapi/look_up_order_id
I understand that you can also get information about users who deleted or reinstalled the app from the content of the document.
On the other hand, are there any temporal limits to the past?
For example, can the above API make requests for purchases made one year ago, five years ago, or ten years ago?
Hi,
I am using Node.js for updating my game achievements. Also not sure what is the recommended programming language to use for this.
I will want to add Achievement Localization to my existing achievement.
I was following the document here:
https://developer.apple.com/documentation/appstoreconnectapi/post-v1-gamecenterachievementlocalizations
const postData = {
type: "gameCenterAchievementLocalizations",
attributes: {
locale: "it-IT",
name: "XXXXXXXXXXX",
afterEarnedDescription: "XXXXXXXXXXXXXX",
beforeEarnedDescription: "XXXXXXXXXXXXXXXXXXXXXXXX"
},
relationships: {
gameCenterAchievement: {
data: {
type: "gameCenterAchievement",
id: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
}
}
};
let axiosConfig = {
headers:{
Authorization: `Bearer ${token}` }
};
const response = axios.post('https://api.appstoreconnect.apple.com/v1/gameCenterAchievementLocalizations', postData, axiosConfig);
After I run the above code, it throw me an error 422.
status: '422',
code: 'ENTITY_UNPROCESSABLE',
title: 'The request entity is not a valid request document object',
detail: "Unexpected or invalid value at 'type'.",
meta: { position: [Object] }
Any idea what went wrong with my code?
Thank you
The endpoint https://api.appstoreconnect.apple.com/v1/apps/{app id}/appStoreVersions is returning some very strange data as of sometime this afternoon (Pacific time).
We are only seeing a subset of builds. They are verrrry old and they are not in order. This exact same list is shown in the app store connect web dashboard when I view my apps history suggesting it uses the same API call.
I recently created my account on Apple Developer Program, and paid up. However, it took around 2 days for the apple's system to recognize my payment and sent me verification email.
This was almost 24 hours ago, however I am not been able to login to connect so far. When I click on Connect -> app, it takes me to https://appstoreconnect.apple.com/login and when I try to login, I see the error displayed below.
This is my developer dashboard currently.
Can someone help out or guide on this please?
I've set up the Discovery and Engagement Report via the API to create daily reports. I'm using the Standard report so it includes all of the data and doesn't remove any as per the privacy policy.
It's providing impression data for the App Store Search and App Store Browse source types but it's missing impression data for the others (web referrer and app referrer) - this data is available in the dashboard.
Also, the impression data that I do have does not align with the dashboard, I thought using the standard report would mean all of the data would get provided.
The product page view data is correctly being provided in the data for each of the source types.
Any ideas why it's missing?
Hi,
I could not find it in the official documentation, so I assume it is not ready yet.
I wonder if there is any other way to create campaign links and get analytics on them programmatically.
Otherwise, what is the right place to submit a request for it? Or perhaps it is on the horizon already?
Hello,
I am trying to use iTMSTransporter to update my app's metadata, however I am getting error code 1117.
"The content type for the specified apple_id of 'XXXXXX' is not supported by the metadata lookup functionality. (1117)"
Any idea on what would cause that?
I have no outstanding terms to accept or anything like that and my app is in status "Prepare for Submission".
I suspect this might be happening because I currently have new In App Purchases in review that have been denied because they were not yet accessible in the app for testing. The recommendation was to upload a new build.
However, in order to upload a new build for testing I need to update my metadata.
I have a lot of metadata so would like to use iTMSTransporter, but then I get that error.
Thanks for your help!
I'm getting a "There was an error uploading your screenshot. Try again later." error when trying to upload a screenshot under Review Information.
Tried both Safari / Chrome, JPG/PNG and screenshot size is correct.
Looking at the network logs, it is also returning a 409 Conflict error. Is there a known issue?
We have a requirement for our app to set "Automatically release this version" and "Release update to all users immediately." Essentially, we want the build to be released to 100% of users once it is approved, without any further action needed from our side. We are using App Store Connect APIs to release our app.
To achieve this:
I am creating an App Store version by setting AppStoreConnectReleaseType enum to AFTER_APPROVAL in AppStoreVersionCreateRequestData.
I am not enabling phased release.
I am submitting the app for review.
My main concern is understanding the App Store's default behavior for app submissions, particularly whether the default action is to release the update to 100% of users immediately or in a phased manner. If the default behavior is to release to 100% of users, our implementation should meet the requirement. However, if the default is a phased release, I am uncertain if our approach will fulfill our requirement.
Any insights into the App Store's default release behavior would be greatly appreciated.
The App Store Connect API documentation still doesn't list the new 6.9" iPhone display type: https://developer.apple.com/documentation/appstoreconnectapi/screenshotdisplaytype
I already opened a similar topic about the new iPad Pro 13" screenshot type in May (4 months ago), but nobody replied and that screenshot type is still not listed in the specification. I also created a bug report in Feedback Assistant back then, without any reply.
Why does it take so long to update the API specification?
Hello,
A user subscribed by in-app purchase subscription in the app "Target Leaderboard". We have got the transaction Id and base64 encoded receipt data in response. We can generate the JWT by the In-app purchase key file and key Id. But when we try to fetch all subscriptions by "https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions" by passing the transaction Id, blank response is returned. Why it is happening?
Also, when we are try to fetch original transaction Id by "https://sandbox.itunes.apple.com/verifyReceipt" by passing the base64 encoded receipt data and SharedSecret, code 21003 is returned. Why it is happening? Please help.
I have been sending requests to the Appstore Connect API for 3 types of reports; download data, discovery data, and install data.
The documentation notes that data is available as far back as Jan 1, 2024. I have found this to be true with install data reports. But the other two go back only about 5 weeks.
The process of getting these reports involves two HTTP requests, one to get segment instances with the report ID and one to get media links with the segment IDs.
I am using the 'granularity' and 'WEEKLY' param but I get the same results with other options.
I don't think it's an error with my code because I'm receiving data for earlier dates but not dates before 5 weeks ago.
I need some ideas to move forward because I need to backfill the data to at least April, 2024.
Hi!
I'm using the App Store Connect API to automate the setup of Game Center achievements. However, I'm facing an issue when it comes to uploading the achievement icon.
I referred to the following link and tried to use the Create an Achievement Image API: https://developer.apple.com/documentation/appstoreconnectapi/create_an_achievement_image
This API includes a GameCenterAchievementImageCreateRequest.Data.Attributes object, which has properties like fileName and fileSize. However, there is no property for the file path, only the file name.
I also checked the page about uploading assets to App Store Connect: https://developer.apple.com/documentation/appstoreconnectapi/uploading_assets_to_app_store_connect
Unfortunately, there is no specific mention of how to upload an achievement image.
When I use the GameCenterAchievementImageCreateRequest.Data.Attributes and set fileName to "XXXX" (for example), the request completes successfully, but the achievement page only displays the file name XXXX, and the image is not loaded as expected.
Any advice or guidance would be greatly appreciated. Thank you in advance!
With the recently introduced Enterprise API Program, this should allow us to interact with the developer portal via the API instead of needing an account signed into Xcode.
I followed the following steps to generate a key:
Logged into App Store Connect.
Navigated to Users and Access.
Selected Integrations.
Generated an API key with the Admin role.
Saved the key, the key identifier, and the issuer identifier.
Now, when using xcodebuild with the -allowProvisioningUpdates switch, I added -authenticationKeyPath, -authenticationKeyID, and -authenticationKeyIssuerID with the correct values.
xcodebuild spits out the following error:
xcodebuild: error: Invalid authentication key credential specified (CryptoKit.CryptoKitASN1Error.invalidPEMDocument)
What am I doing wrong/what did I miss? The developer portal shows that the key was "used" by updating the last used date.