All posts
AUTOMATION

App Store Connect API pagination and rate limits: building robust pricing automations for iOS apps

A practical guide to Apple's paginated response model and rate limit behavior for developers building App Store Connect pricing automations at scale.

By the AppsOps team · · 7 min read

When you start automating App Store Connect pricing—syncing subscription tiers across territories, scheduling promotional price drops, or running nightly audits that catch unexpected Apple adjustments—two friction points appear quickly. Pagination means the API returns large result sets in chunks, and rate limits mean Apple throttles how many requests you can fire in a window. Developers who discover both walls mid-production run at 2 AM, during a campaign launch, lose hours they cannot get back.

This post maps both systems in practical detail. It assumes you have already set up your API key and understand how JWT authentication works. The goal is to get your automation code to run to completion reliably, not just in the happy path.

How the App Store Connect API structures paginated responses

The App Store Connect API uses cursor-based pagination across every list endpoint. Each response includes a links object with a next URL when more pages exist. The pageSize query parameter controls how many records are returned per call; the default is 20 for most endpoints, with a maximum of 200.

For pricing work, the key paginated endpoints are:

Endpoint Default page size Max page size Typical result volume
GET /v1/apps 20 200 1–200 (most catalogs fit one page)
GET /v1/appPriceTiers 20 200 ~90 tiers (fits comfortably in one page)
GET /v1/territories 20 200 175 (fits in one call at max pageSize)
GET /v1/subscriptionPrices 20 200 Scales with catalog depth
GET /v1/appPriceSchedules/{id}/manualPrices 20 200 Per-app; 1–175 territory overrides

The next cursor URL contains an opaque token or offset. You should never construct these URLs manually—use the next link verbatim from each response and follow it until no next link is returned. Some endpoints return an empty data array on the final call while still providing a next link one page too late; always check data.length === 0 as your loop-exit condition rather than relying solely on the absence of a next link.

A practical observation from developers in the community: fetching all 175 territories in a single call (pageSize=200) is reliable and costs one request. This matters when you are building a pricing audit that iterates over territory-level overrides; fetching territories once and caching the result for the duration of the run is worth the few lines of code it requires.

175 App Store territories your pricing automation must traverse without a dropped page

Apple's rate limit model for the App Store Connect API

Apple does not publish a single definitive rate limit figure in its public documentation, but the developer community and Apple's own error handling guidance give a reasonably clear picture. Rate limits apply at the API key level, not per endpoint. When you exceed the limit, the API returns HTTP 429 with a Retry-After header indicating how many seconds to wait before retrying.

Community reports from developers building App Store Connect automations—including teams at RevenueCat and Fastlane maintainers—suggest practical sustained throughput is in the range of a few hundred read requests per minute per key, with write operations subject to stricter throttling. Apple's documentation explicitly warns that limits can change and advises building retry logic rather than relying on any specific number.

A few nuances matter for pricing automation specifically:

Test your retry logic before you need it. The worst time to discover a gap in your 429 handler is during a Black Friday price update when your automation gets throttled halfway through 80 apps. Write an explicit test that mocks a 429 response with a short Retry-After, verify exponential backoff fires correctly, and keep this test in CI. Two hours of defensive engineering here saves one very bad morning.

Common failure patterns and how to handle them

Rate limits and pagination each produce characteristic bugs. Understanding the failure pattern makes them easier to diagnose quickly.

Cursor invalidation mid-walk. If you pause a paginated walk—for example, because a rate limit fired and you slept for 60 seconds—and Apple's data changed while you waited (a price update committed, a subscription was archived), the cursor may be stale. Apple may return an error or an inconsistent page. The safest recovery is to restart the walk from the beginning when you detect an unexpected response. For large catalogs, this argues for design choices that avoid long pauses mid-walk: complete reads before writes, and handle 429s by backing off completely and retrying the entire operation rather than resuming from a cursor.

