Skip to main content

Set up webhook integration

Adapty webhook integration consists of the following steps:

  1. You set up your endpoint to have the Content-Type header as application/json.
  2. You configure the integration in the Adapty Dashboard. Within this step, you can optionally map Adapty events with your event names.
  3. Adapty sends a verification request to your server.
  4. Your server sends a verification response to Adapty
  5. Test your webhook integration.

Configure webhook integration in the Adapty Dashboard

Within Adapty, you can configure separate flows for production events and test events received from the Apple or Stripe sandbox environment or Google test account.

For production events, use the Production endpoint URL field specifying the URL to which the callbacks will be sent. Additionally, configure the Authorization header value for production endpoint field - the header for your server to authenticate Adapty events. Note that we'll use the value specified in the Authorization header value for production endpoint field as the Authorization header exactly as provided, without any changes or additions.

For test events, employ the Sandbox endpoint URL and Authorization header value for sandbox endpoint fields accordingly.

To set up the webhook integration:

  1. Open Integrations -> Webhook in your Adapty Dashboard.
  1. Turn on the toggle to initiate the integration.
  2. Fill out the integration fields:
FieldDescription
Production endpoint URLURL that is used by Adapty to send HTTP POST requests to this URL when events occur.
Authorization header value for production endpoint

The header that your server will use to authenticate requests from Adapty in production. Note that we'll use the value specified in this field as the Authorization header exactly as provided, without any changes or additions.

Although not mandatory, it's strongly recommended for enhanced security.

Additionally, for your testing needs in the staging environment, two other fields are available:

Testing fieldDescription
Sandbox endpoint URLAdapty will use this URL to send HTTP POST requests when events occur in the staging environment.
Authorization header value for sandbox endpoint

The header that your server will use to authenticate requests from Adapty during testing in the sandbox environment. Note that we'll use the value specified in this field as the Authorization header exactly as provided, without any changes or additions.

Although not mandatory, it's strongly recommended for enhanced security.

  1. Choose the events you want to receive and map their names.
  2. Additional fields and options are not obligatory; use them as needed.
  3. Remember to click the Save button to confirm the changes.

Please note that the moment you click the Save button, Adapty will send a verification request and will wait for your server verification response.

Choose events to send and map event names

Choose the events you want to receive in your server by enabling the toggle next to it. If your event names differ from those used in Adapty and you need to keep your names as is, you can set up the mapping by replacing the default Adapty event names with your own in the Events names section of the Integrations -> Webhooks page.

The event name can be any string. You cannot leave the fields empty for enabled events. If you accidentally removed Adapty event name, you can always copy the name from the Events to send to 3d-party integrations topic.

Adapty's verification request

After you enable webhook integration in the Adapty Dashboard, Adapty will automatically send a isMount POST verification request to your endpoint.

Json
{
adapty_check: {{check_string}}
}
note

Be sure your endpoint supports Content-Type: application/json header

Your server's verification response

Your server must reply with a 200 or 201 HTTP status code and send the response outlined below with the identical check_string.

Json
{
adapty_check_response: {{check_string}}
}

Once Adapty receives the verification response in the correct format, your Adapty webhook integration is fully configured.

From then on, Adapty will send the selected events to your specified URL as they happen. Ensure your server promptly confirms each Adapty event with a response status code in the 200-404 range.

Set up your server to process Adapty events

Webhook event structure

Adapty will send you those events you've chosen in the Events names section of the Integrations -> Webhooks page.

Each event is wrapped into the following structure:

