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.

Posts under App Store Connect API tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

I need the Python code for connecting to my Apple appstore sales reports
I am trying to create an API that connects to the apple app store, I already converted my p8 into a JWT, it works for other appstore information but not sales. Here is what I have so far, this is a mix of a lot of techniques I tried. Can someone give me the full code they use if they do something similar? import requests import json import zlib from io import StringIO Constants API_ENDPOINT = 'https://api.appstoreconnect.apple.com/v1/salesReports' Load JWT token from file with open("My location for my JWT file", "r") as file: token = file.read().strip() def get_sales_report(): headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/a-gzip' } params = { 'filter[frequency]': 'DAILY', # For testing purposes, using DAILY frequency 'filter[reportType]': 'SALES', 'filter[vendorNumber]': 'My vendor', 'filter[reportDate]': '2022-08-01' # Sample date for testing } response = requests.get(API_ENDPOINT, headers=headers, params=params) if response.status_code == 200: try: # Decompress the gzipped content buffer = io.BytesIO(response.content) with gzip.GzipFile(fileobj=buffer) as f: content = f.read().decode('utf-8') # Convert the content to a DataFrame data = [line.split('\t') for line in content.split('\n') if line] df = pd.DataFrame(data[1:], columns=data[0]) return df except Exception as e: return pd.DataFrame(columns=['Error'], data=[f'Failed to process the report. Error: {e}']) else: return pd.DataFrame(columns=['Error'], data=[f'Received unexpected status code {response.status_code}: {response.text}']) sales_df = get_sales_report() print(sales_df)
2
0
1.3k
Aug ’23
How can i get all the AppStore for an app with the "App Store Connect API"?
Hey there, I want to fetch all the reviews from an app of mine. Seems like the limit is 200 per request. How can I get all the reviews and not just 200? i don't want to scrape the web and prefer to use the API I wasn't able to do that following this guide. this is my code: def generate_token(key_id: str, issuer: str, private_key: str): """this function creates a token to access Apple's App Store API""" # get current and expiration time # note:apple will ban every request with an expiration time > 20 minutes current_time = int(time.time()) expiration_time = current_time + 900 # prepare the jtw headers headers = { "alg": "ES256", "kid": key_id, "typ": "JWT", } # prepare the payload payload = { "iss": issuer, "iat": current_time, "exp": expiration_time, "aud": "appstoreconnect-v1", } # generate the token token = jwt.encode( payload, private_key, algorithm="ES256", headers=headers, ) # print and retutn print(token) return token def app_store_reviews(app_id: str, key_id: str, issuer: str, private_key: str): """this function returns all the reviews of an app on the app store.""" # prepare API request url = f"https://api.appstoreconnect.apple.com/v1/apps/{app_id}/customerReviews?limit=200" token = generate_token(key_id, issuer, private_key) headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} # Make the GET request response = requests.get(url, headers=headers) # request is successful if response.status_code == 200: reviews_data = response.json() print(reviews_data) # request failed else: print(response.text) Cheers, Flippo
1
1
593
Aug ’23
App Store - App Analytics Product Page Views
Is it possible to get app analytics data such as product page views from an Apple Api? See below image showing the data we're looking to get from an API. I've seen code like below. Is this the way to get app analytics data? The below code isn't quite complete. Is there documentation somewhere of how to get this data properly? Is this URL an internal URL that shouldn't be used? https://appstoreconnect.apple.com/analytics/api/v1/data/time-series import requests import json url = "https://appstoreconnect.apple.com/analytics/api/v1/data/time-series" adamId = "0000000000" # App ID measures = "installs" # or "impressionsTotalUnique" cookie_dqsid = "dqsid=ey...." # ????? payload = json.dumps({ "adamId": [adamId], "measures": [measures], "frequency": "day", "startTime": "2021-10-16T00:00:00Z", "endTime": "2021-11-14T00:00:00Z", "group": { "metric": measures, "dimension": "source", "rank": "DESCENDING", "limit": 100 } }) headers = { 'Host': 'appstoreconnect.apple.com', 'X-Requested-By': 'dev.apple.com', 'Cookie': cookie_dqsid, 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload, allow_redirects=False) print(response.text)
0
0
635
Aug ’23
How can the AppStoreConnect API be used to download certificates to sign passes?
I am sure I am missing a pretty elementary step - but - I'm at a loss. I can build a certificate using KeyChain Access, upload the CSR, download the Certificate from the developer portal website and sign Apple Wallet Passes all day long. No Problem. So I thought I'd try to automate some processes with the AppStoreConnectAPI. I want to download the certificate from the app store and use it to sigh passes instead of file on the disk. So I find the right certificate from the API, and one of the token in there is a big byte stream called "certificateContent"... which I assumed would be the same binary data as what I uploaded (and whats on disc). But it doesn't work - it "fails to sign". I must be missing some step that is preventing me from being able to use that key. I have a feeling the a key or something is missing from the certificate I download from Apple's API. Any ideas?
2
0
517
Aug ’23
appstoreconnect visibleApps randomly response wrong data
https://api.appstoreconnect.apple.com/v1/users/2a449234-15b3-4056-bd87-3cfe65711a52/visibleApps when calling this api, it's response change randomly calling 100 times, somtime I got { "data" : [ ], "links" : { "self" : "https://api.appstoreconnect.apple.com/v1/users/2a449234-15b3-4056-bd87-3cfe65711a52/visibleApps" }, "meta" : { "paging" : { "total" : 0, "limit" : 50 } } } somtime I got { "data" : [ { "type" : "apps", "id" : "***", "attributes" : { "name" : "***", "bundleId" : "***", ... and the data count also random (no one edit the user role and visibleapps) this occurred after 2023/08/17 08:40 (GMT+8) I wonder if it's caused by api met error and return the incomplete data array back? for example, user A has 3 visible apps and app1 <-- fail here then return "data" : [ ] app1 app2 app3 <-- fail here then return "data" : [ {app1 detail}, {app2 detail}]
0
0
345
Aug ’23
Relationship between App Store Version, App Clip Default Experiences and App Clip Advanced Experiences in App Store Connect API
According to the App Store Connect API documentation we can get the Default App Clip Experience for an App Store Version, and since on the App Store Connect website we have a single App Clip section for an iOS App, it seems that an App Store Version can have 0 or 1 Default App Clip Experience. But there is no direct way of getting the Advanced App Clip Experiences. The only way I can see is by getting the App Clip object first for the App, then listing all Default and Advanced App Clip Experiences for that App Clip. This makes me wonder: are Advanced App Clip Experiences not directly linkes to an App Store Version like the Default App Clip Experience? Does the list of Default App Clip Experiences returned from an App Clip object always contain a single object, or can it be more than one (perhaps older versions linked to old App Store Versions)? What is the relationship between App Store Version, App Clip Default Experiences and App Clip Advanced Experiences?
0
0
423
Aug ’23
App Store Server Notifications on TestFlight
We are implementing IAP in our React-Native app, currently only on IOS, specifically subscriptions. We have configured the Sandbox Server URL to an endpoint on our Dev server, and the Production Server URL to an endpoint on our Production server. In addition, we are using the Apple App Store Server Node.js Library on our Backend to verify receipts, getting transactions history, etc. We are using the Sandbox environment on our Dev backend, and the Production environment on our Production backend. We are not sure if that is the correct setup, although that is what we understood from multiple sources. While testing with TestFlight, with production apple accounts, we were expecting to receive the server notifications on our Production server, but they were all were received on our Development server (Sandbox endpoint). Is that the correct behavior or are we missing something? We figured the Sandbox endpoint was for testing purposes and because of that should be on our Development backend while we develop.
1
0
676
Aug ’23
api 401 Unauthorized when in product env
I test the api in sandbox env. It works fine. curl --location 'https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/history' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ij......' \ --data '{ "startDate":1693324766487, "endDate" :1693324766587 }' But in production env , it return 401 Unauthorized error. My app is not publish to the apple store. How could i confirm [errorCode 4040005] like follow steps: If you don’t have environment information, follow these steps: Call the endpoint using the production URL. If the call succeeds, the original transaction identifier belongs to the production environment. If you receive an [errorCode 4040005] with errorMessage as OriginalTransactionIdNotFoundError, (or HTTP response code 404 from the Send Consumption Information endpoint), call the endpoint using the sandbox environment. If the call succeeds, the original transaction identifier belongs to the sandbox environment. If the call fails with the same error code, the original transaction identifier isn’t present in either environment.
0
0
544
Aug ’23
Failed to perform Annual Membership Subscription
Dear Support Team, Just to let you know that I am still struggling on making payment for Annual Membership Subscription Payments through VISA Card where it comes with a message that the payment transaction can not be completed. I even visited the Bank Offices to ask for the reason and confirmed that currently there is scarcity of US Dollars in the Market so they have restricted some payments from Tanzanian Shillings to US dollars. So they asked me if your end can send me the bill in USD so that the Bank can make payments to you by debiting my account. This is due to the fact that the Annual Membership Subscription Window displays the figure in Tanzanian Shillings instead of US Dollars In this regard kindly help to resolve the matter as currently I am stacked on uploading the IOS apps for use. Waiting to hear from your end soon. Regards
1
0
278
Sep ’23
JWT token for API not working in Python
Hi, I'm writing a Python script to automate the extraction of reports from the Apple App Store Connect API, more specifically the SALES and the SUBSCRIBER reports, using Airflow. The code passed the tests but when implemented in production, the Airflow task calling the Apple App Store Connect API fails, due to a 401 unauthorized error. This suggests there is some issue with the authentication (JWT / bearer token) part. I tried various solutions but none of them worked. Here is part of the code, at this point I don't really understand what is wrong. Any help in identifying the issue is appreciated: class AppStore(ReadApi): def __init__( self, api_secret_conf: dict, vendor_number: int, **kwargs, ): ReadApi.__init__(self, **kwargs) self.kid = api_secret_conf["kid"] # Key ID self.iss = api_secret_conf["iss"] # Issuer ID self.private_key = api_secret_conf["private_key"] # Private key self.vendor_number = int(vendor_number) def generate_jwt_token(self): # Generate jwt token required by App Store Connect API # Each token is valid for 20 minutes (max time allowed) jwt_headers = {"alg": "ES256", "kid": self.kid, "typ": "JWT"} jwt_payload = { "iss": self.iss, "iat": int(time.time()), "exp": int(time.time()) + 60 * 20, "aud": "appstoreconnect-v1", } private_key = self.private_key.encode("utf8") token = jwt.encode( jwt_payload, private_key, algorithm="ES256", headers=jwt_headers ) decoded_token = token.decode("utf-8") return decoded_token
0
0
426
Sep ’23
App Store Connect Access Keys
Our CICD team was pinged by our development team that when using FastLane our user provisioning profiles weren't updating properly. After spending some time investigating we realized that we only have a App Store Connect key for our customer facing account. We have 2 accounts a customer facing & an enterprise in-house account. When trying to setup an access key for us to use for our enterprise account, we found that that account appears to not have App Store Connect abilities. The specific thing we need access to is the ability to generate an access key for our CICD pipeline from our enterprise account, as we did for our customer facing one. Is it only allowed for customer facing accounts or can in-house enterprise accounts have access as well? App Store Connect is the only way to generate access keys to use the App Store Connect APIs.
1
0
327
Sep ’23
xCode Version 15.0 - Simulator Screen Shots for 5.5 inch iPhone
In order to submit your app for review you must provide a screenshot for the 5.5 inch iPhone (iPhone 6S Plus, 7 Plus, 8 Plus). The simulator for these phones is not included in the standard set provided in xCode. After researching there is a method described where you can download simulator sets for previous iOS releases. I downloaded both the iOS 13 and iOS 14 set but still unable to get at one of the mentioned iPhone simulators. Has anyone solved this problem short of getting an actual iPhone hardware to do the screen shots on. Thanks,
11
2
5.2k
Oct ’23
Trying to generate token for API Request with 15 day life time. But the Appstoreconnect rejects a token with a lifetime greater than 20 minutes
I using the below to generate the token. but it returns 401 due to token life time > 20 minuts import requests, time, json from authlib.jose import jwt KEY_ID = "key_id" ISSUER_ID = "issuer_id" EXPIRATION_TIME = int(round(time.time() + (30.0 * 60.0))) # 20 minutes timestamp PATH_TO_KEY = "AuthKey_keyid.p8" with open(PATH_TO_KEY, "r") as f: PRIVATE_KEY = f.read() header = {"alg": "ES256", "kid": KEY_ID, "typ": "JWT"} payload = { "iss": ISSUER_ID, "exp": EXPIRATION_TIME, "aud": "appstoreconnect-v1", "scope": ["GET /v1/salesReports?filter[frequency]=DAILY&filter[reportDate]=2023-09-01&filter[reportSubType]=DETAILED&filter[vendorNumber]={vendor_number}&filter[reportType]=SUBSCRIBER&filter[version]=1_3"] } # Create the JWT token = jwt.encode(header, payload, PRIVATE_KEY) print(token) # API Request JWT = "Bearer " + token.decode() URL = "https://api.appstoreconnect.apple.com/v1/salesReports" HEAD = {"Authorization": JWT} params = { "filter[frequency]": "DAILY", "filter[reportDate]": "2023-09-01", "filter[reportSubType]": "DETAILED", "filter[vendorNumber]": "vendor_number", "filter[reportType]": "SUBSCRIBER", "filter[version]": "1_3" } r = requests.get(URL, params=params, headers=HEAD) print(r) Do you have any suggestions to generate the token with 15 days life time
0
0
418
Sep ’23
Check agreements programatically through the API
Hi All, We levarage the API to build our apps and upload to App Store Connect. Is there a way we can proactively check if the agreements are all set through the API or any other automatic way? That way we validate this before starting the build on our end and save a good amount of time (as we need to ask our clients to review and accept agreements and it take a lot of time).
0
0
293
Sep ’23
App Store Connect API - create certificate from CSR
Hi, i am trying to upload certificate signing request (CSR) for Pass Type ID via API, using this endpoint https://api.appstoreconnect.apple.com/v1/certificates. Request body looks like this, with POST method and content type application/json: { "data": { "attributes": { "certificateType": "PASS_TYPE_ID", "csrContent": "LS0tL...S0tLS0K" }, "type": "certificates" } } csrContent is base64 encoded. The response from API is: { "errors" : [ { "id" : "71a...4c9", "status" : "404", "code" : "NOT_FOUND", "title" : "The specified resource does not exist", "detail" : "There is no identifier with ID 'null' on this team." } ] } CSR was created with KeyChain on Mac (as described here: https://developer.apple.com/help/account/create-certificates/create-a-certificate-signing-request), but i can also do it with OpenSSL. First of all, there is no pairing information between Pass Type Identifier and certificate in request. Status 404? I would expect 400. And given detail is totally useless... The documentation is poor for this topic: https://developer.apple.com/documentation/appstoreconnectapi/create_a_certificate. So that brings me to the idea of adding it (Pass Type Identifier) to the CSR content, but where? I am able to read all certificates stored via Developer Account and put them together with private keys... but storing it is pain... Does anyone have an idea?
2
1
760
Apr ’24