Token expiry during bulk runs. JWT tokens are valid for 20 minutes after generation. A script that reads 200 apps, pages through their subscription groups, then begins writing prices can easily span more than 20 minutes. The fix is to track your token's expiry time (it is the exp claim in the JWT payload) and regenerate the token proactively when 2–3 minutes remain, rather than waiting for an authentication error to surface mid-write.

Silent 429 headers. Some HTTP client libraries silently drop headers they do not recognize or fail to parse Retry-After values that are expressed as an HTTP date string rather than a delta-seconds integer. Implement a generic exponential backoff (start at 5 seconds, double up to a ceiling of 120 seconds) that kicks in whenever you receive a 429, regardless of whether the header parses correctly. The specific value is a hint; the fallback is always correct.

Concurrent write conflicts. If two automation processes—say, a nightly price sync and a manual operator trigger—run simultaneously and both attempt to update the same app's price schedule, one will receive a 409 conflict response. Design your automation to hold a lightweight advisory lock (a database row, a Redis key, an S3 object) before writing, and fail fast rather than retrying writes into an active conflict.

Empty final page with a spurious next link. This is a known quirk in some versions of the App Store Connect API. Always check whether the returned data array is empty before processing. If it is empty but a next link is present, treat the response as the end of the result set and stop walking.

Designing a resilient pricing automation pipeline

With pagination and rate limits understood, a few architectural decisions make the difference between automation that runs reliably and automation that breaks silently and produces partial updates—which can be worse than no update at all.

Read completely before writing. Fetch the current state of all apps, subscription groups, and price schedules before issuing a single write. This approach uses more requests upfront but avoids write-then-read inconsistencies where your code makes a decision based on state that is about to change. The price-update workflow guide covers how to structure this sequence in practice.

Use batch endpoints where Apple provides them. Rather than issuing 175 individual territory price-creation requests for a new subscription schedule, use the endpoints that accept territory arrays in a single request body. Apple's subscription price endpoint allows specifying price points for multiple territories in one call. Consulting the API reference for the batch variants before writing a loop saves significant quota and run time.

Design for idempotency. Your pipeline should be safe to re-run after a partial failure. Track which app–territory–price combinations were successfully applied and skip them on a subsequent run. A simple log file keyed on the app bundle ID and target price tier is enough for most catalogs. If your run is interrupted at record 47 of 80, the next run should resume cleanly rather than duplicating work or triggering unnecessary Apple re-processing.

Cap your request rate explicitly. Do not rely on Apple to throttle you correctly. Build an explicit rate limiter into your code—a token bucket or a simple sleep between batches—set comfortably below the estimated quota. A ceiling of 60–80 read requests per minute gives meaningful headroom without sacrificing run time on typical catalogs. For write operations, a more conservative 10–15 per minute is appropriate given the stricter throttling behavior observed in practice.

Separate audit runs from change runs. An audit that reads all current prices and reports anomalies does not need write access and should use a read-only API key. Keeping these concerns on separate keys makes it easier to identify which process is consuming quota and avoids a runaway audit script eating into the write budget you need for campaign launches.

Pricing automation at the App Store Connect API level is ultimately a reliability engineering problem as much as a product one. The underlying operations are simple—read price tiers, compute target prices, post updates—but doing them correctly at scale, across a full 175-territory catalog, and with correct handling of the failure modes described here, is what separates automation that runs unattended for months from automation that requires babysitting.

For more on the types of operations worth automating, see the App Store Connect API automation guide and the discussion of territory-level pricing strategy.

Sources and further reading

Share this post

Ready to put this into practice?

AppsOps is the first App Store ops dashboard — PPP-fair pricing for 175 App Store territories, AI metadata localization in 39 languages, AI screenshot localization for 14 Apple device classes, and one-click App Store Connect API push — all from one dashboard, all for $19/month.

Try AppsOps free — no card →

Related reading