Json
{
"profile_id": "772204ce-ebf6-4ed9-82b0-d8688ab62b01",
"customer_user_id": "john.doe",
"idfv": "00000000-0000-0000-0000-000000000000",
"idfa": "00000000-0000-0000-0000-000000000000",
"advertising_id": "00000000-0000-0000-0000-000000000000",
"profile_install_datetime": "2020-02-18T18:40:22.000000+0000",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
"email": "[email protected]",
"event_type": "non_subscription_purchase",
"event_datetime": "2023-02-18T18:40:22.000000+0000",
"event_properties": <event-specific properties>,
"event_api_version": 1,
"profiles_sharing_access_level": [{"profile_id": "f9e83cb0-0cf3-4e92-b1a4-733311fe5800", "customer_user_id": "[email protected]"}],
"attributions": {"attribution_source1": <attribution_data>, "attribution_source2": <attribution_data>, ...},
"user_attributes": {"attribute_name1": "attribute_value1", "attribute_name2": "attribute_value2", ...}
"integration_ids": {"firebase_app_instance_id": "val1", "branch_id": "val2", "one_signal_player_id": "val3", ... }
}

Event parameters

PropertyTypeDescription
profile_idStringThe Сustomer user ID of the profile in Adapty.
customer_user_idStringUser ID you use in your app to identify the user. For example, it can be your user UUID, email, or any other ID. Null if you didn't set it.
idfvStringThe identifier for vendors (IDFV) is a unique code assigned to all apps developed by a single developer, which in this case refers to your apps
idfaStringThe identifier for advertisers (IDFA) is a random device identifier assigned by Apple to a user's device.
advertising_idStringThe Advertising ID is a unique code assigned by the Android Operating System that advertisers might use to uniquely identify a user's device.
profile_install_datetimeISO 8601 date & timeInstallation date and time in format IOS 8601: starting with the year, followed by the month, the day, the hour, the minutes, seconds, and milliseconds. For example, 2020-07-10T15:00:00.000000+0000, represents the 10th of July 2020 at 3 p.m.
profiles_sharing_access_levelJSON

A list of objects, each containing the IDs of users who share the access level (including the current profile):

  • profile_id: (UUID4) The Adapty Profile ID sharing the access level, including the current profile.
  • customer_user_id: (string) The Customer User ID, if provided.

This is used when your app allows Sharing paid access between user accounts.

user_agentStringUser-agent used by the browser on the device.
emailStringE-mail of your user.
event_typeStringEvent name as set up in the in the Events names section of the Integrations -> Webhooks page in lowercase.
event_datetimeISO 8601 date & timeEvent date and time in format IOS 8601 : starting with the year, followed by the month, the day, the hour, the minutes, seconds, and milliseconds. For example, 2020-07-10T15:00:00.000000+0000, represents the 10th of July 2020 at 3 p.m.
event_propertiesJSONJSON of event properties.
event_api_versionIntegerAdapty API version. The current value is 1.
attributionsJSONJSON of attribution data.
user_attributesJSONJSON of custom user attributes.
integration_idsJSONJSON of user integration identifiers. If a user doesn't have any identifier or integrations are disabled, then a null is sent.
warning

Note that this structure may grow over time — with new data being introduced by us or by the 3rd parties we work with. Make sure that your code that processes it is robust enough and relies on the specific fields, but not on the structure as a whole.

Webhook integration enables the control of sending attribution and user attributes.

  • Enable the Send Attribution option in the Integrations -> Webhooks page to send the information about the source of app installs from data providers.
  • Enable the Send User Attributes option to send custom user attributes set up from the Adapty SDK, such as user preferences and app usage data.

Attribution data

If you've chosen to send attribution data, the following data will be sent with the event:

Field nameField typeDescription
network_user_idstrID assigned to the user by the attribution source.
statusstrCan be organic, non_organic or unknown.
created_atISO 8601 dateDate and time of attribution record creation.
channelstrMarketing channel name.
campaignstrMarketing campaign name.
ad_groupstrAttribution ad group.
ad_setstrAttribution ad set.
creativestrAttribution creative keyword.

Event properties

