Skip to main content

Migration guide to server-side API v2

Adapty's Server-Side API v2 introduces new capabilities and improvements to help you manage access levels, transactions, and user profiles more effectively.

Why Migrate?

The second version of the Server-Side API gives you more flexibility and features when working with Adapty:

  • Separate access level management: Assign access levels to users without requiring transaction details, making it easier to handle compensations, bonuses, or other non-transactional scenarios.
  • Record one-time purchases: Log transactions for consumable product purchases by providing consumable-product-specific fields.
  • Enhanced transaction details: Include more data with transactions, like refunds, billing issues, cancellation reasons, renewals, and more.
  • Profile updates: Instead of just adding attributes, you can update a user’s profile. For instance, you can add installation metadata or disable external analytics if needed.

Although v1 is still supported, we recommend moving to v2 for expanded functionality and ongoing updates.

Changes Overview

ChangeRequired action
Base URL and EndpointBase URL and all endpoints are changed. Update your configuration as described in the request endpoints
Request Headers
  1. Add either adapty-profile-id or adapty-customer-user-id as a header.
  2. Add a new adapty-platform header.
Request and Response StructureModify parameters as outlined for each request and update your integration to handle the new response formats.
Changed access level managementThe old Prolong/grant a subscription for a user request is now split into three:

Migration Steps

note

To simplify using our server-side API, we've prepared a Postman collection and an environment file you can download and import into Postman.

Download the collection and environment

Step 1. Configure request headers

Add new request headers as follows:

HeaderDescription
adapty-profile-id(Required, choose one) The user’s Adapty profile ID. Visible in the Adapty ID field in the Adapty Dashboard -> Profiles -> specific profile page. Interchangeable with adapty-customer-user-id, use any of them.
adapty-customer-user-id

(Required, choose one) The user’s ID in your system. Visible in the Customer user ID field in the Adapty Dashboard -> Profiles -> specific profile page. Interchangeable with adapty-profile-id, use any of them.

⚠️ Works only if you identify users in your app code using the Adapty SDK.

adapty-platformSpecify the app's platform. Possible options: iOS, macOS, iPadOS, visionOS, Android.

Step 2. Change transaction and access management requests

In version 1, you used to use:

They are now replaced with three separate requests to distinguish between adding transactions and managing access levels:

  1. Grant Access Level: Use this request to extend an access level without linking it to a transaction.
  2. Revoke Access Level: to immediately revoke or shorten access.
  3. Set Transaction: Use this request to add transaction details to Adapty with access levels.

Step 2.1. How to grant access level

info

For a detailed description, refer to the Grant access level request.

In version 1, the Prolong/grant a subscription for a user request was used to grant access. Now you can grant access with the Grant access level request without providing transaction details.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/grant/access-level/
  • Parameters to keep:
    • access_level_id: Previously in the endpoint. Required.
    • starts_at: Now nullable.
    • expires_at: Optional for lifetime access and nullable.

Step 2.2. How to revoke or shorten access level

info

For a detailed description, refer to the Revoke access level request.

In version 1, you used the Revoke access level request to immediately revoke access and the Prolong/Grant a Subscription for a User request to shorten it. Now you can use the Revoke access level request for both actions.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/purchase/profile/revoke/access-level/
  • Parameters to keep:
    • access_level_id: Required.
    • expires_at: Nullable unless access is revoked immediately.

Step 2.3. How to record a subscription transaction

info

For a detailed description, refer to the Set transaction request.

In version 1, transactions were recorded using the Prolong/Grant a Subscription for a User request, which was limited to subscription transactions.

In version 2, this functionality has been replaced by the Set Transaction request. This request can handle both subscription transactions and one-time purchases.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/purchase/set/transaction/
  • Details: The parameters required vary based on whether the transaction is a subscription or a one-time purchase. See the guidelines below for recording subscription transactions.

New fields

ParameterChangeTypeRequiredNullableDescription
billing_issue_detected_atAddedISO 8601 dateThe datetime when a billing issue was detected (e.g., a failed card charge). Subscription might still be active. This is cleared if the payment goes through.
cancellation_reasonAddedStringPossible reasons for cancellation include: voluntarily_cancelled, billing_error, price_increase, product_was_not_available, refund, upgraded, or unknown.
environmentAddedString

Environment where the transaction took place. Options are Sandbox or Production.

Replaces the is_sandbox parameter.

grace_period_expires_atAddedISO 8601 dateThe datetime when the grace period will end, if the subscription is currently in one.
is_family_sharedAddedBooleanA Boolean value indicating whether the product supports family sharing in App Store Connect. iOS only. Always false for iOS below 14.0 and macOS below 11.0.
offerAddedObjectRepresents the purchase offer as an object. See the Offer object.
originally_purchased_atAddedISO 8601 dateFor subscription chains, this is the purchase date of the original transaction, linked by store_original_transaction_id.
purchase_typeAddedStringSpecifies product type, here set to subscription.
purchased_atAddedISO 8601 dateIndicates most recent purchase date.
refunded_atAddedISO 8601 dateIndicates subscription refund datetime if applicable.
renew_statusAddedBooleanIndicates if subscription auto-renewal is enabled.
renew_status_changed_atAddedISO 8601 dateIndicates when auto-renewal status changed.
variation_idAddedStringThe variation ID used to trace purchases to the specific paywall they were made from.

