When App Store Server Notifications V2 don't reach your server, stop guessing and ask Apple what happened: call Request a Test Notification in the App Store Server API, then Get Test Notification Status with the token it returns. The status lists each send attempt with a result such as TLS_ISSUE, TIMED_OUT or UNSUCCESSFUL_HTTP_RESPONSE_CODE, which points at the cause. The usual causes are on Apple's own setup pages: no URL (or only a sandbox URL) in App Store Connect, a server without TLS 1.2 or later, a port other than 443 or 1024 and up, a firewall that blocks Apple's 17.0.0.0/8 range, or a reply that isn't HTTP 200 to 206.
What Apple sends and what it expects back
The App Store sends each notification as an HTTP POST with a JSON body. For version 2 the body is responseBodyV2, whose signedPayload is signed by the App Store in JWS format. Your server answers with a status code:
- HTTP
200, or any code from200to206, means success. - HTTP
40xor50xasks the App Store to retry. Apple counts all other codes as unsuccessful. - You don't have to return a body.
If the first attempt doesn't get a success response, Apple retries version 2 notifications five times, at 1, 12, 24, 48 and 72 hours after the previous attempt. Retries happen only in production. In the sandbox, Apple says the App Store server tries once.
Version 1 notifications are deprecated; Apple says to implement the V2 endpoint instead.
Check the setup, in this order
- The URL is in App Store Connect. In Apps, select the app, then App Information under General, then App Store Server Notifications. Set the Production Server URL and, for testing, the Sandbox Server URL, and choose Version 2 for each. Apple's help page lists the roles that can do this: Account Holder, Admin, App Manager or Marketing.
- You understand which URL gets what. Apple's help page says that without a sandbox URL, sandbox and production notifications both go to the production URL, and that if you provide only a sandbox URL, no notifications are sent in production. You may use the same URL for both.
- TLS 1.2 or later. Apple states your server "must support the Transport Layer Security (TLS) 1.2 protocol or later". The
TLS_ISSUEresult also mentions a certificate that can't be validated. - The port. If the URL names a port, it must be
443or1024and up. - The firewall. If your server only accepts listed IP addresses, add
17.0.0.0/8. Apple says this covers both sandbox and production. - The reply. Return
200as soon as you've received the post. TheTIMED_OUTresult tells you to "check that your server isn't processing messages in line", so store the body and process it afterwards. Apple doesn't publish a timeout value. - The environment you're testing. A sandbox purchase sends one notification, with no retries, to the sandbox URL (or to production if there is no sandbox URL).
Apple doesn't say how long a newly saved URL takes to start receiving notifications.
How to check: test notification, status, history
The App Store Server API needs a JSON Web Token signed with an In-App Purchase key. Generate the key in App Store Connect under Users and Access > Integrations > In-App Purchase; Apple lets you download the private key only once. Use the sandbox host for the sandbox URL and the production host for the production URL.
1. Ask for a TEST notification.
curl -X POST -H "Authorization: Bearer $JWT" \
https://api.storekit-sandbox.apple.com/inApps/v1/notifications/test
# {"testNotificationToken": "..."}
Apple sends the TEST notification to your sandbox URL when you call the sandbox host, and to your production URL when you call api.storekit.apple.com.
2. Read what Apple recorded.
curl -H "Authorization: Bearer $JWT" \
https://api.storekit-sandbox.apple.com/inApps/v1/notifications/test/$TOKEN
The response has a sendAttempts array (up to six: the first attempt and up to five retries), each with an attemptDate and a sendAttemptResult, plus the signedPayload Apple tried to send. You can check a token for up to six months. What the results mean, from Apple's list:
sendAttemptResult | Apple's description, shortened | Look at |
|---|---|---|
SUCCESS | Apple got a success response. | Your code after the reply. |
TLS_ISSUE | No TLS session, or the certificate couldn't be validated. | Certificate chain, TLS 1.2+. |
UNSUCCESSFUL_HTTP_RESPONSE_CODE | No HTTP 200 response. | Auth middleware, routing, status code. |
TIMED_OUT | No response before the timeout. | Reply first, process later. |
NO_RESPONSE | No valid HTTP response. | Server or proxy. |
CIRCULAR_REDIRECT | A redirect loop. | Redirect rules (http to https, trailing slash). |
PREMATURE_CLOSE | The connection closed during the send. | Proxy, load balancer. |
SOCKET_ISSUE | A network error. | DNS, firewall, port. |
INVALID_RESPONSE | An invalid response. | The response your server writes. |
UNSUPPORTED_CHARSET | A charset Apple doesn't support. | Response headers. |
OTHER | Another error. | All of the above. |
3. Find real notifications you missed. Get Notification History (POST /inApps/v1/notifications/history) returns the version 2 notifications Apple attempted to send, with their send attempts. Send startDate and endDate in UNIX milliseconds; add "onlyFailures": true to see only the ones that didn't reach you, including those still being retried. History covers 180 days in production and 30 days in the sandbox, 20 records per response.
curl -X POST -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \
-d '{"startDate": 1761955200000, "endDate": 1762041600000, "onlyFailures": true}' \
https://api.storekit.apple.com/inApps/v1/notifications/history
Apple notes that history records show the purchase as it was when the notification was sent. For the current state, call Get All Subscription Statuses or Get Transaction History.
4. Read the payload. To see what a notification contains, paste the signedPayload (or the whole body) into the App Store JWS decoder. Apple's steps: split the JWS into header, payload and signature, Base64URL-decode the payload to get the notification type and data, then decode signedTransactionInfo and signedRenewalInfo the same way. On your server, validate each signature with the algorithm named in the header's alg.
FAQ
Production notifications arrive but sandbox ones don't. Why?
Check that the sandbox URL is set and uses Version 2, then call Request a Test Notification on the sandbox host. Remember that the sandbox makes a single attempt, so one failure is final; Get Notification History in the sandbox goes back 30 days.
The test notification works but real ones don't. What next?
Call Get Notification History with onlyFailures for the period of the purchase. If nothing is listed, Apple did not attempt a notification for that event; check the notification types Apple documents for it. If attempts are listed, their sendAttemptResult tells you why they failed.
My server got the notification but Apple keeps retrying. Why?
Apple only counts 200 to 206 as success. A 401 from an auth layer, a redirect, or a slow reply that times out all count as failures, and in production Apple retries up to five times over several days.
I configured Version 1. Will I get the test notification?
Yes. Apple sends TEST in the version 2 format whether your URL is set to version 1 or version 2. Version 1 is deprecated, so switch to version 2 after testing it in the sandbox.
My server was down for a day. Are those notifications lost?
In production Apple retries five times, at 1, 12, 24, 48 and 72 hours after each previous attempt, so a one-day outage may be covered by a later retry. Get Notification History also returns notifications from the last 180 days, so you can fetch the ones you missed.
Sources
All read on 1 November 2026.
- App Store Server Notifications, Apple Developer Documentation
- Enabling App Store Server Notifications, Apple Developer Documentation
- Receiving App Store Server Notifications, Apple Developer Documentation
- Responding to App Store Server Notifications, Apple Developer Documentation
- responseBodyV2, Apple Developer Documentation
- Request a Test Notification, Get Test Notification Status, CheckTestNotificationResponse, sendAttemptResult, App Store Server API
- Get Notification History, NotificationHistoryRequest, NotificationHistoryResponse, App Store Server API
- App Store Server API, Apple Developer Documentation
- Creating API keys to authorize API requests, Apple Developer Documentation
- Enter server URLs for App Store Server Notifications, App Store Connect Help
Apple's endpoints and limits change; check the pages above for current behaviour.