---
title: "API objects"
description: "Explore Adapty’s server-side API objects to manage subscriptions efficiently."
---

Adapty API has JSON objects so you can understand a response structure and wrap it into your code.

All datetime values are [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), for example, "2020-01-15T15:10:36.517975+0000".

## Access level

Info about customer's [access level](access-level). 

Access levels let you control what your app's users can do in your mobile app without hardcoding specific product IDs. Each product defines how long the user gets a certain access level. So, whenever a user makes a purchase, Adapty grants access to the app for a specific period (for subscriptions) or forever (for lifetime purchases). Alternatively, you can [grant specific access](api-adapty/operations/grantAccessLevel) for a specified time to a user via server-side API.

You can do the following action via Adapty server-side API:

- [Check users's access level](api-adapty/operations/getProfile) by retrieving their profile details
- [Grant specific access](api-adapty/operations/grantAccessLevel) to your end user without providing a transaction
- [Set transaction and grant access level](api-adapty/operations/setTransaction) to your end user
- [Revoke access level](api-adapty/operations/revokeAccessLevel) from your end user

| Parameter                     | Type          | Required | Nullable | Description                                                  |
| :---------------------------- | :------------ | -------- | -------- | :----------------------------------------------------------- |
| access_level_id               | String        | Yes      | No       | ID for the Paid Access Level set up in the Adapty Dashboard. |
| store                         | String        | Yes      | No       | Store where the product was bought. Options: **app_store**, **play_store**, **stripe**, or the name of your [custom store](custom-store). |
| store_product_id              | String        | Yes      | No       | ID of the product in the app store (like App Store, Google Play, Stripe) that unlocked this access level. |
| store_base_plan_id            | String        | Yes      | Yes      | [Base plan ID](https://support.google.com/googleplay/android-developer/answer/12154973) in Google Play or [price ID](https://docs.stripe.com/products-prices/how-products-and-prices-work#use-products-and-prices) in Stripe. |
| store_transaction_id          | String        | Yes      | No       | Transaction ID in the app store (App Store, Google Play, Stripe, etc.). |
| store_original_transaction_id | String        | Yes      | No       | <p>For subscriptions, this ID links the original transaction in the chain of renewals. Later transactions are linked as renewals.</p><p>If there's no renewal, store_original_transaction_id matches store_transaction_id.</p> |
| offer                         | Object | Yes      | No       | The [Offer](server-side-api-objects#offer) object. Can be `null` if the customer has no access levels. |
| environment                   | String        | No       | No       | Environment for the transaction that granted access. Options: `Sandbox`, `Production`. |
| starts_at                     | ISO 8601 date | Yes      | Yes      | The date time when the access level becomes active. Could be in the future. |
| purchased_at                  | ISO 8601 date | Yes      | No       | The datetime of the most recent purchase for the access level. |
| originally_purchased_at       | ISO 8601 date | Yes      | No       | For subscriptions, this is the date and time of the very first (original) purchase in the chain, tied to `store_original_transaction_id`. |
| expires_at                    | ISO 8601 date | Yes      | Yes      | The datetime when the access level expires. Might be in the past, or `null` for lifetime access. |
| renewal_cancelled_at          | ISO 8601 date | Yes      | Yes      | The datetime when auto-renewal was turned off for a subscription. The subscription can still be active; it just won't auto-renew. Set to `null` if the user reactivates the subscription. |
| billing_issue_detected_at     | ISO 8601 date | Yes      | Yes      | The datetime when a billing issue was found (like a failed card charge). The subscription might still be active. This is cleared if the payment goes through later. |
| is_in_grace_period            | Boolean       | Yes      | No       | Shows whether the subscription is in a [grace period](https://developer.apple.com/news/?id=09122019c) (only for auto-renewable subscriptions). |
| cancellation_reason           | String        | Yes      | Yes      | Reason for cancellation, with options like: `voluntarily_cancelled`, `billing_error`, `price_increase`, `product_was_not_available`, `refund`, `upgraded`, `unknown`. |

:::note

Although the SDK includes the `is_active` parameter to check if a subscription is active, the server-side API does not provide this parameter. However, you can determine subscription status at any time by checking whether the current date falls between the `starts_at` and `expires_at` parameters.

:::

---

## Installation Meta

Information about installation of the app on a specific device. 

You can do the following action via Adapty server-side API:

- [Create a profile with spesific installation meta](api-adapty/operations/createProfile)
- [Update user's installation meta](api-adapty/operations/updateProfile)

| Parameter          | Type   | Required | Nullable | Description                                                  |
| :----------------- | :----- | -------- | -------- | :----------------------------------------------------------- |
| device_id          | String | Yes      | No       | The device identifier is generated on the client side.       |
| device             | String | No       | Yes      | The end-user-visible device model name.                      |
| locale             | String | No       | Yes      | The locale used by the end user.                             |
| os                 | String | No       | Yes      | The operating system used by the end user.                   |
| platform           | String | No       | Yes      | The device platform used by the end user.                    |
| timezone           | String | No       | Yes      | The timezone of the end user.                                |
| user_agent         | String | No       | Yes      | Details about the end user environment: device, operating system, and browser information of the end user interacting with your application. |
| idfa               | String | No       | Yes      | The Identifier for Advertisers, assigned by Apple to a user's device. |
| idfv               | String | No       | Yes      | The Identifier for Vendors (IDFV) is a code assigned to all apps by one developer and is shared across all apps by that developer on your device. |
| advertising_id     | String | No       | Yes      | The Advertising ID is a unique identifier offered by the Android Operating System that advertisers might use to uniquely identify you. |
| android_id         | String | No       | Yes      | On Android 8.0 (API level 26) and higher versions of the platform, a 64-bit number (expressed as a hexadecimal string), unique to each combination of app-signing key, user, and device. For more details, see [Android developer documentation](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID). |
| android_app_set_id | String | No       | Yes      | An [AppSetId](https://developer.android.com/design-for-safety/privacy-sandbox/reference/adservices/appsetid/AppSetId) - unique, per-device, per developer-account user-resettable ID for non-monetizing advertising use cases. |

---

## Non Subscription

Info about non-subscription purchases. These can be one-time \(consumable\) products, unlocks \(like new map unlock in the game\), etc.  

You can do the following action via Adapty server-side API:

- [Check user's current non-subscriptions](api-adapty/operations/getProfile) by retrieving their profile details

| Parameter                     | Type          | Required | Nullable | Description                                                  |
| :---------------------------- | :------------ | -------- | -------- | :----------------------------------------------------------- |
| purchase_id                   | String        | Yes      | No       | Identifier of the purchase in Adapty. You can use it to ensure that you've already processed this purchase, for example tracking one-time products. |
| store                         | String        | Yes      | No       | Store where the product was purchased. Possible values are: **app_store**, **play_store**, **stripe**, name of your [custom store](custom-store). |
| store_product_id              | String        | Yes      | No       | Identifier of the product in the app store (App Store/Google Play/Stripe, etc.) that unlocked this access level. |
| store_base_plan_id            | String        | Yes      | Yes      | [Base plan ID](https://support.google.com/googleplay/android-developer/answer/12154973) in the Google Play Store or [price ID](https://docs.stripe.com/products-prices/how-products-and-prices-work#use-products-and-prices) in Stripe. |
| store_transaction_id          | String        | Yes      | No       | The ID of the transaction in the app store (App Store/Google Play/Stripe, etc.). |
| store_original_transaction_id | String        | Yes      | No       | <p>In case of prolonged subscriptions, a chain of subscriptions is generated. The original transaction i the very first transaction in this chain and the chain is linked by it. Other transactions in the chain are prolongations.</p><p>If no prolongation, `store_original_transaction_id` will coincide with `store_transaction_id`.</p> |
| purchased_at                  | ISO 8601 date | Yes      | No       | The datetime when the access level was purchased the latest time. |
| environment                   | String        | No       | No       | Environment of the transaction that provided the access level. Possible values: `Sandbox`, `Production.` |
| is_refund                     | Boolean       | Yes      | No       | Indicates if the product has been refunded.                  |
| is_consumable                 | Boolean       | Yes      | No       | Indicates whether the product is consumable.                 |

---

## One-Time Purchase

| Parameter                     | Type          | Required | Nullable | Description                                                  |
| :---------------------------- | :------------ | -------- | -------- | :----------------------------------------------------------- |
| purchase_type                 | String        | Yes      | No       | The type of product purchased. Possible value: `one_time_purchase`. |
| store                         | String        | Yes      | No       | Store where the product was bought. Possible values: `app_store`, `play_store`, `stripe`, or the Store ID of your [custom store](custom-store). |
| environment                   | String        | No       | No       | Transaction environment that provided the access level. Options: `Sandbox`, `Production`. `Production` is used by default. |
| store_product_id              | String        | Yes      | No       | The product ID in the app store (App Store, Google Play, Stripe, etc.) that unlocked this access level. |
| store_transaction_id          | String        | Yes      | No       | Transaction ID in the app store (App Store, Google Play, Stripe, etc.). |
| store_original_transaction_id | String        | Yes      | No       | <p>For recurring subscriptions, this is the original transaction ID that links the chain of renewals. The original transaction is the first in the chain; later transactions are renewals.</p><p>If there's no renewal, `store_original_transaction_id` matches `store_transaction_id`.</p> |
| offer                         | Object        | No       | Yes      | The offer used for the purchase as an [Offer](server-side-api-objects#offer) object. |
| is_family_shared              | Boolean       | No       | No       | A 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. `false` is used by default. |
| price                         | Object        | Yes      | No       | Price of the one-time purchase as a [Price](server-side-api-objects#price) object. An initial subscription purchase with zero cost is a free trial; a renewal with zero cost is a free renewal. |
| purchased_at                  | ISO 8601 date | Yes      | No       | The datetime when the access level was last purchased.       |
| refunded_at                   | ISO 8601 date | No       | No       | If refunded, shows the datetime of the refund.               |
| cancellation_reason           | String        | No       | No       | Possible reasons for cancellation: `voluntarily_cancelled`, `billing_error`, `price_increase`, `product_was_not_available`, `refund`, `cancelled_by_developer`, `new_subscription`, `unknown`. |
| variation_id                  | String        | No       | No       | The variation ID used to trace purchases to the specific paywall they were made from. |

---

## Offer

Information on the applied offer. The Offer object is a part of the  [Subscription](server-side-api-objects#subscription), and [Access level](server-side-api-objects#access-level) objects.

You can do the following actions with offers via Adapty server-side API:

- [Apply offer](api-adapty/operations/setTransaction) when setting a transaction to your user

| Parameter | Type   | Required | Nullable | Description                                                  |
| -- | ------ | -------- | -------- | ------------------------------------------------------------ |
| category | String | Yes      | No       | The category of the applied offer. Options are: **introductory**, **promotional**, **offer_code**, **win_back**. |
| type | String | Yes      | No       | The type of active offer. Options are: **free_trial**, **pay_as_you_go**, **pay_up_front**, and **unknown**. If this isn't null, it means the offer was applied in the current subscription period. |
| id | String | No       | Yes      | The ID of the applied offer.                                 |

## Price

Information about the cost of your product in local currency. The Price object is a part of the  [Subscription](server-side-api-objects#subscription) and Purchase objects.

You can do the following actions with product price via Adapty server-side API:

- [Set transaction to your user](api-adapty/operations/setTransaction) and specify its price

| Parameter | Type   | Required | Nullable | Description                               |
| --------- | ------ | -------- | -------- | ----------------------------------------- |
| country   | String | Yes      | No       | The country where the price applies.      |
| currency  | String | Yes      | No       | The currency used for the price.          |
| value     | Float  | Yes      | No       | The product's cost in the local currency. |

---

## Profile

Info about the [customer and their subscription](server-side-api-objects#profile)

You can do the following actions with user profiles via Adapty server-side API:

- [Retrieve/get the end-user's profile](api-adapty/operations/getProfile) with their access levels, subscriptions, non-subscriptions, etc.
- [Create a new end-user profile](api-adapty/operations/createProfile)
- [Update your end-user profile](api-adapty/operations/updateProfile)
- [Delete your end-user](api-adapty/operations/deleteProfile)

| Parameter         | Type       | Nullable           | Description                                                  |
| ----------------- | ---------- | ------------------ | ------------------------------------------------------------ |
| app_id            | String     | :heavy_minus_sign: | The internal ID of your app. You can see in the the Adapty Dashboard: [App Settings -> General tab](https://app.adapty.io/settings/general). |
| profile_id        | UUID       | :heavy_minus_sign: | Adapty profile ID. You can see it in the **Adapty ID** field on the Adapty Dashboard -> [Profiles](https://app.adapty.io/profiles/users) -> specific profile page. |
| customer_user_id  | String     | :heavy_plus_sign:  | The ID of your user in your system. You can see it in the **Customer user ID** field on the Adapty Dashboard -> [Profiles](https://app.adapty.io/profiles/users) -> specific profile page. It will work only if you [identify the users](identifying-users) in your mobile app code via Adapty SDK. |
| total_revenue_usd | Float      | :heavy_minus_sign: | A float value representing the total revenue in USD earned in the profile. |
| segment_hash      | String     | :heavy_minus_sign: | Internal parameter.                                          |
| timestamp         | Integer    | :heavy_minus_sign: | Response time in milliseconds, needs for resolve a race condition. |
| custom_attributes | Array      | :heavy_minus_sign: | <p>A maximum of 30 custom attributes to the profile are allowed to be set. If you provide the `custom_attributes` array, you must provide at least one attribute key.</p><p>**Key:** The key must be a string with no more than 30 characters. Only letters, numbers, dashes, points, and underscores allowed</p><p>**Value:** The attribute value must be no more than 30 characters. Only strings and floats are allowed as values, booleans will be converted to floats. Send an empty value or null to delete the attribute.</p> |
| access_levels     | Array      | :heavy_plus_sign:  | Array of [Access level](server-side-api-objects#access-level) objects. Can be null if the customer has no access levels. |
| subscriptions     | Array      | :heavy_plus_sign:  | Array of [Subscription](server-side-api-objects#subscription) objects. Can be null if the customer has no subscriptions. |
| non_subscriptions | Array      | :heavy_plus_sign:  | Array of [Non-Subscription](server-side-api-objects#non-subscription) objects. Can be null if the customer has no purchases. |

## Product

This object contains details about a product in Adapty.

| Name                           | Type    | Required | Description                                                  |
| ------------------------------ | ------- | -------- | ------------------------------------------------------------ |
| title                          | String  | No       | **Product name** from the [**Products**](https://app.adapty.io/products) section in the Adapty Dashboard. |
| is_consumable                  | Boolean | Yes      | Indicates whether the product is consumable.                 |
| adapty_product_id              | UUID    | No       | Internal product ID as used in Adapty.                       |
| vendor_product_id              | String  | Yes      | The product ID in app stores.                                |
| introductory_offer_eligibility | Boolean | No       | Specifies if the user is eligible for an iOS introductory offer. |
| promotional_offer_eligibility  | Boolean | No       | Specifies if the user is eligible for a promotional offer.   |
| base_plan_id                   | String  | No       | [Base plan ID](https://support.google.com/googleplay/android-developer/answer/12154973) for Google Play or [price ID](https://docs.stripe.com/products-prices/how-products-and-prices-work#use-products-and-prices) for Stripe. |
| offer                          | JSON    | No       | An [Offer](web-api-objects#offer-object) object as a JSON.   |

```json showLineNumbers
{
  "title": "Monthly Subscription w/o Trial",
  "is_consumable": true,
  "adapty_product_id": "InternalProductId",
  "vendor_product_id": "onemonth_no_trial",
  "introductory_offer_eligibility": false,
  "promotional_offer_eligibility": true,
  "base_plan_id": "B1",
  "offer": {
    "category": "promotional",
    "type": "pay_up_front",
    "id": "StoreOfferId"
  }
}

```

## RemoteConfig

This object contains information about a [remote config](customize-paywall-with-remote-config) for a paywall.

```json showLineNumbers
{
  "lang": "en",
  "data": "{\"bodyItems\":[{\"spacerValue\":{\"height\":20,\"style\":{\"type\":\"emptySpace\"}},\"type\":\"spacer\"},{\"mediaValue\":{\"ratio\":\"1:1\",\"source\":{\"fileType\":\"image\",\"reference\":{\"en\":\"bundle/images/new1.png\"}},\"widthStyle\":\"full\"},\"type\":\"media\"},{\"titleValue\":{\"alignment\":\"center\",\"subtitleConfig\":{\"fontSize\":17,\"text\":\"\",\"color\":\"#FFFFFF\"},\"titleConfig\":{\"fontSize\":22,\"text\":\"\"}},\"type\":\"title\"},{\"productListValue\":{\"items\":[{\"productId\":\"exampleapp.oneWeek\",\"promoText\":\"paywall.promo-1.title\",\"backgroundColor\":\"#0B867D\"},{\"discountRate\":80,\"productId\":\"exampleapp.oneYear\",\"promoText\":\"paywall.promo-2.title\",\"backgroundColor\":\"#0B867D\"}],\"layout\":\"vertical\"},\"type\":\"productList\"}],\"defaultProductId\":\"exampleapp.oneWeek\",\"footer\":{\"singleProductValue\":{\"customTitles\":{\"exampleapp.oneWeek\":\"Subscribe\",\"exampleapp.oneYear\":\"Subscribe\"},\"productId\":\"exampleapp.oneWeek\"},\"type\":\"singleProduct\"},\"id\":\"exampleapp\",\"isFullScreen\":true,\"settings\":{\"backgroundColor\":\"#000000\",\"closeButtonAlignment\":\"left\",\"closeButtonIconStyle\":\"light\",\"colorScheme\":{\"accent\":\"#007566\",\"background\":\"#001B0D\",\"label\":\"#FFFFFF\",\"primary\":\"#10C6B6\",\"secondaryLabel\":\"#FFFFFF\",\"seperator\":\"#FFFFFF\"},\"isFullScreen\":true,\"shouldShowAlertOnClose\":false,\"showCloseButtonAfter\":1,\"triggerPurchaseWithAlert\":false,\"triggerPurchaseWithProductChange\":false}}"
}

```

| Name | Type   | Required | Description                                                  |
| ---- | ------ | -------- | ------------------------------------------------------------ |
| lang | String | Yes      | <p>Locale code for the paywall localization. It uses language and region subtags separated by a hyphen (**-**).</p><p>Examples: `en` for English, `pt-br` for Brazilian Portuguese.</p><p>Refer to  [Localizations and locale codes](localizations-and-locale-codes) for more details.</p> |
| data | String | Yes      | Serialized JSON string representing the remote config of your paywall. You can find it in the **Remote Config** tab of a specific paywall in the Adapty Dashboard. |

## Subscription

Info about your end user subscription.  You can do the following action via Adapty server-side API:

- [Check the user's current subscription](api-adapty/operations/getProfile) by retrieving their profile details
- [Set transaction to your user](api-adapty/operations/setTransaction) and grant a subscription to them

| Parameter                     | Type          | Required | Nullable | Description                                                  |
| :---------------------------- | :------------ | -------- | -------- | :----------------------------------------------------------- |
| purchase_type                 | String        | Yes      | No       | The type of product purchased. Possible value: `subscription`. |
| store                         | String        | Yes      | No       | Store where the product was bought. Options include `app_store`, `play_store`, `stripe`, or the Store ID of your [custom store](custom-store). |
| environment                   | String        | No       | No       | Environment where the transaction took place. Options are `Sandbox` or `Production`. `Production` is used by default. |
| store_product_id              | String        | Yes      | No       | ID of the product in the app store (App Store, Google Play, Stripe, etc.) that unlocked this access level. |
| store_transaction_id          | String        | Yes      | No       | Transaction ID in the app store (App Store, Google Play, Stripe, etc.). |
| store_original_transaction_id | String        | Yes      | No       | <p>For subscriptions, this ID links to the first transaction in a renewal chain. Each renewal is connected to this original transaction.</p><p>If there's no renewal, `store_original_transaction_id` matches `store_transaction_id`.</p> |
| offer                         | Object        | No       | Yes      | The offer used in the purchase, provided as an [Offer](server-side-api-objects#offer) object. |
| is_family_shared              | Boolean       | No       | No       | A 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. `false` is used by default. |
| price                         | Object        | Yes      | No       | Price of the subscription or purchase as a [Price](server-side-api-objects#price) object. An initial subscription purchase with zero cost is a free trial; a renewal with zero cost is a free renewal. |
| purchased_at                  | ISO 8601 date | Yes      | No       | The datetime of the most recent access level purchase.       |
| refunded_at                   | ISO 8601 date | No       | No       | The datetime when the subscription was refunded, if applicable. |
| cancellation_reason           | String        | No       | No       | Possible reasons for cancellation include: `voluntarily_cancelled`, `billing_error`, `price_increase`, `product_was_not_available`, `refund`, `upgraded`, or `unknown`. |
| variation_id                  | String        | No       | No       | The variation ID used to trace purchases to the specific paywall they were made from. |
| originally_purchased_at       | ISO 8601 date | Yes      | No       | For subscription chains, this is the purchase date of the original transaction, linked by `store_original_transaction_id`. |
| expires_at                    | ISO 8601 date | Yes      | No       | The datetime when the access level expires. It may be in the past and `null` for lifetime access. |
| renew_status                  | Boolean       | Yes      | No       | Indicates if auto-renewal is enabled for the subscription.   |
| renew_status_changed_at       | ISO 8601 date | No       | No       | The datetime when auto-renewal was either enabled or disabled. |
| billing_issue_detected_at     | ISO 8601 date | No       | No       | The datetime when a billing issue was detected (e.g., a failed card charge). The subscription might still be active. This is cleared if the payment goes through. |
| grace_period_expires_at       | ISO 8601 date | No       | No       | The datetime when the [grace period](https://developer.apple.com/news/?id=09122019c) will end if the subscription is currently in one. |

:::note

Although the SDK includes the `is_active` parameter to check if a subscription is active, the server-side API does not provide this parameter. However, you can determine subscription status at any time by checking whether the current date falls between the `starts_at` and `expires_at` parameters of the [Access Level](#access-level) object.

:::