Webhooks

Send in-app subscription and purchase events to your server with webhooks

Qonversion validates user receipts with app stores and sends subscription events to your HTTP endpoints.
Keep in mind events delivery time when using webhooks to manage subscriber statuses on your back-end. Webhook events are delivered within 20 to 120 seconds of the event occurring. Please consider using checkEntitlements method of Qonversion SDK to get real-time subscription status on the client-side.

1. Set up the webhook URL

  1. Navigate to the Integrations section in your Qonversion account and select Webhooks.
  2. Register your URL and Qonversion will send a request
  3. Press the "Add new integration" or "Save" button. If the endpoint server returns a 200 response code, the integration is activated.

2. Request format

Qonversion sends POST request to webhook URL every time an event occurs. The request header contains Authorization-Token Value as Basic authorization field. Use that to protect your server from unwanted requests.

☝️

SSL certificate

Remember, maintaining secure connections is essential for the integrity and reliability of your application's communication.

Ensure the SSL certificate used is not expired and your server's CA bundle is up-to-date to recognize the latest root CAs.

Request Header:

Authorization: Basic {Header Authorization-Token}
Accept: application/json

Request Body:

{
    "event_name": "trial_converted",
    "user_id": "3YjIDEUDaf_5g4IdWw6zcMlLgfg_YQp2",
    "custom_user_id": "",
    "identity_id": "",
    "advertiser_id": "9FD1767D-8B48-45BD-A2F4-1C08B08E56F2",
    "time": 1600000000,
    "created_at": 1600000000,
    "product_id": "com.myapp.subs.9.99.trial",
    "revenue": {
        "value": 7.99,
        "value_usd": 9.99,
        "currency": "GBP",
        "is_proceed": 0,
        "proceeds_rate": 70
    },
    "price": {
        "value": 7.99,
        "value_usd": 9.99,
        "currency": "GBP"
    },
    "transaction": {
        "transaction_id": 500000601234560,
        "original_transaction_id": 500000601234560,
        "expires": 1600259200,
        "grace_period_expires": null,
        "transaction_date": 1600004000
    },
    "properties": {
        "_q_email": "[email protected]"
    },
    "device_id": "0E66565D-4F3A-E366-B3D4-B5DDAC6BBE2E",
    "app_version": "2.1.4",
    "sdk_version": "3.1.0",
    "environment": "production",
    "platform": "iOS",
    "ip": "10.0.0.1",
    "country": "GB",
    "old_product_id": "com.myapp.subs.4.99.trial",
    "new_product_id": "com.myapp.subs.9.99.trial",
    "locale": "en_US",
    "subscription_group": "784563",
    "user_install_date": 1600000000,
    "project_name": "Sample App",
    "app_id": "com.sample.app",
    "quantity": 3,
    "subscription_renew_count": 5,
    "entitlements": [
        {
            "active": true,
            "expires": 1654215637,
            "id": "plus",
            "product": {
                "product_id": "main",
                "subscription": {
                    "current_period_type": "normal",
                    "renew_state": "will_renew"
                }
            },
            "source": "stripe",
            "started": 1652438020
        }
    ],
    "asa_attribution": {
        "org_id": 1234567890,
        "campaign_id": 1234567890,
        "adgroup_id": 1234567890,
        "keyword_id": 1234567890,
        "ad_id": 1234567890,
        "country_or_region": "DE",
        "conversion_type": "Download",
        "click_date": "2024-08-21T16:10Z"
    }
}

Column

Required

Description

event_name

yes

Event name provided in the integration config.
See the details on the events tracked here

user_id

yes

Unique user identifier assigned by Qonversion

custom_user_id

yes

Unique user identifier that you can set with Qonversion SDK methods: User Identifiers

identity_id

yes

Unique user ID for the authenticated users that you can set using identify method of the Qonversion SDK

advertiser_id

yes

IDFA or AAID

time

yes

The time an app store changed a subscription status or a time Qonversion detected the change in the UNIX epoch time format in seconds. Read more about events time here

created_at

yes

The time Qonversion generated the event

product_id

yes

App Store or Google Play Store product identifier

revenue

yes

Dictionary with transaction revenue details. Only events with value filled

price

yes

Dictionary containing the price details of the product

transaction

yes

Dictionary with store transaction IDs and expiration timestamp

properties

yes

User properties provided by SDK. Read more about user properties here

device_id

yes

identifierForVendor or Settings Secure Android ID.

