API reference

App Store Connect reviews API errors and what actually causes them

Apple returns one 401 body for at least six different mistakes and will not tell you which one you made. That is the hardest thing about this API, and it is the first entry below. The rest covers the token lifetime rule that breaks long jobs, the rate-limit header nobody reads, a reply that returns 201 and then never publishes, and the undocumented public RSS feed that signals throttling by pretending it has no reviews.

Sources checked

The endpoints, as documented
List reviews
GET https://api.appstoreconnect.apple.com/v1/apps/{id}/customerReviews
Reply
POST /v1/customerReviewResponses, returns 201. The same call overwrites an existing response.
Delete a reply
DELETE /v1/customerReviewResponses/{id}, returns 204.
Filters
filter[rating], filter[territory], exists[publishedResponse], include=response, sort by rating or createdDate.
Page size
limit maxes out at 200.
Reply state
PUBLISHED or PENDING_PUBLISH. Publishing and deleting are both asynchronous.
One per review
Each customer review can have at most one response.
Token lifetime
exp minus iat must be 20 minutes or less for most requests.
Errors, in the order you will meet them

Authentication credentials are missing or invalid. Provide a properly configured and signed bearer token, and make sure that it has not expired.

We reproduced it

HTTP 401 · code: NOT_AUTHORIZED

What causes it

Any of: no token, a malformed token, the wrong kid, the wrong iss, the wrong aud, the wrong signing algorithm, or an exp more than 20 minutes out. Apple returns a byte-identical body for all of them, so the message tells you nothing about which one it is.

What fixes it

Check the shape before you debug anything else. Header: alg ES256, kid set to your Key ID, typ JWT. Payload for a team key: iss is the Issuer ID, aud is appstoreconnect-v1, plus iat and exp. An individual key is different: it uses sub set to "user" and carries no iss at all, which is the mistake that eats the most time. Send it as Authorization: Bearer.

Worth knowing

We sent both no auth header and a deliberately garbage bearer token to the live API and got back the same response, byte for byte. So the body genuinely carries no diagnostic signal. Do not read anything into its wording.

Apple, Generating tokens for API requests

401s that appear part-way through a long job, on requests that were working minutes earlier.

Vendor documented

HTTP 401

What causes it

The token lifetime rule. Apple computes it as exp minus iat, so minting a token with a comfortable expiry is exactly the wrong instinct here.

What fixes it

Re-sign on a schedule rather than reusing one token for a batch run. Long-lived tokens up to six months exist, but only when the token declares a scope and that scope contains only GET requests.

"Tokens that expire more than 20 minutes into the future are not valid."
Worth knowing

Whether customerReviews is on the allowlist for those long-lived read-only tokens is something we could not determine. Apple renders that resource list as an empty table.

Apple, Generating tokens for API requests

A 401 that started the moment you added a scope claim.

Vendor documented

HTTP 401

What causes it

The scope entries do not match the request you are making. It is an allowlist, not a hint.

What fixes it

Match the entry to the request exactly, or drop the scope claim until the rest works. One quirk worth knowing: Apple ignores limit, cursor and sort when it checks the scope, so those three cannot be the mismatch.

"App Store Connect rejects a token with a scope claim if none of the scope entries match the attempted request."
Apple, Generating tokens for API requests

RATE_LIMIT_EXCEEDED.

Vendor documented

HTTP 429

What causes it

The per-hour ceiling on your API key, over a rolling hour.

What fixes it

Read the X-Rate-Limit header, which is on every response and not only on the 429. It looks like user-hour-lim:3500;user-hour-rem:500; so you can throttle before you get rejected rather than after. Limits are per key, so splitting work across keys splits the budget.

"If you exceed a per-hour limit, the API rejects requests with an HTTP 429 response, with the RATE_LIMIT_EXCEEDED error code."
Apple, Identifying rate limits

POST /v1/customerReviewResponses returns 201 Created, but the reply never appears and developerResponse stays null.

Vendor documented

HTTP 201

What causes it

Usually nothing is wrong. Publication is asynchronous and Apple documents a delay. There has also been at least one Apple-side outage, reported in November 2025, where the same symptom showed up through the App Store Connect web UI as well, meaning it was not an API-client problem at all. That one was later reported as fixed.

What fixes it

Poll the response state rather than assuming 201 means live. It reads PENDING_PUBLISH until it reads PUBLISHED. If the web UI also loses the reply, it is not your code, and there is no client-side fix.

"Responses don't appear in the App Store instantly. Allow some time for the App Store to publish the response."
Apple, POST customerReviewResponses

