Events

17 subscription events that can be sent to 3rd party analytics and webhook. These events will help you to better understand the behavior of your subscribers

Apple and Google send subscription events directly to the server using App Store Server Notifications and Real-time Developer Notifications (RTDN). Therefore, mobile apps can not send events to analytical systems correctly and on-time. For example, if the user subscribed and then didn't open the app, without a server developer will get zero information about subscription status.

After installing Adapty SDK and setting up App Store Server Notifications for iOS and Real-time Developer Notifications (RTDN). for Android, Adapty receives info about your customer behavior and converts it into human-readable events.

📘

Adapty processes events into human-readable format instantly as they created and enriches them with additional information, such as customer ID, consecutive payments, store commission info, and others. Besides that Apple doesn't send events about subscription renewals but we do.

Events

Event NameDescription
subscription_initial_purchaseA user has activated a subscription without a trial period i.e. he was billed instantly
subscription_renewedA subscription was renewed and the user was charged. For both trial and non-trial subscriptions, this event is sent starting from the second billing
subscription_expiredA user has canceled a subscription and it is completely finished
trial_startedA user has activated a trial subscription
trial_convertedA trial period has ended and the user was billed, i.e. first purchase was made
trial_cancelledA trial has expired without converting to a subscription
non_subscription_purchaseAny non-subscription purchase e.g. lifetime access or consumable product such as coins
billing_issue_detectedAn attempt to charge the user was made, but a billing issue happened. Usually, it means the user doesn't have enough card balance
entered_grace_periodThe payment was not successful and the user entered into a grace period. The user still has access to the premium features of your app until the grace period is finished
auto_renew_offA user turned off subscription auto-renewal during the trial. A user still has access to premium features of your app until the end of the trial period
auto_renew_onA user turned on subscription auto-renewal during the trial period
auto_renew_off_subscriptionA user turned off subscription auto-renewal. A user still has access to the premium features of your app until the end of the subscription period
auto_renew_on_subscriptionA user turned on subscription auto-renewal
subscription_refundedA subscription was refunded (e.g. by Apple support)
non_subscription_purchase_refundedNon-subscription purchase was refunded
subscription_pausedUser activated subscription pause (Android only)
access_level_updatedUser's access level updated (Webhook only)

📘

SUBSCRIPTION_EXPIRED(previously SUBSCRIPTION_CANCELED) event means that the subscription completely finished and the user has no longer access to the premium features of the app. When the user unsubscribes, AUTO_RENEW_OFF or AUTO_RENEW_OFF_SUBSCRIPTION is sent. The same logic applied to TRIAL_CANCELLED.

The events above fully cover the users' state in terms of purchases. Let's look at some examples.

Example 1

The user has activated a monthly subscription on April 1st with 7 days trial. On the 4th day, he unsubscribed.

In that case following events will be sent:

  1. trial_started on April 1st
  2. auto_renew_off on 4th April
  3. trial_cancelled on 7th April

Example 2

The user has activated a monthly subscription on April 1st with 7 days trial. On the 10th day, he unsubscribed.

In that case following events will be sent:

  1. trial_started on April 1st
  2. trial_converted on April 7th
  3. auto_renew_off_subscription on April 10th
  4. subscription_cancelled on May 1st

Properties

Property Type Description
price_usd float Product price before Apple/Google cut. Revenue.
proceeds_usd float Product price after Apple/Google cut. Net revenue.
transaction_id str A unique identifier for a transaction such as a purchase or renewal.
original_transaction_id str The transaction identifier of the original purchase.
purchase_date ISO 8601 date The date and time of product purchase.
original_purchase_date ISO 8601 date The date and time of the original purchase.
environment str Could be Sandbox or Production.
vendor_product_id str Product id in Apple/Google store.
event_datetime ISO 8601 date The date and time of the event.
store str Could be app_store or play_store.
trial_duration str Duration of a trial period in days. Sent in a format "{} days" , for example, "7 days".
cancellation_reason str

A reason why the user canceled a subscription.