Removed fields

ParameterChangeDescription
base_plan_idRemovedRemoved. Ass the base plan ID to the store_product_id field in the format product_id:base_plan_id.
duration_daysRemovedRemoved as not needed. The duration is calculated automatically.
introductory_offer_typeRemovedOffer types are now in the offer object.
is_lifetimeRemovedRemoved as it's replaced with the purchase_type parameter.
is_sandboxRemovedReplaced with the environment parameter.
price_localeRemovedMoved to the price object.
proceedsRemoved
starts_atRemovedRemoved as it will be automatically taken from the access level connected to the selected product.

Changed fields

ParameterChangeTypeRequiredNullableChange Description
priceChangedFloat -> Object -> Now represented as a Price object and includes price_locale, country, and value fields.
storeChangedString ->
  1. The field became mandatory.
  2. In addition to standard app stores, you can now use custom stores as well.
vendor_original_transaction_id -> store_original_transaction_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.
vendor_product_id -> store_product_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.
vendor_transaction_id -> store_transaction_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.

Step 2.4. How to record a one-time purchase transaction

info

For a detailed description, refer to the Set transaction request.

In version 1, transactions were recorded using the Prolong/Grant a Subscription for a User request, which was limited to subscription transactions.

In version 2, this functionality has been replaced by the Set Transaction request. This request can handle both subscription transactions and one-time purchases.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/purchase/set/transaction/
  • Details: The parameters required vary based on whether the transaction is a subscription or a one-time purchase. See the guidelines below for recording one-time purchase transactions.

New fields

ParameterChangeTypeRequiredNullableDescription Change
cancellation_reasonAddedStringPossible reasons for cancellation: voluntarily_cancelled, billing_error, price_increase, product_was_not_available, refund, cancelled_by_developer, new_subscription_replace, upgraded, unknown, adapty_revoked.
environmentAddedString

Environment where the transaction took place. Options are Sandbox or Production.

Replaces the is_sandbox parameter.

is_family_sharedAddedBooleanIndicates whether the product supports family sharing in App Store Connect. iOS only. Always false for iOS below 14.0 and macOS below 11.0.
offerAddedObjectRepresents the purchase offer as an object. See the Offer object.
purchase_typeAddedStringSpecifies the type of product purchased. Here set to one_time_purchase.
purchased_atAddedISO 8601 dateThe datetime when the access level was last purchased.
refunded_atAddedISO 8601 dateIf refunded, shows the datetime of the refund.
variation_idAddedStringThe variation ID used to trace purchases to the specific paywall they were made from.

Removed fields

ParameterChangeDescription Change
base_plan_idRemovedRemoved. Ass the base plan ID to the store_product_id field in the format product_id:base_plan_id.
duration_daysRemovedRemoved as not needed. The duration is calculated automatically.
expires_atRemovedRemoved as not relevant to a one-time purchase.
introductory_offer_typeRemovedOffer types are now in the offer object.
is_lifetimeRemovedRemoved as it's replaced with the purchase_type parameter.
is_sandboxRemovedReplaced with the environmentparameter.
price_localeRemovedMoved to the price object.
proceedsRemoved
starts_atRemovedRemoved as not relevant to a one-time purchase.

Changed fields

ParameterChangeTypeRequiredNullableDescription Change
priceChangedFloat -> Object -> Now represented as a Price object and includes price_locale, country, and value fields.
storeChangedString ->
  1. The field became mandatory.
  2. In addition to standard app stores, you can now use custom stores as well.
vendor_original_transaction_id -> store_original_transaction_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.
vendor_product_id -> store_product_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.
vendor_transaction_id -> store_transaction_idRenamed, changedString ->
  1. The field is renamed.
  2. The field beca,e mandatory.

Step 3. Change Get info about a user request

info

For a detailed description, refer to the Get profile request.

Change the request as follows:

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/profile/
  • Change: The User Profile ID or Customer User ID is now passed via headers, and no additional parameters are needed. The extended parameter is no longer needed as the complete profile data is always returned.

Step 4. Change Set the user's attribute request

info

For a detailed description, refer to the Update profile request.

In version 1, you could only update user attributes. With version 2, you can modify a wider range of profile fields, such as installation metadata or analytics settings.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/profile/.
ParameterChangeTypeRequiredNullableDescription Change
analytics_disabledAddedBooleanOption to opt out of external analytics. When disabled, events won’t be sent to integrations, and idfa, idfv, and advertising_id become nullable.
installation_metaAddedDictionaryContains app-specific device details as a dictionary of Installation Meta objects.
storeAddedStringStore where the product was bought. Options include app_store, play_store, stripe, or the name of your custom store.
store_countryAddedStringCountry of the end user app store.
birthdayChangedDate -> ISO 8601 date -> Your end user's birthday.
ip_countryChangedString -> Country of the end user in ISO 3166-2 format. Must be passed if the request is made from the server. Otherwise, determined by request IP.

Step 5. Change Delete user's data request

info

For a detailed description, refer to the Delete profile request.

  • Endpoint: https://api.adapty.io/api/v2/server-side-api/profile/
  • Change: The adapty-profile-id or adapty-customer-user-id is now passed via headers, and no additional parameters are needed.