Skip to main content
Infrastructure

App Store Server API Guide: Endpoints, Use Cases & Code Examples

Complete guide to App Store Server API in StoreKit 2. Learn Get Transaction History, Get All Subscription Statuses, and refund endpoints with Go code examples.

Nikita

Nikita

November 22, 20248 min read
App Store Server API

Hi there, I’m Nikita, a backend developer at Qonversion helping developers optimize in-app purchases and subscription handling.

To manage in-app purchases seamlessly, you need to keep up with updates from App Store and Google Play, and today I'll walk you through the App Store Server API — a relatively recent update in StoreKit 2. We’ll dive deep into its key endpoints, explore how to integrate them into your backend, and discuss best practices for handling subscriptions, refunds, and analytics. I’ll also share some practical tips and examples, including Go-based implementations, to help you get the most out of this powerful API.


Main Endpoints and Their Use Cases

The Apple Server API offers several key endpoints, each serving specific purposes in managing in-app purchases and subscriptions. When migrating your app from StoreKit 1 to StoreKit 2, you'll be working with these. Let's see what each of the endpoints does, what their use cases are, and the data they return.

App Store Server API | Get Transaction History

As an app owner, there are various scenarios where accessing a user's purchase history becomes essential, such as analyzing user behavior, benchmarking app marketing strategies, or optimizing subscription offerings. To achieve this, you can use the following endpoint:Endpoint: GET /inApps/v1/history/{originalTransactionId}

This endpoint allows app owners to retrieve a customer's entire purchase history. It's particularly useful for Analyzing customer behavior, Recognizing loyal customers, Understanding the effectiveness of app strategies and so on.

It returns a list of purchases, that looks like this example

SignedTransactions is a sequence (maximum 20 at a time). Example of single transaction is here:

App Store Server API | Get Transaction Info

To validate transactions you'll need details on a specific transaction.Endpoint: GET /inApps/v1/transactions/{transactionId}

This endpoint is designed to fetch detailed information about a single transaction using a transaction ID. It's useful for Validating transactions, Ensuring the server has the most up-to-date information, Verifying finished consumable transactions

Example of returned data contain single transaction which is same as in History response:

App Store Server API | Get All Subscription Statuses

Get All Subscription Statuses shows the status of all active and inactive subscriptions for a user.Endpoint: GET /inApps/v1/subscriptions/{originalTransactionId}

This endpoint provides the history of a customer's auto-renewable subscriptions. It helps businesses: Understand subscription performance, Manage customer subscriptions effectively, Track subscription lifecycles etc.

This endpoint will return List of subscriptions, and each subscription will contain Transaction Info and Renewal Info data. Transaction Info is equal to structure described earlier. The example for Renewal Info is here:

App Store Server API | Send Consumption Information

Send Consumption Information is used to communicate to Apple when a consumable product has been used.Endpoint: PUT /inApps/v1/transactions/consumption/{originalTransactionId}

In the event of a refund request, this endpoint allows businesses to provide information about the customer's use of a product. This information is used by Apple in the refund decision process, helping businesses: Manage refund requests more effectively and Provide context for consumption of digital goods.

App Store Server API | Look Up Order ID

Look Up Order ID allows for finding transactions based on an order ID.Endpoint: GET /inApps/v1/lookup/{orderId}

This endpoint is used to retrieve information about a specific order using its order ID. It's helpful for Resolving disputes, Verifying the legitimacy of a purchase, Tracking order details and so on.

App Store Server API | Get Notification History

You can also retrieve a history of notifications Apple has sent for a user.Endpoint: GET /inApps/v2/notifications/history

This endpoint allows retrieval of notification history, which is crucial for Syncing server data with the App Store, Tracking important events like subscription renewals, expirations, and refunds, Ensuring no critical notifications are missed.

App Store Server API | Get Refund History

Get Refund History will present you a paginated list of all of a customer’s refunded in-app purchases for your app.Endpoint: GET /inApps/v1/refundHistory/{originalTransactionId}The Get Refund History endpoint allows developers to retrieve details of refunds issued for in-app purchases. It provides insight into refund patterns, enabling businesses to improve customer service and reduce refund requests. This endpoint returns a list of refund events related to a user's transactions. You'll find an example in the “Get Transaction Info” section above.