app_version

no

Application version.

sdk_version

no

Qonversion SDK version.

environment

yes

"production" or "sandbox".

platform

yes

"iOS" or "Android".

ip

yes

Application device IP address.

country

yes

A two-letter code representing a country, defined by the ISO 3166-1 alpha-2 standard, is determined on the Cloud provider's side based on the IP address of the incoming request.

old_product_id

no

Previous product (for product change events).

new_product_id

no

New product (for product change events).

locale

yes

A two-letter code representing a device language based on the device locale.

subscription_group

yes

subscription_group_identifier for iOS or Google base_plan_id for Android.

user_install_date

yes

Timestamp when the user last installed the application.

project_name

yes

The project name of your app from the Qonversion dashboard.

app_id

yes

Store App Id. App Store ID for iOS or Android Package Name for Android.

quantity

yes

Number of consumable in-app purchases. For non-consumable items or subscriptions, it will always return 1.

subscription_renew_count

yes

This represents the total number of times a user's subscription has been renewed.

entitlements

yes

Array of granted user entitlements. Entity's fields are synchronized with our public API.

asa_attribution

no

Dictionary with Apple Search Ads attribution details. Only for events for users who were attributed with the ad.

Revenue and price fields

There are 3 fields that contain transaction details:

  • The revenue field contains a dictionary with details depending on your integration setting Send sales as proceed.
  • The price field always contains a gross price that is charged to a user.
  • The transaction field contains params of the transaction related to the event.

Revenue

Column

Required

Description

value

yes

Value in user's currency

value_usd

yes

Value in USD

currency

yes

Three-letter ISO currency code

is_proceed

yes

1 – if value and value_usd are net excluding app stores' commission;
0 - if values are before deducting app stores commission;

proceeds_rate

yes

70 or 85; Proceeds rate that developer receives after deducting app stores commission.

Price

ColumnRequiredDescription
valueyesValue in user's currency
value_usdyesValue in USD
currencyyesThree-letter ISO currency code

Transaction

Column

Required

Description

transaction_id

yes

Transaction_id from App Store (e.g. 521456677817903) or Play Store (e.g. GPA.4563-9870-7648-87395)

original_transaction_id

yes

Transaction_id from App Store (e.g. 521456677817903) or Play Store (e.g. GPA.4563-9870-7648-87395)

expires

yes

Expire timestamp for purchase, prolong or product change events, event timestamp for refund or upgrade events.

grace_period_expires

yes

Grace period expiration timestamp.
This field returns the timestamp for the grace period expiration.

transaction_date

yes

Timestamp when the transaction was made.

🚧

For the Billing Issue, Trial Canceled, Subscription Canceled, Subscription Upgraded events, the transaction_id field will be the same as for the previous related event.
For the Subscription Renewed, Subscription Downgraded, Subscription Product Changed events, we're sending a newer transaction_id.

Apple Search Ads attribution fields

You need to set up Apple Search Ads integration first, then we will send ASA attribution with all new events for only attributed users. The data in the table below can be found in the asa_attribution field.

{
  ...
  "asa_attribution": {
    "org_id": 1234567890,
    "campaign_id": 1234567890,
    "adgroup_id": 1234567890,
    "keyword_id": 1234567890,
    "ad_id": 1234567890,
    "country_or_region": "DE",
    "conversion_type": "Download",
    "click_date": "2024-08-21T16:10Z"
  }
}

Column

Required

Description

org_id

yes

The identifier of the Organization or Campaign group Id that owns the campaign.

campaign_id

yes

The unique identifier for the campaign.

adgroup_id

yes

The identifier for the ad group.

keyword_id

no

The identifier for the keyword.

ad_id

yes

The identifier representing the assignment relationship between an ad object and an ad group.

country_or_region

yes

The country or region for the campaign.

conversion_type

yes

The type of conversion is either Download or Redownload.

click_date

no

The date and time when the user clicks an ad in a corresponding campaign.
Available only if a user accepts App Tracking Transparency (ATT).

Learn more about fileds from Apple AdSevices documentation.

Retries between Qonversion and Destination Server

Qonversion increases the delivery rate to your server with retries. Retries happen automatically if your server is not responding. This substantially improves the data delivery rate.
Qonversion retries failed destination calls for 24 hours with an increased delay after each attempt. Retries have the following schedule:

AttemptDelay
1Immediately
25 minutes
34 hours
48 hours
524 hours