Can be
iOS & Android
voluntarily_cancelled, billing_error, refund
iOS
price_increase, product_was_not_available, unknown
Android
new_subscription_replace, cancelled_by_developer

subscription_expires_at ISO 8601 date The Expiration date of subscription. Usually in the future.
consecutive_payments int The number of periods, that a user is subscribed without interruptions. Includes the current period.
rate_after_first_year bool Boolean indicates that a vendor reduces cuts to 15%. Apple and Google have 30% first-year cut and 15% after it.
paywall_name str Name of the paywall where the transaction originated.
paywall_revision int Revision of the paywall where the transaction originated.
developer_id str Developer (SDK) ID of the paywall where the transaction originated.
ab_test_name str Name of the A/B test where the transaction originated.
ab_test_revision int Revision of the A/B test where the transaction originated.
profile_event_id uuid Unique event ID that can be used for deduplication.
store_country str Country sent to us by the store.
profile_country str Determined by Adapty, based on profile IP
profile_total_revenue_usd float Total revenue for the profile, refunds included.
variation_id uuid Unique ID of the paywall where the purchase was made.

Each event has the following properties:

transaction_id, original_transaction_id, purchase_date, original_purchase_date, environment, vendor_product_id, event_datetime, store

In addition, some events have additional properties. For the events subscription_refunded and non_subscription_purchase_refunded, it is mandatory to provide the values of price_usd and proceeds_usd as additional properties.

Event NameProperties
subscription_initial_purchaseprice_usd, proceeds_usd, subscription_expires_at, consecutive_payments, rate_after_first_year, trial_duration
subscription_renewedprice_usd, proceeds_usd, subscription_expires_at, consecutive_payments, rate_after_first_year, trial_duration
subscription_cancelledcancellation_reason, trial_duration
trial_startedsubscription_expires_at, trial_duration
trial_convertedprice_usd, proceeds_usd, subscription_expires_at, consecutive_payments, rate_after_first_year, trial_duration
trial_cancelledcancellation_reason, trial_duration
non_subscription_purchaseprice_usd, proceeds_usd
billing_issue_detectedsubscription_expires_at, trial_duration
entered_grace_periodsubscription_expires_at, trial_duration

Event example

{
    "price_usd": 9.99,
    "proceeds_usd": 6.99,
    "transaction_id": "1000000628581600",
    "original_transaction_id": "1000000628581600",
    "purchase_date": "2020-02-18T18:40:22.000000+0000",
    "original_purchase_date": "2020-02-18T18:40:22.000000+0000",
    "environment": "Sandbox",
    "vendor_product_id": "premium",
    "event_datetime": "2020-02-18T18:40:22.000000+0000",
    "store": "app_store"
}

Adapty sends events to your server and 3rd party analytical systems.

Access Level Updated

Adapty has a special event access_level_updated. It is sent only to webhook integration every time the access level is updated/set for a specific customer. Use this event to update a customer's subscription in your database/system. Before you had to keep track of several events to sync subscription state and some cases were not covered, like setting access level manually from Adapty CRM. Now, no matter what was the source of access level changes, you will always receive a dedicated event for that, therefore it's more precise and has more details than subscription_renewed, trial_started, entered_grace_period, etc.

1294
PropertyType
transaction_id str
original_transaction_id str
event_datetime ISO 8601 date
access_level_id str
is_active bool
is_lifetime bool
expires_at ISO 8601 date
starts_at ISO 8601 date
will_renew bool
vendor_product_id str
store str
activated_at ISO 8601 date
renewed_at ISO 8601 date
billing_issue_detected_at ISO 8601 date
is_in_grace_period bool
active_introductory_offer_type str
active_promotional_offer_type str
active_promotional_offer_id str
cancellation_reason str
is_refund bool

We don't send access_level_updated upon subscription expiration - please, refer to expires_at value to end the subscriptions on your side.

Sending Failed

We determine the deliverability based on http status and consider everything outside 200-399 range to be a fail.
If the event failed to reach the integration, Adapty will perform 3 more attempts to send it.
The intervals for each retry are 1, 3 and 5 minutes respectively.