PropertyTypeDescription
profile_iduuidAdapty user ID.
currencystrLocal currency (defaults to USD).
price_usdfloatProduct price before Apple/Google cut. Revenue.
proceeds_usdfloatProduct price after Apple/Google cut. Net revenue.
net_revenue_usdfloatNet revenue (income after Apple/Google cut and taxes) in USD. Can be empty.
price_localfloatProduct price before Apple/Google cut in local currency. Revenue.
proceeds_localfloatProduct price after Apple/Google cut in local currency. Net revenue.
transaction_idstrA unique identifier for a transaction such as a purchase or renewal.
original_transaction_idstrThe transaction identifier of the original purchase.
purchase_dateISO 8601 dateThe date and time of product purchase.
original_purchase_dateISO 8601 dateThe date and time of the original purchase.
environmentstrCan be Sandbox or Production.
vendor_product_idstrProduct ID in the Apple App Store, Google Play Store, or Stripe.
base_plan_idstrBase plan ID in the Google Play Store or price ID in Stripe.
event_datetimeISO 8601 dateThe date and time of the event.
storestrCan be app_store or play_store.
trial_durationstrDuration of a trial period in days. Sent in a format " days" , for example, "7 days".
cancellation_reasonstr

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_atISO 8601 dateThe Expiration date of subscription. Usually in the future.
consecutive_paymentsintThe number of periods, that a user is subscribed to without interruptions. Includes the current period.
rate_after_first_yearboolBoolean indicates that a vendor reduces cuts to 15%. Apple and Google have 30% first-year cut and 15% after it.
promotional_offer_idstrID of promotional offer as indicated in the Product section of the Adapty Dashboard
store_offer_categorystrCan be introductory or promotional.
store_offer_discount_typestrCan be free_trial, pay_as_you_go or pay_up_front.
paywall_namestrName of the paywall where the transaction originated.
paywall_revisionintRevision of the paywall where the transaction originated. The value is set to 1.
developer_idstrDeveloper (SDK) ID of the placement where the transaction originated.
ab_test_namestrName of the A/B test where the transaction originated.
ab_test_revisionintRevision of the A/B test where the transaction originated. The value is set to 1.
cohort_namestrName of the audience to which the profile belongs to.
profile_event_iduuidUnique event ID that can be used for deduplication.
store_countrystrThe country sent to us by the store.
profile_ip_addressstrProfile IP (can be IPv4 or IPv6, with IPv4 preferred when available). It is updated each time IP of the device changes.
profile_countrystrDetermined by Adapty, based on profile IP.
profile_total_revenue_usdfloatTotal revenue for the profile, refunds included.
variation_iduuidUnique ID of the paywall where the purchase was made.
access_level_idstrPaid access level ID
is_activeboolBoolean indicating whether paid access level is active for the profile.
will_renewboolBoolean indicating whether paid access level will be renewed.
is_refundboolBoolean indicating whether transaction is refunded.
is_lifetimeboolBoolean indicating whether paid access level is lifetime.
is_in_grace_periodboolBoolean indicating whether profile is in grace period.
starts_atISO 8601 dateDate and time when paid access level starts for the user.
renewed_atISO 8601 dateDate and time when paid access will be renewed.
expires_atISO 8601 dateDate and time when paid access will expire.
activated_atISO 8601 dateDate and time when paid access was activated.
billing_issue_detected_atISO 8601 dateDate and time of billing issue.
profile_has_access_levelBoolA boolean that indicates whether the profile has an active access level.

Event properties 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",
"profile_has_access_level": true,
"store": "app_store"
}

Handle webhook events

Webhooks are typically delivered within 5 to 60 seconds of the event occurring. Cancellation events, however, may take up to 2 hours to be delivered after a user cancels their subscription.

If your server's response status code is outside the 200-404 range, Adapty will retry sending the event up to 9 times over 24 hours with exponential backoff. We suggest you set up your webhook to do only basic validation of the event body from Adapty before responding. If your server can't process the event and you don't want Adapty to retry, use a status code within the 200-404 range. Also, handle any time-consuming tasks asynchronously and respond to Adapty quickly. If Adapty doesn't receive a response within 10 seconds, it will consider the attempt a failure and will retry