No, there does not, at this time, exist public Apple APIs for reading, listing, or replying to customer reviews.

Vendor documented
What causes it

An Apple staff answer on the developer forums from July 2021. It was true when it was written.

What fixes it

Ignore it. customerReviews and customerReviewResponses shipped in App Store Connect API 2.0, announced at WWDC22. Any answer on this question dated 2021 or earlier is describing a world that no longer exists, and this one still surfaces because it carries an Apple staff badge.

Apple, App Store Connect API 2.0 release notes

The customerReviews count does not match the ratings count in your App Store Connect dashboard.

Unconfirmed
What causes it

They are different datasets. A rating with no written text is not a review, and the API resource covers reviews customers write.

What fixes it

Use App Store Connect reporting for rating counts, and treat the two numbers as unrelated. There is no documented ratings endpoint.

Worth knowing

Apple does not state this anywhere. The forum question asking exactly this got no replies. The explanation is the obvious reading of the resource description, but it is a reading, not a documented fact.

Apple, Customer Reviews

The iTunes customer reviews RSS feed returns HTTP 200 with zero entries, while its own rel="last" link says there are ten pages.

We reproduced it

HTTP 200, empty feed

What causes it

Undocumented per-client throttling. The feed signals it by returning a well-formed but entry-less success. No 429, no error code, nothing in the headers.

What fixes it

Back off and retry rather than assuming the app has no reviews. Validate the entry count, never the status code. A nonexistent app id also returns 200 with an empty feed, as does omitting or mangling the sortBy path segment, so a typo looks identical to a throttle.

Worth knowing

We ran this against three well-known apps. Cold, each page returned 50 entries and pages one through ten worked. After roughly 30 rapid requests, the identical URL began returning 200 with zero entries, and so did every other app we tried, which is what identifies it as per-client rather than per-app. Backing off to one request every 45 seconds restored 50 entries on five consecutive calls with an identical response size. The ceiling is 50 per page across 10 pages, so 500 reviews per storefront, per country code.

You cannot find developer responses anywhere in the public RSS feed.

We reproduced it
What causes it

They are not in it. Responses are available only through the authenticated API.

What fixes it

If you need to know whether a review already has a reply, you need App Store Connect API credentials. There is no public route to that field. Worth noting that the equivalent Google Play data is public, which is why cross-store tooling tends to be asymmetric.

Worth knowing

One widely cited answer also claims the JSON version of the feed drops the review date. That is no longer true. Each entry carries an updated field with a full timestamp.

Both APIs change without notice, and several of the answers this page corrects were right when they were written. If something here has gone stale, tell us and we will recheck the source and restamp the date.

Related reference

Integration FAQ

The questions behind the errors.

What the docs leave out, which popular answers are now wrong, and where the two stores genuinely differ.

See the Reply Argus API

Why does App Store Connect return the same 401 for everything?

Because the body is static. We confirmed it by sending no auth header at all and then a deliberately invalid bearer token, and the two responses came back identical byte for byte. Apple is not going to tell you whether the problem is your kid, your aud, your algorithm or your clock, so work through the token shape systematically instead of reading the message.

What is the 20-minute token rule?

Apple rejects a token whose exp is more than 20 minutes past its iat, and it checks the difference rather than the wall-clock expiry. This is what breaks long-running jobs: everything works for the first stretch and then starts 401ing, which sends people looking for a permissions problem that does not exist. Re-sign periodically.

Can I get developer responses from the public RSS feed?

No. The feed carries reviews only, and we checked the full XML rather than trusting the field list. Responses require authenticated App Store Connect API access. This is a real asymmetry between the stores, since Google exposes reply text on public review data.

Is the iTunes reviews RSS feed deprecated?

Not deprecated, but not supported either. Apple has no developer documentation page for it, publishes no error semantics, and signals throttling by returning an empty success. Treat it as something that works until it does not. Do not confuse it with the App Store Connect metadata XML feed that was decommissioned around 2022, which is a different thing that gets brought up in the same conversations.

How far back can I read reviews?

Through the authenticated API, Apple documents no window, and you page with limit up to 200. Through the public RSS feed you get 50 per page across 10 pages, so 500 per storefront, and the feed is per country code, which means broad coverage requires iterating countries.

Or skip the integration entirely.

Reply Argus already handles both APIs: the token refresh, the rate limits, the reply window, and the publication states. Connect a store and read your reviews through one interface.

2
stores watched
100+
languages
10-day
free trial

Free plan · no card to begin