App Store Connect API for Developers: Automate Your ASO Workflow
The App Store Connect API gives developers programmatic access to manage apps, metadata, pricing, screenshots, and more β everything you do manually in App Store Connect can be automated through REST API calls. For ASO practitioners, this means you can automate metadata updates, schedule keyword changes, manage screenshots at scale, and build custom reporting dashboards that go far beyond what the web interface offers. Yet most developers still log into App Store Connect manually for every change, wasting hours on tasks that could be scripted in minutes.
This guide covers how to use the App Store Connect API for ASO automation: authentication, key endpoints, practical automation scripts, and workflows that save time and reduce errors.
What You Can Automate with the API
ASO-Related Capabilities
| Capability | API Support | ASO Use Case |
|---|---|---|
| App metadata (name, subtitle, description) | β Full | Automate metadata updates across locales |
| Keywords | β Full | Schedule keyword field rotations |
| Screenshots | β Full | Batch upload localized screenshots |
| App previews | β Full | Manage preview videos programmatically |
| Promotional text | β Full | Rotate promotional text on a schedule |
| In-app purchases | β Full | Manage IAP metadata for indexing |
| App pricing | β Full | Automate pricing changes across territories |
| Customer reviews | β Read + Reply | Automated review monitoring and response |
| Analytics | β Read | Build custom ASO dashboards |
| App versions | β Full | Manage version submissions |
Authentication
The API uses JSON Web Tokens (JWT) for authentication:
- Generate an API key in App Store Connect (Users and Access β Keys)
- Download the private key (.p8 file) β store securely
- Note your Key ID and Issuer ID
- Generate a JWT signed with your private key for each API request
// JWT generation example (Node.js)
const jwt = require('jsonwebtoken');
const fs = require('fs');
const privateKey = fs.readFileSync('AuthKey_XXXXX.p8');
const token = jwt.sign({}, privateKey, {
algorithm: 'ES256',
expiresIn: '20m',
issuer: 'YOUR_ISSUER_ID',
header: {
alg: 'ES256',
kid: 'YOUR_KEY_ID',
typ: 'JWT'
}
});
Essential API Endpoints for ASO
Managing App Localizations
Update metadata for specific locales:
GET /v1/apps/{id}/appStoreVersions
GET /v1/appStoreVersions/{id}/appStoreVersionLocalizations
PATCH /v1/appStoreVersionLocalizations/{id}
Use case: Batch-update descriptions, keywords, and promotional text across all localized versions.
Screenshot Management
Upload, reorder, and manage screenshots:
GET /v1/appStoreVersionLocalizations/{id}/appScreenshotSets
POST /v1/appScreenshotSets
POST /v1/appScreenshots
PATCH /v1/appScreenshots/{id} (reorder)
DELETE /v1/appScreenshots/{id}
Use case: Automate screenshot uploads for 20+ locales after a design refresh, maintaining correct ordering.
Customer Reviews
Monitor and respond to reviews:
GET /v1/apps/{id}/customerReviews
POST /v1/customerReviewResponses
Use case: Build an automated review monitoring system that alerts you to negative reviews and drafts responses.
Analytics Reports
Access analytics data programmatically:
POST /v1/analyticsReportRequests
GET /v1/analyticsReportRequests/{id}/reports
GET /v1/analyticsReportInstances
Use case: Build custom dashboards showing impressions, downloads, conversion rates, and keyword performance.
App Pricing
Manage pricing across territories:
GET /v1/apps/{id}/appPriceSchedule
POST /v1/appPriceSchedules
Use case: Automate regional pricing adjustments and promotional pricing periods.
Practical ASO Automation Workflows
Workflow 1: Automated Keyword Rotation
Rotate keywords on a schedule (e.g., seasonal keywords):
# Pseudocode for keyword rotation
def rotate_keywords(app_id, locale, new_keywords):
# 1. Get current app version
version = get_latest_version(app_id)
# 2. Get localization for the target locale
localization = get_localization(version.id, locale)
# 3. Update the keyword field
update_localization(localization.id, {
'keywords': new_keywords # comma-separated, 100 chars max
})
# 4. Log the change
log_keyword_change(app_id, locale, new_keywords, datetime.now())
# Schedule seasonal rotations
schedule.every().month(1).do(rotate_keywords, app_id, 'en-US',
'fitness,workout,new year,resolution,goals,exercise,health,gym,training')
schedule.every().month(6).do(rotate_keywords, app_id, 'en-US',
'fitness,workout,summer,body,exercise,health,gym,training,outdoor')
Workflow 2: Batch Screenshot Upload
Upload screenshots for multiple locales and device types:
def batch_upload_screenshots(app_id, screenshots_dir):
version = get_latest_version(app_id)
for locale_dir in os.listdir(screenshots_dir):
localization = get_localization(version.id, locale_dir)
for device_type in ['iPhone 6.7"', 'iPhone 6.5"', 'iPad Pro']:
# Get or create screenshot set
screenshot_set = get_or_create_screenshot_set(
localization.id, device_type
)
# Upload each screenshot in order
for i, screenshot_file in enumerate(sorted(
glob(f'{screenshots_dir}/{locale_dir}/{device_type}/*.png')
)):
upload_screenshot(screenshot_set.id, screenshot_file, position=i)
print(f"Uploaded screenshots for {len(locales)} locales")
Workflow 3: Promotional Text Rotation
Rotate promotional text without app review:
def update_promotional_text(app_id, locale, text):
version = get_latest_version(app_id)
localization = get_localization(version.id, locale)
update_localization(localization.id, {
'promotionalText': text # 170 chars max, no review needed
})
# Schedule monthly rotations
promotional_calendar = {
1: "New year, new goals! Start 2026 with personalized plans...",
2: "Valentine's special: Share premium with someone you love...",
3: "Spring into action! New features just launched...",
# ... etc
}
current_month = datetime.now().month
update_promotional_text(app_id, 'en-US', promotional_calendar[current_month])
Workflow 4: Review Monitoring and Alerting
Monitor reviews and alert on negative ones:
def monitor_reviews(app_id, alert_threshold=3):
reviews = get_customer_reviews(app_id, sort='-createdDate', limit=50)
for review in reviews:
if review.rating <= alert_threshold:
# Send alert to Slack/email
send_alert({
'title': review.title,
'body': review.body,
'rating': review.rating,
'locale': review.territory,
'date': review.createdDate
})
# Auto-draft response
draft = generate_response_draft(review)
# Submit response (or queue for human review)
if review.rating <= 2:
queue_for_human_review(review, draft)
else:
submit_response(review.id, draft)
Workflow 5: ASO Performance Dashboard
Build a custom dashboard from analytics data:
def generate_aso_report(app_id, days=30):
# Request analytics reports
report = request_analytics_report(app_id, {
'reportType': 'APP_STORE_DISCOVERY',
'frequency': 'DAILY',
'dateRange': last_n_days(days)
})
# Parse and aggregate data
metrics = parse_report(report)
return {
'total_impressions': sum(m.impressions for m in metrics),
'total_downloads': sum(m.downloads for m in metrics),
'conversion_rate': total_downloads / total_impressions * 100,
'top_keywords': get_top_keywords(metrics),
'trend': calculate_trend(metrics),
'comparison_to_previous': compare_periods(metrics, days)
}
API Rate Limits and Best Practices
Rate Limits
The App Store Connect API has rate limits:
- Standard rate limit: 500 requests per minute per token
- Upload limits: Screenshot uploads have specific size and count limits
- Report generation: Analytics report requests may take time to process
Best Practices
- Cache responses β Avoid redundant API calls for data that changes infrequently
- Handle pagination β Large datasets return paginated results
- Retry with backoff β Implement exponential backoff for rate limit errors (429)
- Validate before submitting β Check character limits and format requirements client-side
- Log all changes β Maintain an audit trail of all API-driven metadata changes
- Use relationships wisely β The API uses JSON:API format; include related resources to reduce calls
- Secure your keys β Never commit private keys to version control; use environment variables
Building Your ASO Automation Stack
Starter Stack
For teams beginning with API automation:
- Language: Python or Node.js (best library support)
- Scheduling: Cron jobs or GitHub Actions
- Storage: Simple JSON or SQLite for change logs
- Alerting: Slack webhook or email
Advanced Stack
For teams with mature automation needs:
- Backend: Node.js/Python service with REST API
- Queue: BullMQ or Celery for background jobs
- Database: PostgreSQL for analytics and change history
- Dashboard: React/Next.js frontend
- Monitoring: Grafana or custom dashboards
- CI/CD: Automated screenshot generation and upload pipelines
API Limitations
What You Cannot Do via API
- A/B testing (PPO) β Product Page Optimization can only be set up in the web interface
- Custom Product Pages creation β CPP creation requires the web interface
- App Store Connect settings β Account-level settings are not API-accessible
- Editorial submission β Featuring requests cannot be submitted via API
Workarounds
- Use the API for what it does best (metadata, screenshots, reviews, analytics)
- Complement with manual work for CPP creation and PPO setup
- Consider browser automation (Playwright/Puppeteer) for tasks not supported by the API
Security Considerations
- Key rotation β Rotate API keys periodically (every 90 days recommended)
- Minimal permissions β Create keys with only the permissions needed
- Environment variables β Store keys in environment variables, not code
- Audit logging β Log all API actions with timestamps and responsible user/service
- Access control β Limit who has access to API keys within your team
Getting Started
- Generate an API key in App Store Connect
- Test basic endpoints β List your apps, read current metadata
- Build your first automation β Start with promotional text rotation (lowest risk)
- Expand gradually β Add screenshot management, then keyword rotation
- Build monitoring β Create dashboards and alerts based on analytics data
Combine API automation with Appalize's ASO tools for a complete workflow. Use Appalize for keyword research and tracking, competitive analysis, and creative design, then use the API to implement changes programmatically at scale.
The developers who automate their ASO workflow spend less time on repetitive tasks and more time on strategy. Start with one simple automation, prove the value, and build from there.