These endpoints, along with others, make it easier to manage transactions and ensure smooth experiences for subscription and purchase users.

Handling a Purchase in Your Backend

Suppose a user makes a purchase, and you need to verify it in your backend. Previously, with the now-deprecated Receipt API, the mobile app had to send an entire encrypted receipt, which the backend would then validate with Apple. This receipt contained a wealth of information, such as details on all transactions and renewals associated with the user. However, the process has been simplified with the latest Server API.

Now, instead of sending the entire encrypted receipt as in the older /verifyReceipt process, the mobile app only needs to send a transaction ID. With this ID, your backend can query the "Get Transaction Info" endpoint: GET If the response status is 200 OK, you know the purchase is valid. The response includes signed transaction information, which ensures the authenticity of the data. Calls to the API require authorization using the In-App Purchase key from App Store Connect. This key secures the communication and protects sensitive data. Make sure your integration follows Apple’s guidelines for key management to avoid disruptions.

Example: Verifying a Transaction

Let’s say you receive transactionId = "2000000123456789" from the mobile app. Here’s how you’d verify it (this is what happened under the hood of the library client):

Sample Response:

With this response, you confirm that the user purchased the product. You can now process this information to grant access, update their account, or track the purchase in your analytics.

Handling Subscription Data

If the product is a subscription, you’ll need additional checks to determine if it’s active or expired. Start by decoding the JWSTransaction field in the TransactionInfoResponse to obtain a JWSTransactionDecodedPayload object. This object includes several relevant fields, including expiresDate.If expiresDate is in the past, the subscription has expired, and you should not grant access.Subscriptions often enter a grace period if the payment fails during renewal. During this time, users continue to access the subscription while Apple attempts to recover the payment.

Key considerations for handling grace periods:

Notification of Grace Period: Use the expirationIntent and isInBillingRetryPeriod fields in the subscription status response.- User Access: Allow uninterrupted access during the grace period to ensure a seamless user experience. Renewal Tracking: Monitor the renewalDate field to determine the next attempt date and update the user if the grace period ends unsuccessfully.

Implementing grace period handling reduces user churn and improves satisfaction!

Apple provides official client libraries for interacting with their Server API in only four languages: Swift, Java, Python, and Node.js. For developers using other languages, there are no official libraries, which means you’ll need to either find an unofficial client or implement your own solution.

For our Go-based implementation, there’s a ready-made library, which provides all the necessary functionality for authenticating, querying transactions, and decoding data. This library is robust and easy to use, it's a great choice for integrating Apple’s Server API into your Go application.Assuming response given above you’d decode JWSTransaction to get expiresDate. Let’s say the decoded payload looks like this:

If today’s date is past 2023-11-15 16:11:17 (UTC), the subscription is no longer valid.

Example written in go (with detailed comments)

Enhanced Analytics: Currency and Price

For those tracking revenue and analytics, Apple has added currency and price fields in the new API. These were missing in the old Receipt API. With this data, you can accurately track revenue in your analytics system, categorize purchases by region, and gain insights into purchase behaviors by price tier.

In addition to currency and price, the following fields are valuable for analytics:

  • Storefront: Indicates the user's geographic location.
  • TransactionReason: Differentiates between renewals, upgrades, or cancellations.
  • OfferType: Identifies promotions such as free trials or discounted rates.
  • StorefrontId: Tracks transactions by Apple’s regional storefront IDs.
  • PurchaseDate: Enables time-based analytics and campaign evaluation.

These fields empower developers to conduct detailed revenue analysis and optimize pricing strategies.

Conclusion

The App Store Server API is an indispensable tool for modern app developers. Its extensive endpoints simplify managing in-app purchases, handling subscriptions, and improving customer support. By integrating features like refund history tracking, handling grace periods, and leveraging enhanced analytics, businesses can optimize their operations and deliver a superior user experience. Go developers can use libraries to make integration seamless.

For those tracking revenue and analytics, Apple has added currency and price fields in the new API. These were missing in the old Receipt API. With this data, you can accurately track revenue in your analytics system, categorize purchases by region, and gain insights into purchase behaviors by price tier.

Nikita

Nikita

Backend Engineer at Qonversion

Nikita develops the backend systems powering Qonversion.

Share:

Ready to optimize your subscriptions?

Start using Qonversion today and see the difference.